我正在尝试为 Windows 编写一个简单的函数来回答以下问题。
用户 (U) 是否对文件 (F) 拥有权限 (R)?
哪里,
R 是 (GENERIC_READ, GENERIC_WRITE, GENERIC_EXECUTE)
U 不必登录或冒充
我编写的代码如下所示。应用程序调用显示的第一个 UserHasPermission。
GetEffectiveRightsFromAcl 返回的访问权限对于我测试的所有用户/文件组合 ($001200A9) 都是相同的。我仔细检查了一下,$001200A9 不仅仅是一个指向实际存储访问权限的位置的指针。
我的问题有两个:
1. 有没有更好的方法?
2. 谁能告诉我哪里出错了?
函数 UserHasPermission(APermission: Longword; out HasPermission: Boolean; AFileName: WideString; AUserName: String; ADomainName: String): Boolean;
变量
SID:PSID;
ACL:PACL;
开始
SID := 无;
ACL := 无;
尝试
结果 := GetUserSID(SID, AUserNAme, ADomainName);
结果 := 结果和 GetFileDACL(AFileName, ACL);
结果 := Result 和 UserHasPermission(APermission, HasPermission, ACL, SID);
最后
处置(SID);
结尾;
结尾;
函数 UserHasPermission(APermission: Longword; out HasPermission: Boolean; AACL: PACL; AUserSID: PSID): Boolean;
变量
T:受托人;
权限:ACCESS_MASK;
开始
BuildTrusteeWithSid(@T, AUserSID);
结果 := GetEffectiveRightsFromAcl(AACL, @T, @Rights) = ERROR_SUCCESS;
HasPermission := (Rights and APermission) = APermission;
结尾;
函数 GetUserSID(出 ASID:PSID;AUserName:WideString;const ADomainName:WideString):布尔值;
变量
NSID,NDomain:长字;
使用:SID_NAME_USE;
域名:WideString;
开始
结果:=错误;
如果长度(AUserName)> 0 那么
开始
如果长度(ADomainName)> 0 则
AUserName := ADomainName + '\' + AUserName;
// 确定内存需求
NSID := 0;
NDomain := 0;
LookupAccountNameW(nil, PWideChar(AUserName), nil, NSID, nil, NDomain, Use);
//分配内存
获取内存(ASID,NSID);
SetLength(域名, NDomain);
结果 := LookupAccountNameW(nil, PWideChar(AUserName), ASID, NSID, PWideChar(DomainName), NDomain, Use);
结尾;
结尾;
函数 GetFileDACL(AFileName: WideString; out AACL: PACL): Boolean;
变量
SD:PSecurityDescriptor;
NSD,NN需要:长字;
目前,已取消:Longbool;
开始
GetFileSecurityW(PWideChar(AFileName), DACL_SECURITY_INFORMATION, nil, 0, NNeeded);
GetMem(SD, NNeeded);
尝试
NSD := NNeeded;
结果 := GetFileSecurityW(PWideChar(AFileName), DACL_SECURITY_INFORMATION, SD, NSD, NNeeded);
结果 := Result 和 GetSecurityDescriptorDacl(SD, Present, AACL, Defualted);
结果:=结果和现在;
最后
处置(SD);
结尾;
结尾;