check if user belongs to a certain group

delphi package - easy access to security apis

check if user belongs to a certain group

Postby zifnabbe » Thu May 08, 2008 5:24 pm

Hi,

Is it possible to find out if a user belongs to a certain group?

Thanks
zifnabbe
 
Posts: 7
Joined: Wed May 03, 2006 2:04 pm

Postby Nico Bendlin » Thu May 08, 2008 6:02 pm

Please define the context of "user".
If you are refferring to the user token of the current thread or current process, you might have a look at IsUserAnAdmin/SHTestTokenMembership/CheckTokenMembership.
(if you need a pre-Win2K emulation of CheckTokenMembership in Delphi: http://www.delphipraxis.net/post730030.html#730030)
If you have to deal with non-elevated admins, you might have a look at IsTokenRestricted/GetTokenInformation(TokenElevationType).
Nico Bendlin
 
Posts: 46
Joined: Fri Apr 28, 2006 1:17 pm

Postby zifnabbe » Thu May 08, 2008 11:09 pm

With user I mean the current user account logged into windows.
I would like to know if that user belongs to a certain group (active directory). If so, I allow the user to use a certain application otherwise (s)he may not use it.
zifnabbe
 
Posts: 7
Joined: Wed May 03, 2006 2:04 pm

Postby madshi » Fri May 16, 2008 5:49 pm

Check out NetUserGetGroups and NetGroupGetUsers and related APIs. These also work for ActiveDirectory. You can also use COM objects to access ActiveDirectory. But I find that more complicated than using the "old" APIs.

madSecurity currently does not contain functions to list group users.
madshi
Site Admin
 
Posts: 9506
Joined: Sun Mar 21, 2004 5:25 pm

Postby iconic » Sun May 18, 2008 3:36 am

@Nico: IsUserAnAdminIn() just wraps CheckTokenMembership() and isn't advised to be called directly anymore. In the past I've used IsNTAdmin() API (advpack.dll) to test for admin rights but unfortunately this no longer works correctly under Vista variants. I just compare security identifiers from my current process to the admin group via OpenProcessToken->GetTokenInformation->EqualSID.
This seems to work fine on Windows 2000 - Windows Vista.

--Iconic
iconic
 
Posts: 813
Joined: Wed Jun 08, 2005 5:08 am

Postby Nico Bendlin » Sun May 18, 2008 4:26 am

iconic wrote:@Nico: IsUserAnAdminIn() just wraps CheckTokenMembership() and isn't advised to be called directly anymore.
Who gave/gives this advice?
(edit: Well, there is a comment in MSDN now :))

The linked Delphi source emulates the APIs if they are not present.
Nico Bendlin
 
Posts: 46
Joined: Fri Apr 28, 2006 1:17 pm

Postby iconic » Sun May 18, 2008 5:29 am

@Nico,
Your emulation seems useful. My unemulated implementation is very similar to the methods that you invoke to check for admin rights. I'm actually very surprised that Microsoft has never "officially" backed an API to check for admin rights definitively. It would be nice to have one reliable API not change from the very first NT release to the current Vista build.

Code: Select all
function UserIsAdmin: BOOL;
const
  SECURITY_BUILTIN_DOMAIN_RID = $00000020;
        DOMAIN_ALIAS_RID_ADMINS = $00000220;
var
              hToken: ULONG;
               ulRet: ULONG;
          lpSIDAdmin: Pointer;
                   i: ULONG;
           sidNtAuth: SID_IDENTIFIER_AUTHORITY;
              TokInf: Array [0..$FF] of ULONG;
               lpGrp: ^_TOKEN_GROUPS;
begin
  result := False;
  ZeroMemory(@sidNtAuth.Value, 6);
  ulRet := 0;
  sidNtAuth.Value[5] := 5;
  lpGrp := @TokInf;
  if not OpenProcessToken(DWORD(-1), TOKEN_READ, hToken) then exit;
  if GetTokenInformation(hToken, TokenGroups, @TokInf, $400, ulRet) and (ulRet > 0) then
  begin
  AllocateAndInitializeSid(sidNtAuth, 2, SECURITY_BUILTIN_DOMAIN_RID,
                           DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, lpSIDAdmin);
  for i := 0 to lpGrp^.GroupCount -1 do
    begin
      result := EqualSID(lpsidAdmin, lpGrp^.Groups[i].SID);
      if (result) then break;
    end;
    FreeSID(lpsidAdmin);
  end;
  CloseHandle(hToken);
end;


Nice work!

--Iconic
iconic
 
Posts: 813
Joined: Wed Jun 08, 2005 5:08 am

Postby Nico Bendlin » Sun May 18, 2008 12:31 pm

EqualSID() - without the check if the SID is disabled in the token - will lead to another behaviour than IsUserAnAdmin(). All functions of this kind are intended as an "access check" - but your function will return false positives for "limited" tokens. E.g. in Windows XP [Shift+RMB] on an executable, choose "Run as..." and enable the checkbox to limit the token. Windows XP will just disable the admin SID in the token. In this case your function still returns TRUE. If this is intended (your function is not intended as "access check", but as "group check"), this is the wrong way of doing it - because Windows is free to completely remove the SID from the new token. As I mentioned above, there other functions available to check for "is token limited", "is token un-elevated", and "is the user account in the token a member of group x" (a completely different story).

This has always been a source of confusion, IsUserAnAdmin() and similar do not answer the question "Is the user account included in the token a member of group x?", but they will tell you "Has the token the rights to access an object that is accessible by members of group x?"

Best regards,
Nico Bendlin
Nico Bendlin
 
Posts: 46
Joined: Fri Apr 28, 2006 1:17 pm

Postby iconic » Sun May 18, 2008 1:28 pm

True, it's a small access check with no real sanity checks, it's all I really need however for any programs that I am currently developing. If in the future I come across the need to have a more "bullet proof", versatile admin access checking function I will definitely look back at your emulated functions. Your link is much appreciated to the forum and I'm sure others can benefit from this too.

--Iconic
iconic
 
Posts: 813
Joined: Wed Jun 08, 2005 5:08 am

Postby zifnabbe » Tue May 20, 2008 10:20 am

thanks for all the advice. I'll check these asap. Right now I'm in the middle of a house move and have very limited access to internet.
zifnabbe
 
Posts: 7
Joined: Wed May 03, 2006 2:04 pm


Return to madSecurity

Who is online

Users browsing this forum: No registered users and 1 guest

cron