LDAP query cannot find a specific group in Active Directory - active-directory

I have a macro within Excel that I periodically use to pull out details of group members within Active Directory. It works fine for every group I've tried but I've come across one group that I just do not seem able to get data for.
The relevant bit of the script is below:
Set rootDSE = GetObject("LDAP://[MyDomain.co.uk]/RootDSE")
DomainContainer = rootDSE.Get("defaultNamingContext")
Set conn = CreateObject("ADODB.Connection")
conn.Provider = "ADSDSOObject"
conn.Open "ADs Provider"
Set command = CreateObject("ADODB.Command")
Set command.ActiveConnection = conn
command.Properties("Page size") = 200
groupDistinguisedName = "CN=[Group Name],OU=xxx,OU=xxx,DC=MyDomain,DC=co,DC=uk"
command.CommandText = "<LDAP://" & DomainContainer & ">;(distinguishedName=" & groupDistinguisedName & ");member;subtree"
Set rs = command.Execute
On Error Resume Next
dataVal = rs.Fields("member").Value
I've tried to run the script with a group name that does NOT exist and the script behaves in a different way - dataVal is set to Empty if the group does not exist, but is set to Null for the group I am having problems with, so it would appear that it has found the group but just somehow cannot get the members of the group.
I've tried cutting and pasting the distinguished name directly from Active Directory into the LDAP command string so I know it's not a typo on the name. This group is a large group with lots of members but I've tried other large groups too. I just can't see what could be causing the problem. Any ideas?

The "member" attribute does not include members for primary group membership.
e.g. The "Domain Users" group may have many members but its "member" attribute can be empty.
To check primary group membership, please make use of the primaryGroupToken (group) and the primaryGroupId (user) attribute.
Get the value of primaryGroupToken attribute from group
(Note that primaryGroupToken is an constructed attribute)
Search in the SAME DOMAIN for all users that has the same value in primaryGroupId
e.g. "Domain Users" group has a value of 513 in primaryGroupToken.
That means any user objects in the same domain whose primaryGroupId=513 are members of this "Domain Users" group.
Other comments:
You already know the DN and the server. Why not directly call GetObject("LDAP://[MyDomain.co.uk]/" & groupDistinguisedName) to get the group?
distinguishedName attribute is not indexed. The query can be slow in large env.
If there are >1500 (configurable) members in "member" attribute, you need to use range retrieval. Otherwise you only get 1500.

Related

LDAP query for Window AD

For authentication in Jitsi Meet, we would like to read out a Windows AD group with an ldap query. Unfortunately our ldap query does not work.
LDAP_URL=ldaps://server.domain.local:636/
LDAP_BASE=DC=domain,DC=local
LDAP_BINDDN=CN=bind_user,OU=Administrative Accounts,OU=Benutzer,DC=domain,DC=local
LDAP_BINDPW=*
LDAP_FILTER= (&(|objectclass=user))(|(memberof=CN=group,OU=Jitsi,OU=Sicherheit,OU=Gruppen,DC=domain,DC=local)
(primaryGroupID=4989))
The error must be due to the filter, it works with the filter LDAP_FILTER = (sAMAccountName =% u).
Can you tell me what is wrong with our query.
A few things stand out to me:
The | in front of objectClass should not be there.
You have two closing parentheses after the objectClass condition, but the second one should be moved to the end of the whole query.
Oddly, objectClass=user will actually end up including other objects than just user accounts (like computer accounts). If you want to filter to only user objects, you have to use both (objectClass=user)(objectCategory=person). But that would only matter if you have other types of objects as members of that group.
Maybe this is just an error with pasting into the question, but there is a line break before (primaryGroupID=
I've never used Jitsi, but it may or may not like the space after LDAP_FILTER=. The other examples I see online don't show a space there.
It should look like this:
LDAP_FILTER=(&(objectclass=user)(objectCategory=person)(|(memberof=CN=group,OU=Jitsi,OU=Sicherheit,OU=Gruppen,DC=domain,DC=local)(primaryGroupID=4989)))
That means: find all user objects that are either members of that group, or have a primary group ID of 4989.

Query AD Group to get Custom Attribute on it

I am trying to get a Custom Attribute of a Group in Custom Claim rule.
The problem is no matter what i do, it always queries against User.
Here is how my Custom Claim Rule looks like:
//Rule to get all the Groups user is part of:
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
=> issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/claims/Group"), query = ";tokenGroups;{0}", param = c.Value);
//Rule to fetch url attribute that is on the Group.
c:[Type == "http://schemas.xmlsoap.org/claims/Group"]
=> add(store = "Active Directory", types = ("http://temp/urlsOnGroup"), query = ";url;{0}", param = c.Value);
When this executes, i see an error in the event log on AD FS Server which states that it is trying to find User with GroupName.
How do i specify this Rule so that the last query happens against the Group Name instead of User
Error Message:
Microsoft.IdentityServer.ClaimsPolicy.Language.PolicyEvaluationException:
POLICY0018: Query ';url;{0}' to attribute store 'Active Directory' failed:
'POLICY3826: User name 'GroupName' in LDAP query ';url;GroupName' is not in the
required 'domain\user' format. POLICY3824: The LDAP query to the Active
Directory attribute store must have three parts separated by semicolons. The
first part is the LDAP query filter, the second part is a comma-separated list
of LDAP attribute names, and the third part is the user name in 'domain\user'
format.'. --->
Microsoft.IdentityServer.ClaimsPolicy.Engine.AttributeStore.AttributeStoreQueryF
ormatException: POLICY3826: User name 'GroupName' in LDAP query ';url;GroupName'
is not in the required 'domain\user' format. POLICY3824: The LDAP query to the
Active Directory attribute store must have three parts separated by semicolons.
The first part is the LDAP query filter, the second part is a comma-separated
list of LDAP attribute names, and the third part is the user name in
'domain\user' format.
I want to avoid writing Custom Attribute Store if possible. I have already did that but i am trying to find native way to query agains AD Security Groups.
The required format is e.g.
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/ou"]
=> issue(store = "Active Directory", types = ("http://schemas.company.co.nz/claims/guid"), query = "(ou={0});objectGuid;domain\user", param = c.Value);
The "domain" needs to be the domain for ADFS. The "user" can be anything.
Note rule is free form so may have format errors but you get the idea!

MS Access 2003 - Auto fill form-field based on previous form field.

I am currently attempting to design a database that requires a number of users inputting data via forms.
one of these tables is a 'user' table. Amongst the information in the table is
userid (int),
username (text),
first name (text),
last name (text)
In the even that I'm filling out a form and supply the the username in the username field is it possible if the username already exists to pull the first name and last name from the user table and auto-populate those form fields? If so can you point me in the right direction please?
Directly via access functionality or via vba? If not possible in 2003 is this possible in 2007?
Ok now for the auto fill (yes i did find one example), This will fill the username after you filled the userid (Both should be comboboxes in this case called Usernamecombo and useridcombo)
First make the query with a SQL similar to this:
SELECT [User].username FROM User WHERE ((([User].userid) Like '*' & [Forms]![Yourform]![useridcombo] & '*'));
Lets call this query "qry_username".
Then go to designview of the form and to the properties of the useridcombo, in the event/afterupdate property you make a event procedure (VBA) :
Private Sub useridcombo_AfterUpdate()
[Forms]![yourform]![Usernamecombo].Value = DFirst("username", "qry_username")
Forms("yourform").[Usernamecombo].Requery 'this last line is optional
End sub
Other fields can be added to the VBA pretty simply(dont forget the query)
Private Sub useridcombo_AfterUpdate()
[Forms]![yourform]![Usernamecombo].Value = DFirst("username", "qry_username")
[Forms]![yourform]![Firstnamecombo].Value = DFirst("Firstname", "qry_username")
[Forms]![yourform]![Lastnamecombo].Value = DFirst("Lastname", "qry_username")
Forms("yourform").[Usernamecombo].Requery 'this last line is optional
End sub
I have a similar form and i use to make these field as Comboboxes.
Then set the property row source as a query.
Set the criteria Where like this
WHERE ((([Users].Username) Like '*' & [Forms]![YourForm]![Username] & '*'));
This will allow the user to choose the name as fast as possible
But it will not fill it automatically because my users can have the same username as others.

Get users from Acctive Directory Group

I created an Active Directory domain name 'ADDOMAIN2' having a group name "CommonUsers" having 8 users. but when I do a Directory Search for users in group "CommonUsers" it returns zero result. hers is my code
DirectorySearcher searcher = new DirectorySearcher();
DirectoryEntry directoryEntry = new DirectoryEntry(string.Format("LDAP://{0}", "ADDOMAIN2"), "Administrator", "p#S$w0rd");
string dnPath = directoryEntry.Properties["distinguishedName"].Value.ToString();
// string path = string.Format("LDAP://{0}/{1}{2}", "ADDOMAIN2", "", dnPath);
string path = "LDAP://ADDOMAIN2/CN=CommonUsers,DC=ADDomain2,DC=ADDomain01,DC=WaveDomain";
directoryEntry.Path = path;
searcher.SearchRoot = directoryEntry;
searcher.Filter = "(&(objectCategory=person)(objectClass=user))";
SearchResultCollection rs = searcher.FindAll();
Any Idea what is wrong here?
Thanx
Try using some external LDAP browser (like the old and free version 2.6 of Softerra LDAP Browser) to check whether your query string is really pointing to the correct location.
DirectorySearcher is not used to find users inside a group. It's used to find objects under a base path. Since there is no user objects placed under your AD group object, you won't find anything.
In most cases, you can find the user objects in an AD group from its member attribute. Beware that AD group can contain either group or user. So, some of the entres there may be group. In some cases, the member attribute does not contain AD group nor AD user, it's containing a Foreign Security Principal. This happens if your user is coming from another forest. The primary group is also handled differently. Even "Domain User" is primary group of most of the users in AD, its member attribute doesn't contain anything at all. There are a lot other oddities that makes enumerating an AD group object really hard.
Fortunately, in .NET 3.5, Microsoft provides some useful classes in the framework to do the dirty work for you. Check out System.DirectoryServices.AccountManagement
To get some quick examples, you can check out this codeproject article
Your code should be something like this.
PrincipalContext context = new PrincipalContext(ContextType.Domain, "yourdomain.com");
GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(context, IdentityType.SamAccountName, "Domain Users");
foreach (Principal principal in groupPrincipal.GetMembers(false))
{
Console.Out.WriteLine(principal.DistinguishedName);
}
Console.In.ReadLine();

LDAP query for all users in sub OUs within a particular OU

The active directory I have to deal with is laid out as such: the domain contains many OUs. One of these OUs is named "Primary OU". Within this OU are several OUs named with location of global offices (ie "Chicago" "Paris").
Any user account that is an actual flesh and bone person is put into the OU named for the office they work in as their primary OU. Any user account that is an alias, generic account, or otherwise not directly tied to a real person, has the "Primary OU" OU set as their primary OU.
Data-wise, this primary OU distinction is the only thing that indicates which users are real people, and which users are not. There is no group that contains only real people, no indicator in any field that they are real people or not, and making any changes to active directory or any user accounts is strictly forbidden.
My task is writing a query that will only get all actual flesh and bone people.
Unfortunately LDAP is not exactly my strong suit and the only way I've come up with is searching each of these office sub OUs individually and putting all the results together, but there are a lot of offices and it would require a change to the query if any offices were added, which I need to avoid.
Is there a way to query all users within a particular OU's "sub" OUs, but not return any users directly in the parent OU?
Yes, sure - you would need to:
1) Bind to the particular OU
DirectoryEntry myOU = new DirectoryEntry("LDAP://OU=MyOU,......,DC=MyCompany,DC=com");
2) Enumerate all its sub-OU's
DirectorySearcher subOUsearcher = new DirectorySearcher(myOU);
subOUsearcher.SearchScope = SearchScope.OneLevel; // don't recurse down
subOUsearcher.Filter = "(objectClass=organizationalUnit)";
foreach(SearchResult subOU in subOUsearcher.FindAll())
{
// stick those Sub OU's into a list and then handle them
}
3) One-by-one enumerate all the users in each of the sub-OU's and stick them into a global list of users
DirectorySearcher userSearcher = new DirectorySearcher(myCurrentSubOu);
userSearcher.SearchScope = SearchScope.OneLevel; // don't recurse down
userSearcher.Filter = "(objectClass=user)";
foreach(SearchResult user in userSearcher.FindAll())
{
// stick those users into a list being built up
}
4) Return that list
Marc
// Create a new DirectorySearcher that starts at the root.
// You can start it anywhere you want though
// by providing a value in the DirectoryEntry constructor.
DirectorySearcher searcher = new DirectorySearcher(new DirectoryEntry());
// Set the scope to Subtree in order to search all children.
searcher.SearchScope = SearchScope.Subtree;
// Set the filter to only look for Organizational Units
// that have the name you are looking for.
searcher.Filter = "(&(objectClass=organizationalUnit)(name=" + ouName + "))";
// If you are looking for only one result then do the following two things.
SearchResult result = searcher.FindOne();
DirectoryEntry newDir = result.GetDirectoryEntry();

Resources