目前我們有一個DLL,用於檢查用戶名/密碼是否是使用Windows API LogonUser方法的有效Windows用戶。我們需要增強它,以便檢查用戶是否屬於指定的組。有沒有Windows方法可以做到這一點?如何查找Windows用戶是否屬於指定組?
給定Windows用戶名和密碼,找出用戶是否屬於指定的組。
目前我們有一個DLL,用於檢查用戶名/密碼是否是使用Windows API LogonUser方法的有效Windows用戶。我們需要增強它,以便檢查用戶是否屬於指定的組。有沒有Windows方法可以做到這一點?如何查找Windows用戶是否屬於指定組?
給定Windows用戶名和密碼,找出用戶是否屬於指定的組。
感謝作者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.
最接近單一的API是CheckTokenMembership,剛剛離開獲取用戶的SID和處理該組的問題。
如果您可以使用ATL,請查看CAccessToken類中的方法...即使您無法使用它,也可以查看atlsecurity.h中的實現。
你可以使用「NetUserGetLocalGroups」功能的netapi32.dll得到給定用戶所屬的所有組,然後檢查是否指定的組名稱存在於團體名稱由函數返回。你可以找到函數的用法here