Querying AD: objectClass vs. objectCategory

Posting Updated: there are a few news around this – I’ve left the original post alone – only put a strike through the non-anymore-valid parts (almost all :-). News see below (you may click the “Read more” link.

I was recently talking to a group of devs who are responsible for writing an in-house app that queries AD. As the app is going to query a number of attributes and objects from along the run, I wanted to make sure they build that app in a way they could efficiently query AD.

(I’ll maybe post a line-up of a few guidelines on this in a few days).

The main things that I told them were:

- Do not use the objectClass attribute in your queries. There are two reasons why: it is not in the directory index and it is a multi-valued list. Some of these values are shared with all objects in the domain, as one of the values is “top” – the top object all objects are derived from. Use “objectCategory” instead. That is a single-valued attribute that’s in the index.

 Â

As you can see from the above picture, objectClass is not indexed in the Windows Server 2003 (including R2) schema by default. It has object identifier syntax which basically means that it holds an OID of an object of the directory. There is also a note that “This attribute is multi-valued” under the “Maximum” box that simply means it can hold multiple values. Values saved there are OIDs of all objects in the directory hierarchy it is derived from. For a user account, these are:

top; person; organizationalPerson; user;

interestingly, the same four OIDs are there for a computer object, including a “computer” OID derived from “user”:

 That means that a computer object is derived from a user object. Anyway, what the output above really means is: when using a filter like (objectClass=user), we’ll surely get a list of all computers as well.

Looking at the objectCategory attribute instead, it has a DN syntax which means that it has a DN stored that leads to an object in the directory.
For computers, it is:
objectCategory: CN=Computer,CN=Schema,CN=Configuration,DC=intern,DC=frickelsoft,DC=net;
For users, we have:
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=intern,DC=frickelsoft,DC=net;
that helps us differenciate between users and computers a lot. That’s the third advantage over objectClass, next to the fact that it is single-valued and indexed.

When searching for an objectCategory, you don’t have to specify the full DN like
(objectCategory=DN=Person,CN=Schema,CN=Configuration,DC=intern,DC=frickelsoft,DC=net) – you can simply use the LDAP display name, like
(objectCategory=user) – it’ll get automagically translated to the right DN.

“News” start here (I call them news as they were exactly that to me :-):

One of the devs I was talking to regarding the things they should and shouldn’t do for LDAP access came to me just to tell me that objectClass was indexed in their environment - although I told them that you shouldn’t do that and it wouldn’t be recommended. To my surprise, he was right! I checked with a few machines I call my own and came to the conclusion, that objectClass found its way into the AD indeces after you update the Schema to Server 2008 (or Ex2007 whatever comes first). How could I miss that? I asked some smart folks over at the activedir.org mailing list and what arose was this conversation: http://www.activedir.org/ListArchives/tabid/55/forumid/1/postid/31737/view/topic/Default.aspx

To sum up the conclusions of the conversation:

* objectClass is indexed once you put schema Server 2008 or Exchange 2007 into place
* you cannot un-index objectClass as it is hard-coded. Unchecking the box doesn’t do anything.
* major orgs used objectClass before as simply queries for users only worked with objectClass in combination with objectCategory (&(objectClass=user)(objectCategory=person))
* ESE performed not well on objectClass the early days – it even performed worse if you indexed it
* ESE now performs better on objectClass – but might choose the wrong path for the query and still end up calculating “inefficient”.

4 Comments so far

  1. Mike Kline on December 8th, 2008

    Hey Florain,

    I’m really enjoying your blog. I know you know this but just for future readers. You say don’t use objectclass in the queries.

    It is fine to use if combined, for instance

    (&(objectCategory=person)(objectClass=user)) is a good query to use.

    Thanks
    Mike

  2. florian on December 8th, 2008

    Thanks Mike,

    I’m going to update the article tomorrow or the day after tomorrow. There are a few things about this. The query you mentioned for example is the only valid query for getting user objects only from the directory.

    When updating the schema to Win2008, you’ll notice that the objectClass gets indexed (hard coded) – the MS guys came to the clue that it needs objectClass and some larger orgs would index it by default.

    Thanks,

    Florian

  3. Christian Schroeder on June 26th, 2014

    Hello Florian,

    do you think it is a good idea to enable the indexing of objectClass for Windows Server 2003 DCs / Domains?

    Thanks,

    Christian

  4. florian on June 30th, 2014

    Christian,

    I’d have to look into the specifics – but I was under the impression that objectClass and objectCategory are treated “specially”, and have a separate index used when querying. You should be able figure that out using the LDAP stats control – or with ADFind’s -stats parameter.

    I’ll see if I can make time in the next couple days to find out more.

    thanks!
    Florian