When it comes to searching for an object in the LDAP directory (like Active Directory) most of us will use a LDAP filter to display the objects we are looking for. An LDAP filter is a quick and easy way to construct queries that will be excecuted against the target directory service. Most of the queries are built to query objects of specified class or category for some attributes with additional conditions to narrow the query results, eg:
(&(objectCategory=person)(cn=John Smith))
And interesting situation I came across was when I wanted to perform a query with additional conditions based on some attribute of an object, using a wildcard '*' as an condition in my query I can expect that in a result I will get all the objects regardless of this attribute value. This is only partial true, because such query will not return for us an objects in which this attribute will not have any value (will not be set even for null value). The original problem which pushed me to write this short article was a question from the user how to find all the Active Directory users with Exchange mailboxes and OWA access enabled. Finding all users with mailboxes is pretty easy, but the problem started when it comes to query against enabled protocols. Enabled Exchange protocols configuration is stored in protocolSettings AD attribute. This attribute has no value set if an use has default protocols enabled (which includes OWA because by default all Exchange protocols are enabled for all users). If uses has not default settings for some protocol this attribute has an value which contains modification to the defaults. These modifications are stored in the string format as a value of protocolSettings attribute, for example string valu for HTTP access will look like this "http'1'1'". So first approach which we can use to find all the users with OWA enabled is to user LDAP query as stated below:
(&(objectCategory=person)(protocolSettings=*http'1'1'*))
But in fact we will fail because this will give us only these users who has not default settings for HTTP access to the OWA. Using wildcard for this query:
(&(objectCategory=person)( protocolSettings=*))
Will also not give us expected results because this filter will only give us users with *some* value in the protocolSettings attribute, and as I stated earlier users with default settings are not having any value for this attribute (not null but ). So to get all the users with default settings (which is OWA enabled) and those who has not default settings of the protocols but OWA also is enabled for them we have to use combination of the attributes with a little trick:
(&(&(objectcategory=Person)(homeMDB=*)(|(!(protocolSettings=*))(protocolSetting=*http'1'1')))
As You can see we are using negation of the wildcard to get all of the objects without any value in the protocolSettings attribute. Sometimes such approach can be useful and will require some additional logic in our script or application – because if we want to get all the users from the directory with query based on some attribute we can expect that there can be an object without any value in this attribute – so we have to query twice or construct our LDAP filter in the way showed above.