![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сервис не ShutDownит сервер с выданными привилегиями. [D6, NT4, Win2k, WinXP]
Kacnep © (2006-08-25 07:45:00)Ув. мастера! Сервис по приходу некой команды из сети должен выполнить *.cmd файл. Вот что например
c:\adm\ss.cmd
shutdown /s /f >c:\adm\log.txt
т.е. выключить сервер, но этого не происходит.
Сам командник запускается! Файл log.txt появляется.
Привелегии необходимые вроде бы выдал - не уверен что в том месте программы.
Сервис запускается как Local System.
Может кто нить что подсказать (сервера 2000 и 2003).
Я рассматривал пример
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1147525423&n=5 Вот куски кода...
....
procedure AdjTokenPrivelegs(mmName: string);
var
gler: DWord;
begin
AdjustPriviliges(mmName);
gler:=GetLastError;
if (glerERROR_SUCCESS) then begin
WriteLog(Format('%s: [FAILED] ', [mmName]));
{$IFDEF _DEV_}
ShowError(gler);
{$ENDIF}
exit;
end;
WriteLog(Format('%s: [OK] ', [mmName]));
end;
procedure Tf_Main.ServiceStart(Sender: TService; var Started: Boolean); //эта штука при старте сервера - тут и выдаю привилегии
var
sl_Tmp:TStringList;
s:string;
i:integer;
begin
Started:=FALSE;
AdjTokenPrivelegs(SE_SHUTDOWN_NAME); //выдаем ЭТУ ТОЧНО ПРИВИЛЕГИЮ!!!
AdjTokenPrivelegs(SE_DEBUG_NAME);
WriteLog('Service is starting... ');
if not StartServer then
WriteLog('Error starting server')
else WriteLog('Server started successfully!');
WriteLog('Service is started.');
Started:=TRUE;
end;
....
procedure Tf_Main.id_SrvCommandHandlers0Command(ASender: TIdCommand); //это по приходу команды из сети использую компонент инди
var
PMSI:TStartupInfo;
PMPI:TProcessInformation;
begin
WriteLog(ASender.Context.Connection.Socket.Binding.PeerIP+' -> Shutdown');
if (FIP.Count>0) and (FIP.IndexOf(ASender.Context.Connection.Socket.Binding.PeerIP)>-1) then begin
WriteLog('Execute Shutdown! '+FScript);
FillChar(PMSI,sizeof(PMSI),0);
PMSI.cb:=sizeof(PMSI);
FillChar(PMPI,sizeof(PMPI),0);
try
try //Win32Check(
if not CreateProcess(nil,PChar(FScript),nil,nil,true,0,{false,normal_priority_class,}ni l,nil,PMSI,PMPI) then RaiseLastWin32Error;
except
WriteLog('Error: '+SysErrorMessage(GetLastError));
end;
finally
CloseHandle(PMPI.hProcess);
CloseHandle(PMPI.hThread);
end;
end;//if
end;
Сергей М. (2006-08-25 12:14:00) [21]
> Kacnep © (25.08.06 12:05) [10]
Вот ты стартовал процесс, он УЖЕ работает, УЖЕ выполняет скрипт и вероятно УЖЕ попытался шатдаун выполнить, а ты только еще чухнулся привелегии ему дать)
Стартуй процесс с опцией CREATE_SUSPENDED, назначай ему соотв.привелегии, и уж потом только толкай его на выполнение с этими привелегиями - ResumeThread(PMPI.hThread)
Ketmar (2006-08-25 12:11:00) [22]> [10] Kacnep © (25.08.06 12:05)
CreateProcessAsUser()/LogonUser()?
Kacnep (2006-08-25 12:05:00) [23]так попорядку от простого к сложному...
2 BiN © (25.08.06 11:48) [9]
Мало того! На него никто и не заходил после перезагрузки! Установили сервис запустили в авто и ребутанули! Цель чтобы сервис уже работал (и он работает) и ожидал команды!
2 Чапаев
Опять же... и СМД выполняется и пинг и прочие -простые команды "примитивные" а вот что то типа Шатдауна или... {блин кажется если я про Оракл вас загружу - уныло будет - там жопная аутентификация}
2 Остальные вот код но это только для Шатдауна!!! А мне требуется грубоговоря сделать копию списка админский прав!!!
procedure Tf_Main.id_SrvCommandHandlers0Command(ASender: TIdCommand);
const
PrivelegStr='SeShutdownPrivilege';
var
PMSI:TStartupInfo;
PMPI:TProcessInformation;
hTok: THandle;
tp: TTokenPrivileges;
begin
WriteLog(ASender.Context.Connection.Socket.Binding.PeerIP+' -> Shutdown');
if (FIP.Count>0) and (FIP.IndexOf(ASender.Context.Connection.Socket.Binding.PeerIP)>-1) then begin
WriteLog('Execute Shutdown! '+FScript);
FillChar(PMSI,sizeof(PMSI),0);
PMSI.cb:=sizeof(PMSI);
FillChar(PMPI,sizeof(PMPI),0);
try
try
Win32Check(CreateProcess(nil,PChar(FScript),nil,nil,false,0,{false,normal_priori ty_class,}nil,nil,PMSI,PMPI));
if OpenProcessToken(PMPI.hProcess, TOKEN_ADJUST_PRIVILEGES+TOKEN_QUERY, hTok) then //я так понял тут начинаю работать с процессом
try
// Get the LUID for privilege.
if LookupPrivilegeValue(nil, PChar(PrivelegStr),tp.Privileges[0].Luid) then begin
tp.PrivilegeCount:=1; // one privilege to set
tp.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
// Get privilege for this process.
AdjustTokenPrivileges(hTok,False,tp,0,PTokenPrivileges(nil)^, PDWord(nil)^);
end
finally
// Cannot test the return value of AdjustTokenPrivileges.
if (GetLastError <> ERROR_SUCCESS) then raise Exception.Create('AdjustTokenPrivileges enable failed');
CloseHandle(hTok);
end
else raise Exception.Create('OpenProcessToken failed');
except
WriteLog('Error: '+SysErrorMessage(GetLastError));
end;
finally
CloseHandle(PMPI.hProcess);
CloseHandle(PMPI.hThread);
end;
end;//if
end;
BiN (2006-08-25 11:48:00) [24]
> Kacnep © (25.08.06 11:21) [5]
Компьютер при этом залочен?
Ketmar (2006-08-25 11:48:00) [25]сильно подозреваю, что или никак, или неправильно. однозначно -- код в студию.
Чапаев (2006-08-25 11:45:00) [26]> Все эти команды и возможно другие должен выполнять мой
> CreateProcess(nil,PChar(FScript),nil,nil,true,0,nil,nil,
> PMSI,PMPI);
Вообще кошернее выполнить cmd.exe, которому в качестве аргумента передаётся командный файл...
Сергей М. (2006-08-25 11:38:00) [27]
> Нашел кучу примеров как наделять процесс какой то какими
> то правами
Показывай, как ты наделяешь стартуемый твоим сервисом процесс шатдаун-правом ..
Kacnep (2006-08-25 11:21:00) [28]Люди :( не смог разобраться с правами - знаний не хватает.
А сейчас и времени.
Думал что проще получиться.
Общая ситуация такая.
ВНИМАНИЕ! На сервере никто не залогинен!!! Это обязан выполнить процесс!Преред выключением сервера - на нем должен выполниться скрипт гашения скажем оракловой базы.
Если я залогинюсь на сервак то гашу так.
sqlplus {если выполняет эту команду сервис - почему то требуется прописать пути а если вручную запускаю то пути берет из переменных окружения} /nolog @{путь где лежит\}скрипт гашение базы.
Потом выключаю сервер 2003
shutdown /s /f
Все эти команды и возможно другие должен выполнять мой
CreateProcess(nil,PChar(FScript),nil,nil,true,0,nil,nil,PMSI,PMPI);
Я даже не знаю как точно вопрос задать... %(
В общем надо как то процесс запуска скрипта наделить всеми! полномочиями администратора именно этого сервера на котором он выполняется.
Помогите. Тут у меня знаний не хватает. Нашел кучу примеров как наделять процесс какой то какими то правами - но какие конкретно мне нужны - не понимаю кроме seShutDown....
Сергей М. (2006-08-25 08:55:00) [29]
> в доке про CreateProcess - сказано что он сам выдает код
> ошибки
Ну так ты ж все равно при этом исключение возбуждаешь (см. raiselastwin32error)..
Конечно код
try
if not CreateProcess(..) then RaiseLastWin32Error;
except
WriteLog('Error: '+SysErrorMessage(GetLastError));
end;
полностью эквивалентен этому
try
Win32Check(CreateProcess(..));
except
WriteLog('Error: '+SysErrorMessage(GetLastError));
end;
но код с Win32Check и короче в написании и изящней ..
Kacnep (2006-08-25 08:23:00) [30]2 Сергей М.
Насчет Вин32Чек
Просто в доке про CreateProcess - сказано что он сам выдает код ошибки...
Не стал лишнюю ф-ю юзать. Но это ж не принципиально.
Насчет ДРУГОГО процесса - сейчас попробую...
Спасибо за советы!
Сергей М. (2006-08-25 08:21:00) [31]И чем тебе Win32Check не угодил - тоже не понятно)
Сергей М. (2006-08-25 08:19:00) [32]
> Привелегии необходимые вроде бы выдал
Ты их кому выдал-то ? Сервису. А инициатором шатдауна кто является ? Совсем другой процесс, тот самый который у тебя скрипт исполняет. Вот как раз ему-то и нужны эти привелегии, а не сервису.