Page 1 of 1

Determine if a file requires elevated privileges

Posted: Wed Jan 16, 2008 11:11 pm
by smartins
I have a small program that receives information from a shell extension activated when the user right-clicks folders or files that then takes action on those selected items.

Under Vista I can have folders/files that require elevated privileges to be accessed and others that don't.

I've compared a few files that require and do not require elevation and came up with the following comparison to see if it requires elevation or not:

1) If it has "Authenticated Users" with Modify and Write permissions, OK
2) If it has "Everyone" with Modify and Write permissions, OK
3) If it has "Steven Martins" (the user name I'm currently log on in Vista) with Modify and Write permissions, OK

4) If it has "Users" without Modify and Write permissions, Elevation Needed! (but not if 1) is present)

Any idea on how I can do these validations using FileSecurity from madSecurity?

Thanks!

Posted: Mon Jan 21, 2008 11:39 am
by madshi
Here's a little function which may help you:

Code: Select all

function CheckAccess(acl: IAcl; account: IAccount; neededAccessRights: dword) : boolean;
var i : integer;
begin
  result := false;
  with acl do
    for i := 0 to ItemCount - 1 do
      if Items[i].Account = account then
      begin
        result := (Items[i].Type_ = atAllowed) and
                  (Items[i].Access and neededAccessRights = neededAccessRights);
        break;
      end;
end;
Please note that I've not really tested this function. I've just written it from the top of my head. But I think it should work.

Posted: Mon Jan 21, 2008 11:42 am
by madshi
You can use something like this to use the code above:

Code: Select all

var acl : IAcl;
begin
  acl := FileSecurity('c:\whatever').DAcl;
  if CheckAccess(acl, Everyone, $12345678) and
     CheckAccess(acl, CurrentUser, $23456789) and
     [...] then
Please do not use Account('Authenticated Users'), because this way you would limit your code to work on English OSs. Instead on your PC run this little program:

Code: Select all

MessageBox(0, pchar(Account('Authenticated Users').SidStr), 'sid', 0);
This will output the SID of the "Authenticated Users" account. Then in your code use "Account('S-......')". This will make sure that your code is language independent. Same thing with the "Users" account.

Posted: Fri Jan 25, 2008 12:35 am
by smartins
Thanks, that did it! :D