Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do you check if a user has access rights for a file with the windows api
    text
    copied!<p>I am trying to write a simple function for windows that answers the following question. </p> <p>Does user (U) have rights (R) on file (F)? <br> Where,<br>    R is some combination of (GENERIC_READ, GENERIC_WRITE, GENERIC_EXECUTE) <br>    U does not have to be logged in or impersonated <br></p> <p>The code that I wrote is shown below. The application calls the first UserHasPermission that is shown.</p> <p>The access rights returned by GetEffectiveRightsFromAcl are the same for all user/file combinations that I tested ($001200A9). I double checked and $001200A9 is not just a pointer to the location where the access rights are actually stored.</p> <p>My question is twofold: <br> 1. Is there a better way of doing this?<br> 2. Can anyone tell me where I am going wrong?</p> <pre> 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; </pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload