Здравствуйте, doc_d0s, Вы писали:
_>Доброго времени суток. _>У кого есть пример работы с вышеописанной ф-ией, конкретно интересует назначение привелегий перед вызовом оной ф-ии.
Здравствуйте, _Dreamer, Вы писали:
_D>Здравствуйте, doc_d0s, Вы писали:
_>>Доброго времени суток. _>>У кого есть пример работы с вышеописанной ф-ией, конкретно интересует назначение привелегий перед вызовом оной ф-ии.
_D>MSDN ?
А откуду по вашему я узнал про эту ф-ию, в МСДН есть даже код, который не желает работать...
Здравствуйте, 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>>
Не восхрапи на работе, ибо храпом своим разбудишь начальника своего.
Hello _spin_, you wrote:
>> Для того чтобы тот код работал нужно иметь права системы, насколько я помню. Т.е. функция предназначена для сервисов. > работает и в GUI без всяких проблем.
Приведи пример именно с CreateProcessAsUser. Тогда и поговорим.
ЗЫ: Получить привелегии отладки по дефолту могут лишь администраторы и система, насколько помню. А ты ведь наверное свой код из под админа запускал. Так?
Здравствуйте, 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.
Здравствуйте, Slava Antonov, Вы писали:
SA>Hello _spin_, you wrote:
>>> Для того чтобы тот код работал нужно иметь права системы, насколько я помню. Т.е. функция предназначена для сервисов. >> работает и в GUI без всяких проблем.
SA>Приведи пример именно с CreateProcessAsUser. Тогда и поговорим.
Если вспомню — захвачу код с работы, чтоб уж точно работало всё.
SA>ЗЫ: Получить привелегии отладки по дефолту могут лишь администраторы и система, насколько помню.
"дефолт" — вещь относительная и зависит от версии ОС в некоторых случаях.
SA>А ты ведь наверное свой код из под админа запускал. Так?
Да, из-под админа
Вообще-то вопрос был
...конкретно интересует назначение привелегий перед вызовом оной ф-ии...
так что я считаю, что как пример назначения привилегий мой код подходит. А что для этого нужны ещё права — надо думать отдельно.
ИМХО, прежде чем приступать к добавлению подобных функций в своё приложение надо ОЧЕНЬ хорошо подумать. Я считаю, что если есть необходимость делать в системе что-то от имени админа — надо делать сервис, который будет работать под системой или админом и иметь соответствующие права. А в большинстве случаев можно обойтись более точной настройкой политик безопасности. gpedit ещё никто не отменял.
Как показывает мой опыт как админа — админовский пароль, однажды узнанный не-админом может привести к очень серьёзнам последствиям, а админы и не-админы бывают разные...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Не восхрапи на работе, ибо храпом своим разбудишь начальника своего.