AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Profilverzeichnisse aller Nutzer ermitteln
Thema durchsuchen
Ansicht
Themen-Optionen

Profilverzeichnisse aller Nutzer ermitteln

Ein Thema von Dalai · begonnen am 15. Feb 2014 · letzter Beitrag vom 17. Feb 2014
Antwort Antwort
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#1

Profilverzeichnisse aller Nutzer ermitteln

  Alt 15. Feb 2014, 14:40
Hey Leute ,

nachdem ich nun vergeblich - vermutlich auch mit den falschen Suchbegriffen - mehr als einen halben Tag rumgesucht und rumprobiert habe, beanspruche ich mal wieder euer Wissen.

Mein Ziel ist es, eine Liste aller auf einem Windows-System existierenden Nutzer zu ermitteln (geht ja einfach mit NetUserEnum), allerdings brauche ich zwingend zu jedem Nutzer die Informationen über sein Profilverzeichnis (also wo das liegt); und das muss auf jedem Windows-System (ab Win2k) auch ohne Domäne funktionieren.

Warum mache ich den Zirkus? Ich gebe mal ein Beispiel: Gegeben sei ein Nutzer mit dem Loginnamen Hans. Bei dessen erster Anmeldung wird sein Profilverzeichnis angelegt, z.B. C:\Users\Hans. Später wird der Nutzer umbenannt in Willi. Das Profilverzeichnis bleibt natürlich stehen. Ich brauche aber beide Informationen, sowohl den Loginnamen Willi als auch den Ort des Profilverzeichnisses C:\Users\Hans.

Inzwischen habe ich rausgefunden, dass die Informationen, die MSDN-Library durchsuchenNetUserEnum und MSDN-Library durchsuchenNetUserGetInfo in die Datenstruktur MSDN-Library durchsuchenUSER_INFO_2 oder MSDN-Library durchsuchenUSER_INFO_3 liefern, wohl nur (wenn überhaupt) auf Servern oder in Domänen gefüllt sind, insbesondere die für mich relevanten Teile usri3_home_dir und usri3_profile.

Hat jemand für mich Suchbegriffe, Funktionsnamen oder ähnliches, die die benötigten Informationen liefern können?

Die Frage bezieht sich übrigens nur beschränkt auf Delphi. Letztlich brauche ich die Funktionalität in AutoIt, aber das nur nebenbei.

MfG Dalai
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#2

AW: Profilverzeichnisse aller Nutzer ermitteln

  Alt 15. Feb 2014, 15:26
Also, auch wenn du die Verzeichnisse ermitteln kannst, bedeutete es nicht, dass du auf sie zugreifen kannst. Denn bei der Erstellung wird man gefragt ob andere auf das Verzeichnis zugreifen können (zumindest bei XP).

Weiterhin weiß ich, auch wenn ich es selbst noch nie genutzt habe, dass in der Registry die Userkonten vermerkt sind (ich glaube in der HK_USERS). Ob man das irgendwie nutzen kann, weiß ich aber nicht.
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#3

AW: Profilverzeichnisse aller Nutzer ermitteln

  Alt 15. Feb 2014, 15:54
Also, auch wenn du die Verzeichnisse ermitteln kannst, bedeutete es nicht, dass du auf sie zugreifen kannst.
Der Nutzer, der die Abfrage tätigt, hat zu dem Zeitpunkt in jedem Fall Adminrechte.

Zitat:
Denn bei der Erstellung wird man gefragt ob andere auf das Verzeichnis zugreifen können (zumindest bei XP).
Hab ich noch nie gesehen. Hast du das vielleicht mit der Freigabe eines Verzeichnisses verwechselt?

Zitat:
Weiterhin weiß ich, auch wenn ich es selbst noch nie genutzt habe, dass in der Registry die Userkonten vermerkt sind (ich glaube in der HK_USERS). Ob man das irgendwie nutzen kann, weiß ich aber nicht.
Natürlich sind sie das. Aber unter HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList stehen nur die SIDs der Nutzer sowie deren Nutzerprofile (ProfileImagePath). In diesem Fall bräuchte ich einen Weg, die Nutzernamen zur SID zu ermitteln. Das geht sicher irgendwie. Insgesamt bringt mir dieser Schlüssel aber nicht viel, denn dort sind auch die SIDs von Domänenkonten vermerkt, zu denen man ohne DC wohl nicht an den Nutzernamen kommt. Es geht mir aber nur um lokale Nutzerkonten.

MfG Dalai
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Profilverzeichnisse aller Nutzer ermitteln

  Alt 15. Feb 2014, 16:15
Zitat:
Hab ich noch nie gesehen. Hast du das vielleicht mit der Freigabe eines Verzeichnisses verwechselt?
Nein, auch als Admin wirst Du unter Umständen gefragt, wenn Du auf Dateien zugreifen willst die anderen Benutzern "gehören".
Markus Kinzler
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.060 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Profilverzeichnisse aller Nutzer ermitteln

  Alt 16. Feb 2014, 11:32
Mein Ziel ist es, eine Liste aller auf einem Windows-System existierenden Nutzer zu ermitteln (geht ja einfach mit NetUserEnum), allerdings brauche ich zwingend zu jedem Nutzer die Informationen über sein Profilverzeichnis (also wo das liegt); und das muss auf jedem Windows-System (ab Win2k) auch ohne Domäne funktionieren.

Inzwischen habe ich rausgefunden, dass die Informationen, die MSDN-Library durchsuchenNetUserEnum und MSDN-Library durchsuchenNetUserGetInfo in die Datenstruktur MSDN-Library durchsuchenUSER_INFO_2 oder MSDN-Library durchsuchenUSER_INFO_3 liefern, wohl nur (wenn überhaupt) auf Servern oder in Domänen gefüllt sind, insbesondere die für mich relevanten Teile usri3_home_dir und usri3_profile.
Das ist so nicht ganz korrekt!
Beide Funktionen funktionieren auch auf lokaler Ebene ohne Domänencontroller!
Einfach ServerName in beiden Funktionen leer lassen bzw. leeren Pointer übergeben und schon füllt dir das lokale Betriebssystem die angeforderten User-Records.

Zitat von MSDN:
ServerName [in]
Pointer to a constant string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this parameter is NULL, the local computer is used.
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#6

AW: Profilverzeichnisse aller Nutzer ermitteln

  Alt 16. Feb 2014, 13:10
Das ist so nicht ganz korrekt!
Beide Funktionen funktionieren auch auf lokaler Ebene ohne Domänencontroller!
Richtig. Aber eben nicht die von mir gewünschten Felder/Infos.

Zitat:
Einfach ServerName in beiden Funktionen leer lassen bzw. leeren Pointer übergeben und schon füllt dir das lokale Betriebssystem die angeforderten User-Records.
Hast du es mal selbst ausprobiert, und dabei in den Datenstrukturen Home- und Profilverzeichnisse gefunden? Ich würde ja nicht fragen, wenn ich die gewünschten Informationen dort gefunden hätte.

MfG Dalai
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.343 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Profilverzeichnisse aller Nutzer ermitteln

  Alt 16. Feb 2014, 13:19
Wenn die API wirklich diese Informationen nicht zur Verfügung stellt, sollte es doch über die Registryzweige unter HKEY_USERS gehen, oder? Dort liegen ja die einzelnen Userzweige und der des aktuellen Users wird beim Login unter HKEY_CURRENT_USER eingeblendet.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#8

AW: Profilverzeichnisse aller Nutzer ermitteln

  Alt 16. Feb 2014, 14:19
Wenn die API wirklich diese Informationen nicht zur Verfügung stellt, sollte es doch über die Registryzweige unter HKEY_USERS gehen, oder? Dort liegen ja die einzelnen Userzweige und der des aktuellen Users wird beim Login unter HKEY_CURRENT_USER eingeblendet.
Nein, Irrtum. Unter HKEY_USERS sind nur die Zweige der Nutzer eingeblendet, die derzeit angemeldet sind (siehe Wikipedia). Davon abgesehen komme ich dort weder an den Nutzernamen (Loginname) noch ans Profilverzeichnis.

-----

Ich hab gestern noch eine Lösung erarbeitet, die ganz gut funktioniert, aber wie immer wäre es schön, wenn das irgendwie schöner ginge. Im Grunde wird hier folgendes gemacht:
  • Ermittlung aller auf dem System existierenden Nutzernamen mit NetUserEnum (Level 0)
  • Ermittlung der SID zu jedem Nutzernamen mit GetAccountSid
  • Öffnen des Registry-Schlüssels HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList mit der SID und Auslesen (und Expandieren von Umgebungsvariablen) von ProfileImagePath
Delphi-Quellcode:
function GetAccountSid(const Server, User: WideString; var Sid: PSID): DWORD;
function ConvertSidToStringSid(SID: PSID; var StringSid: LPSTR): Boolean; stdcall;
    external 'advapi32.dllname 'ConvertSidToStringSidA';

implementation


function ExpandEnvStr(const sInput: string): string;
const
  MAXSIZE = 32768; // laut PSDK sind 32k das Maximum
begin
  SetLength(Result, MAXSIZE);
  SetLength(Result,
            ExpandEnvironmentStrings(PChar(sInput), @Result[1], Length(Result))-1);
            //-1 um abschließendes #0 zu verwerfen
end;


function GetAccountSid(const Server, User: WideString; var Sid: PSID): DWORD;
var
  dwDomainSize, dwSidSize: DWord;
  R : LongBool;
  wDomain : WideString;
  Use : DWord;
begin
  Result := 0;
  SetLastError(0);
  dwSidSize := 0;
  dwDomainSize := 0;
  R := LookupAccountNameW(PWideChar(Server), PWideChar(User), nil, dwSidSize,
    nil, dwDomainSize, Use);
  if (not R) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
  begin
    SetLength(wDomain, dwDomainSize);
    Sid := GetMemory(dwSidSize);
    R := LookupAccountNameW(PWideChar(Server), PWideChar(User), Sid,
      dwSidSize, PWideChar(wDomain), dwDomainSize, Use);
    if not R then
    begin
      FreeMemory(Sid);
      Sid := nil;
    end;
  end
  else
    Result := GetLastError;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  EntriesRead, TotalEntries, ResumeHandle : DWORD;
  UserInfo : lpUSER_INFO_0;
  lpBuffer : Pointer;
  i : Integer;
  Res : LongWord;
  sl : TStringList;
  sSID : PChar;
  ptrSID : PSID;
  reg : TRegistry;
begin
    ListBox1.Clear;
    sl:= TStringList.Create;
    ResumeHandle := 0;
    repeat
        Res:= NetUserEnum(nil, 0, 0, lpBuffer, 0, EntriesRead, TotalEntries, ResumeHandle);

        if (Res = NERR_SUCCESS) or (Res = ERROR_MORE_DATA) then
        begin
            UserInfo := lpBuffer;
            for i := 0 to EntriesRead-1 do
            begin
                sl.Add(WideCharToString(UserInfo^.usri0_name));
                ListBox1.Items.Add('------------------------------------------');
                ListBox1.Items.Add(WideCharToString(UserInfo^.usri0_name));
                Inc(UserInfo);
            end;
            NetApiBufferFree(lpBuffer);
        end;
   until (Res <> ERROR_MORE_DATA);

   for i:=0 to sl.Count-1 do
   begin
       GetAccountSid('', sl[i], ptrSID);
       if ConvertSidToStringSid(ptrSID, sSID) then
       begin
           ListBox1.Items.Add(sSID);
           reg:= TRegistry.Create;
           reg.RootKey:= HKEY_LOCAL_MACHINE;
           if reg.OpenKeyReadOnly('\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\' + sSID) then
               ListBox1.Items.Add(ExpandEnvStr(reg.ReadString('ProfileImagePath')));
           reg.CloseKey;
           reg.Free;
       end;
   end;
   sl.Free;
end;
Hinweis: Das ist nur ein Testprojekt, daher an einigen Stellen keine Auswertung der Funktionsrückgaben und alles in der Methode Button1Click. Die Funktion GetAccountSid hab ich von Luckie gemopst. Die Implementation in Delphi diente sowieso nur dem Zweck, das einfacher testen und dann nach AutoIt übertragen zu können. Falls jemand Interesse am AutoIt-Code hat, dann einfach fragen . Noch ein Tip für alle Suchmaschinenbenutzer: Die Funktionen ConvertSidToStringSid und GetAccountSid existieren in AutoIt bereits als UDF _Security__SidToStringSid bzw. _Security__GetAccountSid).

MfG Dalai
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.060 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Profilverzeichnisse aller Nutzer ermitteln

  Alt 17. Feb 2014, 11:05
Zitat:
Einfach ServerName in beiden Funktionen leer lassen bzw. leeren Pointer übergeben und schon füllt dir das lokale Betriebssystem die angeforderten User-Records.
Hast du es mal selbst ausprobiert, und dabei in den Datenstrukturen Home- und Profilverzeichnisse gefunden? Ich würde ja nicht fragen, wenn ich die gewünschten Informationen dort gefunden hätte.
Tatsache!
Wenn man mal nicht auf Arbeit ist und den Quelltext vor sich hat...

Wenn unsere Applikation keinen DC findet, dann weichen wir auf Known Folders aus, die aber für alle User gleich sind.
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#10

AW: Profilverzeichnisse aller Nutzer ermitteln

  Alt 17. Feb 2014, 20:36
Wenn unsere Applikation keinen DC findet, dann weichen wir auf Known Folders aus, die aber für alle User gleich sind.
Das nutzt aber auch nur etwas, wenn der Name des Profilverzeichnisses exakt mit dem Benutzernamen übereinstimmt. Mit dem im OP gegebenen Beispiel kommt man da nicht weit...

Ich hab mittlerweile die Vermutung, dass die Datenfelder bzgl. Home bzw. Profil in USER_INFO_x für die Angaben Stammverzeichnis stehen, die standardmäßig leer sind (siehe Bild). Ob das so genau stimmt, weiß ich nicht, und spielt letztlich für die Fragestellung keine Rolle.

MfG Dalai
Miniaturansicht angehängter Grafiken
dp_benutzerverwaltung_eigenschaftennutzer.png  
  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 04:10 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