2

我正在尝试使用以下代码从另一个用户帐户下的另一个 Windows 应用程序调用执行应用程序:

procedure TForm1.Button3Click(Sender: TObject);
var
  userName: string;
  password: string;
  domain: string;
  path: string;
  logonok: boolean;
  impok: boolean;
  hUserToken: THandle;
  ProcessCreatedOK: Boolean;
  startupInfo: TStartupInfo;
  processInfo: TProcessInformation;
  err: DWORD;
begin
    username := 'theusername';
    password := 'thepassword';
    domain := '';
    Path := 'myapp.exe';

    LogonOK := LogonUser(PWideChar(username), PWideChar(domain), PWideChar(password),
      LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, hUserToken);

    if LogonOK then
    begin
      impOK := ImpersonateLoggedOnUser(hUserToken);

      if impok then
      begin
        FillChar(startupInfo, SizeOf(startupInfo), 0);
        startupInfo.CB := SizeOf(startupinfo);
        startupInfo.dwFlags := STARTF_USESHOWWINDOW;
        startupinfo.wShowWindow := SW_SHOWNORMAL;

        NewState.PrivilegeCount := 1;
        res := LookupPrivilegeValue(
          nil,
          SE_ASSIGNPRIMARYTOKEN_NAME,
          NewState.Privileges[0].Luid);
          Win32Check(res);

        NewState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
        res := AdjustTokenPrivileges(
          hUserToken,
          False,
          NewState,
          SizeOf(NewState),
          nil,
          returnLength);
        Win32Check(res);

        NewState.PrivilegeCount := 1;
        res := LookupPrivilegeValue(
          nil,
          SE_INCREASE_QUOTA_NAME,
          NewState.Privileges[0].Luid);
          Win32Check(res);

        NewState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
        res := AdjustTokenPrivileges(
          hUserToken,
          False,
          NewState,
          SizeOf(NewState),
          nil,
          returnLength);
        Win32Check(res);

        ProcessCreatedOK := CreateProcessAsUser(
           hUserToken,
           nil,
           PChar(path),
           nil, nil,
           false,
           CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil,
           startupInfo, processInfo);

        if GetLastError <> 0 then
        begin
          err := GetlastError;
          ShowMessage(inttostr(err) + ' ' +  SysErrorMessage(err));
        end;
      end;
    end;

我收到 1314“客户端未持有所需权限”错误。

现在通过一些挖掘,我可以看到我需要对模拟帐户应用一些权限:SE_ASSIGNPRIMARYTOKEN_NAME 和 SE_INCREASE_QUOTA_NAME?

有人对如何做到这一点有一些建议吗?

我已经看到了这个 Stackoverflow答案中给出的 JCL 示例,但我在帐户权限方面遇到了类似的问题。

我不想使用 CreateProcessWithLogonW - 我可以根据要求解释原因。

4

1 回答 1

5

使用AdjustTokenPrivileges. 首先,调用LookupPrivilegeValue获取您想要的权限的ID,然后设置它们。这是一个改编自我碰巧拥有的一些 C 代码的示例:

var
  NewState: TTokenPrivileges;

NewState.PrivilegeCount := 1;
res := LookupPrivilegeValue(nil, Se_AssignPrimaryToken_Name,
  @NewState.Privileges[0].Luid);
Win32Check(res);

NewState.Privileges[0].Attributes := Se_Privilege_Enabled;
res := AdjustTokenPrivileges(hUserToken, False, @NewState,
  SizeOf(NewState), nil, nil);
Win32Check(res);
于 2012-09-26T14:58:16.913 回答