LarsFosdal

Get AD User Group Memberships

Dec 19th, 2014
585
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. unit ActiveDSUtil;
  2.  
  3. /// Written by Lars Fosdal, 16 DEC 2014, using Delphi XE7
  4. /// Note that calling AD functions is slow.
  5. /// To create ActiveDS_tlb, in the IDE, go View|Installed Type Libraries
  6. /// Find "Active DS Type Library", right click, select Import,
  7. /// use defaults for first page, then "Create Unit" on second page
  8.  
  9. interface
  10. uses
  11.   Classes, SysUtils, ActiveX, ActiveDS_tlb, web.win.adstypes;
  12.  
  13. type
  14.   TADGroupList = array of String;
  15.   TAnonParamFunc<TA,TR> = reference to function (const v:TA):TR;
  16.  
  17.   /// <summary> Enumerates the group memberships of an AD user </summary>
  18.   function EnumADUserGroupMemberships(const aDomain, aUser: String; EnumHandler: TAnonParamFunc<IAdsGroup, Boolean>):Boolean;
  19.  
  20.   /// <summary> Returns a list of all AD groups for an AD user </summary>
  21.   function GetADUserGroupMemberships(const aDomain, aUser: String):TStringList;
  22.  
  23.   /// <summary> Checks if an AD user is member of one or more specific groups</summary>
  24.   function UserHasADGroupMembership(const aDomain, aUser: String; const GroupList: TAdGroupList): Boolean;
  25.  
  26.  
  27. implementation
  28.  
  29. function EnumADUserGroupMemberships(const aDomain, aUser: String; EnumHandler: TAnonParamFunc<IADsGroup, Boolean>):Boolean;
  30. var
  31.   hr: HREsult;
  32.   User: IADsUser;
  33.   Enum: IEnumVariant;
  34.   varGroup: OleVariant;
  35.   EnumHelper: LongWord;
  36. begin
  37.   Result := False;
  38.   CoInitialize(nil);
  39.   try
  40.     hr := ADsGetObject('WinNT://'+aDomain+'/'+aUser+',user',IID_IADsUser3 , User);
  41.     if not Failed(hr)
  42.     then begin
  43.       try
  44.         Enum := User.Groups._NewEnum as IEnumVariant;
  45.         while Assigned(Enum) and (Enum.Next(1, varGroup, EnumHelper) = S_OK)
  46.         do begin
  47.           try
  48.             if EnumHandler(IDispatch(varGroup) as IADsGroup)
  49.              then EXIT(True);
  50.           finally
  51.             VariantClear(varGroup);
  52.           end;
  53.         end;
  54.       finally
  55.         User := nil;
  56.       end;
  57.     end;
  58.   finally
  59.     CoUninitialize;
  60.   end;
  61. end;
  62.  
  63. function GetADUserGroupMemberships(const aDomain, aUser: String):TStringList;
  64. var
  65.   List: TStringList;
  66. begin
  67.   List := TStringList.Create;
  68.   List.BeginUpdate;
  69.   try
  70.     EnumADUserGroupMemberships(aDomain, aUser,
  71.       function(const Group: IAdsGroup):Boolean
  72.       begin
  73.         Result := False;
  74.         List.Add(Group.Name + ' ' + Group.Class_);
  75.       end);
  76.   finally
  77.     List.Sort;
  78.     List.Insert(0, aDomain +'\'+ aUser);
  79.     List.EndUpdate;
  80.     Result := List;
  81.   end;
  82. end;
  83.  
  84. function UserHasADGroupMembership(const aDomain, aUser: String; const GroupList: TAdGroupList): Boolean;
  85. begin
  86.   Result := EnumADUserGroupMemberships(aDomain, aUser,
  87.       function(const Group: IAdsGroup):Boolean
  88.       var
  89.         GroupName: String;
  90.       begin
  91.         for GroupName in GroupList
  92.         do begin
  93.           Result := CompareText(GroupName, Group.Name) = 0;
  94.           if Result
  95.            then Break; // Return true for first match
  96.         end;
  97.       end);
  98. end;
  99.  
  100. end.
RAW Paste Data