Is there a .NET class that can parse CN= strings out of LDAP?

后端 未结 7 569
梦毁少年i
梦毁少年i 2020-12-17 18:15

I\'ve got a string that I\'m fetching from LDAP for Active Directory group membership and I need to parse it to check if the user is a member of the AD group. Is there a cl

相关标签:
7条回答
  • 2020-12-17 19:08

    To answer the parsing question, use PInvoke with DsGetRdnW. For code, see my answer to another question: https://stackoverflow.com/a/11091804/628981.

    But it sounds like you're doing it wrong. First, get the SID for your target group:

    string targetGroupName = //target group name;
    DirectorySearcher dsTargetGroup = new DirectorySearcher();
    dsTargetGroup.Filter = string.Format("(sAMAccountName={0})", targetGroupName);
    SearchResult srTargetGroup = dsTargetGroup.FindOne();
    DirectoryEntry deTargetGroup = srTargetGroup.GetDirectoryEntry();
    byte[] byteSid = (byte[])deTargetGroup.Properties["objectSid"].Value;
    SecurityIdentifier targetGroupSid = new SecurityIdentifier(byteSid, 0);
    

    Then, it depends on what you have. If the user is running your app (or authenticated to your website/service), then enumerate the SIDs in the token. For example, in desktop apps use WindowsIdentity.GetCurrent().Groups. Otherwise, you'll need to get a DirectoryEntry for the user and then get the tokenAttributes attribute like spoulson suggested:

    DirectoryEntry deTargetUser = //target user;
    DirectorySearcher dsTargetUser = new DirectorySearcher(deTargetUser);
    dsTargetUser.SearchScope = SearchScope.Base; //tokenGroups is a constructed attribute, so have to ask for it while performing a search
    dsTargetUser.Filter = "(objectClass=*)"; //this is closest thing I can find to an always true filter
    dsTargetUser.PropertiesToLoad.Add("tokenGroups");
    SearchResult srTargetUser = dsTargetUser.FindOne();
    foreach(byte[] byteGroupSid in srTargetUser.Properties["tokenGroups"])
    {
        SecurityIdentifier groupSid = new SecurityIdentifier(byteGroupSid, 0);
        if(groupSid == targetGroupSid)
        {
            //success
        }
    }
    

    Just in case you need to get a DirectoryEntry from a SID, you can get the search string by:

    public static string GetSIDSearchFilter(SecurityIdentifier sid)
    {
        byte[] byteSid = new byte[sid.BinaryLength];
        sid.GetBinaryForm(byteSid, 0);
        return string.Format("(objectSid={0})", BuildFilterOctetString(byteSid));
    }
    
    public static string BuildFilterOctetString(byte[] bytes)
    {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.Length; i++)
        {
            sb.AppendFormat("\\{0}", bytes[i].ToString("X2"));
        }
        return sb.ToString();
    }
    
    0 讨论(0)
提交回复
热议问题