How can I convert from a SID to an account name in C#

后端 未结 10 1016
囚心锁ツ
囚心锁ツ 2020-12-01 02:56

I have a C# application that scans a directory and gathers some information. I would like to display the account name for each file. I can do this on the local system by g

相关标签:
10条回答
  • 2020-12-01 03:22

    Get the current domain:

    System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain();
    

    Get a directory entry from ldap and the domain name:

    DirectoryEntry de = new DirectoryEntry(string.Format("LDAP://{0}", domain));
    

    Get the sid from an ActiveDirectoryMembershipProvider ActiveDirectoryMembershipUser:

    ActiveDirectoryMembershipUser user = (ActiveDirectoryMembershipUser)Membership.GetUser();
    var sid = (SecurityIdentifier)user.ProviderUserKey;
    

    Get the username from the SecurityIdentifier:

    (NTAccount)sid.Translate(typeof(NTAccount));
    

    Get directory search done on an activedirectory with the domain directory entry and username:

    DirectorySearcher search = new DirectorySearcher(entry);
            search.Filter = string.Format("(SAMAccountName={0})", username);
            search.PropertiesToLoad.Add("Name");
            search.PropertiesToLoad.Add("displayName");
            search.PropertiesToLoad.Add("company");
            search.PropertiesToLoad.Add("homePhone");
            search.PropertiesToLoad.Add("mail");
            search.PropertiesToLoad.Add("givenName");
            search.PropertiesToLoad.Add("lastLogon");
            search.PropertiesToLoad.Add("userPrincipalName");
            search.PropertiesToLoad.Add("st");
            search.PropertiesToLoad.Add("sn");
            search.PropertiesToLoad.Add("telephoneNumber");
            search.PropertiesToLoad.Add("postalCode");
            SearchResult result = search.FindOne();
            if (result != null)
            {
                foreach (string key in result.Properties.PropertyNames)
                {
                    // Each property contains a collection of its own
                    // that may contain multiple values
                    foreach (Object propValue in result.Properties[key])
                    {
                        outputString += key + " = " + propValue + ".<br/>";
                    }
                }
            }
    

    Depending on the data in your active directory, you will get a varied response in the output.

    Here is a site that has all the user properties I needed:

    0 讨论(0)
  • 2020-12-01 03:24

    You can also get account name of special accounts like "Everyone" with code like this that will work regardless of user's language settings:

       SecurityIdentifier everyoneSid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
       string everyone = everyoneSid.Translate(typeof(System.Security.Principal.NTAccount)).ToString();
    
    0 讨论(0)
  • System.DirectoryServices.AccountManagement.UserPrincipal class (msdn link) has a static function FindByIdentity to convert an SID to a User object. It should be able to work both against the local machine or an LDAP/Active Directory server. I have only used it against active directory.

    Here is an example that I have used in IIS:

    // Set the search context to a specific domain in active directory
    var searchContext = new PrincipalContext(ContextType.Domain, "YOURDOMAIN", "OU=SomeOU,DC=YourCompany,DC=com");
    // get the currently logged in user from IIS
    MembershipUser aspUser = Membership.GetUser();
    // get the SID of the user (stored in the SecurityIdentifier class)
    var sid = aspUser.ProviderUserKey as System.Security.Principal.SecurityIdentifier;
    // get the ActiveDirectory user object using the SID (sid.Value returns the SID in string form)
    var adUser = UserPrincipal.FindByIdentity(searchContext, IdentityType.Sid, sid.Value);
    // do stuff to user, look up group membership, etc.
    
    0 讨论(0)
  • 2020-12-01 03:29

    Great. I cribbed some LookupAccountSid() code from here:

    http://www.pinvoke.net/default.aspx/advapi32.LookupAccountSid

    And that worked, though I had to provide the host name myself. In the case of a UNC path I can just take the first component of it. When it's a mapped drive, I use this code to convert the path to a UNC one:

    http://www.wiredprairie.us/blog/index.php/archives/22

    It seems to work, so that's how I'll do it, unless someone comes up with a situation in which the first component of a UNC path isn't the host name...

    Thank you all for your help.

    0 讨论(0)
提交回复
热议问题