我正在尝试为Windows编写一个简单的函数来回答以下问题。
用户(U)是否在文件(F)上拥有权利(R)?
其中,
R是(GENERIC_READ,GENERIC_WRITE,GENERIC_EXECUTE)的某种组合
U不必登录或模拟
我写的代码如下所示。应用程序调用显示的第一个UserHasPermission。
GetEffectiveRightsFromAcl返回的访问权限与我测试的所有用户/文件组合相同($ 001200A9)。我仔细检查过,$ 001200A9不只是指向实际存储访问权限的位置的指针。
我的问题是双重的:
1.有更好的方法吗?
谁能告诉我哪里出错了?
function UserHasPermission(APermission: Longword; out HasPermission: Boolean; AFileName: WideString; AUserName: String; ADomainName: String): Boolean; var SID: PSID; ACL: PACL; begin SID := nil; ACL := nil; try Result := GetUserSID(SID, AUserNAme, ADomainName); Result := Result and GetFileDACL(AFileName, ACL); Result := Result and UserHasPermission(APermission, HasPermission, ACL, SID); finally Dispose(SID); end; end; function UserHasPermission(APermission: Longword; out HasPermission: Boolean; AACL: PACL; AUserSID: PSID): Boolean; var T: TRUSTEE; Rights: ACCESS_MASK; begin BuildTrusteeWithSid(@T, AUserSID); Result := GetEffectiveRightsFromAcl(AACL, @T, @Rights) = ERROR_SUCCESS; HasPermission := (Rights and APermission) = APermission; end; function GetUserSID(out ASID: PSID; AUserName: WideString; const ADomainName: WideString): Boolean; var NSID, NDomain: Longword; Use: SID_NAME_USE; DomainName: WideString; begin Result := False; if Length(AUserName) > 0 then begin if Length(ADomainName) > 0 then AUserName := ADomainName + '\' + AUserName; // determine memory requirements NSID := 0; NDomain := 0; LookupAccountNameW(nil, PWideChar(AUserName), nil, NSID, nil, NDomain, Use); // allocate memory GetMem(ASID, NSID); SetLength(DomainName, NDomain); Result := LookupAccountNameW(nil, PWideChar(AUserName), ASID, NSID, PWideChar(DomainName), NDomain, Use); end; end; function GetFileDACL(AFileName: WideString; out AACL: PACL): Boolean; var SD: PSecurityDescriptor; NSD, NNeeded: Longword; Present, Defualted: Longbool; begin GetFileSecurityW(PWideChar(AFileName), DACL_SECURITY_INFORMATION, nil, 0, NNeeded); GetMem(SD, NNeeded); try NSD := NNeeded; Result := GetFileSecurityW(PWideChar(AFileName), DACL_SECURITY_INFORMATION, SD, NSD, NNeeded); Result := Result and GetSecurityDescriptorDacl(SD, Present, AACL, Defualted); Result := Result and Present; finally Dispose(SD); end; end;
答案 0 :(得分:2)
GetEffectiveRightsFromAcl与我测试的所有用户/文件组合相同($ 001200A9)。
这一切都取决于ACL,例如如果每个人都被授予完全控制权,那么任何使用都将具有完全控制权。
代码看起来很合理,并且您正在使用其中一个Win32安全API(GetEffectiveRightsFromAcl
)来完成繁重的工作。
建议:创建非常具体的ACL来测试你的代码(SDDL使这更容易),从没有授权的那个开始,然后只包括一个不同的用户。