Конференция "Сети" » Принадлежность группе пользователя в AD [D7, WinXP]
 
  • ilshat (02.09.08 10:15) [0]
    Как выяснить принадлежит ли пользователь определенной группе в Active Directory?
  • ilshat (02.09.08 15:08) [1]
    написал сам.. недождалси

    {*******************************************************}
    {                                                       }
    {     Copyright (c) 2008 by Ilshat I. Fakhrislamov      }
    {*******************************************************}
    unit CheckUpUserInGroup;

    interface

    uses
    SysUtils,ADODB,Variants;

    function FCheckUpUserInGroup(UserName: string; GroupName: string; DomainName: string): boolean;

    implementation

    function FCheckUpUserInGroup(UserName: string; GroupName: string; DomainName: string): boolean;
    var
     i: integer;
     ArrayMemberOf: variant;
     MemberOfString: string;
     NewADOConnection: TADOConnection;
     NewADOQuery: TADOQuery;
    begin
     Result := false;
     UserName:=AnsiUpperCase(Trim(UserName));
     GroupName:=AnsiUpperCase(Trim(GroupName));

     NewADOConnection:=TADOConnection.Create(nil);

     with NewADOConnection do
     begin
       LoginPrompt:=false;
       ConnectionString:='Provider=ADsDSOObject;Encrypt Password=False;Mode=Read;Bind Flags=0';
     end;
     NewADOQuery:=TADOQuery.Create(nil);
     with NewADOQuery do
     begin
       SQL.Text:='select memberof from ''LDAP://'+DomainName+''' where userPrincipalName='''+UserName+'@'+DomainName+'''';
       Connection:=NewADOConnection;
     end;
     NewADOQuery.Open;

     if not NewADOQuery.IsEmpty then
     begin
       ArrayMemberOf:=NewADOQuery.FieldByName('memberof').AsVariant;
       i:=VarArrayLowBound(ArrayMemberOf,1);
       while i<=VarArrayHighBound(ArrayMemberOf,1) do
       begin
         MemberOfString:=VarToStr(NewADOQuery.FieldByName('memberof').Value[i]);
         i:=i+1;
         if Pos(GroupName,AnsiUpperCase(MemberOfString))>0 then Result:=true;
       end;
     end;

     NewADOQuery.Close;
     NewADOQuery.Destroy;
     NewADOConnection.Destroy;
    end;

    end.
  • Weaver (08.07.09 12:16) [2]
    При запросе


    select distinguishedName,Name from 'LDAP://DC=*,DC=*' where objectClass='user' or objectClass='group'



    Получаю "Отсутствует право доступа" ("Permission denied"). Пробовал на двух разных AD, в обоих имею самые полные права. Куда копать?
  • clickmaker © (08.07.09 12:59) [3]
    а логин-пароль не нужны в ConnectionString?
  • Weaver (08.07.09 18:02) [4]
    используется связка ADOConnection и ADOQuery. В ADOConnection прописан провайдер и связка имя пароль (точную строку в данный момент не приведу). Открытие ADOConnection срабатывает успешно. Затем пытаюсь открыть ADOQuery (с вышеуказанным запросом) - срабатывает исключение с текстом "Отсутствует право доступа"
  • stepka (31.08.09 19:06) [5]
    select distinguishedName,Name from 'LDAP://DC=*,DC=*' where objectClass='user' or objectClass='group' ошибка в этой строке скорее всего т.к. у вас запрос не дописан полностью.
    У мен ябыла такая же ошибка с ограниченным доступом, вылечилось вот так:
    select distinguishedName,Name from 'LDAP://CN=Users,DC=domain,DC=ru' where objectClass='user' or objectClass='group'
  • ronin2007 © (08.06.10 12:26) [6]
    Функция очень полезная, да вот только возникает вопрос, а если пользователь напрямую не входит в заданную группу? Т.е. входит в какую-то, а та в свою очередь входит в заданную. Как подправить эту функцию?
  • ronin2007 © (11.06.10 05:59) [7]
    Переделал немного под себя. Теперь обрабатывается вложенность групп. Убрал параметр имя домена, т.к. он у меня один. Кому надо, легко может добавить.
    Пользуйтесь наздоровье.

    function FCheckUpUserInGroup(UserName: string; GroupName: string): boolean;
    var
    i: integer;
    ArrayMemberOf: variant;
    MemberOfString: string;
    NewADOConnection: TADOConnection;
    NewADOQuery: TADOQuery;
    CheckedGroups:String; //Здесь будут запоминаться уже проверенные группы
      function CheckUpGroupInGroup(GroupName1,GroupName2:String):boolean;
      var
        i: integer;
        ArrayMemberOf: variant;
        MemberOfString: string;
        NewADOConnection: TADOConnection;
        NewADOQuery: TADOQuery;
      begin
        Result := false;
        GroupName1:=AnsiUpperCase(Trim(GroupName1));      //искомая группа
        GroupName2:=AnsiUpperCase(Trim(GroupName2));      //группа, в которую  входит пользователь
        if GroupName1=GroupName2 then
        begin
          Result:=true;
          Exit;
        end;
        if pos(','+GroupName2+',',CheckedGroups)>0 then Exit; //Выходим, если эта группа уже проверялась
        // нужно узнать не входил ли группа GroupName2 в группу GroupName1
        //Для этого смотрим в какие группы входит GroupName2 и повторяем для каждой группы CheckUpGroupInGroup(GroupName1,GroupName2)
        NewADOConnection:=TADOConnection.Create(nil);
        NewADOQuery:=TADOQuery.Create(nil);
        try
          with NewADOConnection do
          begin
            LoginPrompt:=false;
            ConnectionString:='Provider=ADsDSOObject;Encrypt Password=False;Mode=Read;Bind Flags=0';
          end;

          //ищем в какие группы входит группа GroupName2
          with NewADOQuery do
          begin
            SQL.Text:='select memberof from ''LDAP://DC=MyDomen,DC=ru'' where objectcategory=''group'' and samaccountname='''+GroupName2+'''';
            Connection:=NewADOConnection;
          end;
          NewADOQuery.Open;
          if not NewADOQuery.IsEmpty then
          if not NewADOQuery.FieldByName('memberof').IsNull then
          begin
            ArrayMemberOf:=NewADOQuery.FieldByName('memberof').AsVariant;
            i:=VarArrayLowBound(ArrayMemberOf,1);
            while i<=VarArrayHighBound(ArrayMemberOf,1) do
            begin
              MemberOfString:=VarToStr(NewADOQuery.FieldByName('memberof').Value[i]);
              MemberOfString:=ExtractWord(1,MemberOfString,[',']);
              MemberOfString:=ExtractWord(2,MemberOfString,['=']);
              MemberOfString:=AnsiUpperCase(MemberOfString);
              i:=i+1;
              if CheckUpGroupInGroup(GroupName1,MemberOfString) then
              begin
                Result:=true;
                break;
              end
              else
              CheckedGroups:=CheckedGroups+MemberOfString+',';
            end;
          end
          else CheckedGroups:=CheckedGroups+GroupName2+',';
        finally
          NewADOQuery.Close;
          NewADOQuery.Destroy;
          NewADOConnection.Destroy;
        end;
      end;
    begin
    Result := false;
    UserName:=AnsiUpperCase(Trim(UserName));
    GroupName:=AnsiUpperCase(Trim(GroupName));
    CheckedGroups:=',';
    NewADOConnection:=TADOConnection.Create(nil);
    NewADOQuery:=TADOQuery.Create(nil);
    try
      with NewADOConnection do
      begin
        LoginPrompt:=false;
        ConnectionString:='Provider=ADsDSOObject;Encrypt Password=False;Mode=Read;Bind Flags=0';
      end;

      with NewADOQuery do
      begin
        SQL.Text:='select memberof from ''LDAP://DC=MyDomen,DC=ru'' where userPrincipalName='''+UserName+'@MyDomen.RU''';
        Connection:=NewADOConnection;
      end;
      NewADOQuery.Open;
      if not NewADOQuery.IsEmpty then
      if not NewADOQuery.FieldByName('memberof').IsNull then
      begin
        ArrayMemberOf:=NewADOQuery.FieldByName('memberof').AsVariant;
        i:=VarArrayLowBound(ArrayMemberOf,1);
        while i<=VarArrayHighBound(ArrayMemberOf,1) do
        begin
          MemberOfString:=VarToStr(NewADOQuery.FieldByName('memberof').Value[i]);
          MemberOfString:=ExtractWord(1,MemberOfString,[',']);
          MemberOfString:=ExtractWord(2,MemberOfString,['=']);
          MemberOfString:=AnsiUpperCase(MemberOfString);
          i:=i+1;
          if CheckUpGroupInGroup(GroupName,MemberOfString) then
          begin
            Result:=true;
            break;
          end;
        end;
      end;
    finally
      NewADOQuery.Close;
      NewADOQuery.Destroy;
      NewADOConnection.Destroy;
    end;
    end;
  • ronin2007 © (11.06.10 08:15) [8]
    Ещё раз, немного подправленная, т.к. обнаружились баги:

    function FCheckUpUserInGroup(UserName: string; GroupName: string): boolean;
    var
    i: integer;
    ArrayMemberOf: variant;
    MemberOfString: string;
    NewADOConnection: TADOConnection;
    NewADOQuery: TADOQuery;
    CheckedGroups:String; //Здесь будут запоминаться уже проверенные группы
     function CheckUpGroupInGroup(GroupName1,GroupName2:String):boolean;
     var
       i: integer;
       ArrayMemberOf: variant;
       MemberOfString: string;
       NewADOConnection: TADOConnection;
       NewADOQuery: TADOQuery;
     begin
       Result := false;
       if GroupName1=GroupName2 then
       begin
         Result:=true;
         Exit;
       end;
       if pos(','+GroupName2+',',CheckedGroups)>0 then Exit; //Выходим, если эта группа уже проверялась
       // нужно узнать не входил ли группа GroupName2 в группу GroupName1
       //Для этого смотрим в какие группы входит GroupName2 и повторяем для каждой группы CheckUpGroupInGroup(GroupName1,GroupName2)
       NewADOConnection:=TADOConnection.Create(nil);
       NewADOQuery:=TADOQuery.Create(nil);
       try
         with NewADOConnection do
         begin
           LoginPrompt:=false;
           ConnectionString:='Provider=ADsDSOObject;Encrypt Password=False;Mode=Read;Bind Flags=0';
         end;

         //ищем в какие группы входит группа GroupName2
         with NewADOQuery do
         begin
           SQL.Text:='select memberof from ''LDAP://DC=MyDomen,DC=ru'' where objectcategory=''group'' and samaccountname='''+GroupName2+'''';
           Connection:=NewADOConnection;
         end;
         NewADOQuery.Open;
         if not NewADOQuery.IsEmpty then
         if not NewADOQuery.FieldByName('memberof').IsNull then
         begin
           ArrayMemberOf:=NewADOQuery.FieldByName('memberof').AsVariant;
           i:=VarArrayLowBound(ArrayMemberOf,1);
           while i<=VarArrayHighBound(ArrayMemberOf,1) do
           begin
             MemberOfString:=VarToStr(NewADOQuery.FieldByName('memberof').Value[i]);
             MemberOfString:=ExtractWord(1,MemberOfString,[',']);
             MemberOfString:=ExtractWord(2,MemberOfString,['=']);
             MemberOfString:=AnsiUpperCase(MemberOfString);
             i:=i+1;
             if CheckUpGroupInGroup(GroupName1,MemberOfString) then
             begin
               Result:=true;
               break;
             end;
           end;
         end
         else CheckedGroups:=CheckedGroups+GroupName2+',';
       finally
         NewADOQuery.Close;
         NewADOQuery.Destroy;
         NewADOConnection.Destroy;
       end;
     end;
    begin
    Result := false;
    UserName:=AnsiUpperCase(Trim(UserName));
    GroupName:=AnsiUpperCase(Trim(GroupName));
    CheckedGroups:=',';
    NewADOConnection:=TADOConnection.Create(nil);
    NewADOQuery:=TADOQuery.Create(nil);
    try
     with NewADOConnection do
     begin
       LoginPrompt:=false;
       ConnectionString:='Provider=ADsDSOObject;Encrypt Password=False;Mode=Read;Bind Flags=0';
     end;

     with NewADOQuery do
     begin
       SQL.Text:='select memberof from ''LDAP://DC=MyDomen,DC=ru'' where samaccountname='''+UserName+'''';
       Connection:=NewADOConnection;
     end;
     NewADOQuery.Open;
     if not NewADOQuery.IsEmpty then
     if not NewADOQuery.FieldByName('memberof').IsNull then
     begin
       ArrayMemberOf:=NewADOQuery.FieldByName('memberof').AsVariant;
       i:=VarArrayLowBound(ArrayMemberOf,1);
       while i<=VarArrayHighBound(ArrayMemberOf,1) do
       begin
         MemberOfString:=VarToStr(NewADOQuery.FieldByName('memberof').Value[i]);
         MemberOfString:=ExtractWord(1,MemberOfString,[',']);
         MemberOfString:=ExtractWord(2,MemberOfString,['=']);
         MemberOfString:=AnsiUpperCase(MemberOfString);
         i:=i+1;
         if CheckUpGroupInGroup(GroupName,MemberOfString) then
         begin
           Result:=true;
           break;
         end;
       end;
     end;
    finally
     NewADOQuery.Close;
     NewADOQuery.Destroy;
     NewADOConnection.Destroy;
    end;
    end;
 
Конференция "Сети" » Принадлежность группе пользователя в AD [D7, WinXP]
Есть новые Нет новых   [134436   +25][b:0][p:0.001]