locked
how to convert AD User SID to NT account ( Domain\User Account ) RRS feed

  • Question

  • Hi there,

    I have a question is regarding convert AD user SID to NTAccount (DOMAIN\User Account.). My environment is Windows 2016 server (LDAP Path: dev.testing.pri; Domain: DEVTST) and one testing program lives in another client (Windows 2019). my code is like the following:

    using (DirectoryEntry directoryEntry = new DirectoryEntry("LDAP://" + ldapPath, account, passWord, AuthenticationTypes.Secure))
    {
        var filter = "(userPrincipalName=" + emailAccount + ")";
    
        using (DirectorySearcher directorySearcher = new DirectorySearcher(directoryEntry, filter))
        {
            directorySearcher.PropertiesToLoad.AddRange(_properties);
    
            using (System.DirectoryServices.SearchResultCollection results = directorySearcher.FindAll())
            {
                var properties = from p in results[0].Properties.OfType<DictionaryEntry>()
                                 let values = (p.Value as ResultPropertyValueCollection).OfType<object>()
                                 orderby p.Key
                                 select new { Name = p.Key, Value = String.Join(", ", values) };
                
                foreach (var _prop in properties)
                    Console.WriteLine($"{_prop.Name} = {_prop.Value}");
    
                var prop = (byte[])results[0].Properties["objectsid"][0];
                var sid = new SecurityIdentifier(prop, 0);
                var ntaccount = sid.Translate(typeof(NTAccount));
                var accountName = ntaccount.ToString();
            }  
    
            Console.WriteLine(GetCurrentDomain.GetLDAPAttributes<string>(user.Properties["displayName"]));
            Console.WriteLine(GetCurrentDomain.GetDomain(user));
            Console.WriteLine(GetCurrentDomain.GetDomain(user) + "\\" + GetCurrentDomain.GetLDAPAttributes<string>(user.Properties["samAccountName"]));
    
            Console.ReadLine();
        }
    }

    var ntaccount = sid.Translate(typeof(NTAccount)); --> error comes up, the error is like the following: does anyone have any idea on it?? Thanks

    Some or all identity references could not be translated. at System.Security.Principal.SecurityIdentifier.Translate(IdentityReferenceCollection sourceSids, Type targetType, Boolean forceSuccess) at System.Security.Principal.SecurityIdentifier.Translate(Type targetType) at Cons.Sample.Program.Main(String[] args) in C:\Users\Administrator\source\repos\Cons.Sample\Cons.Sample\Program.cs:line 59 mscorlib


    Hi there, if you found my comment very helpful then please | Propose as answer | . Thanks and Regards.

    Wednesday, May 13, 2020 7:54 AM

Answers

  • You are supposed to use directoryEntry.Properties["name"][0].ToString().ToUpper() to concat with "\" and sAMAccountName of the user. (I'm assuming single domain environment)

    I suppose the credential you use to run the code is not a domain user, therefore the SecurityIdentifier().Tranlate() trick won't work.

    For that to work you're advised to impersonate that code block to a domain user. (Any basic domain user of that domain should be able to translate SID and usernames. Using the login credential you pass to DirectoryEntry will do)

    Disclaimer: I'm just reciting what should work, plus a little verification with ADExplorer to check the property name. Asker should verify and see whether it works or not.

    • Edited by cheong00Editor Thursday, May 14, 2020 6:06 AM
    • Marked as answer by Will .H Sunday, May 17, 2020 2:13 PM
    Thursday, May 14, 2020 5:47 AM
    Answerer
  • Hi Daniel,

    Thanks for your reply. the problem has been solved on my own. The main cause is 

    "var ntaccount = sid.Translate(typeof(NTAccount));" just can be use the client joined in the domain. so if my client (A) is belonged to the domain, everything works well. on the contrary, if (A) leaves the domain, the error comes up. 

    Thanks


    Hi there, if you found my comment very helpful then please | Propose as answer | . Thanks and Regards.

    • Marked as answer by Will .H Sunday, May 17, 2020 2:12 PM
    Friday, May 15, 2020 4:25 AM

All replies

  • Providing the link to the duplicate post that you already submitted (https://social.msdn.microsoft.com/Forums/en-US/70afe186-4719-4457-92dc-be3995575495/regarding-active-directory-for-extracting-user-nt-name-prewindows-2000-user-logon-name?forum=csharpgeneral) so others have context.

    Michael Taylor http://www.michaeltaylorp3.net

    Wednesday, May 13, 2020 1:32 PM
  • You are supposed to use directoryEntry.Properties["name"][0].ToString().ToUpper() to concat with "\" and sAMAccountName of the user. (I'm assuming single domain environment)

    I suppose the credential you use to run the code is not a domain user, therefore the SecurityIdentifier().Tranlate() trick won't work.

    For that to work you're advised to impersonate that code block to a domain user. (Any basic domain user of that domain should be able to translate SID and usernames. Using the login credential you pass to DirectoryEntry will do)

    Disclaimer: I'm just reciting what should work, plus a little verification with ADExplorer to check the property name. Asker should verify and see whether it works or not.

    • Edited by cheong00Editor Thursday, May 14, 2020 6:06 AM
    • Marked as answer by Will .H Sunday, May 17, 2020 2:13 PM
    Thursday, May 14, 2020 5:47 AM
    Answerer
  • Hi Will .H,
    The translate method can be used for non-local SIDs, but only for domain accounts.
    Based on your error, I find some related threads and hope these are helpful to you.
    [How can I convert from a SID to an account name in C#]
    ["Some or all identity references could not be translated."]
    Best Regards,
    Daniel Zhang


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Will .H Sunday, May 17, 2020 2:13 PM
    • Unmarked as answer by Will .H Sunday, May 17, 2020 2:13 PM
    Thursday, May 14, 2020 9:24 AM
  • Hi Daniel,

    Thanks for your reply. the problem has been solved on my own. The main cause is 

    "var ntaccount = sid.Translate(typeof(NTAccount));" just can be use the client joined in the domain. so if my client (A) is belonged to the domain, everything works well. on the contrary, if (A) leaves the domain, the error comes up. 

    Thanks


    Hi there, if you found my comment very helpful then please | Propose as answer | . Thanks and Regards.

    • Marked as answer by Will .H Sunday, May 17, 2020 2:12 PM
    Friday, May 15, 2020 4:25 AM
  • Hi Will .H,
    I am glad you have solved the problem. We appreciated you shared us your solution. And we also hope you can mark it as an answer. By marking a post as Answered, you help others find the answer faster.
    Best Regards,
    Daniel Zhang


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, May 15, 2020 5:42 AM