Query Active Directory users who are managed by given manager's sAMAccountName - active-directory

I'm trying to search active directory users whose manager's username is given in the search request, but I always get 0 records regardless of the manager's username I pass.
To achieve this, I executed the following LDAP query:
(manager=sAMAccountName=Administrator)
I also tried by manager's common name like this:
(manager=cn=John Smith)
Can anyone write me an LDAP query that returns all users whose manager's sAMAccountName=administrator ?

manager has distinguished name syntax, therefore, if manager is used in an assertion, the full DN must be used as the value. Neither of the examples you gave meet this criteria. You must correct the filter to use a distinguished name.
The syntax of manager:
attributeTypes: ( 0.9.2342.19200300.100.1.10 NAME 'manager'
EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
X-ORIGIN 'RFC 4524' )
To determine the syntax, use the LDAP Parameters Assignment page. On that page, search for the OID following the SYNTAX keyword (1.3.6.1.4.1.1466.115.121.1.12). That shows that it's DN syntax. Also, the EQUALITY matching rule is distinguishedNameMatch.
An example of an assertion in a filter using the correct syntax:
manager=cn=Manager Number One,ou=managers,ou=people,dc=example,dc=com
All attributes values used in an assertion must have the syntax defined for that attribute type in the schema.
Update
Verify the entries exist with a known good tool such as ldapsearch to ensure that the correct parameters are known for the search request. For example:
$ ldapsearch -h hostname -p port -b 'dc=sahara,dc=local' \
-D [your-bind-dn] -w [your-bind-dn-password] \
-s sub \
'(manager=cn=Izzeddeen Alkarajeh,ou=managers,ou=people,dc=sahara,dc=local)' \
1.1
If this search returns no entries, check with the LDAP administrators to ensure that the BIND DN in use has permission o read those entries.
see also
LDAP: Mastering Search Filters
LDAP: Search best practices
LDAP: Programming practices

I know this is old but I figured out a way to do this in C# that I have yet to find on stackoverflow.
using (var pc = new PrincipalContext(ContextType.Domain, "yourdomain.com"))
using (var user = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, "samAccountName"))
{
DirectoryEntry de = (DirectoryEntry)user.GetUnderlyingObject();
if (de.Properties["directReports"].Count != 0)
managedFound = de.Properties["directReports"];
}
This will give you a list of strings that you can then parse out the CN using this:
managedUserName = Regex.Match(managedFound.ToString(), #"CN[=].*?[,]").Value.Replace("CN=", "").Replace(",", "");
Then, the following to get the User properties:
UserPrincipal managedUser = UserPrincipal.FindByIdentity(pc, IdentityType.Name, managedUserName);

Related

What is the proper way to get some specific user attributes from Active Directory via LDAP C API?

I am trying to get some user attributes from Active Directry using Windows LDAP API. I am using:
Active Directory Version: The one that comes with Windows Server 2012
LDAP version: 3
Wldap32.lib version: The one that comes with Windows 10 x64
Eg:
PCHAR myAttributes[4];
myAttributes[0] = "DistinguishedName";
myAttributes[1] = "DisplayName";
myAttributes[2] = "PasswordExpired";
myAttributes[3] = "mail";
ldap_search_s(
myLdapConnection, // Ldap connection
myDomain, // DN to start search
LDAP_SCOPE_SUBTREE, // Scope
myFilter, // Filter
myAttributes, // Retrieve list of attributes
0, // Get both attributes and values
&mySearchResult // [out] Search results
);
It returns DistinguishedName, DisplayName and mail attributes, but does not reuturn the PasswordExpired attribute.
I queried with some other attributes and it looks like it does not return attributes with boolean values as well as the EmailAddress attribute.
Why does it not return PasswordExpired attribute?
What about EmailAddress ?
Is there a difference between EmailAddress and mail ?
There is no PasswordExpired LDAP attribute in Active Directory. To build your query look at this URL for attribute names in standard Active Directory schema https://msdn.microsoft.com/en-us/library/ms675090(v=vs.85).aspx. To check if password for given account is expired you'll need to check userAccountControl attribute, which is actually value storing flags of different states of user account https://msdn.microsoft.com/en-us/library/ms680832(v=vs.85).aspx. There is IADsUser interface that will translate this all for you in case you don't have to stick just to LDAP https://msdn.microsoft.com/en-us/library/aa746343(v=vs.85).aspx
You will find current primary email address in mail attribute. There is no EmailAddress LDAP attribute, unless you meant E-mail-Addresses which is CN for the same schema attribute as mail, so no difference there.
See above. In general if you do not have compelling reason to stick just to C/LDAP I'd recommend you to use .Net Framework instead. Otherwise you have a lot of work ahead of you - not just interpreting bit flags like in case of password expiration but possibly also with different authentication methods, different structures capturing time and date, accounting for timezones, UTF, chasing referrals and other stuff you might need depending on complexity of what you want to achieve. You will be productive much faster in .Net Framework. See DirectoryServices https://msdn.microsoft.com/en-us/library/mt481534(v=vs.110).aspx namespace or Security namespace https://msdn.microsoft.com/en-us/library/mt481561(v=vs.110).aspx for details.

LDAP search using distinguishedName

I know the answer is probably no, however, I figured before I give up I may as well ask.
Is it possible to find all objects in OU using distinguishedName, let say I need to find all objects in OU which is called Groups, i try to use something like this, but it dosn't work
(DN=*OU=Groups,OU=Corp-Users,DC=fabrikam,DC=internal)
Try ldapsearch -s one -h ldaphost -b "OU=Groups,OU=Corp-Users,DC=fabrikam,DC=internal" "objectclass=*" dn to get all nodes of the level OU=Groups,OU=Corp-Users,DC=fabrikam,DC=internal. Replace the -s one with -s sub to get all subentries as well.
What does it do?
It uses OU=Groups,OU=Corp-Users,DC=fabrikam,DC=internal as the search base (-b) and searches just on that level (-s one) or on all sublevels (-s sub) all nodes that have an attribute objectclass set (which should be every node!)
The rest is just syntactical stuff that might be needed like setting the LDAP-Host (-h ldaphost) or just returning the dn (the dn right at the end)
I'm not sure what the command for windows is though.

ldap nested group (attribute to look while parsing for group membership)

To retrieve groups belonging to all users I am using following filter:
(&(objectclass=*)(member:1.2.840.113556.1.4.1941:=cn=sam,DC=aaaldap,DC=com))
And, i am able to retrieve multiple DN entries like:
1. GOT ENTRY: DN => CN=group1,CN=Users,DC=aaaldap,DC=com
LDAP: Attribute Length Valueldap_get_dn
1d21h: LDAP: cn 6 group1
2. LDAP: GOT ENTRY: DN => CN=group2,CN=Users,DC=aaaldap,DC=com
LDAP: Attribute Length Valueldap_get_dn
1d21h: LDAP: cn 6 group2
All i am interested is in group membership, so i want to parse the attribute CN received in the entry and would like to assume this as a group.
Can someone suggest if this will be a valid assumption of parsing CN attribute and mark its value as "group" membership to which it belongs to?
You should specify a real objectClass instead of just *, to limit the search to whatever object class you are using for groups. Then anything you get back must be a group. The search may also run faster.

How to get the nested groups in LDAP/AD?

We have an LDAP login problem of a specific user and I'm suspecting that this is due to cyclic groups assignment in LDAP, i.e. the user is assigned to groups A,B,C,D. Group A contains sub-groups E,F,G and group E contains group A again.
If I query for the user I can see that he has been assigned with 50+ groups and each group may contain more groups and each of those may contain more....
My question is if there's a query I can run to get the nested groups inside those main groups all the way down instead of going each group and do it manually?
The server is AD
To find all the groups that "user1" is a member of (adaptation of this answer see AD search filter):
Set the base to the groups container DN; for example root DN (dc=dom,dc=fr)
Set the scope to subtree
Use the following filter : (member:1.2.840.113556.1.4.1941:=cn=user1,cn=users,DC=x)
Example with LDIFDE.EXE (native command line AD search on windows) :
ldifde -f t.txt -d "DC=dom,DC=fr" -r "(member:1.2.840.113556.1.4.1941:=CN=jblanc,OU=MonOu,DC=dom,DC=fr)"
Remark : as far as I remember there is a small syntax difference with in brackets user DN name. '1.2.840.113556.1.4.1941' is not working in W2K3 SP1, it begins to work with SP2. I presume it's the same with W2K3 R2. I test here with W2K8R2.
With Apache Directory Studio :
Result :

How do I filter an LDAP query for groups containing a specific user?

How do I filter an Active Directory LDAP query to groups containing the authenticated/bound user (or any user at all)? This works fine:
(&(objectClass=group)(member=*))
>>> lots of results
But I can't go any more detail:
(&(objectClass=group)(member=*S*))
>>> nothing
The MSDN mentions using a filter like this:
(member:1.2.840.113556.1.4.1941:=(cn=user1,cn=users,DC=x))
But even ignoring the crazy hyper magic number involved in that, I always get 0 results when I try to filter with that (even replacing cn=user1,cn=users,DC=x with my own distinguishedName, even replacing it with *).
You need the full DN of the user i.e
(&(member=CN=Your Name,OU=Your OU,DC=company,DC=com)(objectClass=group))
take note you cannot use * in this one
So the crazy hyper magic number involved in recursive search is explained in Search Filter Syntax.
To find in one search (recursively) all the groups that "user1" is a member of:
Set the base to the groups container DN; for example root DN (dc=dom,dc=fr)
Set the scope to subtree
Use the following filter: (member:1.2.840.113556.1.4.1941:=cn=user1,cn=users,DC=x)
explicited using LDIFDE.EXE the command line tool included in Windows Server it gives:
ldifde -f user1Grps.ldf -d "dc=societe,dc=local" -r "(member:1.2.840.113556.1.4.1941:=cn=user1,ou=Monou,dc=societe,dc=local)"
If you are running that on a W2K8 or W2K8 R2 server be careful to run as administrator.
If you are programming in C# you can use:
/* Retreiving a principal context
*/
Console.WriteLine("Retreiving a principal context");
PrincipalContext domainContext = new PrincipalContext(ContextType.Domain, "WM2008R2ENT:389", "dc=dom,dc=fr", "jpb", "PWD");
/* Look for all the groups a user belongs to
*/
UserPrincipal aUser = UserPrincipal.FindByIdentity(domainContext, "user1");
PrincipalSearchResult<Principal> a = aUser.GetAuthorizationGroups();
foreach (GroupPrincipal gTmp in a)
{
Console.WriteLine(gTmp.Name);
}

Resources