目前我们有一个DLL,用于检查用户名/密码是否是使用Windows API LogonUser方法的有效Windows用户。我们需要对其进行增强,以便检查用户是否也属于指定的组。是否有Windows方法可以做到这一点?
给定Windows用户名和密码,找出用户是否属于指定组。
答案 0 :(得分:1)
您可以使用netapi32.dll中的“NetUserGetLocalGroups”函数获取给定用户所属的所有组,然后检查指定的组名是否存在于函数返回的组名中。你可以找到函数用法here
答案 1 :(得分:0)
最接近的单个API是CheckTokenMembership,这就留下了获取用户的SID和处理该组的问题。
如果您可以使用ATL检查CAccessToken类上的方法......即使您不能使用它,也可以查看atlsecurity.h中的实现示例。
答案 2 :(得分:0)
感谢Abhijit,该功能似乎可以完成这项工作,我还发现这个链接有示例代码:
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.