![]() |
SCM Verbindung unter anderen Benutzer namen
Hallo,
Ich habe da mal wieder eine Frage für die Cracks unter euch. Ich habe einen bestimmten Thread, der probiert via Service Control Manager (SCM) Verbindung einen Service auf einem anderen (oder auch den eignen, was dann trivial wäre) zu restarten. Mein Problem ist dabei, dass der Process, dem dieser Thread gehört, selbst ein Service ist, der selbst verständlich mit den Rechten des Benutzers "System" läuft. "System" hat aber keine Rechte auf den SCM eines entfernten Computers. Daher bestehen zwei Möglichkeiten. Der Thread der die Verbindung aufbaut muß mit anderen Rechten (unter einem anderen Benutzer) laufen oder die SCM Verbindung kann unter einen anderen Benutzernamen hergestellt werden. Nur weiß ich weder wie man das eine, noch wie man das andere macht.
Delphi-Quellcode:
Den bisher bestehend den Code des Threads habe ich hier mal hineingestellt. Dieser Thread soll einmal Teil eins Guardian Service sein.
{$REGION 'TimeOutHandler Thread'}
procedure TTimeOutHandler.setTimeOutMessage(Value : TTimeOutMessage); var i : Integer; begin FTimeOutMsg.ApplId:=Value.ApplId; FTimeOutMsg.ApplExe:=Value.ApplExe; FTimeOutMsg.ApplService:=Value.ApplService; FTimeOutMsg.ApplIP:=Value.ApplIP; FTimeOutMsg.ThreadId:=Value.ThreadId; FTimeOutMsg.CodePartId:=Value.CodePartId; FTimeOutMsg.StackCount:=Value.StackCount; setLength(FTimeOutMsg.Stack,Value.StackCount); for i := 0 to length(value.Stack) - 1 do FTimeOutMsg.Stack[i]:=Value.Stack[i]; FStep:= thsConnectService; end; procedure TTimeOutHandler.executeStateMachine; var schService, //Service Handle schSCManager:Integer; //Service Manager Handle; StackString, EmailText: TStringlist; ActionText, ListString:String; i : integer; function GuardianStopService: boolean; var ServiceState: SERVICE_STATUS; //Service State begin Result:=True; // Get the Services State Result:= QueryServiceStatus( schService, ServiceState); // is the Service allready stopped? if Result then if ServiceState.dwCurrentState > SERVICE_STOPPED then begin if ( ServiceState.dwCurrentState = SERVICE_STOP_PENDING ) then begin Sleep( ServiceState.dwWaitHint ); Result:= QueryServiceStatus( schService, ServiceState); if Result then Result := ServiceState.dwCurrentState = SERVICE_STOPPED; end else begin result:= ControlService( schService, SERVICE_CONTROL_STOP, ServiceState ); if ( ServiceState.dwCurrentState = SERVICE_STOP_PENDING ) then begin Sleep( ServiceState.dwWaitHint ); Result:= QueryServiceStatus( schService, ServiceState); if Result then Result := ServiceState.dwCurrentState = SERVICE_STOPPED; end; end; end; end; //function function GuardianStartService: boolean; var ServiceState: SERVICE_STATUS; //Service State CheckCount : Integer; Args : String; SvArgs : PAnsiChar; begin Args:=''; SvArgs:=PAnsiChar(Args); // Start the Service result:=StartService(schService,0,SvArgs); { // Get the Services State if Result then Result:= QueryServiceStatus( schService, ServiceState); // wait maximum 10s to get the Service in running state; CheckCount:=0; if Result then begin while ((ServiceState.dwCurrentState = SERVICE_START_PENDING) or (CheckCount<9) and result) do begin inc(CheckCount); sleep(1000); Result:= QueryServiceStatus( schService, ServiceState); end; if result then result :=ServiceState.dwCurrentState = SERVICE_RUNNING; end;} end; //function function GuardianOpenService(TimeOutMsg: TTimeOutMessage):Boolean; var Par1, Par2, Args : String; SvArgs : PAnsiChar; i: Integer; begin Args:=char(0); SvArgs:=PChar(Args); // Par1:=char(0); Par1:=TimeOutMsg.ApplIP+char(0); Par2:=TimeOutMsg.ApplService+char(0); Result:=True; //get Service Manager Handle: schSCManager := OpenSCManager(PChar(Par1),SERVICES_ACTIVE_DATABASE,SC_MANAGER_ALL_ACCESS); Result:= not(schSCManager = 0); //get Service Handle if Result then begin schService := OpenService(schSCManager,PChar(Par2), SERVICE_ALL_ACCESS); result:= not(schService = 0); end else i:=GetLastError; end; begin while not Terminated do begin case FStep of {$REGION 'thsConnectService'} thsConnectService: begin ActionText:='Tried: '; if not FTimeoutActions.RestartService then FStep:=thsKillExecutable else begin ActionText:=ActionText+'restart Service: '; if FTimeOutMsg.ApplService <> '' then begin if GuardianOpenService(FTimeOutMsg) then FStep:=thsStopService else begin FStep:=thsKillExecutable; ActionText:=ActionText+'couldn''t connect to Service Manager!'; end; end else begin ActionText:=ActionText+'Have no Service Name!'; FStep:=thsKillExecutable; end; end; end; {$ENDREGION} {$REGION 'thsStopService'} thsStopService: begin sleep(5000); if GuardianStopService then FStep:= thsStartService else begin ActionText:=ActionText+'Couldn''t stop the Service!'; FStep:=thsKillExecutable; End; end; {$ENDREGION} {$REGION 'thsStartService'} thsStartService: begin sleep(5000); if GuardianStartService then begin FStep:= thsSendMail; ActionText:=ActionText+'sucessfull'; end else begin ActionText:=ActionText+'Couldn''t start the Service!'; FStep:=thsKillExecutable; End; end; {$ENDREGION} {$REGION 'thsKillExecutable'} thsKillExecutable: Begin FStep:= thsSendMail; End; {$ENDREGION} {$REGION 'thsSendMail'} thsSendMail: if not FTimeoutActions.SendMail then FStep:=thsTerminateThread else begin EmailText:=TStringlist.Create; with EmailText do begin Delimiter:=#13; Clear; append('Application Timeout happens:'); append('============================'); append('Local Server Time: '+DateTimeToStr(now)); append('Application Computer IP: '+FTimeOutMsg.ApplIP); append('Application Executable Name: '+FTimeOutMsg.ApplExe); append('Application Service Name: '+FTimeOutMsg.ApplService); append('Application Internal Id: '+inttostr(FTimeOutMsg.ApplId)); if FTimeOutMsg.ThreadId>-1 then begin append('Application internal Thread Id: '+IntToStr(FTimeOutMsg.ThreadId)); if FTimeOutMsg.CodePartId>-1 then begin append('Application Thread Codepart Id: '+IntToStr(FTimeOutMsg.CodePartId)); append('The Codepart was not left of refreshed after the preset time interval'); append('Stack of entered codeparts:'); for i := 0 to FTimeOutMsg.StackCount - 1 do begin append('Level( '+IntToStr(i) +'):'+IntToStr(FTimeOutMsg.Stack[i])); end; end else begin append('The Applications Thread doesn''t send the its idle signal after the preset time interval'); end; end else append('The Application doesn''t send the application idle signal after the preset time interval'); append(ActionText); end; Form1.sendEmail(EmailText); EmailText.Free; FStep:= thsTerminateThread; end; {$ENDREGION} {$REGION 'thsTerminateThread'} thsTerminateThread: terminate; {$ENDREGION} end; end; end; procedure TTimeOutHandler.execute(); begin // inherited execute; executeStateMachine; end; {$ENDREGION} Ich hoffe jemand kann mir da helfen |
Re: SCM Verbindung unter anderen Benutzer namen
Du könntest dein Service in den SCM Einstellungen, als anderer Benutzer starten lassen.
Alles andere wird sich als schwer erweisen, weil man ein Token von einem Remoteuser benötigt. Das geht aber nur, wenn man sich einloggt und das erfordert ein PAsswort. Ok, du könntest das Passwort zwischenspeichern und dann mit LogonUser das Token dadurch erhalten. |
Re: SCM Verbindung unter anderen Benutzer namen
Soetwas habe ich mir bereits gedacht. Glücklich bin ich nartürlich nicht. Aber erstmal danke
|
Re: SCM Verbindung unter anderen Benutzer namen
Hallo Leute
Noch ein Nachtrag. Der SCM kanns wirklich nicht. Aber mit WMI hat man ein sehr mächtiges Mittel. 1. Anmeldung als beliebiger Benutzer auf dem Zielsystem. 2. Services Stoppen und Starten. 3. Programme, die sich auf dem System befinden abbrechen und auch Starten. 4. System reboot ... und noch viel mehr. Da ich von natur aus unter Druck stehe habe ich mich natürlich kundig gemacht etwas fertiges zu suchen und bin auch fündig geworden unter ![]() Da ihr für mich immer so hilfreich seit wollte ich da nur noch mitteilen Bernd |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz