Winapi 查找给定SID是否属于由SID标识的组
我正在编写一个windows服务,它根据不同的规则执行操作,其中一个规则基于请求的用户身份 因此,它接收请求用户SID,然后将其与内部SID列表进行比较,以决定将执行什么操作。使用Winapi 查找给定SID是否属于由SID标识的组,winapi,Winapi,我正在编写一个windows服务,它根据不同的规则执行操作,其中一个规则基于请求的用户身份 因此,它接收请求用户SID,然后将其与内部SID列表进行比较,以决定将执行什么操作。使用EqualSIDAPI函数可以使这非常容易 然而,我现在面临的情况是,服务清单中的一些小岛屿发展中国家是集团小岛屿发展中国家,而不是用户小岛屿发展中国家 这意味着我必须找到一种方法来测试接收到的SID是否等于列表中的SID,或者是否属于列表中由SID表示的组 我环顾四周,看看有哪些API可用,并找到了关于需要令牌句柄的
EqualSID
API函数可以使这非常容易
然而,我现在面临的情况是,服务清单中的一些小岛屿发展中国家是集团小岛屿发展中国家,而不是用户小岛屿发展中国家
这意味着我必须找到一种方法来测试接收到的SID是否等于列表中的SID,或者是否属于列表中由SID表示的组
我环顾四周,看看有哪些API可用,并找到了关于需要令牌句柄的CheckTokenMembership
。这就是我有点迷茫的地方,因为服务不一定位于同一台机器上,所以我似乎找不到从收到的SID创建有效令牌句柄的方法
服务本身在默认的“NT服务”帐户下运行,我更希望它能保持这种状态
您建议我使用什么API
目标语言是Delphi,但我能理解纯C语言中的示例。在查看了其他各种内容后,我终于找到了实现这一点的方法。简而言之,答案是
Active Directory服务接口
也称为ADSI
如果其他人正在查看,请提供更多详细信息,以下是在Delphi中实现此目的的一系列步骤:
活动DS类型库
对象集导入Delphi。这将创建带有所有必要接口的ActiveDs\u TLB
单元function ADsGetObject(lpszPathName: WideString; const riid: TGUID; out ppObject): HRESULT; safecall;
var
SIDUser: IADSUser;
User: IADSUser;
SIDGroup: IADSGroup;
Group: IADSGroup;
begin
// Bind using the SID
AdsGetObject('LDAP://<SID=S-1-5-7>', IADSUser, SIDUser);
// rebind using the distinguished name as suggested by MSDN
AdsGetObject('LDAP://' + SIDUser.Get('distinguishedName'), IADSUser, User);
// Use the User instance
ShowMessage(User.FullName);
// Same method for group
AdsGetObject('LDAP://<SID=S-1-5-32-545>', IADSGroup, SIDGroup);
AdsGetObject('LDAP://' + SIDGroup.Get('distinguishedName'), IADSGroup, Group);
// IsMember does not seem to work with LDAP
// https://groups.google.com/forum/#!topic/microsoft.public.adsi.general/2d-e4HPXGfA
// http://www.rlmueller.net/Programs/IsMember4.txt
// if Group.IsMember(User.ADsPath) then
if AdsIsMember(User, 'S-1-5-32-545') then
ShowMessage('InGroup');
end;
有了这些,我现在可以检查给定的SID是否属于由其SID定义的组
function ADsIsMember(const User: IADSUser; const GroupSID: string): Boolean;
const
TokenGroupsId = 'tokenGroups';
var
PropNames: array of OleVariant;
TokenGroups: OleVariant;
TokenGroupLow: Integer;
TokenGroupHigh: Integer;
TokenGroupIndex: Integer;
SIDBytes: array of Byte;
SIDAsString: PChar;
begin
Result := False;
SetLength(PropNames, 1);
PropNames[0] := TokenGroupsId;
User.GetInfoEx(PropNames, 0);
TokenGroups := User.Get(TokenGroupsId);
TokenGroupLow := VarArrayLowBound(TokenGroups, 1);
TokenGroupHigh := VarArrayHighBound(TokenGroups, 1);
for TokenGroupIndex := TokenGroupLow to TokenGroupHigh do
begin
SIDBytes := TokenGroups[TokenGroupIndex];
ConvertSidToStringSid(@SIDBytes[0], SIDAsString);
if GroupSID = SIDAsString then
Exit(True);
end;
end;