Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Wie startet Firefox seinen Update Service? (https://www.delphipraxis.net/197914-wie-startet-firefox-seinen-update-service.html)

QuickAndDirty 18. Sep 2018 13:48

Wie startet Firefox seinen Update Service?
 
Hallo, ich habe mir einen Update Service geschrieben.
Wie bei FF soll der nicht die ganze Zeit laufen sondern einfach nur wenn er gebraucht wird.
Nun bekomme ich den Service ohne Admin privilegien nicht gestartet.
openService
meldet "Access Denied"

Wie macht FF das mit seinem Update Service?

Luckie 18. Sep 2018 14:50

AW: Wie startet Firefox seinen Update Service?
 
Könnte man ihn eventuell in die Aufgabenplanung eintragen, damit er alle 7 Tagen sich startet und nach Updates guckt?

jobo 18. Sep 2018 14:54

AW: Wie startet Firefox seinen Update Service?
 
Weiß nicht, wie er das genau macht. Worauf Du aber vielleicht hinaus willst:
Bei der FF Installation wird gefragt, ob automatisch nach Updates gesucht werden soll (oder sogar explizit nach diesem Service gefragt)
Sagt man nein, passiert natürlich nichts.
Sagt man ja, gibt es eine UAC Abfrage und das Setup erlangt Admin Rechte, mit deren Hilfe es sicher den Service einrichtet, also auch dem Service selbst das Recht (weiter)gibt.

(So ungefähr aus dem Kopf, das Spiel ist prinzipbedingt immer sehr ähnlich)

QuickAndDirty 18. Sep 2018 15:05

AW: Wie startet Firefox seinen Update Service?
 
Ja ich weiß. Mein Service läuft ja auch als "System" Service und er wurde mit "RUNAS" installiert.

Schokohase 18. Sep 2018 15:07

AW: Wie startet Firefox seinen Update Service?
 
Hat irgendwer schon mal den FireFox bei einem Update genau beobachtet?
Was ist Euch da aufgefallen?

Eben, nix!

Der fragt für die Installation noch nicht mal nach dem Administrator-Zugang trotz UAC.

Und warum?

Weil die Installation von dem MozillaMaintenance Service durchgeführt wird. Dieser Dienst läuft im Kontext von Lokales System und darf somit auch installieren.

Dieser Dienst ist aber im Normal-Zustand beendet und wird nur dann erweckt, wenn es ein Update gibt.

Genau darum geht es hier in diesem Thread. Wie weckt Otto-Normal-User den Service auf, damit dieser mit seinen höheren Rechten die Installation vollzieht.

Ich habe es gerade mal ausprobiert und das geht mit
Code:
net start MoziallaMaintenance
(auch als Otto-Normal-User).

QuickAndDirty 18. Sep 2018 15:07

AW: Wie startet Firefox seinen Update Service?
 
Zitat:

Zitat von Luckie (Beitrag 1413489)
Könnte man ihn eventuell in die Aufgabenplanung eintragen, damit er alle 7 Tagen sich startet und nach Updates guckt?

Denke das ginge, aber ich dachte immer, dass FF den Service bei Bedarf startet.
Ich weiß nur nicht WIE?
Der Mozilla Update Service läuft, wie mein Service, im "System" Benutzerkontext.
Der FF läuft als Benutzer.
Wie startet FF den Dienst?

QuickAndDirty 18. Sep 2018 15:21

AW: Wie startet Firefox seinen Update Service?
 
Zitat:

Zitat von Schokohase (Beitrag 1413493)
Ich habe es gerade mal ausprobiert und das geht mit
Code:
net start MoziallaMaintenance
(auch als Otto-Normal-User).

Hm...Ich weiß es ist etwas bitchy aber warum geht das nicht mit mit dem Servicemanager von windows...?
Liegts daran das OpenService einen Zugang zu allerlei Anderem liefert, neben der Möglichkeit den Service zu starten?

ich gucke gerade vielleicht nehme ich mir mit den flags hier einfach zuviel heraus und man muss sich selbst in den anforderungen beschneiden damit es klapt?

Delphi-Quellcode:
  hServiceManager := OpenSCManager(nil, nil, SC_MANAGER_CONNECT);
  if hServiceManager > 0 then
  begin
    GetLastError;
    hService := OpenService(hServiceManager,
                            PChar(ServiceName),
                            SERVICE_START);
    err := GetLastError;
    if ERR >0 then
    Begin
      {$IFDEF FrameWork_VCL}
      Showmessage(SysErrorMessage(GetLastError));
      {$ENDIF}
      {$IFDEF FrameWork_FMX}
      TDialogService.Showmessage(SysErrorMessage(GetLastError));
      {$ENDIF}
    End;

Schokohase 18. Sep 2018 15:47

AW: Wie startet Firefox seinen Update Service?
 
Probier es mal mit https://stackoverflow.com/a/30514865/1744164 (da musst du minimal noch Hand anlegen damit es läuft)

MyRealName 18. Sep 2018 16:12

AW: Wie startet Firefox seinen Update Service?
 
Kann es sein, dass er den service beim windows start hoch fährt, dieser nach einem update schaut und wnen nichts da ist, der service sich einfach beendet ?
(Hab kein FF, von daher nur theorie)

QuickAndDirty 18. Sep 2018 16:19

AW: Wie startet Firefox seinen Update Service?
 
hab das versuch, geht leider nicht.
Aber wieso sollte es funktionieren wenn ich start und Query rechte anfordere...
das ist zurzeit die funktion.
Delphi-Quellcode:
function TServiceController.StartService(ServiceName : string) : TServiceStatusReturn;
var
  hService : SC_HANDLE;
  hServiceManager : SC_HANDLE;
  pDummy : PChar;
  Tries : Integer;
  err:Cardinal;
begin
  Result := ServiceGetStatus(nil,PChar(ServiceName));
  if Result <> ssrStopped then
    Exit;
//  SetServiceObjectSecurity() // vermutlich
  hServiceManager := OpenSCManager(nil, nil, SC_MANAGER_CONNECT );
  if hServiceManager > 0 then
  begin
    GetLastError;
    hService := OpenService(hServiceManager,
                            PChar(ServiceName),
                            SERVICE_START);
    Err := getlasterror;
    if ERR >0 then
    Begin
      {$IFDEF FrameWork_VCL}
      Showmessage(SysErrorMessage(GetLastError));
      {$ENDIF}
      {$IFDEF FrameWork_FMX}
      TDialogService.Showmessage(SysErrorMessage(GetLastError));
      {$ENDIF}
    End;

    if hService > 0 then
    begin
      pDummy := nil;
      if winsvc.StartService(hService, 0, pDummy) then
      begin
        Tries := 5;
        repeat
          Sleep(10000);
          Result := ServiceGetStatus(nil,pchar(ServiceName));
          Dec(Tries);
        until (Tries = 0) or (Result = ssrRunning);
      end
      else
      begin
        Result := ssrError;
      end;
      CloseServiceHandle(hService);
    end
  end;
  CloseServiceHandle(hServiceManager);
end;
Vermutlich ist der fehler, dass ich den Service mit Shellexecute installiere...
Wenn ich den Service auch über den ServiceManager installieren würde könnte ich die via UAC Angeforderten rechte nutzen um diese funktion SetServiceObjectSecurity()auszuführen.
hmm

QuickAndDirty 18. Sep 2018 16:20

AW: Wie startet Firefox seinen Update Service?
 
Zitat:

Zitat von MyRealName (Beitrag 1413499)
Kann es sein, dass er den service beim windows start hoch fährt, dieser nach einem update schaut und wnen nichts da ist, der service sich einfach beendet ?
(Hab kein FF, von daher nur theorie)

Starttyp des Mozilla Update Service ist manuell

QuickAndDirty 18. Sep 2018 16:23

AW: Wie startet Firefox seinen Update Service?
 
hab zurzeit diese rechte auf dem Service
Laut
SC SDSHOW MyUpdateService
Code:
D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)
mit
Code:
sc sdset MyUpdateService D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RPWP;;;IU)
erweitere ich die rechte sinnvoll am besten direkt nach installation des service....wegen der uac.

geht sowas im batch
Code:
SC SDSHOW MyUpdateService > tempfile.txt
type tempfile.txt | echo (A;;RPWP;;;IU)>tempfile.txt
type tempfile.txt > SC SDSET MyUpdateService
naja auf jedenfall lässt sich der dienst jetzt auch ohne rechte starten

Sherlock 19. Sep 2018 07:26

AW: Wie startet Firefox seinen Update Service?
 
Nur mal nebenbei eine kleine Beobachtung von mir, als reiner Anwender (falls es dem TE lediglich um "ich will aber wissen wie es funktioniert" geht, bitte ignorieren):
<Rant>
Firefox läuft bei mir den ganzen Tag. Wenn es mal ein Update gibt, sagt er mir das, und auch, daß ich ihn neu starten muß damit es durchgeführt werden kann. In meinem Anwendungsfall (und ich vermute ich bin nicht der Einzige, der so "arbeitet") hat der Dienst nichts zu tun, was nicht der Browser von sich aus auch machen könnte. Andere Software setzt das auch ohne Dienst um, beim Start wird geprüft, ob es eine neuere Version gibt und gefragt, ob das jetzt installiert werden soll oder später oder eben gar nicht. Prominente Beispiele dafür sind paint.net und Notepad++. Die Entwickler dieser Produkte sind sicherlich nicht zu blöd, einen Update-Dienst zu entwickeln, aber es hat auch Vorteile, wenn man das die Anwendung selbst machen läßt, und auch den Benutzer mit einbezieht:
  • Dienste haben eventuell negative Auswirkungen auf die Performance
  • Vorschnell installierte Updates können eventuell negative Auswirkungen haben
Ich sehe ansonsten keine Vorteile, außer das man nur einmal die UAC abnicken muss, was eigentlich auch ein Nachteil ist, denn auch zB die Firefox Update Server könnten mal gekapert werden und dann haben wir den Salat.
</Rant>

Aber zum lernen, wie so ein Dienst funktioniert und installiert wird, ist das sicher eine tolle Gelegenheit. Dem Endanwender würde ich es dennoch nicht zumuten wollen.

Sherlock

mkinzler 19. Sep 2018 07:27

AW: Wie startet Firefox seinen Update Service?
 
Der Dienst sorgt dafür, dass das Update von jedem Benutzer ausgeführt werden kann.

QuickAndDirty 19. Sep 2018 09:52

AW: Wie startet Firefox seinen Update Service?
 
Ja der Dienst "konserviert" halt die UAC-Abfrage und hat System Rechte. Und Ich will einfach vermeiden jedesmal die IT Abteilung bemühen zu müssen.
Die Software die dort ein Update erfährt wird oft aktualisiert, da sie diverse Instanzen einer Mobilen App verwaltet
Die Apps aus dem Playstore/Applestore aktualisieren sich ja eigenständig,
so dass man Aktualisierungen der Software nicht Kunde für Kunde ausrollen kann....

QuickAndDirty 19. Sep 2018 10:35

AW: Wie startet Firefox seinen Update Service?
 
Ich muss quasi diesen C# code in das AfterInstall Event vom dienst bringen denke ich.
Code:
wchar_t sddl[] = L"D:"
  L"(A;;CCLCSWRPWPDTLOCRRC;;;SY)"          // default permissions for local system
  L"(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)"  // default permissions for administrators
  L"(A;;CCLCSWLOCRRC;;;AU)"                // default permissions for authenticated users
  L"(A;;CCLCSWRPWPDTLOCRRC;;;PU)"          // default permissions for power users
  L"(A;;RP;;;IU)"                          // added permission: start service for interactive users
  ;

PSECURITY_DESCRIPTOR sd;

if (!ConvertStringSecurityDescriptorToSecurityDescriptor(sddl, SDDL_REVISION_1, &sd, NULL))
{
   fail();
}

if (!SetServiceObjectSecurity(service, DACL_SECURITY_INFORMATION, sd))
{
   fail();
}
Sähe dann so aus
Delphi-Quellcode:

interface
......
function ConvertStringSecurityDescriptorToSecurityDescriptorA(StringSecurityDescriptor: LPCSTR;
  StringSDRevision: DWORD; var SecurityDescriptor: PSECURITY_DESCRIPTOR;
  SecurityDescriptorSize: PULONG): BOOL; stdcall;
{$EXTERNALSYM ConvertStringSecurityDescriptorToSecurityDescriptorA}
function ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptor: LPCWSTR;
  StringSDRevision: DWORD; var SecurityDescriptor: PSECURITY_DESCRIPTOR;
  SecurityDescriptorSize: PULONG): BOOL; stdcall;
{$EXTERNALSYM ConvertStringSecurityDescriptorToSecurityDescriptorW}
function ConvertStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor: LPCTSTR;
  StringSDRevision: DWORD; var SecurityDescriptor: PSECURITY_DESCRIPTOR;
  SecurityDescriptorSize: PULONG): BOOL; stdcall;
{$EXTERNALSYM ConvertStringSecurityDescriptorToSecurityDescriptor}
....

implementation
....
const
  advapi32 = 'advapi32.dll';
  {$IFDEF UNICODE}
  AWSuffix = 'W';
  {$ELSE}
  AWSuffix = 'A';
 {$ENDIF UNICODE}
function ConvertStringSecurityDescriptorToSecurityDescriptorA; external advapi32 name 'ConvertStringSecurityDescriptorToSecurityDescriptorA';
function ConvertStringSecurityDescriptorToSecurityDescriptorW; external advapi32 name 'ConvertStringSecurityDescriptorToSecurityDescriptorW';
function ConvertStringSecurityDescriptorToSecurityDescriptor; external advapi32 name 'ConvertStringSecurityDescriptorToSecurityDescriptor' + AWSuffix;

procedure TMyUpdateService.ServiceAfterInstall(Sender: TService);
var
  SA: TSecurityAttributes;
  Permission:String;
  SvcMgr,SvcHandle: SC_HANDLE;
  ServiceName:String;
begin
  Permission := 'D:' +
  '(A;;CCLCSWRPWPDTLOCRRC;;;SY)' +         // default permissions for local system
  '(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)' + // default permissions for administrators
  '(A;;CCLCSWLOCRRC;;;AU)' +               // default permissions for authenticated users
  '(A;;CCLCSWRPWPDTLOCRRC;;;PU)' +         // default permissions for power users
  '(A;;RP;;;IU)';                         // added permission: start service for interactive users

  SA.nLength := SizeOf(SA);
  SA.bInheritHandle := True;
  if not ConvertStringSecurityDescriptorToSecurityDescriptor(PWideChar(Permission),
                                                         1,
                                                         SA.lpSecurityDescriptor,
                                                         nil
                                                         ) then RaiseLastOSError;
{$IF DEFINED(CLR)}
  SvcMgr := OpenSCManager('', nil, SC_MANAGER_ALL_ACCESS);
{$ELSE}
  SvcMgr := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
{$ENDIF}
  if SvcMgr = 0 then RaiseLastOSError;
  try
    ServiceName :=self.Name;
    SvcHandle := OpenService(SvcMgr, PWidechar(ServiceName) , SERVICE_ALL_ACCESS);
    if SvcHandle = 0 then RaiseLastOSError;
    try
      SetServiceObjectSecurity(SVCHandle,DACL_SECURITY_INFORMATION,SA.lpSecurityDescriptor);
    finally
      CloseServiceHandle(SvcHandle);
    end;
  finally
    CloseServiceHandle(SvcMgr);
  end;


  LocalFree(HLOCAL(SA.lpSecurityDescriptor));
end;
Falls mal jemand sowas braucht. Es ist getestet und funktioniert
Mit RUNAS und UAC Elevation den Service installieren und dann einfach bei Bedarf mit userrechten starten...


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:17 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