我想用C语言编写一个函数来检查给定用户是否是组的成员(它基于我在stackoverflow上找到的代码如何以编程方式确定用户帐户是否是特定组的成员在 Windows 中?)。我在 WinCC 软件中开发了这个功能,它是一个 scada 系统。
这是我的代码:
//Insert the header starting here
#include "WinApi.h"
#include "GlobalDefinitions.h"
BOOL CheckGroupMembership(char* UserName, char* Password, char* Domain, char* Group)
{
HRESULT result;
SID_NAME_USE SIDType;
WCHAR szDomain[256];
DWORD dwSidSize=0;
DWORD dwSize;
HANDLE user;
BOOL b=FALSE,returnval;
SID* pSid;
WCHAR szGroup[50];
// Convertit le nom du groupe en wide string
result=MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,Group,strlen(Group),szGroup,50);
printf("Nom du groupe : %ls\r\n",szGroup);
//recupere SID groupe
//premier appel de lookup pour allouer la bonne taille de SID (remis à jour dans dwSidSize);
LookupAccountNameW(NULL,szGroup,NULL,&dwSidSize,szDomain,&dwSize,&SIDType);
if (dwSidSize)
{
pSid=(SID*)malloc(dwSidSize);
//note : pas besoin de lui fournir un domaine si la machine est déjà intégrée dedans
LookupAccountNameW(NULL,szGroup,pSid,&dwSidSize,szDomain,&dwSize,&SIDType);
printf("dwSidSize %d \r\n",dwSidSize);
printf("Infos SID : %x , %x, %x - %d \r\n", pSid->Revision,pSid->SubAuthorityCount,pSid->IdentifierAuthority,SIDType);
// Récupère le handle de l'utilisateur
returnval=LogonUserA(UserName,Domain,Password,2,0,&user);
printf("User %d - %x \r\n",user,returnval);
returnval=CheckTokenMembership(user,pSid,&b);
}
printf("returnval %d - b : %d - %d\r\n",returnval,b,GetLastError());
free(pSid);
return b;
}
无论我做什么,CheckGroupMemberShip 之外的返回值都是假的。我认为 LookupAccountNameW 效果很好,如果我放置一个有效的组,我就会在 SID 结构中得到一些有效的信息。如果我放置一个不存在的组,它只会给我零。
我认为 LogonUserA 也工作得很好,好像我提供有效信息 returnval 为 true,否则为 false。
只有 checkGroupMembership 似乎没有回答我。
虽然有些事情我不太明白:为什么有一个请求组的 SID 列表,而不仅仅是一个?有没有可以比较 SID 结构中的值和与现有组对应的 SID 的地方?无论我给他什么(组或用户名),看起来 SIDType 在 LookupAccountNameW 的输出中总是相同的,为什么?最后, GetLastError 似乎对我没有帮助。它总是给我0,为什么?
需要注意的是:“WinApi.h”是定制的,因为我只想导入我的应用程序中严格需要的内容。如果您认为这可能是问题,我可以发布它。
提前感谢您的回答,
朱利安