模拟管理员以重新启动Windows服务

Kaw*_*hii 3 delphi delphi-7

我有一个重启某些Windows服务的Delphi应用程序.

如果执行此应用程序的用户具有管理权限(Administrators组成员),则服务重新启动将成功.

对于普通用户,服务重启将失败.

如果普通用户使用"右键单击"以管理员身份运行,它也会成功.但是,普通用户必须输入管理员用户名和密码.

我想为普通用户解决这个问题.

我的想法是在代码中"冒充用户",显然冒充本地管理员帐户.

但是,它仍然无效.

这是我的代码:

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;
Run Code Online (Sandbox Code Playgroud)

我称之为:

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;
Run Code Online (Sandbox Code Playgroud)

服务重启将失败.如果用户以管理员身份运行它(右键单击RunAs),它就可以运行.

模仿本身运作良好.我可以通过获取当前用户名来检查它.但是,为什么它仍然不起作用.看起来用户在没有管理员权限的情况下进行模拟.

还有其他任何形象吗?

Dav*_*nan 6

这是可以预料的.在UAC下,管理员组中的用户会收到筛选的令牌,除非他们通过UAC提升过程.您正在模仿其他用户,但是您没有UAC提升,因此拥有过滤的,降低的权限令牌.

为了执行具有提升权限的代码,在UAC下,您必须通过UAC提升过程.如果你可以避免这样做,那么UAC将毫无意义.

据我所知,你有以下原则选择:

  1. 启动另一个进程来完成工作,使用runasshell动词强制提升,或者确实使用其他一些机制来安排提升.这将引导您完成要避免的UAC对话框.
  2. 作为替代方案,安装两个服务.第一个服务是您当前安装的服务,即您要重新启动的服务.第二个服务是一个小而简单的服务,其唯一任务是执行重新启动.因为第二个服务在没有UAC的会话0中运行,所以您可以轻松地安排它有足够的权限重新启动第一个服务.当您需要从桌面应用程序重新启动服务1时,请向服务2发送请求,以便服务2可以执行服务1的重新启动.

顺便说一句,我注意到你没有检查你的电话中的错误ImpersonateLoggedOnUser.