LDAP Filter Syntax Query - ldap

What would be the syntax for LDAP for the below scenario:
Where sAMAccountName = GRA-* without $. I want the records which are highlighted in green.
This is my current LADP Filter for your reference:
(&(objectClass=user)sAMAccountName=GRA-*))
Anyone, Please help with the correct syntax.

Your filter can work, but you're missing a ( in front of sAMAccountName:
(&(objectClass=user)(sAMAccountName=GRA-*))
But you may be able to do better. If those ones that end in $ are computer objects (which always have sAMAccountNames that end in $, but also have an objectClass of user), then you can make sure you only get user objects by including (objectCategory=person):
(&(objectClass=user)(objectCategory=person)(sAMAccountName=GRA-*))
If, for whatever reason, those $ objects are actually user accounts, then you can exclude them with (!sAMAccountName=*$):
(&(objectClass=user)(objectCategory=person)(sAMAccountName=GRA-*)(!sAMAccountName=*$))

Related

user wants to apply a quite complex "User Search Filter" in his LDAP Configuration

user have to apply a quite complex "User Search Filter" in his LDAP Configuration.
The filter is too big and exceed the 256 allowed character. For customer business policy is not possible to modify the LDAP structure or data How can we proceed?
Here there is a sample of the filter:
(&
(|
(memberOf=CN=Applicazione_DocB_AmmApplicativo,OU=Intranet,OU=Gruppi,DC=CBMAIN,DC=CBDOM,DC=IT)
(memberOf=CN=Applicazione_DocB_AmmPiattaforma,OU=Intranet,OU=Gruppi,DC=CBMAIN,DC=CBDOM,DC=IT)
(memberOf=CN=Applicazione_DocB_ArchFIRead,OU=Intranet,OU=Gruppi,DC=CBMAIN,DC=CBDOM,DC=IT)
(memberOf=CN=Applicazione_DocB_ArchFIWrite,OU=Intranet,OU=Gruppi,DC=CBMAIN,DC=CBDOM,DC=IT)
(memberOf=CN=Applicazione_DocB_AreaFinanza,OU=Intranet,OU=Gruppi,DC=CBMAIN,DC=CBDOM,DC=IT)
(memberOf=CN=Applicazione_DocB_Arm,OU=Intranet,OU=Gruppi,DC=CBMAIN,DC=CBDOM,DC=IT)
(memberOf=CN=Applicazione_DocB_BoGestCanc,OU=Intranet,OU=Gruppi,DC=CBMAIN,DC=CBDOM,DC=IT)
(memberOf=CN=Applicazione_DocB_BoUpdDocum,OU=Intranet,OU=Gruppi,DC=CBMAIN,DC=CBDOM,DC=IT)
(memberOf=CN=Applicazione_DocB_Crif,OU=Intranet,OU=Gruppi,DC=CBMAIN,DC=CBDOM,DC=IT)
(memberOf=CN=Applicazione_DocB_VisualBase,OU=Intranet,OU=Gruppi,DC=CBMAIN,DC=CBDOM,DC=IT)
(memberOf=CN=Applicazione_DocB_VisualEsteso,OU=Intranet,OU=Gruppi,DC=CBMAIN,DC=CBDOM,DC=IT)
)(|
(userAccountControl=512)
(userAccountControl=544)
(userAccountControl=66048)
)
)
Have the customer create one single group to control access to the application, then they can add all of those groups to that one group. Then you only need to look at that one group. However, you will need to use the LDAP_MATCHING_RULE_IN_CHAIN operator so that it will look at the members of nested groups.
If the name of that new group is Applicazione_DocB, that would look something like this:
(memberOf:1.2.840.113556.1.4.1941:=CN=Applicazione_DocB,OU=Intranet,OU=Gruppi,DC=CBMAIN,DC=CBDOM,DC=IT)
Your conditions on userAccountControl can also be simplified. That attribute is a bit flag, which means that each bit in the binary value is a flag that means something. Those values are listed in the documentation for userAccountControl. The three conditions you are using are:
512: ADS_UF_NORMAL_ACCOUNT
544: ADS_UF_NORMAL_ACCOUNT | ADS_UF_PASSWD_NOTREQD (password not required)
66048: ADS_UF_NORMAL_ACCOUNT | ADS_UF_DONT_EXPIRE_PASSWD (password does not expire)
If the intent is to exclude disabled accounts (514: ADS_UF_NORMAL_ACCOUNT | ADS_UF_ACCOUNTDISABLE), then you can do that by using the LDAP_MATCHING_RULE_BIT_AND operator to check if the second bit is not set (which indicates a disabled account), like this:
(!userAccountControl:1.2.840.113556.1.4.803:=2)
Putting that all together, you get a query that is less than 256 characters:
(&(memberOf:1.2.840.113556.1.4.1941:=CN=Applicazione_DocB,OU=Intranet,OU=Gruppi,DC=CBMAIN,DC=CBDOM,DC=IT)(!userAccountControl:1.2.840.113556.1.4.803:=2))

Trying to filter an AD export script in powershell by user type?

I've been asked to pull a report containing User's name, username, enabled/disabled, and the last login time from our Windows server 2008 domain. I'm using the script below and it's working, but the problem is it's pulling built-in security accounts and some system accounts, and I need just users. Does anyone know if this filtering is possible? The script I'm using is below. Thanks in advance!
$ADUserParams=#{
'Server' = 'servername.domain.local'
'Searchbase' = 'DC=domain,DC=local'
'Searchscope'= 'Subtree'
'Filter' = '*'
'Properties' = '*'
}
$SelectParams=#{
'Property' = 'CN', 'SAMAccountname', 'DisplayName', 'enabled', 'lastlogondate',
}
get-aduser #ADUserParams | select-object #SelectParams | export-csv "c:\temp\users.csv"
At the very least you'll want to modify your filter to something like:
'(&(|(objectclass=person)(objectclass=inetorgperson))(!(objectclass=computer)))'.
That will still leave Administrator, Guest and and domain/realm trusts you've got, but otherwise it's pretty clean.
'(&(sAMAccountType=805306368)(!(isCriticalSystemObject=TRUE)))' is even cleaner, and may be exactly what you need. This uses sAMAccountType, but I pulled from existing AD users rather than build that value from scratch.
Also there is no Enabled attribute. The closest you can get is userAccountControl. lastLogonDate is actually lastLogonTimestamp.
part of your requirements for the report are to show all users in AD, this would include system and built-in accounts. That being said, ff you can exclude the OUs or containers that contain the built-in/system accounts you don't want in the report that would be easiest. It looks like your trying to audit the whole AD DS and should use exclusions otherwise only include the OU that contains the User Accounts as long as it is only possible to not have User accounts anywhere else.
It really depends on what you can use to separate your built-ins and system accounts.
The easiest way would be to add a SearchBase to your $ADUserParams:
$ADUserParams=#{
'Server' = 'servername.domain.local'
...
'SearchBase' = 'OU=Lemmings,DC=contoso,DC=com'
}
If there's one OU that you need to filter out, try adding a Where-Object:
get-aduser #ADUserParams | ?{$_.DistinguishedName -notlike '*ou=Beancounters,*'} | select-object #SelectParams | export-csv c:\temp\users.csv"
The ?{ } bit is an alias for the Where-Object command. $_ represents the objects passed along the pipe.
This is all assuming that these accounts are cleanly separated by OU, however. I know this isn't true in my environment.
You might have to play around for a while before finding something that will separate your users cleanly. It might help to store your initial query as a variable, $users = Get-ADUser #ADUserParams, and see what you can pick apart:
$users | ?{$_.SomeProperty -eq 'SomeValue'}
Try running $users[0] to get an idea of what properties there might be to help you filter through these users. If you need to wrap your head around things like -eq and -like, take a look here.
If all the accounts you're wanting to filter contain a character like $, you could filter the output like so:
$users | ?{$_.SamAccountName -notlike "*$*"}

Need to build list of group members

I have a server with its own local Groups. These groups hold AD users. I use them to apply permissions for the user in a web app. I need to generate a list of all the users in the group.
This is the script I'm trying to use:
dsquery group -samid "MyGroup" | dsget group "MyGroup" -members >c:\List.txt
I've tried many generations of this code and all I get are errors. At least this one creates a text file before it errors (with nothing in it).
So what am I doing wrong (I confess I'm new to this command line tool).
EDIT: the error I'm getting is "dsget failed:Value for 'Target object for this command' has incorrect format."
Thanks in advance.
I too am a newbie.
But I beleive you want is:
dsquery group -name "MyGroup" | dsget group -members > c:\List.txt
Where you replace "MyGroup" with the name of the group you are looking for. If looking for multiple groups which begin the same way, surround MyGroup with asterisks instead of quotation marks.

Using DN in Search Filter

In my LDAP Client program sometimes I have to include the DN value within the search filter. But this DN is changing frequently and every I have to change this filter in my code.
When I googled it for that I got something like this
Suppose you want to pull all users of ObjectType = Person from the R&D and HR ous, but not any users from Marketing and PM. The filter would be:
(&(objectClass=person)(|(ou:dn:=ResearchAndDevelopment)(ou:dn:=HumanResources)))
Can anybody explain this more in detail?
You should check RFC 2254 (The String Representation of LDAP Search Filters).
LDAP filters use polish notation for the boolean operators. So the operator is written before its operands:
(&(condition1)(condition2)(condition3)...)
The example above means that you want all LDAP entries which satisfy condition1 AND condition2 AND condition3 and so on.
Then there are condition themselves. They are very simple and can consist only of few types:
present condition - (attrName=*)
simple condition - (attrName>=value) / (attrName<=value) / (attrNamevalue=value) / (attrName~=value)
substring condition - (attrName=*value*) / (attrName=*value) / (attrName=value*)
extensible condition - (attrName:dn:=value) / (attrName:matchingRule:=value)
The extensible condition with the :dn: keyword means, that you want attributes from the entry DN to be considered as well. So for your case entry cn=John Doe,ou=HumanResources,ou=Users,dc=example,dc=com would match the filter (ou:dn:=HumanResource).
Translating your example filter to an English sentence would be:
Find me all LDAP entries which have objectClass equal to person and have either ResearchAndDevelopment or HumanResources in their ou attribute or somewhere on their DN.
You can use dn into base and set search scope as base.
That is, set dn value into base, and set search scope as base(search scope is one of base, sub and one).
If you really need to search by the whole DN, you can search with:
(distinguishedName=CN=MyCommonName,OU=SomeEnv,...,DC=SomeDir)

Modify entry in OpenLDAP directory

I have a large Openldap directory. In the directory the display name property for every is filled but i need to modify these entry and make it like "givenName + + sn". Is there are way i can do it directly in the directory just like sql queries (update query). I have read about the ldapmodify but could not find the way to use it like this.
Any help in this regard will be appreciated.
There is no way to do this with a single LDAP API call. You'll always have to use one LDAP search operation to get givenname and sn attributes, and one LDAP modify operation to modify the displayName attribute.
If you use the command line ldaptools "ldapsearch" and "ldapmodify", you can do this easily with some shell scripting, but you'll have to be careful: sometimes ldapsearch(1) can return LDIF data in base64 format, with UTF-8 strings that contain characters beyond ascii. For instance: 'sn:: Base64data' (note the double ':')
So, if I were you I would use a simple script in my language of choice, that has an LDAP API, instead of using shell commands. This would save me the troubles of base64 decoding that the ldaptools sometimes impose.
For instance, with php-cli, your script would be roughly like this (perhaps some more error checking would be appropriate):
<?php
$ldap = ldap_connect('host');
ldap_bind($ldap, ...);
$sr = ldap_search($ldap, 'ou=people,...', 'objectclass=*');
$entries= ldap_get_entries($ldap, $sr);
for($i=0; $i<$entries['count']; $i++) {
$modify = array('displayname' => $entries[$i]['givenname'] . ' ' . $entries[$i]['sn']);
ldap_modify($ldap, $entries[$i]['dn'], $modify);
}
Addendum: if you want to keep this data up to date without any intervention, you will probably need to use a specialized OpenLDAP module that keeps "virtual" attributes, or even a virtual directory, such as Penrose or Oracle Virtual Directory, on top of OpenLDAP. However this might be overkill for a simple concatenation of attributes.