How can i get the IADs interface of an Active Directory user – by username?
Note: Native code
i am trying to write the function that can get the IADs interface of a user in Active Directory.
i have the following “pseudocode” so far:
public IADs GetUserObject(string samAccountName)
{
IADs ads;
//Get the current domain's distinguished name ("dc=stackoverflow,dc=com")
AdsGetObject("LDAP://rootDSE", IADs, ref ads);
String dn = ads.Get("defaultNamingContext"); //"dc=stackoverflow,dc=com"
String path;
//Attempt #1 to bind to a user by username
path = "LDAP://sSAMAccountName="+samAccountName+",dc=stackoverflow,dc=com"
AdsGetObject(path, IADs, ref ads); //invalid syntax
return ads;
}
The trick, that i cannot figure out, is how to bind to the user by their account name. The following variantions don’t work:
LDAP://sSAMAccountName=ian,dc=stackoverflow,dc=comLDAP://dc=stackoverflow,dc=com;(&(objectCategory=user)(sAMAccountName=ian))<LDAP://dc=stackoverflow,dc=com>;(&(objectCategory=user)(sAMAccountName=ian))
Edit:
A version that does work, but doesn’t answer my question, is:
LDAP://cn=Ian Boyd,ou=Avatar Users,dc=stackoverflow,dc=comIt doesn’t answer my question for two reasons:
- i don’t know the user’s
CN(Common-Name) (e.g. Ian Boyd), only theirsAMAccountName(e.g. ian)- doesn’t work for users not in the Avatar Users organizational unit; and i don’t know a user’s OU
Which comes from the notes i had before:
Note:
- i don’t know the name of the domain (but that’s okay, i can get it at runtime)
- i don’t know the name of any active directory servers
- i don’t know the folder that the user is in
tl;dr: How would you write the utility function:
public IADs GetUserObject(string samAccountName)
{
//TODO: ask stackoverflow
}
Update 2:
Note:
- i already know how to query for information about a user using .NET’s DirectorySearcher
- i already know how to query for information about a user using the Active Directory Services OLEDB provider with ADO (using the SQL syntax, but not the native syntax)
- i’m now looking for code to query for information about a user using Active Directory Services COM objects (hence the question about getting an
IADsfor a user)
Update 3:
It certainly might require me to apply “filters“, except i don’t know where. The only ActiveDs interface that mentions Filter is IADSContainer, but i don’t know where to get one.
i tried randomly to get the IADsContainer interface from the root IADs interface, but “rootDSE” doesn’t support IADsContainer:
IADs ads = AdsGetObject("LDAP://rootDSE");
IADsContainer container = (IADsContainer)ads; //interface not supported exception
i could
- ask a question on how to get the
IADsContainerof the AD root- so i can ask how to recursively search active diretory
- so i can ask how to filter using
IADsContainer
- so i can ask how to filter using
- so i can ask how to recursively search active diretory
But keeping track of all these questions is difficult.
If you know the value of
sAMAccountNameand need to getIADsof the user you need first find the user in Active Directory by thesAMAccountNameand getdistinguishedNameattribute of the user. You know already how to getIADsbydistinguishedName.So you should just follow the code from MSDN for example. First you get
IDirectorySearchinterface of the AD container ofdefaultNamingContextof"LDAP://rootDSE".Then you use IDirectorySearch::ExecuteSearch to apply search using the filter string:
Note: The search filter syntax is described here.
you use the known value of
sAMAccountNameinstead oftheName.for
pAttributeNamesyou can useLPOLESTRarray which consist fromL"distinguishedName"only (seepszNonVerboseListfrom the code example and look the code ofFindUsersin case ofbIsVerboseasFALSE).You should get
distinguishedNameattribute of first (and the only if any exist) found item. HavingdistinguishedNameattribute you can useAdsGetObjectto get theIADsof the user.Alternatively you can get
objectGUIDattribute of the user instead ofdistinguishedNameattribute and use binding by GUID syntax, but the usage ofdistinguishedNameI personally find more clear and understandable.This means that conceptually it can be broken down into two steps:
samAccountNameIADsfor a distinguishedNameAnd splitting the code: