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.
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@
