Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to retrieve SAMAccountName from Active Directory

I implemented a method that returns a list of Active Directory users, I would like to retrieve SAMAccountName like this Domain\Administrator.

This is the method I use:

public Collection<software_user> GetUsersFromAD(String adConnectionString)
{
    var users = new Collection<software_user>();

    using (var directoryEntry = new DirectoryEntry(adConnectionString))
    {
        var directorySearcher = new DirectorySearcher(directoryEntry);
        directorySearcher.Filter = "(&(objectClass=user))";
        var propertiesToLoad = new[] 
        { 
           "SAMAccountName", 
           "displayName", 
           "givenName", 
           "sn", 
           "mail", 
           "userAccountControl", 
           "objectSid" 
        };
        directorySearcher.PropertiesToLoad.AddRange(propertiesToLoad);

        foreach (SearchResult searchEntry in directorySearcher.FindAll())
        {
            var userEntry = searchEntry.GetDirectoryEntry();
            var ldapUser = new software_user();
            ldapUser.User_name = NullHandler.GetString(userEntry.Properties["displayName"].Value);

            if (string.IsNullOrEmpty(ldapUser.User_name))
               continue;
            ldapUser.User_name = NullHandler.GetString(userEntry.Properties["SAMAccountName"].Value);
            ldapUser.email = NullHandler.GetString(userEntry.Properties["mail"].Value);
            ldapUser.user_shortname = NullHandler.GetString(userEntry.Properties["givenName"].Value);
            var userAccountControl = (int)userEntry.Properties["userAccountControl"].Value;
            //ldapUser.IsActive = (userAccountControl & UF_ACCOUNTDISABLE) != UF_ACCOUNTDISABLE;
            var sid = new SecurityIdentifier((byte[])userEntry.Properties["objectSid"][0], 0).Value;
            //ldapUser.SId = sid;
            users.Add(ldapUser);
         }
    }
    return users;
}
like image 346
unknownUser Avatar asked Apr 11 '12 18:04

unknownUser


2 Answers

First off: Domain\Administrator is NOT a SAM account name! The SAM account name is a unique (over the whole domain) name of up to 20 characters in length - typically it's your "Windows user name" (e.g. Administrator) - but it does NOT include the domain name. That value made up of domain\username is NOT stored in Active Directory anywhere!


If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:

  • Managing Directory Security Principals in the .NET Framework 3.5
  • MSDN docs on System.DirectoryServices.AccountManagement

Basically, you can define a domain context and easily find users and/or groups in AD:

// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");

if(user != null)
{
   // do something here....     
   string samAccountName = user.SamAccountName;
}

The new S.DS.AM makes it really easy to play around with users and groups in AD!

If you want to search for a whole group of users (or groups or computers), you can use a PrincipalSearcher and a "query-by-example" principal to do your searching:

// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

// define a "query-by-example" principal - here, we search for a UserPrincipal 
// and with the last name (Surname) of "Miller"
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.Surname = "Miller";

// create your principal searcher passing in the QBE principal    
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);

// find all matches
foreach(var found in srch.FindAll())
{
    // do whatever here - "found" is of type "Principal" - it could be user, group, computer.....          
}
like image 198
marc_s Avatar answered Oct 29 '22 00:10

marc_s


You can translate a user as a Distinguished name to DOMAIN\SAMaccount form using the Object's SID, and the System.Security.Principal.SecurityIdentifier.Translate command.

public Collection<software_user> GetUsersFromAD(String adConnectionString)
    {
            var users = new Collection<software_user>();

            using (var directoryEntry = new DirectoryEntry(adConnectionString))
            {
                    var directorySearcher = new DirectorySearcher(directoryEntry);
                    directorySearcher.Filter = "(&(objectClass=user))";
                    var propertiesToLoad = new[] 
                    { 
                         "SAMAccountName", 
                         "displayName", 
                         "givenName", 
                         "sn", 
                         "mail", 
                         "userAccountControl", 
                         "objectSid" 
                    };
                    directorySearcher.PropertiesToLoad.AddRange(propertiesToLoad);

                    foreach (SearchResult searchEntry in directorySearcher.FindAll())
                    {
                            var userEntry = searchEntry.GetDirectoryEntry();
                            var ldapUser = new software_user();
                            ldapUser.User_name = NullHandler.GetString(userEntry.Properties["displayName"].Value);

                            if (string.IsNullOrEmpty(ldapUser.User_name))
                                 continue;
                            ldapUser.User_name = NullHandler.GetString(userEntry.Properties["SAMAccountName"].Value);
                            ldapUser.email = NullHandler.GetString(userEntry.Properties["mail"].Value);
                            ldapUser.user_shortname = NullHandler.GetString(userEntry.Properties["givenName"].Value);
                            var userAccountControl = (int)userEntry.Properties["userAccountControl"].Value;

                            //ldapUser.IsActive = (userAccountControl & UF_ACCOUNTDISABLE) != UF_ACCOUNTDISABLE;
                            SecurityIdentifier sid = new SecurityIdentifier((byte[])userEntry.Properties["objectSid"][0], 0).Value;
    -->                     NTAccount account = (NTAccount) sid.Translate(typeof(NTAccount));
    -->                     ldapUser.User_name = account.ToString();

                            //ldapUser.SId = sid;
                            users.Add(ldapUser);
                     }
            }
            return users;
    }
like image 25
Christopher G. Lewis Avatar answered Oct 29 '22 01:10

Christopher G. Lewis