Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi SCM Verbindung unter anderen Benutzer namen (https://www.delphipraxis.net/105994-scm-verbindung-unter-anderen-benutzer-namen.html)

Alex2.2 3. Jan 2008 13:58


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:
{$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}
Den bisher bestehend den Code des Threads habe ich hier mal hineingestellt. Dieser Thread soll einmal Teil eins Guardian Service sein.

Ich hoffe jemand kann mir da helfen

Dezipaitor 3. Jan 2008 17:12

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.

Alex2.2 4. Jan 2008 15:40

Re: SCM Verbindung unter anderen Benutzer namen
 
Soetwas habe ich mir bereits gedacht. Glücklich bin ich nartürlich nicht. Aber erstmal danke

Alex2.2 10. Jan 2008 18:28

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 http://www.online-admin.com/download.html. Damit geht viel mehr aus ich eigentlich vor hatte. Das zeug kostet allerding 60€. Aber das bezahlt meine Firma.

Da ihr für mich immer so hilfreich seit wollte ich da nur noch mitteilen


Bernd


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:28 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz