Hallo, Fabian hier. Letztens habe ich an einer Anfrage gearbeitet, bei der "nebenbei" ein Thema aufgekommen ist, welches man schnell übersehen bzw. darüber stolpern kann. Daher an dieser Stelle ein paar Zeilen dazu; im Kern geht es um den Anwendungsbereich von domänenlokalen Gruppen.

Im konkreten Fall wurde eine Gruppenrichtlinie erstellt, die über eine Sicherheitsfilterung auf der Gruppenrichtlinie nur von Mitgliedern (bzw. verschachtelten Mitgliedern) einer dafür eingerichteten domänenlokalen Gruppe (domain local group) übernommen werden durfte. Diese domänenlokale Gruppe, nennen wir sie an dieser Stelle „DomainLocal_Grp_GPO1“, enthielt dann eine globale Gruppe „Global_Grp_GPO1“, der die Benutzer zugeordnet waren, die die Richtlinie übernehmen sollten:

Soweit erst einmal kein Problem – nur bemerkten wir, daß die Gruppenrichtlinie nicht auf dem Benutzerobjekt griff, nachdem wir uns an einem Testclient angemeldet hatten. Wir stellten über die Ausgabe von „GPRESULT /Z“ fest, daß der Benutzer zwar als Mitglied der globalen Gruppe „Global_Grp_GPO1“ angegeben war, jedoch die (verschachtelte) Mitgliedschaft in der Gruppe „DomainLocal_Grp_GPO1“ im Anmeldetoken des Benutzers nicht zu finden war.

Nachdem mögliche Problempunkte wie zum Beispiel die „MaxTokenSize“ u.ä. ausgeschlossen waren, schauten wir noch einmal genauer auf die Konstellation: Der Benutzer war korrekt an der Domäne angemeldet, in der auch die Gruppenrichtlinie sowie die domänenlokale Gruppe „DomainLocal_Grp_GPO1“ lag. Es zeigte sich jedoch, daß der Client in einer anderen Domäne lag – und genau hier liegt das Problem.

Domänenlokale Gruppen sind der Definition nach nur in der Domäne verfügbar, in der sie angelegt sind. Wird für einen Benutzer ein Anmeldetoken beim Logon erzeugt, gibt der authentifizierende Domänencontroller nur die globalen als auch universellen Gruppenmitgliedschaften (bzw. die dazugehörigen SIDs) in der Antwort zurück, nicht die domänenlokalen Gruppenmitgliedschaften. Der Client selbst baut nun das Anmeldetoken des Benutzers zusammen – und zwar aus diesen zurückgegebenen SIDs der globalen und universellen Gruppen sowie der vom Client ausgelesenen "lokalen" Gruppen.

Bei der Anmeldung wird auch der Domänencontroller der Client-Domäne nach Gruppenmitgliedschaften des Benutzers gefragt. Im Windows 2000 native mode und höher kommen hier die domänenlokalen Gruppen dazu, in denen der Benutzer Mitglied ist - direkt oder durch Verschachtelung (in globalen und universellen Gruppen). Die gesamte Liste der SIDs wird auf dem Ressourcen-Computer (von der "Local Security Authority", kurz "LSA") gegen die Mitglieder der lokalen Gruppen geprüft und lokale Mitgliedschaften landen dann ebenfalls im Anmeldetoken des Benutzers.

Erst bei einem Zugriffsversuch auf eine Ressource, die in einer anderen Domäne liegt als der Client-Domäne, wird ein Zugriffstoken für die Zielressource erzeugt – und hier werden nun auch die SIDs der domänenlokalen Gruppe von der "Local Security Authority" dem Zugriffstoken hinzugefügt.

Dies kann man recht einfach nachvollziehen, indem man sich mit einem Benutzer jeweils einmal auf einem Client der eigenen Domäne und einmal auf einem Client, der Mitglied einer anderen Domäne ist (etwa einer Child-Domäne), anmeldet und sich etwa mittels des Windows Server 2003 Support Tools „whoami“ das Anmeldetoken anschaut (in Windows Vista / 2008 wird "whoami" standardmäßig schon mitgeliefert und muß nicht nachinstalliert werden):

Anmeldetoken des Benutzers "testuser" auf einem Client derselben Domäne (DOMAIN1):


C:\Program Files\Support Tools>whoami /all
[User]     = "DOMAIN1\testuser"  S-1-5-21-236985210-982365471-3598741365-1113

[Group 1] = "DOMAIN1\Domain Users"  S-1-5-21-236985210-982365471-3598741365-513
[Group 2] = "Everyone"  S-1-1-0
[Group 3] = "BUILTIN\Users"  S-1-5-32-545
[Group 4] = "NT AUTHORITY\INTERACTIVE"  S-1-5-4
[Group 5] = "NT AUTHORITY\Authenticated Users"  S-1-5-11
[Group 6] = "LOCAL"  S-1-2-0
[Group 7] = "DOMAIN1\ Global_Grp_GPO1"  S-1-5-21-236985210-982365471-3598741365-1114
[Group 8] = "DOMAIN1\ Universal_Grp_GPO1"  S-1-5-21-236985210-982365471-3598741365-1122
[Group 9] = "DOMAIN1\ DomainLocal_Grp_GPO1"  S-1-5-21-236985210-982365471-3598741365-1119



Anmeldetoken des Benutzers "testuser" auf einem Client einer anderen Domäne (CHILD1):


C:\Program Files\Support Tools>whoami /all
[User]     = "DOMAIN1\testuser"  S-1-5-21-236985210-982365471-3598741365-1113

[Group 1] = "DOMAIN1\Domain Users"  S-1-5-21-236985210-982365471-3598741365-513
[Group 2] = "Everyone"  S-1-1-0
[Group 3] = "BUILTIN\Users"  S-1-5-32-545
[Group 4] = "NT AUTHORITY\INTERACTIVE"  S-1-5-4
[Group 5] = "NT AUTHORITY\Authenticated Users"  S-1-5-11
[Group 6] = "LOCAL"  S-1-2-0
[Group 7] = "DOMAIN1\ Global_Grp_GPO1"  S-1-5-21-236985210-982365471-3598741365-1114
[Group 8] = "DOMAIN1\ Universal_Grp_GPO1"  S-1-5-21-236985210-982365471-3598741365-1122

Da die domänenlokale Gruppe “DomainLocal_Grp_GPO1” wie oben zu sehen nun nicht im Anmeldetoken des Testbenutzers vorhanden ist, wird die Policy auch nicht angewendet  - denn es wird im Fall des Policy Processings das Anmeldetoken des Benutzers auf dem Client mit der ACL der Policy abgeglichen (Attribut "nTSecurityDescriptor"), bevor auf das Dateisystem des SYSVOL-Servers zugegriffen wird. Das bedeutet, daß es gar nicht zum benötigten Ressourcenzugriff auf die SYSVOL-Freigabe kommt, um das Zugriffstoken des Benutzers um die domänenlokale Gruppe seiner eigenen Domäne zu erweitern. Ein Zugriff direkt auf die SYSVOL-Freigabe / Ressource wäre hingegen erfolgreich.

Die zusätzliche Prüfung der Group Policy Engine ist aber nötig, weil die Engine das Zugriffsflag „Gruppenrichtlinie übernehmen“ (engl. "Apply Group Policy") auswerten muss. Das Recht „Gruppenrichtlinie übernehmen��� wird bei Active Directory und Zugriffen auf SYSVOL nicht verwendet.

Da es also keine Übereinstimmung der benötigten SID im Anmeldetoken des Benutzers, angemeldet  auf dem Client in einer anderen Domäne, mit der ACL des Gruppenrichtlinienobjekts „GPO1“ existiert,  wird diese Policy auch nicht angewendet:

C:\> GPRESULT /Z

[...]

USER SETTINGS
--------------
    CN=testuser,OU=Users,OU=Corp,DC=domain1,DC=test
    Last time Group Policy was applied: 11/6/2008 at 3:28:44 PM
    Group Policy was applied from:      DC01.domain1.test
    Group Policy slow link threshold:   500 kbps

    Applied Group Policy Objects
    -----------------------------
        Default Domain Policy

    The following GPOs were not applied because they were filtered out
    -------------------------------------------------------------------
        GPO1
            Filtering:  Denied (Security)

        CORP Settings
            Filtering:  Not Applied (Empty)

        Local Group Policy
            Filtering:  Not Applied (Empty)

    The user is a part of the following security groups:
    ----------------------------------------------------
        Domain Users
        Everyone
        BUILTIN\Users
        NT AUTHORITY\INTERACTIVE
        NT AUTHORITY\Authenticated Users
        LOCAL
        Global_Grp_GPO1
        Universal_Grp_GPO1

[...]


Was schließen wir daraus?

Entgegen dem empfohlenen „AGDLP“ Vorgehen bei der Rechtevergabe auf Ressourcen wie Freigaben, Drucker o.ä., kann es also in bestimmten (multi-Domänen) Konstellationen Sinn machen, Policies nicht über eine Sicherheitsfilterung auf domänenlokale Gruppen zu beschränken. Universelle Gruppen sind hier in diesem Szenario die bessere Wahl - so wie in allen Fällen, wenn nicht auf Ressourcen wie zum Beispiel Drucker oder Freigaben Rechte vergeben werden, sondern direkt auf "AD-Objekte", wie es auch Group Policies sind.

Grundsätzlich sollte geprüft werden, ob die Benutzer eines Active Directory Forests sich auf Computern verschiedener Domänen innerhalb des Forests anmelden, da es hier zu den beschriebenen Problemen kommen kann, wenn domänenlokale Gruppen verwendet werden.

Klar - "lokal heißt lokal" werden sich einige Leser denken. Aber Hand aufs Herz: Man denkt bei der Anmeldung eines Benutzers nur selten daran zu prüfen, ob der Client, auf dem man sich gerade befindet, ebenfalls in der gleichen Domäne liegt, wie der anmeldende Benutzer.

Viele Grüße
Fabian