Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Mitgliedschaft in Windows-Benutzergruppe feststellen (https://www.delphipraxis.net/186129-mitgliedschaft-windows-benutzergruppe-feststellen.html)

berens 6. Aug 2015 08:59

Mitgliedschaft in Windows-Benutzergruppe feststellen
 
Hallo zusammen,
leider komme ich mit meinem Problem http://www.delphipraxis.net/184812-w...verwenden.html nicht weiter. Die Jedi-JWSCL Dokumentation ist einfach viel zu schlecht, und auch über z.B. die SvComponents etc. komme ich nicht weiter weil das Thema einfach viel zu komplex ist, und kein Einstiegspunkt zu finden ist.

Ich lasse nun meine Anforderungen an dieses eigentlich triviale Thema in Bodenlose fallen und würde mich schon mit folgendem Total glücklich schätzen:

Wie kann ich prüfen, ob ein Benutzer|der aktuell angemeldete Windows Benutzer Mitglied einer Windows-Gruppe ist, oder Mitglied einer Gruppe, die in eben dieser Gruppe Mitglied ist?

Beispielprogramm:
3 Buttons, der erste darf nur gedrückt werden, wenn man Mitglied in der Windows- oder Domänenen-Gruppe "Marketing" ist, der zweite nur bei Mitgliedschaft in "Vertrieb", und der dritte bei "Alle Mitarbeiter". Die Gruppe "Alle Mitarbeiter" enthält nur die Windows-Gruppen "Vertrieb" und "Marketing". Button 3 muss sich also auch drücken lassen da/wenn der aktuell angemeldete Benutzer nicht namentlich in der Gruppe "Alle Mitarbeiter" aufgeführt ist, da er z.B. bereits Mitglied in "Vertrieb" ist.

In meiner Datenbank würde ich dann einfach für die verschiedenen Rechte (Programm starten, Datensätze verändern, etc.) jeweils die SIDs der berechtigten Benutzer/Gruppen speichern.


Edit:
Falls jemand kostenpflichtige Komponenten kennt, die das erledigen können: die sind auch herzlich willkommen!

Sir Rufo 6. Aug 2015 11:50

AW: Mitgliedschaft in Windows-Benutzergruppe feststellen
 
Hast du dir schon mal diesen Link angesehen?
http://stackoverflow.com/questions/3...tive-directory

berens 6. Aug 2015 14:57

AW: Mitgliedschaft in Windows-Benutzergruppe feststellen
 
Danke Rufo, diese Seite war mir noch nicht bekannt und liefert für die grundlegende Arbeit einen unfassbar guten und einfach Ansatz. Vielen Dank für die Info.

Leider ist es so, dass -in einer Domäne- mir die Gruppe "Alle Mitarbeiter" nicht angezeigt wird, wenn ich von der TADSIUserInfo.Groups anzeigen lasse; es steht halt nur (unter anderem) "Vertrieb" drinnen.

Somit würde nach aktuellem Stand, der Benutzer nicht Button 3 drücken dürfen, was aber laut der normalen Windows vererbung(?) eigentlich so sein sollte, da er/ich ja Mitglied in der Gruppe "Vertrieb" bin, die ja Mitglied von "Alle Mitarbeiter" ist.

Leider noch nicht ganz die Lösung, denn ich denke mir Rekursion mir jetzt alle AD-Gruppen per Hand zu durchsuchen würde ggf. dann sehr viel länger dauern.

Aber wir sind auf dem richtigen Weg.

Hat jemand eine Idee wie ich weitermachen kann?

p80286 6. Aug 2015 15:13

AW: Mitgliedschaft in Windows-Benutzergruppe feststellen
 
Nun ich beschäftige mich auch manchmal mit dieser Fragestelung und habe "ADSI" nachdem die Aufrufe in ADSHlp von safecall auf stdcall korrigiert waren ans Laufen bekommen. Leider werden nicht alle Gruppen angezeigt.
Allerdings verschweigt auch das "Active Directory Verwaltungscenter" von MS einige Gruppen, insbesonders alle Gruppen die die Zugriffe auf Laufwerke im Netz regeln sind nicht vorhanden.

Gruß
K-H

generic 6. Aug 2015 15:50

AW: Mitgliedschaft in Windows-Benutzergruppe feststellen
 
So so etwas hab ich damals den Processtoken ausgelesen:

Delphi-Quellcode:
uses jwasddl

var
  TokenHandle, ReturnLength, int_size: Cardinal;
  TokenInformation : PTokenGroups;
  aTokenUser: PSIDAndAttributes;
  i: integer;

begin
  if OpenProcessToken(GetCurrentProcess(), TOKEN_READ, TokenHandle) then
  begin
    GetTokenInformation(TokenHandle, TOKENUSER, nil, 0, ReturnLength);
    int_size:=ReturnLength;
    aTokenUser:=AllocMem(int_size);
    if GetTokenInformation(TokenHandle, TOKENUSER, aTokenUser, int_size, ReturnLength) then
    begin
// hier die USER Sid
    end;
    FreeMem(aTokenUser);

    GetTokenInformation(TokenHandle, TokenGroups, nil, 0, ReturnLength);
    int_size:=ReturnLength;
    TokenInformation:=AllocMem(int_size);
    if GetTokenInformation(TokenHandle, TokenGroups, TokenInformation, int_size, ReturnLength) then
      for i:=0 to TokenInformation.GroupCount-1 do
        with TokenInformation.Groups[i] do
        begin
// hier gibt es die SID der Gruppe
        end;
    FreeMem(TokenInformation);
    CloseHandle(TokenHandle);
  end;
end;
Der Code ist von 2004 - wenn du den produktiv einsetzten willst, empfehle ich noch paar try finally blöcke.

Wenn du noch eine Idee brauchst, wie du später die Rechte dynamisch modellierst dann schau mal hier:
http://www.dynamicaccesscontrol.com/

berens 6. Aug 2015 16:40

AW: Mitgliedschaft in Windows-Benutzergruppe feststellen
 
Also das Listet mir wesentlich mehr Gruppen auf als das andere Verfahren, aber meine tatsächliche Gruppe "Vertrieb" fehlt hier irgendwie? Das angemeldete Konto stimmt auf jeden Fall, auch die anderen Gruppen passen generell.

(Mit dem anderen Verfahren wurde "Vertrieb" auch korrekt angezeigt.)




Delphi-Quellcode:
function ConvertSidToStringSidW(SID: PSID; var StringSid: LPWSTR): Boolean; stdcall;
    external 'advapi32.dll' name 'ConvertSidToStringSidW';

implementation

{$R *.dfm}

function ConvertStringSidToSid(StringSid: PWideChar; var Sid: PSID): Boolean; stdcall; external 'advapi32.dll' name
'ConvertStringSidToSidW';


function StrSIDToName(const StrSID: Widestring; var Name: string; var SIDType: DWORD): Boolean;
var
  SID : PSID;
  Buffer : PansiChar;
  NameLen, TempLen : Cardinal;
  err : Boolean;
begin
  SID := nil;
  err := ConvertStringSIDToSID(PWideChar(StrSID), SID);
  if err then
  begin
    NameLen := 0;
    TempLen := 0;
    LookupAccountSidA(nil, SID, nil, NameLen, nil, TempLen, SIDType);
    GetMem(Buffer, NameLen);
    try
      err := LookupAccountSidA(nil, SID, Buffer, NameLen, nil, TempLen, SIDType);
      if err then
        SetString(Name, Buffer, Namelen);
    finally
      FreeMem(Buffer);
    end;
  end;
  if Assigned(SID) then
    LocalFree(Cardinal(SID));
  result := err;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
 adsi: TADSI;
 ui: TADSIUserInfo;

  TokenHandle, ReturnLength, int_size: Cardinal;
  TokenInformation : PTokenGroups;
  aTokenUser: PSIDAndAttributes;
  i, j: integer;
  t: string;
  w: PAnsiChar;
  c1, c2, c3: Cardinal;
begin
//  adsi := TADSI.Create(Self);
//  adsi.GetUser(adsi.CurrentDomain, adsi.CurrentUserName, ui);
//  ShowMessage(ui.Groups);


  if OpenProcessToken(GetCurrentProcess(), TOKEN_READ, TokenHandle) then
  begin
    GetTokenInformation(TokenHandle, TOKENUSER, nil, 0, ReturnLength);
    int_size:=ReturnLength;
    aTokenUser:=AllocMem(int_size);
    if GetTokenInformation(TokenHandle, TOKENUSER, aTokenUser, int_size, ReturnLength) then
    begin

// hier die USER Sid
      ConvertSidToStringSidA(aTokenUser.Sid, w);
      ListBox1.Items.Add('!UserSID: ' + w);
      StrSIDToName(w, t, c1);
      ListBox2.Items.Add('!UserSID: ' + t);
    end;
    FreeMem(aTokenUser);

    GetTokenInformation(TokenHandle, TokenGroups, nil, 0, ReturnLength);
    int_size:=ReturnLength;
    TokenInformation:=AllocMem(int_size);
    if GetTokenInformation(TokenHandle, TokenGroups, TokenInformation, int_size, ReturnLength) then
      for i:=0 to TokenInformation.GroupCount-1 do
        with TokenInformation.Groups[i] do
        begin
        ConvertSidToStringSidA(TokenInformation.Groups[i].Sid, w);

           ListBox1.Items.Add(w);
            StrSIDToName(w, t, c1);
           ListBox2.Items.Add(t);
// hier gibt es die SID der Gruppe
        end;
    FreeMem(TokenInformation);
    CloseHandle(TokenHandle);
  end;

  ListBox1.Sorted := False;
  ListBox1.Sorted := True;
  ListBox2.Sorted := False;
  ListBox2.Sorted := True;

end;

berens 17. Aug 2015 11:55

AW: Mitgliedschaft in Windows-Benutzergruppe feststellen
 
Zunächst nochmal vielen Dank allen, die geantwortet haben.

In diesem Thread darf ich nun auch nochmal Werbung für mein Tutorial machen, wie ich das eigentliche Problem gelöst habe:
http://www.delphipraxis.net/186242-w...verwenden.html

Falls jemand nun wirklich die Gruppenmitgliedschaft feststellen will, kann er mit diesem Tutorial eine SecurityDescriptor erstellen, der (nur) die gewünschte Gruppe mit einem Beispielrecht enthält, und dann prüfen, ob der (aktuell angemeldete) Benutzer dieses Recht hat. Benutzer erhalten ja automatisch die Rechte der Gruppen in der sie sind, ausgenommen die der Admin-Gruppen (hier muss das Programm mit rechte Maustaste - als Administrator starten ausgeführt werden.

ACHTUNG -Wichtiger Nachtrag zu diesem kompletten Thread
Zitat:

Nimmt man einen Benutzer in eine Gruppe auf, muss Dieser sich erst neu an Windows anmelden, damit die Änderungen wirksam werden!

Der Benutzer ist NICHT Mitglied egal welcher generischen Administrator-Gruppen (Domänen-Admins etc.), wenn das Programm nicht mit rechter Maustaste --> Als Administrator ausführen gestartet wurde.
Somit könnte es sein, dass die hier aufgeführten Probleme damit zusammen gehangen haben, dass ich zum Testzeitpunkt noch nicht erneut an Windows angemeldet war, so dass die Gruppenmitgliedschaft noch nicht "aktiv" war!

Memnarch 17. Aug 2015 13:17

AW: Mitgliedschaft in Windows-Benutzergruppe feststellen
 
Muss man sich auch neu anmelden, wenn man GPUpdate ausführt o.O?

berens 17. Aug 2015 13:27

AW: Mitgliedschaft in Windows-Benutzergruppe feststellen
 
Ich habe es eben auf einem Windows 2012 Server getestet.
Auch "gpupdate /force" aktualisiert NICHT die Gruppenmitgliedschaft. (Meines Wissens ist dieser Befehl eh nur für die Aktualisierung der Gruppenrichtlinien zuständig...)

Mit "whoami /all" bzw. "whoami /all > x:\1.txt" kann man sich von Windows direkt den Mitgliedschafts-Status alle Gruppen anzeigen lassen.

Mein Testverlauf:
1) whoami /all
--> Ich bin nicht Mitglied der Gruppe
2) Gruppenmitgliedschaft über "Active-Directory-Benutzer und -Computer" geändert, dieses Fenster dann geschlossen
3) whoami /all
--> Ich bin nicht Mitglied der Gruppe
4) gpupdate /force
5) whoami /all
--> Ich bin nicht Mitglied der Gruppe
6) Abmelden / Anmelden an Windows
7) whoami /all
--> Ich BIN Mitglied der Gruppe

Das Problem besteht sowohl bei Lokalen Gruppen, wie in der Domäne.

generic 19. Aug 2015 13:47

AW: Mitgliedschaft in Windows-Benutzergruppe feststellen
 
Zitat:

Zitat von Memnarch (Beitrag 1312436)
Muss man sich auch neu anmelden, wenn man GPUpdate ausführt o.O?

Gruppenrichtlinien (Registryeinträge) haben nicht mit dem aktuellen Prozesstoken zu tun!
Das mit den neu Anmelden, wird nur gemacht, dass die Prozess welche bereits laufen z.B. Explorer, die neuen Registry-Einstellungen lesen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:16 Uhr.
Seite 1 von 2  1 2      

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