But notice the binary field :objectsid. This is the binary form of the string you may see sometimes when using AD, called SID, and it looks something like “S-1-5-21-123-456-789”. In order to find the users group you would take the :primarygroupid and the users :objectsid to generate the groups SID.
Only the last group of numbers in the SID corresponds to the current object, so to find the SID for another object we can just take off the last number group and replace it with the :primarygroupid, 1114. However, first we need to convert the binary string into a SID string.
The binary form of the SID is as follows:
byte 1: SID structure revision (always 1, but it could change in the future). This becomes the first number group.
byte 2: The number of sub-authorities in the SID. This is discarded for the string, but you can use it to work out the number of number groups ahead.
byte 3 – 9: Identifier Authority. This field should be converted to hexadecimal as the second number group.
byte 10 onwards: A variable length list of unsigned 32bit integers, the number of which is defined in byte 2.
Here is ruby code for doing the conversion:
sid = 
sid << data.to_s
rid = ""
(6).downto(1) do |i|
rid += byte2hex(data[i,1])
sid << rid.to_i.to_s
sid += data.unpack("bbbbbbbbV*")[8..-1]
"S-" + sid.join('-')
ret = '%x' % (b.to_i & 0xff)
ret = '0' + ret if ret.length < 2
Note: Originally I was using unpack with L* instead of V*. My tests were passing fine on my machine, but not on our CI server. As it turns out the endiness of L is dependent on the processor, and the CI is an old PPC G4.
Using the SID string you can now do an LDAP search with Net::LDAP::Filter.eq(“objectSID”, sid_string) to find the user. Replace the last number group with that from :primarygroupid and it’ll find the group. So if the user SID is S-1-5-21-123-456-789 and the :primarygroupid is 1114, the group’s SID will be S-1-5-21-123-456-1114.