Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LsaEnumerateAccountRights always returns "File not found"

I'm calling the Advapi32.dll LsaEnumerateAccountRights function having a policy handle from LsaOpenPolicy and an account SID from LookupAccountName.

However, try as I might, I'm always getting back 0xC0000034 which after translation by LsaNtStatusToWinError gives me "The file referenced cannot be found."

Which isn't a whole lot of good. My code handles this and goes on to grant the account SID the SeServiceLogonRight using LsaAddAccountRights, so I know that the policy handle and the account SID are fine as that would bomb out if something was wrong with one of those.

The end result is that the account does have the right it needs so overall the code works.

However, I'm using this within an MSI custom action, the Install checks to see if the account has the right and if it doesn't (or it fails as above) it grants the right and remembers it has done it in the install state. If a rollback happens and it added the right it then removes it. We never remove in an uninstall as other applications may have been installed using the same domain account that the services we run use.

So the problem is when an MSI performs a rollback - it will always remove the right as it always thinks it has added it. So checking the rights using LsaEnumerateAccountRights is used for this - but I just can't get it to work.

Any idea - please note that I'm using c# with DllImport attribute to expose the Win32 functions, and I'm not the worlds best Win32 programmer having been Unix before C#!

like image 460
Alan Mullett Avatar asked Dec 30 '22 13:12

Alan Mullett


1 Answers

I have been struggling with this, too, but have just cracked it...

Retrospectively, I now see there was a clue in the msdn documentation: "The accounts returned by this function hold the specified privilege directly through the user account, not as part of membership to a group."

See: link text

Get the policy handle from LsaOpenPolicy() and an account SID from LookupAccountName() exactly as you said.

If the username you entered was the name of a group ("Users", "Administrators", etc) then LsaEnumerateAccountRights() works fine and enumerates all the rights for the group.

If you call it on a username whose rights derive solely from the groups of which it is a member, then it returns 0xc0000034 (= Windows error 2 - The system cannot find the "file" specified), meaning (we now realise) "cannot find any individually assigned additional rights". It seems that the Windows Error 2 translation is a catch-all for "what you were looking for has not been found".

Now... If you have ntrights.exe, run it... for example:

ntrights +r SeNetworkLogonRight -u MyUserName

Then, LsaEnumerateAccountRights() works fine, returns without error and enumerates a single right, "SeNetworkLogonRight".

like image 101
David Woodward Avatar answered Jan 07 '23 06:01

David Woodward