2009-01-28 169 views
1

我正在嘗試爲windows編寫一個簡單的函數來解答以下問題。如何檢查用戶是否具有windows api文件的訪問權限

是否用戶(U)有權利(R)上的文件(F)?
其中,
R是(GENERIC_READ,GENERIC_WRITE,GENERIC_EXECUTE)的一些組合
U未在要記錄或模擬的

,我寫如下所示的代碼。應用程序調用顯示的第一個UserHasPermission。

由GetEffectiveRightsFromAcl返回的訪問權限是我測試的所有用戶/文件組合($ 001200A9)相同。我加倍檢查和$ 001200A9不只是一個指向實際存儲訪問權限的位置的指針。

我的問題是雙重的:
1.有沒有更好的方法來做到這一點?
2.誰能告訴我哪裏出錯了?

 
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; 

回答

2

GetEffectiveRightsFromAcl是我測試的所有用戶/文件組合($ 001200A9)相同。

這一切都取決於ACL,例如如果每個人都被授予完全控制權,那麼任何使用都將完全控制。

代碼看起來合理的,您使用的是Win32的安全API(GetEffectiveRightsFromAcl)的人做繁重。

建議:創建非常特定的ACL來測試您的代碼(SDDL使這更容易),從一個沒有授權的開始,然後一個只包含一個不同的用戶。

+0

你的代碼非常正確。我在測試時感到疲倦和沮喪,即不小心。感謝代碼審查,一切正常,現在我明白髮生了什麼。 – 2009-03-24 14:42:30

相關問題