* * *

Author Topic: LDAP, objectsid is there a cross platform method for converting to string?  (Read 597 times)

snorkel

  • New member
  • *
  • Posts: 38
Hi,
I have a ldap application written with Synapse and what I want to do is get the users
primary group using the primarygroupID (which is a RID).  In order for this to work you have to
get the string representation of the binary objectsid attribute that LDAP returns and then replace that RID part of the SID with the primarygroupid and then use that string to find the users primary group very quickly.
The string representation of the binary sid looks like this:
S-1-5-21-2127521184-1604012920-1887927527-72713

There are windows API functions that will do this, but I couldn't find a cross platform way of doing it in FP/Lazarus. 

I found this which does a good job of explaining how to decode the objectsid:
http://blogs.msdn.com/b/oldnewthing/archive/2004/03/15/89753.aspx

So if nothing already exists, it shouldn't be that big a deal to convert the binary to hex and then pull out the parts.


snorkel

  • New member
  • *
  • Posts: 38
Re: LDAP, objectsid is there a cross platform method for converting to string?
« Reply #1 on: February 10, 2012, 09:46:59 pm »
Well, I couldn't find anything already made for Pascal, so I came up with something.
I don't know if I did a good job on the math for converting the binary data to decimal numbers, but it works.
You can use the returned SID string in a LDAP query and pretty much instantly find the users primary group name.
If anyone knows a more elegant solution comments are welcome.

The function takes two ansistrings, one is the SID as retrieved using the Synapse ldapsend unit and the other
is the users primary group id.  The sid string contains the binary objectsid attribute from Active Directory.

Code: [Select]
function decode_sid(sid,pgid:ansistring):string;
var
   version,authority,s:string;
   subauth_count:integer;
   x,y,high,low:integer;
begin
     result:='S';
     //First byte is the version
     version:= intTostr(ord(sid[1]));
     result:=result+'-'+version;
     //Get the second byte
     authority:= intTostr(ord(sid[2]));
     result:=result+'-'+authority;
     //btye 8 is the number of sub auth
     subauth_count:= ord(sid[8]);
     high:=12;
     low:=9;
     //Process the sub authorities
     //For the purpose of getting the primary group
     //I skip the last one and instead use the
     //primary groupid value.
     for y := 0 to subauth_count-2 do
       begin
             for x := high  downto low do
                 s:=s+IntToHex(Ord(sid[x]), 2);
             s:=intTostr(strToint('$'+s));
             result:=result+'-'+s;
             high:=high+4;
             low:=low+4;
             s:='';
       end;
       result:=result+'-'+pgid;
end;


This is the result of the function:

S-1-5-21-1935655697-573735546-1801674531-136046

which can then be used in a search like this:

searchstr:=format('(objectSid=%s)',[sid]);
if fldap.Search(basedn,False,searchstr,attributes) then
    begin
            if fldap.SearchResult.Count > 0 then
               showmessage(fldap.SearchResult.Items[0].Attributes.Get('cn'));
    end;


« Last Edit: February 10, 2012, 09:51:55 pm by snorkel »

BigChimp

  • Hero Member
  • *****
  • Posts: 1012
    • CheckRide remote control and other open source projects
Re: LDAP, objectsid is there a cross platform method for converting to string?
« Reply #2 on: February 11, 2012, 08:41:17 am »
Good job, Snorkel.

Personnally, I prefer to have this kind of info/solution/working code available in the wiki (e.g. there's a page dealing with Synapse and one with Windows programming); could I suggest you consider putting the info up at the wiki next time a similar situation arises?

I'm saying this very carefully because I understand you asked for help, got none, found out stuff yourself, was generous enough to put the answer on the forum and then some bozo asks you for more. It's not meant that way, just to let you know of an alternative way of posting relevent help data/snippets.


Thanks,
BigChimp
CheckRide remote control and other open source projects:
https://bitbucket.org/reiniero/

snorkel

  • New member
  • *
  • Posts: 38
Re: LDAP, objectsid is there a cross platform method for converting to string?
« Reply #3 on: February 11, 2012, 03:51:09 pm »
Hi,
I have some spare time next week and I could add a section to the wiki on Synapse and LDAP with this example and how to authenticate and search, get user attributes
etc.
I created a wiki acount, but I don't see how to add a new section to the Synapse one.  Does a admin have to do that?

BigChimp

  • Hero Member
  • *****
  • Posts: 1012
    • CheckRide remote control and other open source projects
Re: LDAP, objectsid is there a cross platform method for converting to string?
« Reply #4 on: February 11, 2012, 03:56:01 pm »
Great, Snorkel, thanks.

If you're logged in to the wiki, and open an article (not the main page, that's locked), you should see a menu Views to the right. There should be an Edit hyperlink there, which allows you to edit the entire page content at once.

Additionally, [edit] links will pop up for subsections, which allow you to edit the... well you get my drift.

Under Navigation/Help you get acces to this link: http://wiki.lazarus.freepascal.org/Help:Editing with more details on editing, but even I could do simple edits without it  :)

Also, under Navigation/Recent changes, you can see what pages other users have recently edited, so you can keep up to date with new info  :)

If you search for a page that doesn't exist, the wiki offers to create the page for you - that's one way of creating brand new pages.

Thanks again,
BigChimp
CheckRide remote control and other open source projects:
https://bitbucket.org/reiniero/

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads