CreateProcessAsUser
От: doc_d0s  
Дата: 25.07.06 20:06
Оценка:
Доброго времени суток.
У кого есть пример работы с вышеописанной ф-ией, конкретно интересует назначение привелегий перед вызовом оной ф-ии.
Re: CreateProcessAsUser
От: _Dreamer Россия  
Дата: 26.07.06 06:18
Оценка:
Здравствуйте, doc_d0s, Вы писали:

_>Доброго времени суток.

_>У кого есть пример работы с вышеописанной ф-ией, конкретно интересует назначение привелегий перед вызовом оной ф-ии.

MSDN ?
Re[2]: CreateProcessAsUser
От: doc_d0s  
Дата: 31.07.06 19:04
Оценка:
Здравствуйте, _Dreamer, Вы писали:

_D>Здравствуйте, doc_d0s, Вы писали:


_>>Доброго времени суток.

_>>У кого есть пример работы с вышеописанной ф-ией, конкретно интересует назначение привелегий перед вызовом оной ф-ии.

_D>MSDN ?

А откуду по вашему я узнал про эту ф-ию, в МСДН есть даже код, который не желает работать...
Re[3]: CreateProcessAsUser
От: Slava Antonov Россия http://deadbeef.narod.ru
Дата: 31.07.06 23:59
Оценка:
Hello doc_d0s, you wrote:

> А откуду по вашему я узнал про эту ф-ию, в МСДН есть даже код, который не желает работать...


Для того чтобы тот код работал нужно иметь права системы, насколько я помню. Т.е. функция предназначена для сервисов.

--
Всего хорошего, Слава
ICQ: 197577902
Posted via RSDN NNTP Server 2.0
Re[4]: CreateProcessAsUser
От: _spin_ Россия  
Дата: 01.08.06 14:34
Оценка:
Здравствуйте, Slava Antonov, Вы писали:

SA>Для того чтобы тот код работал нужно иметь права системы, насколько я помню. Т.е. функция предназначена для сервисов.


работает и в GUI без всяких проблем. Алгоритм установки привилегий прост:

Взять привилегии текущего процесса,
Добавить/удалить необходимые привилегии
Запустить процесс AsUser.

Следующий код (взято из DelphiWorld, проверено, работает) выставляет
отладочные привилегии самому себе и имея эти привилегии рубит процесс по его PID`у, после чего удаляет отладочные привилегии.



function ProcessTerminate(dwPID:Cardinal):Boolean; 
var 
 hToken:THandle; 
 SeDebugNameValue:Int64; 
 tkp:TOKEN_PRIVILEGES; 
 ReturnLength:Cardinal; 
 hProcess:THandle; 
begin 
 Result:=false; 
 // Добавляем привилегию SeDebugPrivilege  
 // Для начала получаем токен нашего процесса 
 if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES 
  or TOKEN_QUERY, hToken ) then 
    exit; 

 // Получаем LUID привилегии 
 if not LookupPrivilegeValue( nil, 'SeDebugPrivilege', SeDebugNameValue )  
  then begin 
   CloseHandle(hToken); 
   exit;  
  end; 

 tkp.PrivilegeCount:= 1; 
 tkp.Privileges[0].Luid := SeDebugNameValue; 
 tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; 

 // Добавляем привилегию к нашему процессу 
 AdjustTokenPrivileges(hToken,false,tkp,SizeOf(tkp),tkp,ReturnLength); 
 if GetLastError()< > ERROR_SUCCESS  then exit; 

 // Завершаем процесс. Если у нас есть SeDebugPrivilege, то мы можем 
 // завершить и системный процесс 
 // Получаем дескриптор процесса для его завершения 
 hProcess := OpenProcess(PROCESS_TERMINATE, FALSE, dwPID); 
 if hProcess =0  then exit; 
  // Завершаем процесс 
   if not TerminateProcess(hProcess, DWORD(-1)) 
    then exit; 
 CloseHandle( hProcess ); 
  
 // Удаляем привилегию  
 tkp.Privileges[0].Attributes := 0;  
 AdjustTokenPrivileges(hToken, FALSE, tkp, SizeOf(tkp), tkp, ReturnLength); 
 if GetLastError() < >  ERROR_SUCCESS 
  then exit; 
  
 Result:=true;  
end;
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Не восхрапи на работе, ибо храпом своим разбудишь начальника своего.
Re[5]: CreateProcessAsUser
От: Slava Antonov Россия http://deadbeef.narod.ru
Дата: 01.08.06 23:21
Оценка:
Hello _spin_, you wrote:

>> Для того чтобы тот код работал нужно иметь права системы, насколько я помню. Т.е. функция предназначена для сервисов.

> работает и в GUI без всяких проблем.

Приведи пример именно с CreateProcessAsUser. Тогда и поговорим.

ЗЫ: Получить привелегии отладки по дефолту могут лишь администраторы и система, насколько помню. А ты ведь наверное свой код из под админа запускал. Так?

--
Всего хорошего, Слава
ICQ: 197577902
Posted via RSDN NNTP Server 2.0
Re[6]: CreateProcessAsUser
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 02.08.06 11:52
Оценка:
А что именно надо? В MSDN есть удобоваримый пример с CreateProcessWithLogon. Не подойдёт?
Re[7]: CreateProcessAsUser
От: Slava Antonov Россия http://deadbeef.narod.ru
Дата: 02.08.06 12:33
Оценка:
Hello Nuzhny, you wrote:

> А что именно надо? В MSDN есть удобоваримый пример с CreateProcessWithLogon. Не подойдёт?


Вы его запускали? Работает? Из обычного приложения?

--
Всего хорошего, Слава
ICQ: 197577902
Posted via RSDN NNTP Server 2.0
Re[8]: CreateProcessAsUser
От: Danchik Украина  
Дата: 02.08.06 13:01
Оценка:
Здравствуйте, Slava Antonov, Вы писали:

SA>Hello Nuzhny, you wrote:


>> А что именно надо? В MSDN есть удобоваримый пример с CreateProcessWithLogon. Не подойдёт?


SA>Вы его запускали? Работает? Из обычного приложения?


Да работает. Где то в инете нарыл работающий сампл (пробовал):
unit vApi;

interface

uses
  Windows;

procedure MyCreateProcess(ConstCommandLine : string; Domain, UserName, Password : pWideChar);

function CreateProcessWithLogonW(const lpUsername : PWideChar; const lpDomain : PWideChar;
  const lpPassword : PWideChar; dwLogonFlags : DWORD; const lpApplicationName : PWideChar;
  lpCommandLine : PWideChar; dwCreationFlags : DWORD; lpEnvironment : Pointer;
  const lpCurrentDirectory : PWideChar; lpStartupInfo : PStartupInfo; lpProcessInfo : PProcessInformation): Boolean;
  stdcall;

const
  LOGON_WITH_PROFILE         = $00000001;
  LOGON_NETCREDENTIALS_ONLY  = $00000002;
  LOGON_ZERO_PASSWORD_BUFFER = $80000000;

implementation

uses
  SysUtils;

{$WARN SYMBOL_DEPRECATED OFF}
{ ADVAPI32.DLL functions }
type
  TCreateProcessWithLogonW = function(const lpUsername : PWideChar; const lpDomain : PWideChar; const lpPassword : PWideChar;
    dwLogonFlags : DWORD; const lpApplicationName : PWideChar; lpCommandLine : PWideChar;
    dwCreationFlags : DWORD; lpEnvironment : Pointer; const lpCurrentDirectory : PWideChar;
    lpStartupInfo : PStartupInfo; lpProcessInfo : PProcessInformation): Boolean; stdcall;

const
  DllName = 'advapi32.dll';

var
  DllHandle: THandle;
  _CreateProcessWithLogonW: TCreateProcessWithLogonW;

function InitLib: Boolean;
begin
  if DllHandle = 0 then
    if Win32Platform = VER_PLATFORM_WIN32_NT then begin
      DllHandle := LoadLibrary(DllName);
      if DllHandle <> 0 then begin
        @_CreateProcessWithLogonW := GetProcAddress(DllHandle,
          'CreateProcessWithLogonW');
      end;
    end;
  Result := (DllHandle <> 0);
end;

function NotImplementedBool: Boolean;
begin
  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  Result := False;
end;

function CreateProcessWithLogonW(const lpUsername : PWideChar; const lpDomain : PWideChar;
  const lpPassword : PWideChar; dwLogonFlags : DWORD; const lpApplicationName : PWideChar;
  lpCommandLine : PWideChar; dwCreationFlags : DWORD; lpEnvironment : Pointer;
  const lpCurrentDirectory : PWideChar; lpStartupInfo : PStartupInfo; lpProcessInfo : PProcessInformation): Boolean;
  stdcall;
begin
  if InitLib and Assigned(_CreateProcessWithLogonW) then
    Result := _CreateProcessWithLogonW(lpUsername, lpDomain, lpPassword,
      dwLogonFlags, lpApplicationName, lpCommandLine, dwCreationFlags,
      lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInfo)
  else
    Result := NotImplementedBool;
end;

procedure MyCreateProcess(ConstCommandLine : string; Domain, UserName, Password : PWideChar);
var
  Title: WideString;
  MyStartupInfo: STARTUPINFO;
  ProcessInfo: PROCESS_INFORMATION;
  CommandLine: array[0..512] of WideChar;
begin
  Title := 'Application';
  FillChar(MyStartupInfo, SizeOf(MyStartupInfo), 0);
  MyStartupInfo.cb := SizeOf(MyStartupInfo);

  StringToWideChar(ConstCommandLine, CommandLine, Sizeof(CommandLine) div SizeOf(WideChar));

  MyStartupInfo.lpTitle := PWideChar(Title);
  if not CreateProcessWithLogonW(PWideChar(UserName), PWideChar(Domain),
    PWideChar(Password), LOGON_WITH_PROFILE, nil,
    CommandLine, 0, nil, nil, @MyStartupInfo, @ProcessInfo)
  then
    RaiseLastOSError
  else begin
    CloseHandle(ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hThread);
  end;
end;

initialization

finalization
  if DllHandle <> 0 then
    FreeLibrary(DllHandle);
end.
Re[6]: CreateProcessAsUser
От: _spin_ Россия  
Дата: 02.08.06 13:57
Оценка: -1
Здравствуйте, Slava Antonov, Вы писали:

SA>Hello _spin_, you wrote:


>>> Для того чтобы тот код работал нужно иметь права системы, насколько я помню. Т.е. функция предназначена для сервисов.

>> работает и в GUI без всяких проблем.

SA>Приведи пример именно с CreateProcessAsUser. Тогда и поговорим.

Если вспомню — захвачу код с работы, чтоб уж точно работало всё.

SA>ЗЫ: Получить привелегии отладки по дефолту могут лишь администраторы и система, насколько помню.

"дефолт" — вещь относительная и зависит от версии ОС в некоторых случаях.

SA>А ты ведь наверное свой код из под админа запускал. Так?

Да, из-под админа

Вообще-то вопрос был

...конкретно интересует назначение привелегий перед вызовом оной ф-ии...


так что я считаю, что как пример назначения привилегий мой код подходит. А что для этого нужны ещё права — надо думать отдельно.

ИМХО, прежде чем приступать к добавлению подобных функций в своё приложение надо ОЧЕНЬ хорошо подумать. Я считаю, что если есть необходимость делать в системе что-то от имени админа — надо делать сервис, который будет работать под системой или админом и иметь соответствующие права. А в большинстве случаев можно обойтись более точной настройкой политик безопасности. gpedit ещё никто не отменял.

Как показывает мой опыт как админа — админовский пароль, однажды узнанный не-админом может привести к очень серьёзнам последствиям, а админы и не-админы бывают разные...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Не восхрапи на работе, ибо храпом своим разбудишь начальника своего.
Re[7]: CreateProcessAsUser
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 02.08.06 17:19
Оценка:
Вот быстро набросал для не-юникода:
DWORD NewProcess(char *szUser,  //имя пользователя
                 char *szDomain, //домен (или имя компьютера, если пользователь - локальный)
                 char *szPassword //пароль)
{
    WCHAR wsUser[255];
    WCHAR wsDomain[255];
    WCHAR wsPassword[255];
    memset(wsUser, 0, 255*sizeof(WCHAR));
    memset(wsDomain, 0, 255*sizeof(WCHAR));
    memset(wsPassword, 0, 255*sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP,
                        0,
                        szUser,
                        (int)strlen(szUser) + 1,
                        wsUser,
                        255*sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP,
                        0,
                        szDomain,
                        (int)strlen(szDomain) + 1,
                        wsDomain,
                        255*sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP,
                        0,
                        szPassword,
                        (int)strlen(szPassword) + 1,
                        wsPassword,
                        255*sizeof(WCHAR));
    
    STARTUPINFO si;
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb= sizeof(STARTUPINFO);

    PROCESS_INFORMATION pi;
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

    CreateProcessWithLogonW(wsUser,
        wsDomain,
        wsPassword,
        LOGON_WITH_PROFILE,
        L"C:\\Program Files\\Marriage\\marriage.exe",
        L"",
        NORMAL_PRIORITY_CLASS,
        0,
        0,
        &si,
        &pi);

    return GetLastError();
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.