LDAP_MATCHING_RULE_IN_CHAIN not working with default AD groups - Domain Users





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















In my program, I need to fetch all the AD groups for a user.
The current version of my program uses System.DirectoryServices.AccountManagement.UserPrincipal.GetAuthorizationGroups.



This works good until we had a new customer with a much largeer AD. There it is really slow. (Up to 60 seconds)



Now I've been looking around, and saw the posts that the AccountManagement is easy to use, but slow.



I also found that LDAP_MATCHING_RULE_IN_CHAIN should also fetch all the nested groups that a user is member of. And is more performant.



From this link.



But I'm having an issue with the default groups that in AD exists.



For example the group "Domain Users" is not returned by the function.
They also have a group "BDOC" that as member have "Domain Users". That group is also not returned.



Trough the GetAuthorizationGroups it is returned correct.



I'm using following code to fetch the groups by user.



VB.NET:



Dim strFilter As String = String.Format("(member:1.2.840.113556.1.4.1941:={0})", oUserPrincipal.DistinguishedName)
Dim objSearcher As New DirectoryServices.DirectorySearcher("LDAP://" & oLDAPAuthenticationDetail.Domain & If(Not String.IsNullOrWhiteSpace(oLDAPAuthenticationDetail.Container), oLDAPAuthenticationDetail.Container, String.Empty))
objSearcher.PageSize = 1000
objSearcher.Filter = strFilter
objSearcher.SearchScope = DirectoryServices.SearchScope.Subtree
objSearcher.PropertiesToLoad.Add(sPropGuid)
objSearcher.PropertiesToLoad.Add(sPropDisplayName)


Dim colResults As DirectoryServices.SearchResultCollection = objSearcher.FindAll()


Afterwards I was testing with the script from the link, if it was possible to fetch all the users from the Domain Users group, by changing the "member" to "memberOf" in the filter.
When I put the Domain Admins group in the filter, it shows the admins correct.
When I put the Domain Users group in the filter, it returns nothing.



Powershell:



$userdn = 'CN=Domain Users,CN=Users,DC=acbenelux,DC=local'
$strFilter = "(memberOf:1.2.840.113556.1.4.1941:=$userdn)"
$objDomain = New-Object System.DirectoryServices.DirectoryEntry("LDAP://rootDSE")
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = "LDAP://$($objDomain.rootDomainNamingContext)"
$objSearcher.PageSize = 1000
$objSearcher.Filter = $strFilter
$objSearcher.SearchScope = "Base"
$colProplist = "name"
foreach ($i in $colPropList)
{
$objSearcher.PropertiesToLoad.Add($i) > $nul
}
$colResults = $objSearcher.FindAll()
foreach ($objResult in $colResults)
{
$objItem = $objResult.Properties
$objItem.name
}


I don't know what I'm doing wrong. Or is it maybe just not possible to fetch the "default groups" with that filter?
What is a good alternative then?










share|improve this question





























    0















    In my program, I need to fetch all the AD groups for a user.
    The current version of my program uses System.DirectoryServices.AccountManagement.UserPrincipal.GetAuthorizationGroups.



    This works good until we had a new customer with a much largeer AD. There it is really slow. (Up to 60 seconds)



    Now I've been looking around, and saw the posts that the AccountManagement is easy to use, but slow.



    I also found that LDAP_MATCHING_RULE_IN_CHAIN should also fetch all the nested groups that a user is member of. And is more performant.



    From this link.



    But I'm having an issue with the default groups that in AD exists.



    For example the group "Domain Users" is not returned by the function.
    They also have a group "BDOC" that as member have "Domain Users". That group is also not returned.



    Trough the GetAuthorizationGroups it is returned correct.



    I'm using following code to fetch the groups by user.



    VB.NET:



    Dim strFilter As String = String.Format("(member:1.2.840.113556.1.4.1941:={0})", oUserPrincipal.DistinguishedName)
    Dim objSearcher As New DirectoryServices.DirectorySearcher("LDAP://" & oLDAPAuthenticationDetail.Domain & If(Not String.IsNullOrWhiteSpace(oLDAPAuthenticationDetail.Container), oLDAPAuthenticationDetail.Container, String.Empty))
    objSearcher.PageSize = 1000
    objSearcher.Filter = strFilter
    objSearcher.SearchScope = DirectoryServices.SearchScope.Subtree
    objSearcher.PropertiesToLoad.Add(sPropGuid)
    objSearcher.PropertiesToLoad.Add(sPropDisplayName)


    Dim colResults As DirectoryServices.SearchResultCollection = objSearcher.FindAll()


    Afterwards I was testing with the script from the link, if it was possible to fetch all the users from the Domain Users group, by changing the "member" to "memberOf" in the filter.
    When I put the Domain Admins group in the filter, it shows the admins correct.
    When I put the Domain Users group in the filter, it returns nothing.



    Powershell:



    $userdn = 'CN=Domain Users,CN=Users,DC=acbenelux,DC=local'
    $strFilter = "(memberOf:1.2.840.113556.1.4.1941:=$userdn)"
    $objDomain = New-Object System.DirectoryServices.DirectoryEntry("LDAP://rootDSE")
    $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
    $objSearcher.SearchRoot = "LDAP://$($objDomain.rootDomainNamingContext)"
    $objSearcher.PageSize = 1000
    $objSearcher.Filter = $strFilter
    $objSearcher.SearchScope = "Base"
    $colProplist = "name"
    foreach ($i in $colPropList)
    {
    $objSearcher.PropertiesToLoad.Add($i) > $nul
    }
    $colResults = $objSearcher.FindAll()
    foreach ($objResult in $colResults)
    {
    $objItem = $objResult.Properties
    $objItem.name
    }


    I don't know what I'm doing wrong. Or is it maybe just not possible to fetch the "default groups" with that filter?
    What is a good alternative then?










    share|improve this question

























      0












      0








      0








      In my program, I need to fetch all the AD groups for a user.
      The current version of my program uses System.DirectoryServices.AccountManagement.UserPrincipal.GetAuthorizationGroups.



      This works good until we had a new customer with a much largeer AD. There it is really slow. (Up to 60 seconds)



      Now I've been looking around, and saw the posts that the AccountManagement is easy to use, but slow.



      I also found that LDAP_MATCHING_RULE_IN_CHAIN should also fetch all the nested groups that a user is member of. And is more performant.



      From this link.



      But I'm having an issue with the default groups that in AD exists.



      For example the group "Domain Users" is not returned by the function.
      They also have a group "BDOC" that as member have "Domain Users". That group is also not returned.



      Trough the GetAuthorizationGroups it is returned correct.



      I'm using following code to fetch the groups by user.



      VB.NET:



      Dim strFilter As String = String.Format("(member:1.2.840.113556.1.4.1941:={0})", oUserPrincipal.DistinguishedName)
      Dim objSearcher As New DirectoryServices.DirectorySearcher("LDAP://" & oLDAPAuthenticationDetail.Domain & If(Not String.IsNullOrWhiteSpace(oLDAPAuthenticationDetail.Container), oLDAPAuthenticationDetail.Container, String.Empty))
      objSearcher.PageSize = 1000
      objSearcher.Filter = strFilter
      objSearcher.SearchScope = DirectoryServices.SearchScope.Subtree
      objSearcher.PropertiesToLoad.Add(sPropGuid)
      objSearcher.PropertiesToLoad.Add(sPropDisplayName)


      Dim colResults As DirectoryServices.SearchResultCollection = objSearcher.FindAll()


      Afterwards I was testing with the script from the link, if it was possible to fetch all the users from the Domain Users group, by changing the "member" to "memberOf" in the filter.
      When I put the Domain Admins group in the filter, it shows the admins correct.
      When I put the Domain Users group in the filter, it returns nothing.



      Powershell:



      $userdn = 'CN=Domain Users,CN=Users,DC=acbenelux,DC=local'
      $strFilter = "(memberOf:1.2.840.113556.1.4.1941:=$userdn)"
      $objDomain = New-Object System.DirectoryServices.DirectoryEntry("LDAP://rootDSE")
      $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
      $objSearcher.SearchRoot = "LDAP://$($objDomain.rootDomainNamingContext)"
      $objSearcher.PageSize = 1000
      $objSearcher.Filter = $strFilter
      $objSearcher.SearchScope = "Base"
      $colProplist = "name"
      foreach ($i in $colPropList)
      {
      $objSearcher.PropertiesToLoad.Add($i) > $nul
      }
      $colResults = $objSearcher.FindAll()
      foreach ($objResult in $colResults)
      {
      $objItem = $objResult.Properties
      $objItem.name
      }


      I don't know what I'm doing wrong. Or is it maybe just not possible to fetch the "default groups" with that filter?
      What is a good alternative then?










      share|improve this question














      In my program, I need to fetch all the AD groups for a user.
      The current version of my program uses System.DirectoryServices.AccountManagement.UserPrincipal.GetAuthorizationGroups.



      This works good until we had a new customer with a much largeer AD. There it is really slow. (Up to 60 seconds)



      Now I've been looking around, and saw the posts that the AccountManagement is easy to use, but slow.



      I also found that LDAP_MATCHING_RULE_IN_CHAIN should also fetch all the nested groups that a user is member of. And is more performant.



      From this link.



      But I'm having an issue with the default groups that in AD exists.



      For example the group "Domain Users" is not returned by the function.
      They also have a group "BDOC" that as member have "Domain Users". That group is also not returned.



      Trough the GetAuthorizationGroups it is returned correct.



      I'm using following code to fetch the groups by user.



      VB.NET:



      Dim strFilter As String = String.Format("(member:1.2.840.113556.1.4.1941:={0})", oUserPrincipal.DistinguishedName)
      Dim objSearcher As New DirectoryServices.DirectorySearcher("LDAP://" & oLDAPAuthenticationDetail.Domain & If(Not String.IsNullOrWhiteSpace(oLDAPAuthenticationDetail.Container), oLDAPAuthenticationDetail.Container, String.Empty))
      objSearcher.PageSize = 1000
      objSearcher.Filter = strFilter
      objSearcher.SearchScope = DirectoryServices.SearchScope.Subtree
      objSearcher.PropertiesToLoad.Add(sPropGuid)
      objSearcher.PropertiesToLoad.Add(sPropDisplayName)


      Dim colResults As DirectoryServices.SearchResultCollection = objSearcher.FindAll()


      Afterwards I was testing with the script from the link, if it was possible to fetch all the users from the Domain Users group, by changing the "member" to "memberOf" in the filter.
      When I put the Domain Admins group in the filter, it shows the admins correct.
      When I put the Domain Users group in the filter, it returns nothing.



      Powershell:



      $userdn = 'CN=Domain Users,CN=Users,DC=acbenelux,DC=local'
      $strFilter = "(memberOf:1.2.840.113556.1.4.1941:=$userdn)"
      $objDomain = New-Object System.DirectoryServices.DirectoryEntry("LDAP://rootDSE")
      $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
      $objSearcher.SearchRoot = "LDAP://$($objDomain.rootDomainNamingContext)"
      $objSearcher.PageSize = 1000
      $objSearcher.Filter = $strFilter
      $objSearcher.SearchScope = "Base"
      $colProplist = "name"
      foreach ($i in $colPropList)
      {
      $objSearcher.PropertiesToLoad.Add($i) > $nul
      }
      $colResults = $objSearcher.FindAll()
      foreach ($objResult in $colResults)
      {
      $objItem = $objResult.Properties
      $objItem.name
      }


      I don't know what I'm doing wrong. Or is it maybe just not possible to fetch the "default groups" with that filter?
      What is a good alternative then?







      vb.net powershell active-directory ldap






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 23 '18 at 18:52









      StinusStinus

      761213




      761213
























          1 Answer
          1






          active

          oldest

          votes


















          1














          The default group is odd. It is not stored in memberOf, or even in the member attribute of the group. That's why your search won't find it. The default group is determined by the primaryGroupId of the user. That attribute stores the RID (the last part of the SID) of the group. It's kind of dumb, I know :)



          I actually wrote an article about the 3 (yes 3) different ways someone can be a member of a group: What makes a member a member?



          I also wrote an article about getting all of the groups a single user belongs to, and how to account for all 3 ways: Finding all of a user’s groups



          For example, here is the C# code I put in that article about how to find the name of the primary group for a user (given a DirectoryEntry). It shouldn't be too hard to translate that to VB.NET:



          private static string GetUserPrimaryGroup(DirectoryEntry de) {
          de.RefreshCache(new {"primaryGroupID", "objectSid"});

          //Get the user's SID as a string
          var sid = new SecurityIdentifier((byte)de.Properties["objectSid"].Value, 0).ToString();

          //Replace the RID portion of the user's SID with the primaryGroupId
          //so we're left with the group's SID
          sid = sid.Remove(sid.LastIndexOf("-", StringComparison.Ordinal) + 1);
          sid = sid + de.Properties["primaryGroupId"].Value;

          //Find the group by its SID
          var group = new DirectoryEntry($"LDAP://<SID={sid}>");
          group.RefreshCache(new {"cn"});

          return group.Properties["cn"].Value as string;
          }


          You are right that the AccountManagement namespace makes things easy, but it really does have terrible performance sometimes. I never use it anymore. I find that DirectoryEntry/DirectorySearcher gives you much more control of how often your code makes calls out to AD.



          I have been meaning to write an article about writing high performance code with DirectoryEntry, but I haven't gotten around to it yet.



          Update: So if you need the nested groups for the user, including membership through the primary group, then you can find the primary group first, then do an LDAP_MATCHING_RULE_IN_CHAIN search for groups that have both the user and the primary group as members:



           (|(member:1.2.840.113556.1.4.1941:={userDN})(member:1.2.840.113556.1.4.1941:={primaryGroupDN}))


          Update: If you want to include Authenticated Users in your search (edit the DC portion of the distinguishedName):



           (|(member:1.2.840.113556.1.4.1941:=CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=domain,DC=com)(member:1.2.840.113556.1.4.1941:={userDN})(member:1.2.840.113556.1.4.1941:={primaryGroupDN})


          Note that you can also use the tokenGroups attribute of a user to find out all of the authentication groups for a user. The tokenGroups attribute is a constructed attribute, so you only get it if you specifically ask for it (with DirectoryEntry.RefreshCache() or, in a search, add it to DirectorySearcher.PropertiesToLoad.



          The caveat is that tokenGroups is a list of SIDs, not distinguishedName, but you can bind directly to an object using the SID with the LDAP://<SID={sid}> syntax.






          share|improve this answer


























          • Thanks for the great post. I've tested the functions, and in my company we only have 1 domain. So I can't test the trusted domains part. But I still have an issue with "A nested group who has the primary group as member". From the example I can find what the primary group is for a user. But take following example: user sgielen has as primairy group Domain Users. Domain Users is member of Group A, and Group A is member of Group B. How to get Domain Users+Group A+Group B?

            – Stinus
            Nov 24 '18 at 13:07













          • There is no way to do that in one search. But after you find the primary group, you can use that in your search. I updated my answer with an example.

            – Gabriel Luci
            Nov 24 '18 at 17:57











          • Thanks, that was exactly what I needed. In my company AD (30,32 sec -> 1,02 sec) But I have 1 wierd thing in my company's AD. From the GetAuthorizationGroups I get that my User is in the following groups. But my user is not in them. CN=Administrators,CN=Builtin,DC=acbenelux,DC=local CN=Users,CN=Builtin,DC=acbenelux,DC=local Any idea how that would happen?

            – Stinus
            Nov 26 '18 at 6:46











          • The Users group likely has Authenticated Users in it, which is one of the "well-known SIDs" that have special meaning. I can't say why the Adminstrators group is showing up, but check it in AD and see what its members are. It's possible there is a similar thing going on there.

            – Gabriel Luci
            Nov 26 '18 at 13:28













          • I made an update to my answer with some more information.

            – Gabriel Luci
            Nov 26 '18 at 13:38












          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53451706%2fldap-matching-rule-in-chain-not-working-with-default-ad-groups-domain-users%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          The default group is odd. It is not stored in memberOf, or even in the member attribute of the group. That's why your search won't find it. The default group is determined by the primaryGroupId of the user. That attribute stores the RID (the last part of the SID) of the group. It's kind of dumb, I know :)



          I actually wrote an article about the 3 (yes 3) different ways someone can be a member of a group: What makes a member a member?



          I also wrote an article about getting all of the groups a single user belongs to, and how to account for all 3 ways: Finding all of a user’s groups



          For example, here is the C# code I put in that article about how to find the name of the primary group for a user (given a DirectoryEntry). It shouldn't be too hard to translate that to VB.NET:



          private static string GetUserPrimaryGroup(DirectoryEntry de) {
          de.RefreshCache(new {"primaryGroupID", "objectSid"});

          //Get the user's SID as a string
          var sid = new SecurityIdentifier((byte)de.Properties["objectSid"].Value, 0).ToString();

          //Replace the RID portion of the user's SID with the primaryGroupId
          //so we're left with the group's SID
          sid = sid.Remove(sid.LastIndexOf("-", StringComparison.Ordinal) + 1);
          sid = sid + de.Properties["primaryGroupId"].Value;

          //Find the group by its SID
          var group = new DirectoryEntry($"LDAP://<SID={sid}>");
          group.RefreshCache(new {"cn"});

          return group.Properties["cn"].Value as string;
          }


          You are right that the AccountManagement namespace makes things easy, but it really does have terrible performance sometimes. I never use it anymore. I find that DirectoryEntry/DirectorySearcher gives you much more control of how often your code makes calls out to AD.



          I have been meaning to write an article about writing high performance code with DirectoryEntry, but I haven't gotten around to it yet.



          Update: So if you need the nested groups for the user, including membership through the primary group, then you can find the primary group first, then do an LDAP_MATCHING_RULE_IN_CHAIN search for groups that have both the user and the primary group as members:



           (|(member:1.2.840.113556.1.4.1941:={userDN})(member:1.2.840.113556.1.4.1941:={primaryGroupDN}))


          Update: If you want to include Authenticated Users in your search (edit the DC portion of the distinguishedName):



           (|(member:1.2.840.113556.1.4.1941:=CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=domain,DC=com)(member:1.2.840.113556.1.4.1941:={userDN})(member:1.2.840.113556.1.4.1941:={primaryGroupDN})


          Note that you can also use the tokenGroups attribute of a user to find out all of the authentication groups for a user. The tokenGroups attribute is a constructed attribute, so you only get it if you specifically ask for it (with DirectoryEntry.RefreshCache() or, in a search, add it to DirectorySearcher.PropertiesToLoad.



          The caveat is that tokenGroups is a list of SIDs, not distinguishedName, but you can bind directly to an object using the SID with the LDAP://<SID={sid}> syntax.






          share|improve this answer


























          • Thanks for the great post. I've tested the functions, and in my company we only have 1 domain. So I can't test the trusted domains part. But I still have an issue with "A nested group who has the primary group as member". From the example I can find what the primary group is for a user. But take following example: user sgielen has as primairy group Domain Users. Domain Users is member of Group A, and Group A is member of Group B. How to get Domain Users+Group A+Group B?

            – Stinus
            Nov 24 '18 at 13:07













          • There is no way to do that in one search. But after you find the primary group, you can use that in your search. I updated my answer with an example.

            – Gabriel Luci
            Nov 24 '18 at 17:57











          • Thanks, that was exactly what I needed. In my company AD (30,32 sec -> 1,02 sec) But I have 1 wierd thing in my company's AD. From the GetAuthorizationGroups I get that my User is in the following groups. But my user is not in them. CN=Administrators,CN=Builtin,DC=acbenelux,DC=local CN=Users,CN=Builtin,DC=acbenelux,DC=local Any idea how that would happen?

            – Stinus
            Nov 26 '18 at 6:46











          • The Users group likely has Authenticated Users in it, which is one of the "well-known SIDs" that have special meaning. I can't say why the Adminstrators group is showing up, but check it in AD and see what its members are. It's possible there is a similar thing going on there.

            – Gabriel Luci
            Nov 26 '18 at 13:28













          • I made an update to my answer with some more information.

            – Gabriel Luci
            Nov 26 '18 at 13:38
















          1














          The default group is odd. It is not stored in memberOf, or even in the member attribute of the group. That's why your search won't find it. The default group is determined by the primaryGroupId of the user. That attribute stores the RID (the last part of the SID) of the group. It's kind of dumb, I know :)



          I actually wrote an article about the 3 (yes 3) different ways someone can be a member of a group: What makes a member a member?



          I also wrote an article about getting all of the groups a single user belongs to, and how to account for all 3 ways: Finding all of a user’s groups



          For example, here is the C# code I put in that article about how to find the name of the primary group for a user (given a DirectoryEntry). It shouldn't be too hard to translate that to VB.NET:



          private static string GetUserPrimaryGroup(DirectoryEntry de) {
          de.RefreshCache(new {"primaryGroupID", "objectSid"});

          //Get the user's SID as a string
          var sid = new SecurityIdentifier((byte)de.Properties["objectSid"].Value, 0).ToString();

          //Replace the RID portion of the user's SID with the primaryGroupId
          //so we're left with the group's SID
          sid = sid.Remove(sid.LastIndexOf("-", StringComparison.Ordinal) + 1);
          sid = sid + de.Properties["primaryGroupId"].Value;

          //Find the group by its SID
          var group = new DirectoryEntry($"LDAP://<SID={sid}>");
          group.RefreshCache(new {"cn"});

          return group.Properties["cn"].Value as string;
          }


          You are right that the AccountManagement namespace makes things easy, but it really does have terrible performance sometimes. I never use it anymore. I find that DirectoryEntry/DirectorySearcher gives you much more control of how often your code makes calls out to AD.



          I have been meaning to write an article about writing high performance code with DirectoryEntry, but I haven't gotten around to it yet.



          Update: So if you need the nested groups for the user, including membership through the primary group, then you can find the primary group first, then do an LDAP_MATCHING_RULE_IN_CHAIN search for groups that have both the user and the primary group as members:



           (|(member:1.2.840.113556.1.4.1941:={userDN})(member:1.2.840.113556.1.4.1941:={primaryGroupDN}))


          Update: If you want to include Authenticated Users in your search (edit the DC portion of the distinguishedName):



           (|(member:1.2.840.113556.1.4.1941:=CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=domain,DC=com)(member:1.2.840.113556.1.4.1941:={userDN})(member:1.2.840.113556.1.4.1941:={primaryGroupDN})


          Note that you can also use the tokenGroups attribute of a user to find out all of the authentication groups for a user. The tokenGroups attribute is a constructed attribute, so you only get it if you specifically ask for it (with DirectoryEntry.RefreshCache() or, in a search, add it to DirectorySearcher.PropertiesToLoad.



          The caveat is that tokenGroups is a list of SIDs, not distinguishedName, but you can bind directly to an object using the SID with the LDAP://<SID={sid}> syntax.






          share|improve this answer


























          • Thanks for the great post. I've tested the functions, and in my company we only have 1 domain. So I can't test the trusted domains part. But I still have an issue with "A nested group who has the primary group as member". From the example I can find what the primary group is for a user. But take following example: user sgielen has as primairy group Domain Users. Domain Users is member of Group A, and Group A is member of Group B. How to get Domain Users+Group A+Group B?

            – Stinus
            Nov 24 '18 at 13:07













          • There is no way to do that in one search. But after you find the primary group, you can use that in your search. I updated my answer with an example.

            – Gabriel Luci
            Nov 24 '18 at 17:57











          • Thanks, that was exactly what I needed. In my company AD (30,32 sec -> 1,02 sec) But I have 1 wierd thing in my company's AD. From the GetAuthorizationGroups I get that my User is in the following groups. But my user is not in them. CN=Administrators,CN=Builtin,DC=acbenelux,DC=local CN=Users,CN=Builtin,DC=acbenelux,DC=local Any idea how that would happen?

            – Stinus
            Nov 26 '18 at 6:46











          • The Users group likely has Authenticated Users in it, which is one of the "well-known SIDs" that have special meaning. I can't say why the Adminstrators group is showing up, but check it in AD and see what its members are. It's possible there is a similar thing going on there.

            – Gabriel Luci
            Nov 26 '18 at 13:28













          • I made an update to my answer with some more information.

            – Gabriel Luci
            Nov 26 '18 at 13:38














          1












          1








          1







          The default group is odd. It is not stored in memberOf, or even in the member attribute of the group. That's why your search won't find it. The default group is determined by the primaryGroupId of the user. That attribute stores the RID (the last part of the SID) of the group. It's kind of dumb, I know :)



          I actually wrote an article about the 3 (yes 3) different ways someone can be a member of a group: What makes a member a member?



          I also wrote an article about getting all of the groups a single user belongs to, and how to account for all 3 ways: Finding all of a user’s groups



          For example, here is the C# code I put in that article about how to find the name of the primary group for a user (given a DirectoryEntry). It shouldn't be too hard to translate that to VB.NET:



          private static string GetUserPrimaryGroup(DirectoryEntry de) {
          de.RefreshCache(new {"primaryGroupID", "objectSid"});

          //Get the user's SID as a string
          var sid = new SecurityIdentifier((byte)de.Properties["objectSid"].Value, 0).ToString();

          //Replace the RID portion of the user's SID with the primaryGroupId
          //so we're left with the group's SID
          sid = sid.Remove(sid.LastIndexOf("-", StringComparison.Ordinal) + 1);
          sid = sid + de.Properties["primaryGroupId"].Value;

          //Find the group by its SID
          var group = new DirectoryEntry($"LDAP://<SID={sid}>");
          group.RefreshCache(new {"cn"});

          return group.Properties["cn"].Value as string;
          }


          You are right that the AccountManagement namespace makes things easy, but it really does have terrible performance sometimes. I never use it anymore. I find that DirectoryEntry/DirectorySearcher gives you much more control of how often your code makes calls out to AD.



          I have been meaning to write an article about writing high performance code with DirectoryEntry, but I haven't gotten around to it yet.



          Update: So if you need the nested groups for the user, including membership through the primary group, then you can find the primary group first, then do an LDAP_MATCHING_RULE_IN_CHAIN search for groups that have both the user and the primary group as members:



           (|(member:1.2.840.113556.1.4.1941:={userDN})(member:1.2.840.113556.1.4.1941:={primaryGroupDN}))


          Update: If you want to include Authenticated Users in your search (edit the DC portion of the distinguishedName):



           (|(member:1.2.840.113556.1.4.1941:=CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=domain,DC=com)(member:1.2.840.113556.1.4.1941:={userDN})(member:1.2.840.113556.1.4.1941:={primaryGroupDN})


          Note that you can also use the tokenGroups attribute of a user to find out all of the authentication groups for a user. The tokenGroups attribute is a constructed attribute, so you only get it if you specifically ask for it (with DirectoryEntry.RefreshCache() or, in a search, add it to DirectorySearcher.PropertiesToLoad.



          The caveat is that tokenGroups is a list of SIDs, not distinguishedName, but you can bind directly to an object using the SID with the LDAP://<SID={sid}> syntax.






          share|improve this answer















          The default group is odd. It is not stored in memberOf, or even in the member attribute of the group. That's why your search won't find it. The default group is determined by the primaryGroupId of the user. That attribute stores the RID (the last part of the SID) of the group. It's kind of dumb, I know :)



          I actually wrote an article about the 3 (yes 3) different ways someone can be a member of a group: What makes a member a member?



          I also wrote an article about getting all of the groups a single user belongs to, and how to account for all 3 ways: Finding all of a user’s groups



          For example, here is the C# code I put in that article about how to find the name of the primary group for a user (given a DirectoryEntry). It shouldn't be too hard to translate that to VB.NET:



          private static string GetUserPrimaryGroup(DirectoryEntry de) {
          de.RefreshCache(new {"primaryGroupID", "objectSid"});

          //Get the user's SID as a string
          var sid = new SecurityIdentifier((byte)de.Properties["objectSid"].Value, 0).ToString();

          //Replace the RID portion of the user's SID with the primaryGroupId
          //so we're left with the group's SID
          sid = sid.Remove(sid.LastIndexOf("-", StringComparison.Ordinal) + 1);
          sid = sid + de.Properties["primaryGroupId"].Value;

          //Find the group by its SID
          var group = new DirectoryEntry($"LDAP://<SID={sid}>");
          group.RefreshCache(new {"cn"});

          return group.Properties["cn"].Value as string;
          }


          You are right that the AccountManagement namespace makes things easy, but it really does have terrible performance sometimes. I never use it anymore. I find that DirectoryEntry/DirectorySearcher gives you much more control of how often your code makes calls out to AD.



          I have been meaning to write an article about writing high performance code with DirectoryEntry, but I haven't gotten around to it yet.



          Update: So if you need the nested groups for the user, including membership through the primary group, then you can find the primary group first, then do an LDAP_MATCHING_RULE_IN_CHAIN search for groups that have both the user and the primary group as members:



           (|(member:1.2.840.113556.1.4.1941:={userDN})(member:1.2.840.113556.1.4.1941:={primaryGroupDN}))


          Update: If you want to include Authenticated Users in your search (edit the DC portion of the distinguishedName):



           (|(member:1.2.840.113556.1.4.1941:=CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=domain,DC=com)(member:1.2.840.113556.1.4.1941:={userDN})(member:1.2.840.113556.1.4.1941:={primaryGroupDN})


          Note that you can also use the tokenGroups attribute of a user to find out all of the authentication groups for a user. The tokenGroups attribute is a constructed attribute, so you only get it if you specifically ask for it (with DirectoryEntry.RefreshCache() or, in a search, add it to DirectorySearcher.PropertiesToLoad.



          The caveat is that tokenGroups is a list of SIDs, not distinguishedName, but you can bind directly to an object using the SID with the LDAP://<SID={sid}> syntax.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 26 '18 at 13:37

























          answered Nov 24 '18 at 0:02









          Gabriel LuciGabriel Luci

          11.6k11525




          11.6k11525













          • Thanks for the great post. I've tested the functions, and in my company we only have 1 domain. So I can't test the trusted domains part. But I still have an issue with "A nested group who has the primary group as member". From the example I can find what the primary group is for a user. But take following example: user sgielen has as primairy group Domain Users. Domain Users is member of Group A, and Group A is member of Group B. How to get Domain Users+Group A+Group B?

            – Stinus
            Nov 24 '18 at 13:07













          • There is no way to do that in one search. But after you find the primary group, you can use that in your search. I updated my answer with an example.

            – Gabriel Luci
            Nov 24 '18 at 17:57











          • Thanks, that was exactly what I needed. In my company AD (30,32 sec -> 1,02 sec) But I have 1 wierd thing in my company's AD. From the GetAuthorizationGroups I get that my User is in the following groups. But my user is not in them. CN=Administrators,CN=Builtin,DC=acbenelux,DC=local CN=Users,CN=Builtin,DC=acbenelux,DC=local Any idea how that would happen?

            – Stinus
            Nov 26 '18 at 6:46











          • The Users group likely has Authenticated Users in it, which is one of the "well-known SIDs" that have special meaning. I can't say why the Adminstrators group is showing up, but check it in AD and see what its members are. It's possible there is a similar thing going on there.

            – Gabriel Luci
            Nov 26 '18 at 13:28













          • I made an update to my answer with some more information.

            – Gabriel Luci
            Nov 26 '18 at 13:38



















          • Thanks for the great post. I've tested the functions, and in my company we only have 1 domain. So I can't test the trusted domains part. But I still have an issue with "A nested group who has the primary group as member". From the example I can find what the primary group is for a user. But take following example: user sgielen has as primairy group Domain Users. Domain Users is member of Group A, and Group A is member of Group B. How to get Domain Users+Group A+Group B?

            – Stinus
            Nov 24 '18 at 13:07













          • There is no way to do that in one search. But after you find the primary group, you can use that in your search. I updated my answer with an example.

            – Gabriel Luci
            Nov 24 '18 at 17:57











          • Thanks, that was exactly what I needed. In my company AD (30,32 sec -> 1,02 sec) But I have 1 wierd thing in my company's AD. From the GetAuthorizationGroups I get that my User is in the following groups. But my user is not in them. CN=Administrators,CN=Builtin,DC=acbenelux,DC=local CN=Users,CN=Builtin,DC=acbenelux,DC=local Any idea how that would happen?

            – Stinus
            Nov 26 '18 at 6:46











          • The Users group likely has Authenticated Users in it, which is one of the "well-known SIDs" that have special meaning. I can't say why the Adminstrators group is showing up, but check it in AD and see what its members are. It's possible there is a similar thing going on there.

            – Gabriel Luci
            Nov 26 '18 at 13:28













          • I made an update to my answer with some more information.

            – Gabriel Luci
            Nov 26 '18 at 13:38

















          Thanks for the great post. I've tested the functions, and in my company we only have 1 domain. So I can't test the trusted domains part. But I still have an issue with "A nested group who has the primary group as member". From the example I can find what the primary group is for a user. But take following example: user sgielen has as primairy group Domain Users. Domain Users is member of Group A, and Group A is member of Group B. How to get Domain Users+Group A+Group B?

          – Stinus
          Nov 24 '18 at 13:07







          Thanks for the great post. I've tested the functions, and in my company we only have 1 domain. So I can't test the trusted domains part. But I still have an issue with "A nested group who has the primary group as member". From the example I can find what the primary group is for a user. But take following example: user sgielen has as primairy group Domain Users. Domain Users is member of Group A, and Group A is member of Group B. How to get Domain Users+Group A+Group B?

          – Stinus
          Nov 24 '18 at 13:07















          There is no way to do that in one search. But after you find the primary group, you can use that in your search. I updated my answer with an example.

          – Gabriel Luci
          Nov 24 '18 at 17:57





          There is no way to do that in one search. But after you find the primary group, you can use that in your search. I updated my answer with an example.

          – Gabriel Luci
          Nov 24 '18 at 17:57













          Thanks, that was exactly what I needed. In my company AD (30,32 sec -> 1,02 sec) But I have 1 wierd thing in my company's AD. From the GetAuthorizationGroups I get that my User is in the following groups. But my user is not in them. CN=Administrators,CN=Builtin,DC=acbenelux,DC=local CN=Users,CN=Builtin,DC=acbenelux,DC=local Any idea how that would happen?

          – Stinus
          Nov 26 '18 at 6:46





          Thanks, that was exactly what I needed. In my company AD (30,32 sec -> 1,02 sec) But I have 1 wierd thing in my company's AD. From the GetAuthorizationGroups I get that my User is in the following groups. But my user is not in them. CN=Administrators,CN=Builtin,DC=acbenelux,DC=local CN=Users,CN=Builtin,DC=acbenelux,DC=local Any idea how that would happen?

          – Stinus
          Nov 26 '18 at 6:46













          The Users group likely has Authenticated Users in it, which is one of the "well-known SIDs" that have special meaning. I can't say why the Adminstrators group is showing up, but check it in AD and see what its members are. It's possible there is a similar thing going on there.

          – Gabriel Luci
          Nov 26 '18 at 13:28







          The Users group likely has Authenticated Users in it, which is one of the "well-known SIDs" that have special meaning. I can't say why the Adminstrators group is showing up, but check it in AD and see what its members are. It's possible there is a similar thing going on there.

          – Gabriel Luci
          Nov 26 '18 at 13:28















          I made an update to my answer with some more information.

          – Gabriel Luci
          Nov 26 '18 at 13:38





          I made an update to my answer with some more information.

          – Gabriel Luci
          Nov 26 '18 at 13:38




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53451706%2fldap-matching-rule-in-chain-not-working-with-default-ad-groups-domain-users%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          Xamarin.form Move up view when keyboard appear

          Post-Redirect-Get with Spring WebFlux and Thymeleaf

          Anylogic : not able to use stopDelay()