Active Directory Primärgruppe eines Users mit PHP finden

Versucht man über LDAP Infos über Benutzeraccounts aus dem Active Directory zu laden, dann wird ein nicht ganz unwichtiges Detail unterschlagen: Die Primary Group des Benutzers. Eine LDAP-Abfrage nach memberOf liefert alle Gruppen, mit Ausnahme der primären. Stattdessen wird im Benutzer-Objekt eine numerische primaryGroupID abgespeichert. Diese ID taucht jedoch im Objekt der Gruppe auf den ersten Blick nicht auf. Das ganze geht sogar noch weiter: Gruppen enthalten mit dem member-Attribut alle Mitglieder. Es liegt also nahe, mit der Abfrage „(&(member=$userDN)(objectType=group))“ alle Gruppen zu finden in denen sich der Benutzer befindet. Leider macht uns das Active Directory hier auch einen Strich durch die Rechnung, es liefert wieder nur alle Gruppen ohne die Primärgruppe.

Im Blog von Adam Retter finden sich Informationen dazu, zusammen mit ein wenig Java-Code. Jedes Objekt im LDAP hat eine eindeutige ID in einem Binärformat, das sich folgendermaßen darstellen lässt:

objectSid: S-1-5-21-681843459-3643254382-3208760350-1119

Der vordere Teil der objectSid ist innerhalb einer „Domain“ identisch, die Objekte unterscheiden sich nur in der letzten Gruppe. Diese Zahl ist identisch mit der primaryGroupID. Alles was wir tun müssen, ist also diese binäre Zeichenkette in einen brauchbaren String umzuwandeln, die letzte Gruppe zu ersetzen, dann können wir damit suchen.

In einem Forum findet sich diese Funktion zum dekodieren der Zeichenkette in einen String:

function decodeSID($value) {
	$sid = "S-";

	// Convert Bin to Hex and split into byte chunks
	$sidinhex = str_split(bin2hex($value), 2);

	// Byte 0 = Revision Level
	$sid .= hexdec($sidinhex[0])."-";

	// Byte 1-7 = 48 Bit Authority
	$sid .= hexdec($sidinhex[6].$sidinhex[5].$sidinhex[4].$sidinhex[3].$sidinhex[2].$sidinhex[1]);

	// Byte 8 count of sub authorities - Get number of sub-authorities
	$subauths = hexdec($sidinhex[7]);

	//Loop through Sub Authorities
	for($i = 0; $i < $subauths; $i++) {
		$start = 8 + (4 * $i);
		// X amount of 32Bit (4 Byte) Sub Authorities
		$sid .= "-".hexdec($sidinhex[$start+3].$sidinhex[$start+2].$sidinhex[$start+1].$sidinhex[$start]);

	}
	return $sid;
}

Diese Funktion liefert die Sid als brauchbaren String:
objectSid: S-1-5-21-681843459-3643254382-3208760350-1119

Der letzte Teil lässt sich jetzt leicht austauschen:

// Sid vom User-Objekt auslesen
$sid = decodeSID($result[0]['objectsid'][0]);
// Den Teilstring vom ersten Zeichen bis zum letzten Bindestrich nehmen, die PrimaryGroupID des Users anhängen.
$gsid = substr($sid, 0, strrpos($sid, "-")+1) . $user['primaryGroupID'];
// Heraus kommt: S-1-5-21-681843459-3643254382-3208760350-1422
$result = ldap_search("(objectsid=$gsid)", array('dn', 'sAMAccountName'), $BASEDN);
$groups[] = $result[0];

Voila, wir haben die gesuchte Gruppe.

Veröffentlicht von

Gerald

Diplom-Informatiker (DH) in Darmstadt. Ich blogge über Entwicklung, Internet, mobile Geräte und Virtualisierung. Meine Beiträge gibt es auch bei Google+ und Facebook.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.