-
Как выяснить принадлежит ли пользователь определенной группе в Active Directory?
-
написал сам.. недождалси
{*******************************************************} { } { 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.
-
При запросе
select distinguishedName,Name from 'LDAP://DC=*,DC=*' where objectClass='user' or objectClass='group'
Получаю "Отсутствует право доступа" ("Permission denied"). Пробовал на двух разных AD, в обоих имею самые полные права. Куда копать?
-
а логин-пароль не нужны в ConnectionString?
-
используется связка ADOConnection и ADOQuery. В ADOConnection прописан провайдер и связка имя пароль (точную строку в данный момент не приведу). Открытие ADOConnection срабатывает успешно. Затем пытаюсь открыть ADOQuery (с вышеуказанным запросом) - срабатывает исключение с текстом "Отсутствует право доступа"
-
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'
-
Функция очень полезная, да вот только возникает вопрос, а если пользователь напрямую не входит в заданную группу? Т.е. входит в какую-то, а та в свою очередь входит в заданную. Как подправить эту функцию?
-
Переделал немного под себя. Теперь обрабатывается вложенность групп. Убрал параметр имя домена, т.к. он у меня один. Кому надо, легко может добавить. Пользуйтесь наздоровье.
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;
-
Ещё раз, немного подправленная, т.к. обнаружились баги:
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;
|