const
SE_ASSIGNPRIMARYTOKEN_NAME = 'SeAssignPrimaryTokenPrivilege';
SE_INCREASE_QUOTA_NAME = 'SeIncreaseQuotaPrivilege';
SE_TCB_NAME = 'SeTcbPrivilege';
function EnablePrivilege(lpPrivilegeName: PChar):Boolean;
var
hToken: dword;
NameValue: Int64;
tkp: TOKEN_PRIVILEGES;
ReturnLength: dword;
begin
Result:=false;
//Ïîëó÷àåì òîêåí íàøåãî ïðîöåññà
OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken);
//Ïîëó÷àåì LUID ïðèâèëåãèè
if not LookupPrivilegeValue(nil, lpPrivilegeName, NameValue) then
begin
CloseHandle(hToken);
exit;
end;
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Luid := NameValue;
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
//Äîáàâëÿåì ïðèâèëåãèþ ê ïðîöåññó
AdjustTokenPrivileges(hToken, false, tkp, SizeOf(TOKEN_PRIVILEGES), tkp, ReturnLength);
if GetLastError() <> ERROR_SUCCESS then
begin
CloseHandle(hToken);
exit;
end;
Result:=true;
CloseHandle(hToken);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
sti:TStartupInfo;
pi:TProcessInformation;
usertoken:THandle;
st:pointer;
begin
if not LogonUser('123','.','111',LOGON32_LOGON_INTERACTIVE ,LOGON32_PROVIDER_DEFAULT,usertoken) then
begin
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER+FORMAT_MESSAGE_FROM_SYSTEM,0,GetLastError,LANG_NEUTRAL,@st,0,0);
ShowMessage(pchar(st));
end;
ZeroMemory(@sti,Sizeof(sti));
if not EnablePrivilege(SE_INCREASE_QUOTA_NAME) then ShowMessage('ошибка 1');
if not EnablePrivilege(SE_ASSIGNPRIMARYTOKEN_NAME) then ShowMessage('ошибка 2');
if not CreateProcessAsUser(usertoken,'c:\windows\system32\calc.exe',0,0,0,false,0,0,0,sti,pi) then
begin
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER+FORMAT_MESSAGE_FROM_SYSTEM,0,GetLastError,LANG_NEUTRAL,@st,0,0);
ShowMessage(pchar(st));
end;
end;
Запуск от имени другого пользователя
Здравствуйте! Бьюсь над проблемой связанной с запуском программ от имени другого пользователя (администратор к примеру). Функция CreateProcessWithLogonW работает прекрасно но отказывается запускать к примеру файлы консоли (.msc) а это в очень важно. Другую функцию CreateProcessAsUser не могу никак разобрать и-за сложных структур (и кстати не факт что эта функция запустит файлы консоли). Просьба может кто-то сталкивался с аналогичной проблемой. Или привидите 100% рабочий код с использованием CreateProcessAsUser. Спасибо!
тоукен пользователя можно получить через функцию LogonUser
BOOL LogonUser(
LPTSTR lpszUsername, // string that specifies the user name
LPTSTR lpszDomain, // string that specifies the domain or server
LPTSTR lpszPassword, // string that specifies the password
DWORD dwLogonType, // specifies the type of logon operation
DWORD dwLogonProvider, // specifies the logon provider
PHANDLE phToken // pointer to variable to receive token handle
);
в ней вроде всё понятно
И что за параметры функции:
DWORD dwLogonType, // specifies the type of logon operation
DWORD dwLogonProvider, // specifies the logon provider
PHANDLE phToken // pointer to variable to receive token handle
какие они значеия могут принемать
dwLogonProvider, точно не помню, но помойму ставится (в стандартных случаях) в NULL
phToken - возвращаемое значение токена аутентификации
Подробнее - http://msdn2.microsoft.com/en-us/library/aa378184.aspx
[quote=Tramp]а можно ли используя функцию LogonUser определить есть ли такой пользователь в сети (сеть доменная).[/quote]
Параметр lpszDomain ни о чем не говорит?
Дело не LogonUser а именно в CreateUser.... так как там после запуска функция возвращает ошибку "Клиент не обладает требуемыми правами"
для LogonUser нужна привилегия SE_TCB_NAME (с ней вроде проблем нет, я у себя проверял - включать её не потребовалось)
для CreateProcessAsUser надо SE_ASSIGNPRIMARYTOKEN_NAME и SE_INCREASE_QUOTA_NAME ( с ней всё нормально).
Вся проблема привилегии SE_ASSIGNPRIMARYTOKEN_NAME она почему то включаться не хочет.
если нужен был код, то вот (по идее он должен работать, но почему то не включается привилегия SE_ASSIGNPRIMARYTOKEN_NAME)
Код:
Не хочет!! Возвращает теперь "пользователь обладает не всеми используемыми правами доступа " Я пробовал подставлять по-разному. Подкиньте ещё идейку пожалуйста.
так он выводит ошибку: ShowMessage('ошибка 2');? или такая проблема только у меня?
А как бы локально залогинить юзера SYSTEM с помощью LogonUser()? GetLastError() после провала LogonUser() выдаёт 1326 "Logon failure — unknown user name or bad password."
Username не должен быть неизвестным, как-будто. А вот с паролем - если он есть, то в SAM? И как его оттуда выдернуть? После Unix модель безопасности в NT кажется очень уж вычурной... В общем, не могу понять, как, если можно и можно ли вообще без грязного хака.
Как вариант(для общего случая), напиши какой-нибудь переходник (например, run.exe), который с помощью ShellExecute запускает нужный тебе файл, а run.exe запускай с помощью CreateProcessWithLogonW.
2ahilles: не только у тебя. Привилегия SE_ASSIGNPRIMARYTOKEN_NAME не хочет устанавливаться, AdjustTokenPrivileges возвращает 1, но при этом появляется ошибка, что не все привилегии были установлены.
Как вариант(для общего случая), напиши какой-нибудь переходник (например, run.exe), который с помощью ShellExecute запускает нужный тебе файл, а run.exe запускай с помощью CreateProcessWithLogonW.
Я так и думал потому как из консоли командой runas тоже не запускаются такие файлы. Буду пробовать.
lifs попробовал, но почему-то открывается пустая консоль. Даже если прото из командной строки запустить mmc.exe с параметром *.msc то же самое.
Код:
CreateProcessWithLogonW(L"user", L".", L"pass", 0, NULL, L"mmc c:\\windows\\system32\\services.msc", 0, NULL, NULL, (LPSTARTUPINFOW)&si, &pi);
Этот вызов запустит просмотр установленных служб от имени user'а.
Точно! оказалось все проще чем я думал! Спасибо!
Цитата: lifs
Запускать нужно так, указывая полный путь к файлу:
Этот вызов запустит просмотр установленных служб от имени user'а.
Код:
CreateProcessWithLogonW(L"user", L".", L"pass", 0, NULL, L"mmc c:\\windows\\system32\\services.msc", 0, NULL, NULL, (LPSTARTUPINFOW)&si, &pi);
Этот вызов запустит просмотр установленных служб от имени user'а.
[COLOR="Magenta"]epi.obj : error LNK2028: unresolved token (0A00004C) "extern "C" int __stdcall CreateProcessWithLogonW(wchar_t const *,wchar_t const *,wchar_t const *,unsigned long,wchar_t const *,wchar_t *,unsigned long,void *,wchar_t const *,struct _STARTUPINFOW *,struct _PROCESS_INFORMATION *)" (?CreateProcessWithLogonW@@$$J244YGHPB_W00K0PA_WKPAX0PAU_STARTUPINFOW@@PAU_PROCESS_INFORMATION@@@Z) referenced in function "void __clrcall likeboom(void)" (?likeboom@@$$FYMXXZ)[/COLOR]
D:\CPP\epi-test\epi\Debug\epi.exe : fatal error LNK1120: 2 unresolved externals
Вот такое у меня происходит :confused:
Я вообще то когда то на Делфи немножко что-то делал... а тут совсем дизориентировался :)
Помогите пожалуйста!