LDAP filter issues
Posted by: Richard Siddaway
I have been using LDAP filters a lot recently. One thing that can cause subtle errors that are difficult to track down are LDAP filters.
As an example consider this code which discovers all objects with the creatorSID attribute set and then resolves that SID to discover the user who created the object. The creatorSID attribute is not set if a domain admin creates the object
function Resolve-SIDtoUser { param ([byte[]]$sid) $sb = New-Object -TypeName System.Text.StringBuilder for ($i=0; $i -lt $sid.Length; $i++){ $sb.AppendFormat("\{0}", $sid[$i].ToString("X2")) | Out-Null } $strsid = $sb.ToString() $root = [ADSI]"" $search = [adsisearcher]$root $search.Filter = "(objectSID=$strsid)" $search.FindOne() | foreach { return $_.Properties.name } } $dom = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() $domain = $dom.GetDirectoryEntry() $dn = $($domain.distinguishedname) "`nScript" $root = [ADSI]"" $search = [adsisearcher]$root $search.Filter = "(mS-DS-CreatorSID=*)" $search.SizeLimit = 3000 $search.FindAll() | foreach { $obj = $_.GetDirectoryEntry() $user = Resolve-SIDtoUser $obj.Properties."mS-DS-CreatorSID".value $obj | select @{N="ObjectClass"; E={$_.SchemaClassName}}, @{N="Name"; E={$_.name}}, @{N="DistinguishedName"; E={$_.distinguishedname}}, @{N="Creator"; E={$user}} } | Format-Table -AutoSize
In this we have to LDAP filters. The one at the bottom
$search.Filter = "(mS-DS-CreatorSID=*)"
fires first and checks for all objects that have the ms-DS-CreatorSID attribute set.
What would happen if this was changed to
$search.Filter = "(mS-DS-CreatorSID=* )"
Looks the same at first glance but actually you would get nothing back! In the original version * indicates that the attribute has a value. You are dealing with strings in the filter to the change looks for ‘* ‘ i.e. something followed by a space!
However
$search.Filter = "(mS-DS-CreatorSID= *)"
does work because the * is still by itself.
This also is an issue if you are using variable substitution to create the filter. Consider the filter in the resolve-sidtouser function
$search.Filter = "(objectSID=$strsid)"
On the face of it changing this to
$search.Filter = "(objectSID=$strsid )"
shouldn’t matter but its the same case as above the space counts.
These rules also apply if you are using an LDAP filter with the Microsoft cmdlets, Quest cmdlets or the provider
The bottom line with LDAP filters be careful of spaces and don’t leave any after the filter definition.




