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/)
-   -   Delphi [gelöst]Impersonate in TService (https://www.delphipraxis.net/176244-%5Bgeloest%5Dimpersonate-tservice.html)

Tonic1024 21. Aug 2013 17:21


[gelöst]Impersonate in TService
 
Hi zusammen...

Ich verwende seit ewigen Zeiten das Impersonate von Luckies webseite. Klappt auch immer ganz prima. Nur leider scheinen die Gegebenheiten innerhalb eines Services etwas anders.

Hier ist mein Code:
Delphi-Quellcode:
function Impersonate(const aUser, aPass: string): Boolean;
var
  LogonType : Integer;
  LogonProvider : Integer;
  strUser : String;
  strDomain : String;
  strPassword : String;
  Token: THandle;
begin
  LogonType := LOGON32_LOGON_INTERACTIVE;
  LogonProvider := LOGON32_PROVIDER_DEFAULT;
  strUser := aUser;
  strDomain := '';
  strPassword := aPass;
  Result := LogonUser(PChar(strUser), nil, PChar(strPassword), LogonType, LogonProvider, Token);
    generateLog('muh1');
  if Result then
  begin
    generateLog('muh2');
    Result := ImpersonateLoggedOnUser(Token); // hier bleibts hängen
    generateLog('muh3');
  end;
end;


// Der Aufruf:
      generateLog('vorher-'+GetUsername);
      Impersonate('User', 'Pass');
      generateLog('nachher-'+GetUsername);
im Log dann Folgendes:
Code:
vorher-SYSTEM
muh1
muh2
Und dann bleibt der Prozess hängen. Gelten für den System-User andere Regeln? Gibt es nen anderen Weg?

Gruß,

Toni

jensw_2000 21. Aug 2013 18:02

AW: Impersonate in TService
 
Zitat:

Zitat von Tonic1024 (Beitrag 1225722)
Gelten für den System-User andere Regeln? Gibt es nen anderen Weg?

Klappt es mit einem ordentlichen Dientkonto, anstatt SYSTEM?

Tonic1024 21. Aug 2013 18:48

AW: Impersonate in TService
 
Was ist den unordentlich wenn man den Dienst so installiert wie er aus dem Kompiler kommt?

jensw_2000 21. Aug 2013 19:34

AW: Impersonate in TService
 
Zitat:

Zitat von Tonic1024 (Beitrag 1225736)
Was ist den unordentlich wenn man den Dienst so installiert wie er aus dem Kompiler kommt?

Was hat der Compiler mit dem Dienst zu tun?
Soll Dir Delphi gültige Service Credentials anlegen und mit in die exe packen?

Das wäre in etwa vergleichbar mit "Ein frisch assembliertes Auto braucht keine Zulassung und keinen Fahrer mit gültiger Fahrerlaubnis... Sonst wäre der Unfug doch gleich mit dabei!".

LOKALES SYSTEM Konto:
- hat eine NULL SID und somit keinen Zugriff auf Netzwerkressourcen
(ist vermutlich auch die Ursache für dein obiges Problem)
- ist eher "unsauber", da viel zu hohe lokale Berechtigungen
- eher störanfällig bei neuen Windows Versionen, da MS die Berechtigungsringe um den Kernel immer weiter härtet und Berechtigungen "nach außen" verlagert. Irgendwann geht irgendwas nicht mehr (wie interaktive Dienste usw.).

Dienstkonto:
- hat eine SID, der Zugriff auf Netzwerkressourcen gewährt werden können
- kann explizit geforderte Berechtigungen erhalten
- ist aber auch nicht mehr "State of the Art"

Managed Service Account:
- hat eine SID, der Zugriff auf Netzwerkressourcen gewährt werden können
- kann explizit geforderte Berechtigungen erhalten
- Windows kümmert sich um komplexe, regelmäßig geänderte Kennwörter

Tonic1024 22. Aug 2013 07:51

AW: Impersonate in TService
 
Der Kompiler hat in sofern etwas damit zu tun, dass er mir einen Button auf dem Form kompiliert hat, der den Dienst so wie er ist Installiert und startet. Oldschool. Hab ein zugegebenermaßen schon recht altes Tutorial verwendet um mich da ein zu arbeiten.

Hab mich noch den ganzen Abend versucht schlau zu lesen in Bezug auf "Managed Service Accounts". Scheint ja nu state of the Art zu sein. Doof ist nur, dass ich schon gern auch alte Betriebsysteme verwenden wollte. Entwickle selbst auf Vista und XP ist hier auch noch nicht ganz tot. Da gibts das offenbar noch nicht. Wenn es also irgendwie geht würd ich gern bei "erprobter", um nicht su sagen altmodischer, Technik bleiben.

Mich wundert auch ein bisschen, dass der Code an der stelle einfach stehen bleibt. Müsste ich, wenn es sich um Rechte- oder Zugriffsprobleme handelt, nicht eine Exception oder negative Rückgabe erwarten?

Toni

jensw_2000 22. Aug 2013 08:10

AW: Impersonate in TService
 
Zitat:

Zitat von Tonic1024 (Beitrag 1225776)
Entwickle selbst auf Vista und XP ist hier auch noch nicht ganz tot. Da gibts das offenbar noch nicht. Wenn es also irgendwie geht würd ich gern bei "erprobter", um nicht su sagen altmodischer, Technik bleiben.

Mich wundert auch ein bisschen, dass der Code an der stelle einfach stehen bleibt. Müsste ich, wenn es sich um Rechte- oder Zugriffsprobleme handelt, nicht eine Exception oder negative Rückgabe erwarten?
Toni

Managed Service Accounts werden in der Domäne erzeugt und können seit Vista / Server 2008 benutzt werden. Ohne AD geht das aber nicht.

Es ist aber auch nicht viel schlechter, wenn man sich ein ganz normales Benutzerkonto erstellt, dem man die nötigen Rechte gibt und das man als Dienstkonto verwendet.


Ohne groß zu forschen...
Eventuell bleibt die Ausführung stehen weil:
- der Service Thread durch eine Exception hängt
- oder der Dienst dem Benutzer SYSTEM auf der Konsole "Session 0" irgendwelche modalen Meldungen anzeigt (die Du dann nicht siehst)
- oder die Benutzerkontensteuerung dem User SYSTEM um eine Elevation bittet

Tonic1024 22. Aug 2013 09:06

AW: Impersonate in TService
 
Klingt plausibel.

Ich hab also jetzt testweise den Dienst mal unter meinem Admin-"Personen-Konto" gestartet und ein Impersonate versucht. Selbes Problem.

Ausserdem hab ich diverse Konstelationen getestet, die den selben Code unter dem Selben Admin-Konto in einer Desktop-Applikation ausführt. Dort funktioniert er weiterhin wie gewohnt und es wird auch keine UAC-Meldung geworfen.


Code:
vorher-Toni
muh1
muh2 
muh3
nachher-Testuser
revert-Toni
Ein von Anfang an enthaltener Try-Except-Block, der den gesammten Execute-Teil des Service-Threads umfasst und einen Log-Eintrag macht damit ich mich an eventuelle Probleme ran tasten kann, wurde bisher nie angesprungen.


Toni

Tonic1024 22. Aug 2013 09:51

AW: [gelöst]Impersonate in TService
 
Meine weiteren Recherchen haben das Problem eingekreist und schlußendlich die Lösung zu Tage gefördert.

Für die, die zukünftig mal ähnliche Probleme haben hier die Lösung:

Delphi-Quellcode:
function Impersonate(const aUser, aPass: string): Boolean;
[..]
begin
  LogonType := LOGON32_LOGON_NETWORK; //LOGON32_LOGON_INTERACTIVE;
[..]
Damit funktioniert Luckies Funktion in Services so wie man es vom Desktop gewohnt ist.

Gruß,

Toni

jensw_2000 22. Aug 2013 09:55

AW: [gelöst]Impersonate in TService
 
Auch wenn man dien Dienst unter dem LOCAL SYSTEM, NETZWERKDIENST usw. laufen lässt?

Tonic1024 22. Aug 2013 10:06

AW: [gelöst]Impersonate in TService
 
Ich installiere und starte den Service wie hier beschrieben. Nackt, Straight und ohne irgendwelche Extras.

Mein Log sieht jetzt so aus:

Code:
vorher-SYSTEM
nachher-Toni
revert-SYSTEM

Genau was ich wollte.

Tonic1024 3. Sep 2013 08:03

AW: [gelöst]Impersonate in TService
 
Nachmal ein Nachtrag von mir. Ich hab noch Probleme gehabt mich auf eine Samba-Freigabe zu verbinden nachdem das Impersonate erfolgreich verlaufen ist.

Windows prüft über die API nur die Korrektheit des Passworts als Hashwert, merkt es sich aber nicht in Klartext. Darum ist es ihm nicht möglich das Passwort bei der Anmeldung am Samba-Dienst zu übergeben. Kein Bug, ein "Sicherheitsfeature", dass sich gottseidank sehr leicht umgehen lässt (Was bringt das dann? :roll:).

Will man sich mit seinem Benutzernamen an einem Server anmelden (das wird nicht nur für Samba zutreffen nehme ich an) muss man eine Konstante verwenden, die zumindest in D2k9, in der Windows.pas fehlt. So hab ich's dennoch hin bekommen:

Delphi-Quellcode:
function Impersonate(const aUser, aPass: string): Boolean;
var
  LogonType: Integer;
  LogonProvider: Integer;
  User: String;
  Pass: String;
  Token: THandle;
const
  LOGON32_LOGON_NETWORK_CLEARTEXT = 8; // Fehlt in der Windows.pas
begin
  LogonType := LOGON32_LOGON_NETWORK_CLEARTEXT; //LOGON32_LOGON_INTERACTIVE;
  LogonProvider := LOGON32_PROVIDER_DEFAULT;
  User := aUser;
  Pass := aPass;
  Result := LogonUser(PChar(User), nil {Domain}, PChar(Pass), LogonType, LogonProvider, Token);
  if Result then
    Result := ImpersonateLoggedOnUser(Token);
end;
Diese Vorgehensweise ist im MSDN dokumentiert. Dort hab ichs gefunden.

Gruß,

Toni

Uwe Raabe 3. Sep 2013 08:10

AW: [gelöst]Impersonate in TService
 
Zitat:

Zitat von Tonic1024 (Beitrag 1226955)
Kein Bug, ein "Sicherheitsfeature", dass sich gottseidank sehr leicht umgehen lässt (Was bringt das dann? :roll:).

Sicherheit kann man immer umgehen. Ob du nun deine Haustür offen stehen lässt (was bringt dann das Schloss?) oder Samstag Vormittag auf dem Stachus den Inhalt deines PasswordSafe laut vorsingst - jedes dieser Sicherheitsfeatures funktioniert nur, wenn man es richtig einsetzt.

Tonic1024 3. Sep 2013 08:40

AW: [gelöst]Impersonate in TService
 
Stimmt schon. Aber würde ich jetzt mit bösen Absichten hier sitzen, hätte ich den Abschnitt im MSDN auch gefunden. Darum leuchtet mir nicht ein in wie fern das die API oder Das Betriebsystem im Ganzen jetzt sicherer gemacht hat. Aber darüber ließe sich sicher vortrefflich Tagelang diskutieren...

[Edit]Der Grundgedanke dahinter wird wohl sein dass das Passwort nicht unnötigerweise in Klartext irgendwo im Speicher steht von wo es ein böser Mensch evtl auslesen kann. Die Frage ist aber doch ob ein Haus besser geschützt ist, um bei deiner Analogie zu bleiben, wenn von vielen vorhanden Türen nur noch der Haupteingang offen steht?[/Edit]

Toni

Uwe Raabe 3. Sep 2013 10:05

AW: [gelöst]Impersonate in TService
 
Zitat:

Zitat von Tonic1024 (Beitrag 1226968)
Der Grundgedanke dahinter wird wohl sein dass das Passwort nicht unnötigerweise in Klartext irgendwo im Speicher steht von wo es ein böser Mensch evtl auslesen kann.

Genau so ist es! Die API forciert diese Sicherheit nicht, bietet sie aber an. Natürlich muss das auch an allen Stellen verwendet werden. Es macht eben keinen Sinn die Haustür zu verriegeln wenn die Terrassentür offen bleibt. Insofern definiert immer das schwächste Glied den Grad der Sicherheit.


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