AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Programm vom Dienst starten mit mehr Rechten???
Thema durchsuchen
Ansicht
Themen-Optionen

Programm vom Dienst starten mit mehr Rechten???

Ein Thema von Sergej_Molotov · begonnen am 28. Sep 2010 · letzter Beitrag vom 11. Jan 2012
Antwort Antwort
Sergej_Molotov

Registriert seit: 18. Jul 2006
61 Beiträge
 
Delphi 11 Alexandria
 
#1

Programm vom Dienst starten mit mehr Rechten???

  Alt 28. Sep 2010, 17:09
Hallo Zusammen,

ich habe eine Anwendung, die als Dienst unter dem System-Account unter Windows läuft. Je nach Anforderung (wird von einem Webservice getriggert) soll der Dienst ein Programm deinstallieren. Da leider nicht jede Software direkt über msi-installiert wird, muss auch ggf. bei einer Deinstallation eine Benutzerinteraktion erfolgen. Hier besteht das Problem, dass der angemeldete User nicht unbedingt administrative Rechte besitzt. So habe ich mir gedacht, dass es möglich sein musste, das ich (als Dienst) eine Prozess für den angemeldeten Benutzer starte, und dass dieser Prozess administrative Rechte hat.

Auf meine Suche nach einer Lösung bin ich auf folgendes gestoßen.
http://www.delphipraxis.net/109191-p...ich-mal-3.html

Dieses ist aber nicht möglich, da bei uns die jwscl nicht verwendet werden soll. Aus diesem Grund suche ich nach einer Lösung mit Delphi-Boardmitteln. Die Verwendung der jwa ist aber möglich.

Delphi-Quellcode:
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm2 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    function CreateProcess4LoggedOnUser(const cmd: String): Cardinal;
    procedure WriteLog(const aMessage: String);
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

uses
  TlHelp32,
  jwaWinBase,
  jwaUserEnv;


procedure TForm2.Button1Click(Sender: TObject);
begin
  CreateProcess4LoggedOnUser('C:\Programme\CCleaner\uninst.exe');
end;

function TForm2.CreateProcess4LoggedOnUser(const cmd: String): Cardinal;
var
  hToken : THandle;
  newToken : THandle;
  blub : Cardinal;
  aSessionId : Cardinal;
  aStartup : Windows.TStartupInfo;
  aPI : Windows.TProcessInformation;
  MyEnv : Pointer;
  bla : DWORD;
begin
  Memo1.Lines.Clear;
  result := 0;

  if Windows.OpenProcessToken(GetCurrentProcess, TOKEN_ALL_ACCESS, hToken) then
  begin
    WriteLog('OpenProcessToken Ok');
    if Windows.ImpersonateLoggedOnUser(hToken) then
    begin
      WriteLog('ImpersonateLoggedOnUser Ok');
      if Windows.DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, nil, SecurityImpersonation, TOKENPRIMARY, newToken) then
      begin
        WriteLog('DuplicateTokenEx Ok');
        aSessionId := jwaWinBase.WTSGetActiveConsoleSessionId;
        bla := DWORD(aSessionId);
        if Windows.SetTokenInformation(newToken, Windows.TokenSessionId, @bla, SizeOf(DWORD)) then //Hier wird ein Fehler ausgelöst: (Error-Code 1314): Dem Client fehlt ein erforderliches Recht
        begin
          WriteLog('SetTokenInformation Ok');

          FillChar(aStartup,SizeOf(TStartupInfo),#0);
          FillChar(aPI,SizeOf(TProcessInformation),#0);
          aStartup.cb := SizeOf(TStartupInfo);
          aStartup.lpDesktop := 'WinSta0\Default';

          MyEnv := nil;
          // Umgebungsvariablen werden vom Benutzer ermittelt.
          if jwaUserEnv.CreateEnvironmentBlock(@MyEnv, newToken, false) then
          begin
            WriteLog('CreateEnvironmentBlock Ok');
            if Windows.CreateProcessAsUser(newToken, pChar(cmd), nil, nil, nil, true, NORMAL_PRIORITY_CLASS or CREATE_NEW_CONSOLE or CREATE_UNICODE_ENVIRONMENT, MyEnv, nil, aStartup ,aPI) then
            begin
              WriteLog('CreateProcessAsUser Ok');
              CloseHandle(aPI.hProcess);
              CloseHandle(aPI.hThread);
            end
            else
            begin
              result := GetLastError;
              WriteLog('7: '+Sysutils.SysErrorMessage(result));
            end;

            jwaUserEnv.DestroyEnvironmentBlock(MyEnv);
          end
          else
          begin
            blub := Windows.GetLastError;
            WriteLog('CreateEnvironmentBlock('+IntToStr(blub)+'): ' + Sysutils.SysErrorMessage(blub));
          end;
        end
        else
        begin
          blub := Windows.GetLastError;
          WriteLog('SetTokenInformation('+IntToStr(blub)+'): ' + Sysutils.SysErrorMessage(blub));
        end;
      end
      else
        WriteLog('DuplicateTokenEx: ' + Sysutils.SysErrorMessage(Windows.GetLastError));
    end
    else
      WriteLog('ImpersonateLoggedOnUser: ' + Sysutils.SysErrorMessage(Windows.GetLastError));
  end
  else
    WriteLog('OpenProcessToken: ' + Sysutils.SysErrorMessage(Windows.GetLastError));
end;


procedure TForm2.WriteLog(const aMessage: String);
begin
  Memo1.Lines.Add(aMessage);
end;

end.
Nun meine simple Frage:
Was mach ich falsch
Thomas
  Mit Zitat antworten Zitat
Sergej_Molotov

Registriert seit: 18. Jul 2006
61 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Programm vom Dienst starten mit mehr Rechten???

  Alt 29. Sep 2010, 08:55
Hallo Zusammen,

ich hab den oben gezeigten Code als Programm und nicht als Dienst ausgeführt. Wenn man dieses als Dienst ausführt, funktioniert es wunderbar. Vielleicht kann ja jemand diesen Code gebrauchen.

Ich entschuldige mich für eure Bemühungen (falls ihr was gemacht haben sollte ).

Grüße aus dem Rheinland
Thomas
  Mit Zitat antworten Zitat
pate444

Registriert seit: 24. Jul 2011
16 Beiträge
 
#3

AW: Programm vom Dienst starten mit mehr Rechten???

  Alt 4. Jan 2012, 10:46
Hi,

ich habe mal deinen Code ohne die Anwendung der Jedi-Units umgeschrieben. Evtl. benötigt den noch irgendwer.

Code:
interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;


function CreateProcess4LoggedOnUser(const cmd: String): Cardinal;


implementation

{$R *.dfm}

uses
  TlHelp32;


function CreateProcess4LoggedOnUser(const cmd: String): Cardinal;
var
  hToken : THandle;
  newToken : THandle;
  blub : Cardinal;
  aSessionId : Cardinal;
  aStartup : Windows.TStartupInfo;
  aPI : Windows.TProcessInformation;
  MyEnv : Pointer;
  bla : DWORD;
  f: textfile;
  root: string;
var
  CreateEnvironmentBlock: function(lpEnvironment: PPointer; hToken: THandle;
    bInherit: BOOL): BOOL; stdcall;
  WTSGetActiveConsoleSessionId: function: DWord; stdcall;
  DestroyEnvironmentBlock: function(lpEnvironment: Pointer): BOOL; stdcall;
begin
  @CreateEnvironmentBlock :=
    GetProcAddress(LoadLibrary('userenv.dll'), 'CreateEnvironmentBlock');
  @WTSGetActiveConsoleSessionId :=
    GetProcAddress(LoadLibrary('kernel32.dll'), 'WTSGetActiveConsoleSessionId');
  @DestroyEnvironmentBlock :=
    GetProcAddress(LoadLibrary('userenv.dll'), 'DestroyEnvironmentBlock');

  result := 0;
  root:= 'D:\temp.txt';
  assignfile(f, root);
  rewrite(f);
  writeln(f, datetimetostr(now())+ ' - Report des Dienstes:');
  if Windows.OpenProcessToken(GetCurrentProcess, TOKEN_ALL_ACCESS, hToken) then
  begin
    Writeln(f, 'OpenProcessToken Ok');
    if Windows.ImpersonateLoggedOnUser(hToken) then
    begin
      WriteLn(f,'ImpersonateLoggedOnUser Ok');
      if Windows.DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, nil, SecurityImpersonation, TOKENPRIMARY, newToken) then
      begin
        WriteLn(f,'DuplicateTokenEx Ok');
        aSessionId := WTSGetActiveConsoleSessionId;
        bla := DWORD(aSessionId);
        if Windows.SetTokenInformation(newToken, Windows.TokenSessionId, @bla, SizeOf(DWORD)) then //Hier wird ein Fehler ausgelöst: (Error-Code 1314): Dem Client fehlt ein erforderliches Recht
        begin
          WriteLn(f,'SetTokenInformation Ok');

          FillChar(aStartup,SizeOf(TStartupInfo),#0);
          FillChar(aPI,SizeOf(TProcessInformation),#0);
          aStartup.cb := SizeOf(TStartupInfo);
          aStartup.lpDesktop := 'WinSta0\Default';

          MyEnv := nil;
          // Umgebungsvariablen werden vom Benutzer ermittelt.
          if CreateEnvironmentBlock(@MyEnv, newToken, false) then
          begin
            WriteLn(f,'CreateEnvironmentBlock Ok');
            if Windows.CreateProcessAsUser(newToken, pChar(cmd),
                nil, nil, nil, true,
                NORMAL_PRIORITY_CLASS or CREATE_NEW_CONSOLE or CREATE_UNICODE_ENVIRONMENT,
                MyEnv, nil, aStartup ,aPI) then
            begin
              WriteLn(f,'CreateProcessAsUser Ok');
              CloseHandle(aPI.hProcess);
              CloseHandle(aPI.hThread);
            end
            else
            begin
              result := GetLastError;
              WriteLn(f,'7: '+Sysutils.SysErrorMessage(result));
            end;

            DestroyEnvironmentBlock(MyEnv);
          end
          else
          begin
            blub := Windows.GetLastError;
            WriteLn(f,'CreateEnvironmentBlock('+IntToStr(blub)+'): ' + Sysutils.SysErrorMessage(blub));
          end;
        end
        else
        begin
          blub := Windows.GetLastError;
          WriteLn(f,'SetTokenInformation('+IntToStr(blub)+'): ' + Sysutils.SysErrorMessage(blub));
        end;
      end
      else
        WriteLn(f,'DuplicateTokenEx: ' + Sysutils.SysErrorMessage(Windows.GetLastError));
    end
    else
      WriteLn(f,'ImpersonateLoggedOnUser: ' + Sysutils.SysErrorMessage(Windows.GetLastError));
  end
  else
    WriteLn(f,'OpenProcessToken: ' + Sysutils.SysErrorMessage(Windows.GetLastError));
  close(f);
end;

end.
  Mit Zitat antworten Zitat
nytaiceman

Registriert seit: 15. Dez 2005
Ort: Schweiz, Bern
58 Beiträge
 
Delphi XE3 Professional
 
#4

AW: Programm vom Dienst starten mit mehr Rechten???

  Alt 4. Jan 2012, 12:11
Wie verhält sich obiger Code, wenn mehrere Benutzer gleichzeitig an einem System angemeldet sind?

Eigentlich müsste man alle angemeldeten Benutzer durchgehen resp. alle Tokens durchgehen und dann bei jedem User (Oder nur bei gewünschten) einen Prozess starten.

Mir gefällt die Möglichkeit sehr, von einem Dienst aus, einen Benutzerprozess zu starten darauf habe ich schon ein paar Mal gewartet, mal schauen was alles noch dabei rauskommt.
Einfach ist nur einfach, wenn Einfach auch einfach ist!
Vermeintlich einfache Workarounds führen irgendwann zu Problemen!
  Mit Zitat antworten Zitat
pate444

Registriert seit: 24. Jul 2011
16 Beiträge
 
#5

AW: Programm vom Dienst starten mit mehr Rechten???

  Alt 4. Jan 2012, 16:34
Hi,

die Version funktioniert nur fehlerfrei auf einem PC mit nur einem Anwender. Ich habe es heute auch schon auf einem Server gestartet und wie erwartet, ist es noch nicht ausgereift. Morgen werde ich mich weiter an den Quellcode wagen und es weiter anpassen.
  Mit Zitat antworten Zitat
nytaiceman

Registriert seit: 15. Dez 2005
Ort: Schweiz, Bern
58 Beiträge
 
Delphi XE3 Professional
 
#6

AW: Programm vom Dienst starten mit mehr Rechten???

  Alt 10. Jan 2012, 12:59
Hallo zusammen,

in der heutigen DP-Nes Sektion ist ein Link auf weitere, nützliche Informationen zu diesem Thema:
http://stackoverflow.com/questions/8...en-change-user

Eventuell bringt euch das weiter wenn es darum geht, für jeden angemeldeten Benutzer aus dem Dienst heraus ein Prozess zu starten.

Gruss
Einfach ist nur einfach, wenn Einfach auch einfach ist!
Vermeintlich einfache Workarounds führen irgendwann zu Problemen!
  Mit Zitat antworten Zitat
pate444

Registriert seit: 24. Jul 2011
16 Beiträge
 
#7

AW: Programm vom Dienst starten mit mehr Rechten???

  Alt 11. Jan 2012, 11:51
Hi,

ja damit habe ich mich auch schon befasst. Ich denke aber, dass es an dem WTSGetActiveConsoleSessionId scheitern wird. Habe es mal mit WTSEnumerateSessions versucht, jedoch stehe ich dabei noch vor einem anderen Problem.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:18 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