Sorry for the delay. Too many things going on. I flagged this to come back to and finally got a chance. Quickies that I see during the day I will fire off, the ones that take a little thought I come back to. :) Especially for this list I try to make sure my ducks are in a row so that I don't get smacked about too much.

Forgive converting to HTML, it makes this post easier to read, at least for me, and since this is all freebee I will do what I like. ;o)


1a. If you want to check multiple bits and ALL bits need to be enabled then you want AND. If you want to check multiple bits and ANY of them can be enabled then you want OR. For a single bit, either one is fine.

1b. Always try to make positive searches instead of NOTed search. A NOT in the filter is more inefficient generally than anything positive you do. Also a NOT filter can give you false positives. This can occur if there are values you aren't expecting or you don't have permissions on the attribute your are NOTing on some objects that you can otherwise see. For example, there are some groups for AzMan that will cause your NOT filter below to break. If you check out the MSDN Schema Def for groupType it looks like they finally got the changes I submitted up there for APP_BASIC and APP_QUERY[1].

Next since grouptype is indexed, you can toss out the objectcategory=group for the query to simply it.

The fastest query I can think of to get local and global groups would be

(grouptype:1.2.840.113556.1.4.804:=6)

The fastest query I can think of to get security enabled local groups would be

(samaccounttype=536870912)

To get all local groups would be

(&(samaccounttype=536870912)(samaccounttype=536870913))


To get security enabled global and universal groups

(samaccounttype=268435456)

To get all global and universal

(&(samaccounttype=268435456)(samaccounttype=268435457))

To understand the sAMAccountType values, use -samdc switch in adfind[2].



2. You can't query AD for the OIDs. If you use adfind, use -bit (which stands for bitwise operator) to tell it to replace occurrences of the string :AND: and :OR: in the strings to the OIDs for you like so (which finds disabled users)

adfind -default -bit -f "&(objectcategory=person)(useraccountcontrol:AND:=2)" -dn

I require the switch in the off chance you just might use :AND: or :OR: as part of your filter for some other reason.


3. Why does adfind output the grouptype in negative numbers. That is actually a very good question. From my end it is a simple answer but I will also give the hard answer... From the adfind standpoint, I ask for that value to come back as a string, Active Directory sends me back the string as you see it and I display it. So Adfind displays a negative number (actually a string of number characters preceded by a dash which we take to mean a negative number) because that is what AD gives it to display.

The deeper answer is found partially in the schema definition and partially in number representation in computers.

First the schema definition

G:\>adfind -sc s:grouptype

AdFind V01.31.00cpp Joe Richards ([EMAIL PROTECTED]) March 2006

Using server: r2dc1.test.loc:389
Directory: Windows Server 2003
Base DN: CN=Schema,CN=Configuration,DC=test,DC=loc

dn:CN=Group-Type,CN=Schema,CN=Configuration,DC=test,DC=loc
>objectClass: top
>objectClass: attributeSchema
>cn: Group-Type
>distinguishedName: CN=Group-Type,CN=Schema,CN=Configuration,DC=test,DC=loc
>instanceType: 4 [WRITABLE(4)]
>whenCreated: 20050805195858.0Z
>whenChanged: 20050805195858.0Z
>uSNCreated: 287
>attributeID: 1.2.840.113556.1.4.750
>attributeSyntax: 2.5.5.9 [INTEGER/ENUMERATION]
>isSingleValued: TRUE
>uSNChanged: 287
>showInAdvancedViewOnly: TRUE
>adminDisplayName: Group-Type
>adminDescription: Group-Type
>oMSyntax: 2
>searchFlags: 9 [INDEX(1);PRESERVE TOMBSTONE(8)]
>lDAPDisplayName: groupType
>name: Group-Type
>objectGUID: {58E64833-8403-4CA7-8D33-D66E64580BF2}
>schemaIDGUID: {9A9A021E-4A5B-11D1-A9C3-0000F80367C1}
>systemOnly: FALSE
>systemFlags: 18 [PAS-ATTR(2);CAT-1(16)]
>isMemberOfPartialAttributeSet: TRUE
>objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=test,DC=loc


1 Objects returned

Note you see that the attributeSyntax is 2.5.5.9 which is an integer (or enumeration which is a fancy name for an integer with fixed values). An integer value is 32 bits in length and has a sign. When I say it has a sign I don't mean it is running around with a chunk of cardboard that says "Save the world from morons!", it means that it can be positive OR negative. An value can be an unsigned integer as well which means it has no sign, all values represented are positive. The way you represent signs in integer values in computers commonly today is with a system called two's complement. This takes the leftmost (or highmost or most significant) bit and calls it the sign bit. If that bit is off, the value is positive, if the value is on, it is negative.

So if you have 32 bits available to express a positive number as you do in an unsigned integer, your effective range of values is 0 to (2^32)-1  (or 0 to 4294967295 decimal.... 0 to 0xFFFFFFFF HEX.... or 0 to 11111111111111111111111111111111 binary). If you take away a bit from the left side[3] you now have reduced the number of positive values by half to allow for negative values or given yourself a range of -(2^31) to (2^31)-1 (or -2147483648 to 2147483647 decimal.... -0x80000000 to 0x7FFFFFFF HEX... -10000000000000000000000000000000 to 1111111111111111111111111111111 binary[4]). You may also recall some earlier conversations about DNT's and what not also using 32 bit integers. A lot of things come down to the representation of numbers at the lowest levels and how they are handled.

Anyway... The "security" bit for groups just happens to be -2147483648 (0x80000000 HEX or 10000000000000000000000000000000 binary)... Look familiar? Yep, it is the sign bit of a 32 bit integer value.

When AD formats the string to send back to me, it looks at the attributeSyntax of the value and says, ah, a signed integer... It formats it accordingly which if it is a security enabled group means that the value will come back negative.

Now there is an interesting corollary here that some of you may have worked out previously or just now as I described this. I haven't ever seen anyone talk about doing it before so I am thinking most people haven't worked this out or maybe haven't thought about it because it isn't often needed... But.... This gives a slightly more efficient method (or at least an apparently slightly more efficient method) of querying for security groups... In all of my testing this has seemed to be slightly faster but I have not done any special code checks inside of AD for it nor any comprehensive charted testing... but, since every security group will be a negative value, it means you should be able to use <=-1 instead of a bitwise comparison. Bitwise is slower than a normal EQ, GE, LE type comparison so logically the fastest way to find security enabled groups would be to look for grouptypes<=-1 like so

adfind -default -f "grouptype<=-1" grouptype

Maybe Eric/Brett could chirp up on whether or not it should always be faster or not.

 

So if you liked reading this little bit on integer numbers and number representation I HIGHLY recommend a book called Code: The Hidden Language of Computer Hardware and Software written by none other than Charles Petzold. It is like $10-$12 and is one of the best reads for techie and semi-techie and even non-techie people who want to have some understanding of what computers are doing. If I taught a computer class, this book would be the required reading for every student because I don't feel today's universities are giving programmers a very good background on why we are where we are, instead just throwing Java and .NET at them and wondering why they are having various issues in real life and why the old folks write code that runs circles around theirs.

Here is a link straight to the book -> http://www.joeware.net/win/musthavebooks.htm

I should put this on my blog I think. Good question. :)

    joe




[1] http://msdn.microsoft.com/library/default.asp?url="">
[2] Or look here
http://msdn.microsoft.com/library/default.asp?url="">
[3] If you took away the bit from the right side you just took away all odd numbers...
[4] Yeah yeah, not proper to put signs on the Hex and Binary values... Did it for emphasis.

--
O'Reilly Active Directory Third Edition -
http://www.joeware.net/win/ad3e.htm






-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] On Behalf Of Matheesha Weerasinghe
Sent: Monday, June 12, 2006 4:08 PM
To: [email protected]
Subject: [ActiveDir] bitwise filters

Guys,

I have a few questions on bitwise filters.

1. I just wanna make sure I've understood bitwise filters correctly.
Basically if I want to check if all bits are set, I should use the
Bitwise AND operator. If I need to check if any number of the bits I
am interested in are set, I should use the OR operator. Therefore the
OR operator is best used in multiple bit checking scenarios. If I am
checking for only one bit (and not multiple bits)   , then I should
use the AND operator. I guess it really doesn't matter. Its just the
logic behind it.

If I want a list of global and local groups, I could either do a
search for groups that are not universal or I could do a seach for
groups that have the bit for either global or local set couldnt I? i.e
(&(objectcategory=group)(grouptype:1.2.840.113556.1.4.804:=6)) or
(&(objectcategory=group)(!(grouptype:1.2.840.113556.1.4.803:=8))).
Please correct me if I am wrong.

2. How do I find the bitwise filter OID for AND or OR without refering
to manuals. Can I query this in the directory or is it hardcoded?


3. Joe,

Could you please explain why the group type value output in adfind is
minus? If I do a query with -f
"(objectcategory=group)(grouptype:1.2.840.113556.1.4.803:=2147483650)"
grouptype, I get -2147483646 as the output. The results are correct. I
just want to understand why the output is minus.

Thanks

M@



Reply via email to