Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Wie findet man den richtigen angemeldeten Windows Benutzer (https://www.delphipraxis.net/192001-wie-findet-man-den-richtigen-angemeldeten-windows-benutzer.html)

DavidKlimas 12. Mär 2017 20:34

Delphi-Version: 5

Wie findet man den richtigen angemeldeten Windows Benutzer
 
Hallo zusammen,

ich hab verschiedenes ausprobiert, kann aber den Benutzernamen nicht finden in dessen Windows Profil ich angemeldet bin.

Delphi-Quellcode:
function UserName: String;
var User: PChar;
    i: DWord;
begin
  i := 1024;
  user := StrAlloc(Succ(i));
  if GetUserName(User, i) then Result := StrPas(User)
                          else Result := 'unknown';
end;
Diese Funktion gibt mir den Benutzernamen von jenem der das Programm ausführt, aber nicht unbedingt jener bei dem ich angemeldet bin: Wenn ich meine App as "Run as Admin" starte, bekomme ich immer den Namen vom Admin zurück.

Wie kann ich den laufenden Benutzernamen finden ?

Danke

Luckie 12. Mär 2017 20:43

AW: Wie findet man den richtigen angemeldeten Windows Benutzer
 
Was ist der "laufende" Benutzername?

Der in dessen Kontext das Programm ausgeführt wird? Der, der vor dem Monitor sitzt oder der, der per RemoteSession angemeldet sind?

DavidKlimas 12. Mär 2017 20:45

AW: Wie findet man den richtigen angemeldeten Windows Benutzer
 
Der bei dem ich bei Windows Angemeldet bin, der der im Startmenu steht, wenn ich unten links auf das Windows zeichen klicke. ;-)

Bei Windows heißt es bei GetUserName:
"If the current thread is impersonating another client, the GetUserName function returns the user name of the client that the thread is impersonating."

Zacherl 12. Mär 2017 21:02

AW: Wie findet man den richtigen angemeldeten Windows Benutzer
 
Versuch mal MSDN-Library durchsuchenWTSGetActiveConsoleSessionId. Existiert allerdings erst seit Vista die API.

Hatte ich damals in folgender Form verwendet, um den aktiven Benutzer aus einem Service heraus abzufragen:
Delphi-Quellcode:
class function TServiceHelper.QueryActiveSessionId: DWord;
var
  WTSGetActiveConsoleSessionId: function: DWord; stdcall;
begin
  Result := 0;
  @WTSGetActiveConsoleSessionId :=
    GetProcAddress(LoadLibrary('kernel32.dll'), 'WTSGetActiveConsoleSessionId');
  if Assigned(@WTSGetActiveConsoleSessionId) then
  begin
    Result := WTSGetActiveConsoleSessionId;
  end;
end;
Edit:
Achso ganz vergessen ... danach brauchst du natürlich noch MSDN-Library durchsuchenWTSQuerySessionInformation mit WTSUserName InfoClass.

DavidKlimas 12. Mär 2017 21:07

AW: Wie findet man den richtigen angemeldeten Windows Benutzer
 
In der Richtung hab ich schon gesucht, konnte aber keine Beispiele zur WTSQuerySessionInformation finden.

Ich probier das mal aus ;-)

Zacherl 12. Mär 2017 21:13

AW: Wie findet man den richtigen angemeldeten Windows Benutzer
 
Ich sehe grade, dass es für die aktuelle Sitzung sogar Konstanten gibt. Folgender Aufruf sollte für dich funktionieren:
Delphi-Quellcode:
function WTSQuerySessionInformationW(hServer: THandle; SessionId: DWord; WTSInfoClass: DWord;
  var ppBuffer: LPTSTR; var BytesReturned: DWord): BOOL; stdcall;
  external 'Wtsapi32.dll';

procedure WTSFreeMemory(pMemory: Pointer); stdcall;
  external 'Wtsapi32.dll';

procedure Test;
const
  WTS_CURRENT_SERVER_HANDLE = 0;
  WTS_CURRENT_SESSION      = DWord(-1);
const
  WTSUserName = 5;
var
  Buffer: LPTSTR;
  BytesReturned: DWord;
begin
  if WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSUserName,
    Buffer, BytesReturned) then
  try
    ShowMessage(Buffer);
  finally
    WTSFreeMemory(Buffer);
  end;
end;

himitsu 12. Mär 2017 21:17

AW: Wie findet man den richtigen angemeldeten Windows Benutzer
 
Zitat:

WTSGetActiveConsoleSessionId
Und was bekommt man bei einer RemoteSitzung, wenn garkeiner vorm PC sitzt?

PS: Wenn man eine Resource anfordert, dann hat man diese gefälligst auch wieder freizugeben!
LoadLibrary -> FreeLibrary
Aber da man davon ausgehen kann, dass diese DLL (kernel32) immer geladen ist, kann man auch einfach MSDN-Library durchsuchenGetModuleHandle verwenden.

Luckie 12. Mär 2017 21:22

AW: Wie findet man den richtigen angemeldeten Windows Benutzer
 
Und wozu muss das ein Programm wissen?

DavidKlimas 12. Mär 2017 21:25

AW: Wie findet man den richtigen angemeldeten Windows Benutzer
 
Super, dass klappt alles wie es soll. Danke an euch

Zacherl 12. Mär 2017 21:27

AW: Wie findet man den richtigen angemeldeten Windows Benutzer
 
Zitat:

Zitat von himitsu (Beitrag 1363972)
Und was bekommt man bei einer RemoteSitzung, wenn garkeiner vorm PC sitzt?

Man bekommt den Namen des Benutzerkontos mit dem man sich per RDP eingeloggt hat. Intern unterscheidet Windows gar nicht mehr großartig zwischen lokalem Login und einer Remote-Session. Session ist Session :stupid:

Zitat:

Zitat von Luckie (Beitrag 1363973)
Und wozu muss das ein Programm wissen?

In meinem Falle benötigte ich das Token des angemeldeten Users, um bestimmte Aktionen in seinem Userkontext ausführen zu können.

Luckie 12. Mär 2017 21:42

AW: Wie findet man den richtigen angemeldeten Windows Benutzer
 
Zitat:

Zitat von Zacherl (Beitrag 1363975)
Zitat:

Zitat von himitsu (Beitrag 1363972)
Und was bekommt man bei einer RemoteSitzung, wenn garkeiner vorm PC sitzt?

Man bekommt den Namen des Benutzerkontos mit dem man sich per RDP eingeloggt hat. Intern unterscheidet Windows gar nicht mehr großartig zwischen lokalem Login und einer Remote-Session. Session ist Session :stupid:

Und wenn gleichzeitig ein Benutzer lokal und der zweite per RemoteSession angemeldet ist?

Zacherl 12. Mär 2017 22:10

AW: Wie findet man den richtigen angemeldeten Windows Benutzer
 
Zitat:

Zitat von Luckie (Beitrag 1363977)
Zitat:

Zitat von Zacherl (Beitrag 1363975)
Zitat:

Zitat von himitsu (Beitrag 1363972)
Und was bekommt man bei einer RemoteSitzung, wenn garkeiner vorm PC sitzt?

Man bekommt den Namen des Benutzerkontos mit dem man sich per RDP eingeloggt hat. Intern unterscheidet Windows gar nicht mehr großartig zwischen lokalem Login und einer Remote-Session. Session ist Session :stupid:

Und wenn gleichzeitig ein Benutzer lokal und der zweite per RemoteSession angemeldet ist?

Wie sich der Code (insbesondere das
Delphi-Quellcode:
WTS_CURRENT_SESSION
) auf Server-Systemen mit mehreren aktiven Sessions verhält, weiß ich leider nicht. Hat jemand einen Windows Server am laufen, der das mal testen mag? Wenn man tatsächlich ausschließlich die lokale Session benötigt, dann gibt es aber auch per MSDN-Library durchsuchenWTSQuerySessionInformation eine Möglichkeit das zu prüfen.

Zacherl 12. Mär 2017 22:40

AW: Wie findet man den richtigen angemeldeten Windows Benutzer
 
Hab schnell einen Windows Server 2016 aufgesetzt und selbst getestet: Es wird tatsächlich immer die Session zurückgegeben, mit der man aktuell angemeldet (also die Session mit der ich das Testprogramm auch tatsächlich starte) ist. Dabei ist es sogar egal, ob ich das Programm per "Ausführen als .." unter einem anderen Benutzerkontext starte.

himitsu 12. Mär 2017 23:24

AW: Wie findet man den richtigen angemeldeten Windows Benutzer
 
Nja, aber dein Service, von dem vorhin auch noch geredet wurde, der wurde von meinem Benutzer gestartet. :stupid:

Luckie 12. Mär 2017 23:47

AW: Wie findet man den richtigen angemeldeten Windows Benutzer
 
Zitat:

Zitat von Zacherl (Beitrag 1363984)
(also die Session mit der ich das Testprogramm auch tatsächlich starte)

Er will aber den lokal angemeldeten Benutzer und nicht den Benutzer der das Programm ausführt.

Zacherl 13. Mär 2017 00:23

AW: Wie findet man den richtigen angemeldeten Windows Benutzer
 
Zitat:

Zitat von Luckie (Beitrag 1363989)
Zitat:

Zitat von Zacherl (Beitrag 1363984)
(also die Session mit der ich das Testprogramm auch tatsächlich starte)

Er will aber den lokal angemeldeten Benutzer und nicht den Benutzer der das Programm ausführt.

Genau das ermöglicht die Funktion. Ich glaube da haben wir uns missverstanden: Die Session unter der ich das Programm starte ist nicht gleichzusetzen mit den Benutzerkontext unter dem das Programm läuft.

Die Session ist fest an den Benutzeraccount gebunden, mit dem du dich einloggst (egal ob lokal oder remote). Sagen wir du loggst dich mit einem eingeschränkten Account "Luckie" ein und bekommst dabei die SessionId 1. Wenn du jetzt einen Prozess startest, läuft dieser standardmäßig auch unter Session 1 und bekommt zudem das Token deines eingeschränkten Accounts zugewiesen - Benutzerkontext wäre also ebenfalls "Luckie". Startest du den selben Prozess mit "Ausführen als" und wählst dort den Account "Admin", dann hat der Prozess zwar das Token vom "Admin" Account, aber dennoch wird es in Session 1 ausgeführt, weshalb die RDP API entsprechend wieder "Luckie" als "Besitzer" der Session ermitteln kann.

Zitat:

Zitat von himitsu (Beitrag 1363987)
Nja, aber dein Service, von dem vorhin auch noch geredet wurde, der wurde von meinem Benutzer gestartet. :stupid:

Seit Vista werden SYSTEM-Services aus Sicherheitsgründen in einer eigenen Session gestartet, welche komplett isoliert ist (Session 0 Isolation). Die Session-Id und das dazugehörige Token des aktuell angemeldeten Benutzers benötigte mein Service, um einen Prozess auf dem Desktop des Benutzers zu starten. Praktisch eine Emulation des "interaktiven Services" (nur dass der Prozess auch nicht im SYSTEM Kontext lief), welcher im Rahmen der Session 0 Isolation abgeschafft wurde.


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