I have a Delphi application that restart certain Windows service.
If the user who execute this application has Administrative rights (member of Administrators group), the service restart would be successful.
For normal user, the service restart would fail.
It will also success if this normal user use "right-click" Run As Administrator. But, the normal user must type in the Administrator username and password.
I want to solve this for the normal user.
My idea is to do "impersonate user" within the code, obviously impersonating the local Administrator account.
But, it still doesn't work.
Here is my code:
function GetCurrUserName: string;
var
Size : DWORD;
begin
Size := MAX_COMPUTERNAME_LENGTH + 1;
SetLength(Result, Size);
if GetUserName(PChar(Result), Size) then
SetLength(Result, Size)
else
Result := '';
end;
function ConnectAs(const lpszUsername, lpszPassword: string): Boolean;
var
hToken : THandle;
begin
Result := LogonUser(PChar(lpszUsername), nil, PChar(lpszPassword), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, hToken);
if Result then
Result := ImpersonateLoggedOnUser(hToken)
else
RaiseLastOSError;
end;
And I call it like this:
try
ConnectAs('Administrator','password');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
// Restart the Windows service
// Done, back to the user
RevertToSelf;
The service restart will fail. If user run it as Administrator (right-click RunAs), it works.
The impersonation itself is working fine. I could check it with getting the current username. But, why it still doesn't work. It looks like the user impersonate without Administrator privilege.
Is there any other kind of impersonation?
This is to be expected. Under UAC users in the administrators group receive a filtered token unless they pass through the UAC elevation process. You are impersonating the other user, but you are doing so without UAC elevation and so have a filtered, reduced privilege token.
In order to execute code with elevated rights, under UAC, you must pass through the UAC elevation process. If you could avoid doing so then UAC would be pointless.
As far as I can tell you have the following principle options:
runas
shell verb to force elevation, or indeed some other mechanism to arrange elevation. This will take your through the UAC dialog which you want to avoid.As an aside, I do note that you don't check for errors in your call to ImpersonateLoggedOnUser
.