如何查找Windows用户是否属于指定组?

时间:2008-11-12 01:36:44

标签: windows

目前我们有一个DLL,用于检查用户名/密码是否是使用Windows API LogonUser方法的有效Windows用户。我们需要对其进行增强,以便检查用户是否也属于指定的组。是否有Windows方法可以做到这一点?

给定Windows用户名和密码,找出用户是否属于指定组。

3 个答案:

答案 0 :(得分:1)

您可以使用netapi32.dll中的“NetUserGetLocalGroups”函数获取给定用户所属的所有组,然后检查指定的组名是否存在于函数返回的组名中。你可以找到函数用法here

答案 1 :(得分:0)

最接近的单个API是CheckTokenMembership,这就留下了获取用户的SID和处理该组的问题。

如果您可以使用ATL检查CAccessToken类上的方法......即使您不能使用它,也可以查看atlsecurity.h中的实现示例。

答案 2 :(得分:0)

感谢Abhijit,该功能似乎可以完成这项工作,我还发现这个链接有示例代码:

http://delphi.newswhat.com/geoxml/forumhistorythread?groupname=borland.public.delphi.nativeapi.win32&messageid=40914cf6@newsgroups.borland.com

unit GetGroupsForUserUnit;

interface

uses
  Windows, SysUtils, Classes, ShellAPI;

type
  {$EXTERNALSYM NET_API_STATUS}
  NET_API_STATUS = DWORD;
  LPLOCALGROUP_USERS_INFO_0 = ^LOCALGROUP_USERS_INFO_0;
  {$EXTERNALSYM LPLOCALGROUP_USERS_INFO_0}
  PLOCALGROUP_USERS_INFO_0 = ^LOCALGROUP_USERS_INFO_0;
  {$EXTERNALSYM PLOCALGROUP_USERS_INFO_0}
  _LOCALGROUP_USERS_INFO_0 = record
    lgrui0_name: LPWSTR;
  end;
  {$EXTERNALSYM _LOCALGROUP_USERS_INFO_0}
  LOCALGROUP_USERS_INFO_0 = _LOCALGROUP_USERS_INFO_0;
  {$EXTERNALSYM LOCALGROUP_USERS_INFO_0}
  TLocalGroupUsersInfo0 = LOCALGROUP_USERS_INFO_0;
  PLocalGroupUsersInfo0 = PLOCALGROUP_USERS_INFO_0;

const
  {$EXTERNALSYM MAX_PREFERRED_LENGTH}
    MAX_PREFERRED_LENGTH = DWORD(-1);
  {$EXTERNALSYM NERR_Success}
    NERR_Success = 0;
  {$EXTERNALSYM NERR_BASE}
    NERR_BASE = 2100;
  {$EXTERNALSYM NERR_UserNotFound}
    NERR_UserNotFound = (NERR_BASE+121);
  {$EXTERNALSYM NERR_InvalidComputer}
    NERR_InvalidComputer = (NERR_BASE+251);
  {$EXTERNALSYM LG_INCLUDE_INDIRECT}
    LG_INCLUDE_INDIRECT = $0001;


{$EXTERNALSYM NetUserGetLocalGroups}
function NetUserGetLocalGroups(servername: PWideChar; username: PWideChar;
  level: DWORD; flags: DWORD; var bufptr: Pointer; prefmaxlen: DWORD;
  var entriesread: DWORD; var totalentries: DWORD): NET_API_STATUS; stdcall;
{$EXTERNALSYM NetApiBufferFree}
function NetApiBufferFree(Buffer: Pointer): NET_API_STATUS; stdcall;

function GetGroupsForNetUser(uname: widestring): string;

implementation

function NetUserGetLocalGroups; external 'netapi32.dll' name
'NetUserGetLocalGroups';
function NetApiBufferFree; external 'netapi32.dll' name 'NetApiBufferFree';

function GetGroupsForNetUser(uname: widestring): string;
// NetUserGetLocalGroups - returns semi-colon delim string of groups.
// Pass in user value returned by GetUserName to get current user.
var
  bufptr: Pointer;
  Status: NET_API_STATUS;
  PrefMaxLen, EntriesRead, TotalEntries: DWord;
  i: integer;
  pTmpBuf: LPLOCALGROUP_USERS_INFO_0;
begin
  PrefMaxLen := MAX_PREFERRED_LENGTH;
  Status := NetUserGetLocalGroups(nil, PWideChar(uname), 0 ,
        LG_INCLUDE_INDIRECT, bufptr, PrefMaxLen,
        EntriesRead, TotalEntries);
  case Status of
    NERR_Success: begin
      result := 'success, but no groups';
      pTmpBuf := bufptr;
      if pTmpBuf <> nil then
        begin
        result := '';
        for i := 0 to EntriesRead - 1 do
        begin
          if pTmpBuf <> nil then
          begin
            if result = '' then
            begin
              result := pTmpBuf.lgrui0_name
            else
              result := result + ';' + pTmpBuf.lgrui0_name;
          end;
          Inc(pTmpBuf);
        end;
      end;
    end;
    ERROR_ACCESS_DENIED: begin
      result := 'The user does not have access.';
    end;
    NERR_InvalidComputer: begin
      result := 'The computer name is invalid.';
    end;
    NERR_UserNotFound: begin
      result := 'The user name could not be found. (' + uname + ')';
    end;
    else begin
      result := 'Unknown error.';
    end;
  end;
   if bufptr <> nil then
          NetApiBufferFree(bufptr);
end;

end.