AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi LDAP/WINNT - versuche die Primary Group eines AD Users holen
Thema durchsuchen
Ansicht
Themen-Optionen

LDAP/WINNT - versuche die Primary Group eines AD Users holen

Offene Frage von "cherry"
Ein Thema von cherry · begonnen am 6. Mai 2010 · letzter Beitrag vom 10. Mai 2010
Antwort Antwort
Benutzerbild von cherry
cherry

Registriert seit: 14. Nov 2005
561 Beiträge
 
RAD-Studio 2009 Ent
 
#1

LDAP/WINNT - versuche die Primary Group eines AD Users holen

  Alt 6. Mai 2010, 16:22
Hallo Leute

Ich versuche grade die Primary Group eines AD Benutzers auszulesen...
1. Alle Gruppen via WINNT holen, da über den LDAP Provider die Primary Groups nicht aufgelistet werden. (DANKE!)
2. per ADSI IDirectorySearch wollte ich dann das PrimaryGroupToken der Gruppen holen und mit dem Benutzer Attribut PrimaryGroupID vergleichen.

Hier ist mein Problem:
Wenn ich statt nach PrimaryGroupID nach sAMAccountName suche, finde ich das ja unter "col.pADsValues^.__MIDL_0010.BackLink.ObjectNa me" -> Wenn ich nach PrimaryGroupID suche, ist dieser String immer nil... Wo ist nun mein Attribut??? irgendwo unter "col.pADsValues^.__MIDL_0010.*...." muss das ja sein oder????
Ist das nur mein Gefühl, oder ist die ganze Welt verrückt geworden!?
  Mit Zitat antworten Zitat
Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
934 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

Re: LDAP/WINNT - versuche die Primary Group eines AD Users h

  Alt 6. Mai 2010, 17:47
Hallo cherry,

du wühlst jetzt schon so lange im ADS-Djungel umher und hast immer noch nicht bei MSDN nachgelesen.

So wird das nichts.

Bis zum nächsten Mal.

Viele Grüße

PS Ist nicht Bös gemeint
  Mit Zitat antworten Zitat
Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
934 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

Re: LDAP/WINNT - versuche die Primary Group eines AD Users h

  Alt 7. Mai 2010, 17:48
Hallo cherry,

nicht gleich Sauer sein.

Das mit der PrimaryGroup ist so eine Sache für sich, nicht ganz Trival.

Als erstes musst du dir die TokenID der Gruppe besorgen, sollte über IADSUser gehen.
Danach benötigst du eine OleDbConnection: "Provider=ADsDSOObject;Encrypt Password=False;Mode=Read;Bind Flags=0;ADSI Flag=-2147483648".
Weiter geht es mit einem OleDBCommand, deren Connection-Eigenschaft auf die vorher erzeugte OleDBConnection verweist und übergibst
dem CommendText folgenden Wert: " String.Format("SELECT distinguishedName, cn, primaryGroupToken FROM '{0}' WHERE objectCategory='group'", Utility.ADsPath);"

Utility.ADsPath ist hier der distingushedName.

Ein OleDBComand.Open, .read und .getValue = fertig.

Ein Delphi-Beispiel habe ich nicht, aber eines in C#:
Code:
        internal static string GroupNameByTokenID(int primaryGroupToken)
        {
            string groupName = String.Empty;
            OleDbConnection connection = new OleDbConnection("Provider=ADsDSOObject;Encrypt Password=False;Mode=Read;Bind Flags=0;ADSI Flag=-2147483648");
            OleDbCommand command = new OleDbCommand();
            command.Connection = connection;
            command.CommandText = String.Format("SELECT distinguishedName, cn, primaryGroupToken FROM '{0}' WHERE objectCategory='group'", Utility.ADsPath);
            connection.Open();
            OleDbDataReader dr = command.ExecuteReader();
            while (dr.Read())
            {
                if (primaryGroupToken == dr.GetInt32(0))
                {
                    groupName = dr.GetValue(1).ToString();
                    break;
                }
            }
            dr.Close();
            return groupName;
        }
Ich hoffe es hilft dir weiter.

Bis bald

Alter Mann
  Mit Zitat antworten Zitat
Benutzerbild von cherry
cherry

Registriert seit: 14. Nov 2005
561 Beiträge
 
RAD-Studio 2009 Ent
 
#4

Re: LDAP/WINNT - versuche die Primary Group eines AD Users h

  Alt 10. Mai 2010, 13:11
Lieber Alter Mann

Danke schon mal für deine Antwort(die Zweite )... natürlich habe ich bei MSDN gesucht nun leider finde ich das was ich suche nicht immer... da arbeite ich noch drann...
Nun habe dein C# Code mal für Delphi übersetzt...
soweit so gut, das klappt auch prima. Da gibts nur ein Problem:
Ich lese alle Gruppen aus und vergleiche die ID, das ist "langsam" und irgendwie doof...

Über den WINNT Provider kriege ich ja bereits alle Gruppen, inkl. der Primären... jetzt wollte ich eben nur die Gruppen vergleichen...
Die suche wollte ich eben mit IDirectorySearch machen: die Suche ist kein Problem doch ich kriegs einfach nicht hin das Attribut "primaryGroupToken" auszulesen, respektive weiss nicht wo sich das befindet im pADsValues... col.pADsValues^.__MIDL_0010.Integer sollte es meiner meinung nach sein, gibt aber immer ne 0 zurück...

Bei (deiner) Variante weiss ich aber nicht wie ich beim SELECT z.B. WHERE cn='gruppe1' or cn='gruppe23' mitgeben kann. Jeder Versuch in der WHERE Klausel ein OR oder AND mitzugeben scheitert.

PS: Hier meine Übersetzung...

Delphi-Quellcode:
function TEADSUsers.GroupNameByTokenID(primaryGroupToken: Integer): string;
var
  ADOConn: TADOConnection;
  ADOSet: TADODataSet;
  I: Integer;
begin
  result := '';
  ADOConn := TADOConnection.Create(nil);
  ADOConn.Provider := 'ADsDSOObject';
  ADOConn.LoginPrompt := false;
  ADOConn.ConnectionString := 'Provider=ADsDSOObject;Encrypt Password=False;Mode=Read;Bind Flags=0;ADSI Flag=-2147483648';
  ADOSet := TADODataSet.Create(nil);
  ADOSet.Connection := ADOConn;
  ADOSet.CommandText := 'SELECT distinguishedName, cn, primaryGroupToken FROM '''+ADSMgr.EADSController.LDAPPATH+''' WHERE objectCategory=''group''';
  ADOSet.Open;
  ADOSet.First;
  for I := 0 to ADOSet.RecordCount -1 do
  begin
    if ADOSet.Fields[0].AsInteger = primaryGroupToken then
      result := ADOSet.Fields[1].AsString;
    ADOSet.Next;
  end;
end;
Ist das nur mein Gefühl, oder ist die ganze Welt verrückt geworden!?
  Mit Zitat antworten Zitat
Benutzerbild von cherry
cherry

Registriert seit: 14. Nov 2005
561 Beiträge
 
RAD-Studio 2009 Ent
 
#5

Re: LDAP/WINNT - versuche die Primary Group eines AD Users h

  Alt 10. Mai 2010, 14:37
hmm...
habs jetzt so gelöst. Jetzt werden nur noch die Gruppen durchsucht von denen der Benutzer mitglied ist...
Das unschöne daran: Ich kann das Attribut "primaryGroupToken" nicht direkt mit IDirectorySearch auslesen, hab jedenfalls nicht herausgefunden wie.
Für Vorschläge fürs "verschönern" und/oder "vereinfachen" der Methode bin ich empfänglich.

Delphi-Quellcode:
{******************************************************************************}
// USER: GET PRIMARY GROUP FOR USER
// do it with WINNT Service, it gets also the primary group...
// read this article for better understanding visit:
// [url]http://support.microsoft.com/kb/321360[/url]
//
// after getting all groups name with WINNT provider we get the LDAPPATHES
// of the groups and then get the Attribute Primary Group Token.
// After comparing with Primary Group ID from the user, we know its
// Primary Group.
{******************************************************************************}
function TEADSUsers.GetPrimaryGroupForUser(user: IADsUser): string;
var
  tmp: OleVariant;
  sAMAccountName: string;
  PGID: Integer;

  objUser: IADs;
  strPath: string;
  Enum: IEnumVariant;
  grps: IAdsMembers;
  grp: IAdsGroup;
  varGroup: OleVariant;
  Temp: LongWord;

  QueryFilter: string;

  search: IDirectorySearch;
  ptrResult: ADS_SEARCH_HANDLE;
  opt: ads_searchpref_info;
  dwCount: DWORD;
  hr: HResult;
  col: ads_search_column;

  dwErr: DWord;
  szErr : array[0..255] of WideChar;
  szName : array[0..255] of WideChar;

  AttrArray: array of PWideChar;

  gr: Array of OleVariant;
  groupPath: string;
  group: IADsGroup;
begin
  result := '';
  try

    // get sAMAccountName
    tmp := user.Get('sAMAccountName');
    sAMAccountName := String(tmp);

    // get Primary Group Id of the user
    tmp := user.Get('PrimaryGroupID');
    PGID := Integer(tmp);

    QueryFilter := '(|';

    // lists all of the groups the user belongs to
    strPath := 'WinNT://'+AdsMgr.ADSController.GetDomain+'/'+sAMAccountName;
    if SUCCEEDED(AccessObject(strPath, IID_IADs, objUser)) then
    begin
      grps := (objUser as IADsUser).Groups;
      Enum := grps._NewEnum as IEnumVariant;
      if Enum <> nil then
      begin
        while Enum.Next(1, varGroup, Temp) = S_OK do
        begin
          grp := IDispatch(varGroup) as IAdsGroup;
          QueryFilter := QueryFilter + '(sAMAccountName=' + grp.Name + ')'
        end;
      end;
    end;

    QueryFilter := QueryFilter + ')';

    // attribute we want to get...
    SetLength(AttrArray, 1);
    getmem(AttrArray[Length(AttrArray)-1], 256);
    //StringToWideChar('primaryGroupToken', AttrArray[Length(AttrArray)-1], 256);
    StringToWideChar('ADSPath', AttrArray[Length(AttrArray)-1], 256);

    // prepare for group.getInfoEx...
    SetLength(gr, 1);
    gr[0] := 'primaryGroupToken';

    // get the search object
    if SUCCEEDED(AccessObject(AdsMgr.ADSController.LDAPPATH, IDirectorySearch, search)) then
    begin
      // set parameters
      opt.dwSearchPref := ADS_SEARCHPREF_SEARCH_SCOPE OR ADS_SEARCHPREF_SORT_ON;
      opt.vValue.dwType := ADSTYPE_INTEGER;
      opt.vValue.__MIDL_0010.Integer := ADS_SCOPE_SUBTREE;
      // setting search preferences
      if not SUCCEEDED(search.SetSearchPreference(opt, 1)) then
      begin
        ADsGetLastError(dwErr, @szErr[0], 254, @szName[0], 254);
        ShowMessage(WideCharToString(szErr));
        Exit;
      end;
      // prepare
      dwCount := Length(AttrArray);
      // execute the search
      hr := search.ExecuteSearch(LPCWSTR(QueryFilter), @AttrArray[0], dwCount, ptrResult);
      // handle the result if hr is S_OK
      if SUCCEEDED(hr) then
      begin
        hr := search.GetNextRow(ptrResult);
        while hr <> S_ADS_NOMORE_ROWS do
        begin
          if Succeeded(search.GetColumn(ptrResult, AttrArray[0], col)) then
          begin
            if col.pADsValues <> nil then
            begin
              groupPath := col.pADsValues^.__MIDL_0010.BackLink.ObjectName;
              // get group
              group := ADsMgr.ADSGroups.GetGroup(groupPath);
              // update cache
              group.GetInfoEx(gr, 0);
              tmp := group.Get('primaryGroupToken');
              // compare token
              if Integer(tmp) = Integer(PGID) then
              begin
                result := groupPath;
                exit;
              end;
            end;
            search.FreeColumn(col);
          end;
          hr := search.GetNextRow(ptrResult);
        end;
      end;
      search.CloseSearchHandle(ptrResult);
    end;
  except
    on e: EOleException do
      AdsMgr.SetLastError(e.Message);
  end;
end;
Ist das nur mein Gefühl, oder ist die ganze Welt verrückt geworden!?
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:06 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz