Skip to content

Commit 238a8a5

Browse files
author
robin.kluth
committed
1.1.15
* Support for 'sidhistory'-field. Returns array of SID-strings if available, otherweise `null`
1 parent 8072fde commit 238a8a5

File tree

1 file changed

+34
-23
lines changed

1 file changed

+34
-23
lines changed

src/LdapAuth.php

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,11 @@ public function login($username, $password, $domainKey)
180180
public function fetchUserData($attributes = "")
181181
{
182182
if (empty($attributes)) {
183-
$attributes = ['sn', 'objectSid', 'givenName', 'mail', 'telephoneNumber'];
183+
$attributes = ['sn', 'objectSid', 'sIDHistory', 'givenName', 'mail', 'telephoneNumber'];
184184
}
185185

186186
array_push($attributes, 'objectSid'); # Push objectsid, regardless of source array, as we need it ALWAYS!
187+
array_push($attributes, 'sIDHistory'); # Push sIDHistory, regardless of source array, as we need it ALWAYS!
187188

188189
$search_filter = '(&(objectCategory=person)(samaccountname=' . $this->_username . '))';
189190

@@ -194,8 +195,9 @@ public function fetchUserData($attributes = "")
194195
if ($entries['count'] > 1) {
195196
return false;
196197
}
197-
$sid = self::SIDtoString($entries[0]['objectsid'][0]);
198-
return array_merge(['sid' => $sid], self::handleEntry($entries[0]));
198+
$sid = self::SIDtoString($entries[0]['objectsid'])[0];
199+
$sidHistory = isset($entries[0]['sidhistory']) ? self::SIDtoString($entries[0]['sidhistory']) : null;
200+
return array_merge(['sid' => $sid, 'sidhistory' => $sidHistory], self::handleEntry($entries[0]));
199201
} else {
200202
return false;
201203
}
@@ -216,13 +218,14 @@ public function searchUser($searchFor, $attributes = "", $searchFilter = "", $au
216218
}
217219

218220
if (empty($attributes)) {
219-
$attributes = ['sn', 'objectSid', 'givenName', 'mail', 'telephoneNumber', 'l', 'physicalDeliveryOfficeName'];
221+
$attributes = ['sn', 'objectSid', 'sIDHistory', 'givenName', 'mail', 'telephoneNumber', 'l', 'physicalDeliveryOfficeName'];
220222
}
221223

222224
array_push($attributes, 'objectSid'); # Push objectsid, regardless of source array, as we need it ALWAYS!
225+
array_push($attributes, 'sIDHistory'); # Push sIDHistory, regardless of source array, as we need it ALWAYS!
223226

224227
if (empty($searchFilter)) {
225-
$searchFilter = "(&(objectCategory=person)(|(objectSid=%searchFor%)(samaccountname=*%searchFor%*)(mail=*%searchFor%*)(sn=*%searchFor%*)(givenName=*%searchFor%*)(l=%searchFor%)(physicalDeliveryOfficeName=%searchFor%)))";
228+
$searchFilter = "(&(objectCategory=person)(|(objectSid=%searchFor%)(sIDHistory=%searchFor%)(samaccountname=*%searchFor%*)(mail=*%searchFor%*)(sn=*%searchFor%*)(givenName=*%searchFor%*)(l=%searchFor%)(physicalDeliveryOfficeName=%searchFor%)))";
226229
}
227230

228231
if ($autodetect) {
@@ -263,8 +266,9 @@ public function searchUser($searchFor, $attributes = "", $searchFilter = "", $au
263266
Yii::warning('No objectsid! ignoring!');
264267
continue;
265268
}
266-
$sid = self::SIDtoString($entry['objectsid'][0]);
267-
$additionalData = ['sid' => $sid, 'dn' => $entry['dn'], 'domainKey' => $i];
269+
$sid = self::SIDtoString($entry['objectsid'])[0];
270+
$sidHistory = isset($entry['sidhistory']) ? self::SIDtoString($entry['sidhistory']) : null;
271+
$additionalData = ['sid' => $sid, 'sidhistory' => $sidHistory, 'dn' => $entry['dn'], 'domainKey' => $i];
268272
if (count($this->domains) > 1) {
269273
// Enable domainName output if more than one domains configured
270274
$additionalData['domainName'] = $this->domains[$i]['name'];
@@ -282,29 +286,36 @@ public function searchUser($searchFor, $attributes = "", $searchFilter = "", $au
282286

283287
public static function SIDtoString($ADsid)
284288
{
285-
$sid = "S-";
286-
//$ADguid = $info[0]['objectguid'][0];
287-
$sidinhex = str_split(bin2hex($ADsid), 2);
288-
// Byte 0 = Revision Level
289-
$sid = $sid . hexdec($sidinhex[0]) . "-";
290-
// Byte 1-7 = 48 Bit Authority
291-
$sid = $sid . hexdec($sidinhex[6] . $sidinhex[5] . $sidinhex[4] . $sidinhex[3] . $sidinhex[2] . $sidinhex[1]);
292-
// Byte 8 count of sub authorities - Get number of sub-authorities
293-
$subauths = hexdec($sidinhex[7]);
294-
//Loop through Sub Authorities
295-
for ($i = 0; $i < $subauths; $i++) {
296-
$start = 8 + (4 * $i);
297-
// X amount of 32Bit (4 Byte) Sub Authorities
298-
$sid = $sid . "-" . hexdec($sidinhex[$start + 3] . $sidinhex[$start + 2] . $sidinhex[$start + 1] . $sidinhex[$start]);
289+
$results = [];
290+
Yii::debug('Converting SID...', __METHOD__);
291+
for ($cnt = 0; $cnt < $ADsid['count']; $cnt++) {
292+
Yii::debug('Run ' . $cnt, __METHOD__);
293+
$sid = "S-";
294+
//$ADguid = $info[0]['objectguid'][0];
295+
$sidinhex = str_split(bin2hex($ADsid[$cnt]), 2);
296+
// Byte 0 = Revision Level
297+
$sid = $sid . hexdec($sidinhex[0]) . "-";
298+
// Byte 1-7 = 48 Bit Authority
299+
$sid = $sid . hexdec($sidinhex[6] . $sidinhex[5] . $sidinhex[4] . $sidinhex[3] . $sidinhex[2] . $sidinhex[1]);
300+
// Byte 8 count of sub authorities - Get number of sub-authorities
301+
$subauths = hexdec($sidinhex[7]);
302+
//Loop through Sub Authorities
303+
for ($i = 0; $i < $subauths; $i++) {
304+
$start = 8 + (4 * $i);
305+
// X amount of 32Bit (4 Byte) Sub Authorities
306+
$sid = $sid . "-" . hexdec($sidinhex[$start + 3] . $sidinhex[$start + 2] . $sidinhex[$start + 1] . $sidinhex[$start]);
307+
}
308+
Yii::debug('Converted SID to: ' . $sid, __METHOD__);
309+
array_push($results, $sid);
299310
}
300-
return $sid;
311+
return $results;
301312
}
302313

303314
public static function handleEntry($entry)
304315
{
305316
$newEntry = [];
306317
foreach ($entry as $attr => $value) {
307-
if (is_int($attr) || $attr == 'objectsid' || !isset($value['count'])) {
318+
if (is_int($attr) || $attr == 'objectsid' || $attr == 'sidhistory' || !isset($value['count'])) {
308319
continue;
309320
}
310321
$count = $value['count'];

0 commit comments

Comments
 (0)