Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Принадлежность группе пользователя в AD [D7, WinXP]


ilshat ©   (2008-09-02 10:15:00) 

Как выяснить принадлежит ли пользователь определенной группе в Active Directory?


ronin2007   (2010-06-11 08:15:00) [1]

Ещё раз, немного подправленная, т.к. обнаружились баги:

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;


ronin2007   (2010-06-11 05:59:00) [2]

Переделал немного под себя. Теперь обрабатывается вложенность групп. Убрал параметр имя домена, т.к. он у меня один. Кому надо, легко может добавить.
Пользуйтесь наздоровье.

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   (2010-06-08 12:26:00) [3]

Функция очень полезная, да вот только возникает вопрос, а если пользователь напрямую не входит в заданную группу? Т.е. входит в какую-то, а та в свою очередь входит в заданную. Как подправить эту функцию?


stepka   (2009-08-31 19:06:00) [4]

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'


Weaver   (2009-07-08 18:02:00) [5]

используется связка ADOConnection и ADOQuery. В ADOConnection прописан провайдер и связка имя пароль (точную строку в данный момент не приведу). Открытие ADOConnection срабатывает успешно. Затем пытаюсь открыть ADOQuery (с вышеуказанным запросом) - срабатывает исключение с текстом "Отсутствует право доступа"


clickmaker   (2009-07-08 12:59:00) [6]

а логин-пароль не нужны в ConnectionString?


Weaver   (2009-07-08 12:16:00) [7]

При запросе


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


Получаю "Отсутствует право доступа" ("Permission denied"). Пробовал на двух разных AD, в обоих имею самые полные права. Куда копать?


ilshat   (2008-09-02 15:08:00) [8]

написал сам.. недождалси

{*******************************************************}
{                                                       }
{     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.


Наверх

Титульная страница Поиск, карта сайта Написать письмо