Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding a User in Active Directory with the Login Name

I'm possibly just stupid, but I'm trying to find a user in Active Directory from C#, using the Login name ("domain\user").

My "Skeleton" AD Search Functionality looks like this usually:

de = new DirectoryEntry(string.Format("LDAP://{0}", ADSearchBase), null, null, AuthenticationTypes.Secure);
ds = new DirectorySearcher(de);
ds.SearchScope = SearchScope.Subtree;
ds.PropertiesToLoad.Add("directReports");
ds.PageSize = 10;
ds.ServerPageTimeLimit = TimeSpan.FromSeconds(2);
SearchResult sr = ds.FindOne();

Now, that works if I have the full DN of the user (ADSearchBase usually points to the "Our Users" OU in Active Directory), but I simply have no idea how to look for a user based on the "domain\user" syntax.

Any Pointers?

like image 909
Michael Stum Avatar asked Oct 02 '08 08:10

Michael Stum


1 Answers

You need to set a filter (DirectorySearcher.Filter) something like:

"(&(objectCategory=person)(objectClass=user)(sAMAccountName={0}))"

Note that you only specify the username (without the domain) for the property sAMAccountName. To search for domain\user, first locate the naming context for the required domain, then search there for sAMAccountName.

By the way, when building LDAP query strings using String.Format, you should generally be careful to escape any special characters. It probably isn't necessary for an account name, but could be if you're searching by other properties such as the user's first (givenName property) or last (sn property) name. I have a utility method EscapeFilterLiteral to do this: you build your string like this:

String.Format("(&(objectCategory=person)(objectClass=user)(sn={0}))", 
              EscapeFilterLiteral(lastName, false)); 

where EscapeFilterLiteral is implemented as follows:

public static string EscapeFilterLiteral(string literal, bool escapeWildcards)
{
    if (literal == null) throw new ArgumentNullException("literal");

    literal = literal.Replace("\\", "\\5c");
    literal = literal.Replace("(", "\\28");
    literal = literal.Replace(")", "\\29");
    literal = literal.Replace("\0", "\\00");
    literal = literal.Replace("/", "\\2f");
    if (escapeWildcards) literal = literal.Replace("*", "\\2a");
    return literal;
}

This implementation allows you treat the * character as part of the literal (escapeWildcard = true) or as a wildcard character (escapeWildcard = false).

UPDATE: This is nothing to do with your question, but the example you posted does not call Dispose on the disposable objects it uses. Like all disposable objects these objects (DirectoryEntry, DirectorySearcher, SearchResultCollection) should always be disposed, normally with the using statement. See this post for more info.

like image 176
Joe Avatar answered Nov 14 '22 12:11

Joe