Einzelnen Beitrag anzeigen

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