A long time ago I wrote an article about this strange WinAPI function called GetEffectiveRightsFromAcl. There was a problem that I showed how to solve (see my article and the comment in the MSDN doc). However, this function has never been a good way for retrieving the possible access mask. It seems that MS has changed the MSDN article of this function and instead wrote an example that uses the MS Authz API. I translated the example but using JWSCL. You can see yourself how different it looks…

I have added some comments to the source code itself so you can read a description directly in the code.

program GetEffectiveRightsFromAclTest;

uses
  JwaWindows,
  JwsclKnownSid,
  JwsclConstants,
  JwsclTypes,
  JwsclExceptions,
  JwsclSecureObjects,
  JwsclSid,
  JwsclDescriptor,
  JwsclAuthCtx,
  JwsclMapping,
  JwsclUtils,
  JwsclACL,

  Dialogs,
  SysUtils;

//computes granted access mask for a security descriptor and a SID
//An error is thrown by an exception - typical JWSCL
function GetEffectiveAccess(const SD : TJwSecurityDescriptor;
                            const Sid : TJwSecurityId) : DWORD;
var
  AuthRM : TJwAuthResourceManager;
  AuthCtx : TJwAuthContext;
  AuthReply : TJwAuthZAccessReply;
  Request : TJwAuthZAccessRequest;
begin
  //The following code uses the MS AuthZ API
  //JWSCL wraps the function calls
  AuthRM := TJwAuthResourceManager.Create('', [], nil, nil);
  try
    //Tell AuthZ to use a SID for access checking
    //We also could use a token and prevent the problem of
    // restricted Administrators in Vista/7
    AuthCtx := TJwAuthContext.CreateBySid(AuthRM, [], Sid, 0, nil);
    try
      //As documented AccessCheck returns a GrantedAccessMask
      //  when using MAXIMUM_ALLOWED
      Request := TJwAuthZAccessRequest.Create(MAXIMUM_ALLOWED,
                  JwNullSID, nil, nil, shOwned);
      try
        //does the access check using a generic mapping to file/folder
        AuthCtx.AccessCheck(0, Request, 0, SD, nil,
           TJwSecurityFileFolderMapping, AuthReply, nil);

        //return the granted access mask
        result := AuthReply.GrantedAccessMask[0];
      finally
        Request.Free;
      end;
    finally
      AuthCtx.Free;
    end;
  finally
    AuthRM.Free;
  end;
end;

//computes granted access mask for a file and username
//An error is thrown by an exception - typical JWSCL
function GetEffectiveAccessFromFile(
             const FileName,
             DomainName, UserName : string) : DWORD;
var
  F : TJwSecureFileObject;
  SD : TJwSecurityDescriptor;
  Flags : TJwSecurityInformationFlagSet;
  Sid : TJwSecurityId;
begin
  //Translate username and domainname into a SID
  //Throws an EJwsclWinCallFailedException if
  //  the username could not be translated
  Sid := TJwSecurityId.Create(DomainName, UserName);
  try
    F := TJwSecureFileObject.Create(FileName);
    try
      //adding siLabelSecurityInformation makes no sense
      //  since it cannot be checked against a simple SID
      Flags := [siOwnerSecurityInformation,
                siGroupSecurityInformation,
                siDaclSecurityInformation];

      //get the security descriptor (result is not cached)
      SD := F.GetSecurityDescriptor(Flags);
      try
        result := GetEffectiveAccess(SD, Sid);
      finally
        SD.Free;
      end;
    finally
      F.Free;
    end;
  finally
    Sid.Free;
  end;
end;

const
  Target = 'C:\Windows';
  UserName = 'Christian';

var AccessMask : TJwAccessMask;
begin
  JwInitWellKnownSIDs;

  AccessMask := GetEffectiveAccessFromFile(Target, '', UserName);
  ShowMessage(Format('File/Folder: %s'#13#10'User: %s'#13#10'%s',
    [Target,
     UserName,
     JwFormatAccessRights(AccessMask, FileFolderMapping)]));
end.

Be aware that the code does the same as GetEffectiveRightsFromAcl.

Restricted Administrator account in Vista/7

Also it does not take into account a restricted Vista account. The reason is that the privileges of an Administrator account are stripped away only when a user logs on. So the account management does not behave differently to Windows XP. Since we use an account name the function only finds the Administrators group in the membership list of the user. Thus we may see a fullly granted access mask as a result when using the function on e.g. the Windows folder.

Integrity Level in Vista/7

Of course, we cannot use the mandatory label (notice siLabelSecurityInformation) of a file or folder because the integrity level of the user is only known when she is logged on. Thus if a folder has a high integrity level, the function will still return full access control even if the user cannot write access (no-write-up) the folder when logged on.

Download

Download GetEffectiveRightsFromAclWithAuthZ.pas