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 に答える