由於我沒有找到任何干淨的解決方案,我決定採用第一種方法:通過對象Sids過濾。
此變通方法有它的侷限性:
- 它僅適用於物體與的objectSID,即用戶和組。
- 它假設所有用戶/組都由相同的權限創建。
- 它假定不存在比大小限制更多的丟失相對SID。
這個想法是先讀取所有可能的對象,然後選出具有最低相對SID的對象。相對SID是在SID的最後一個塊:
S-1-5-21-3188256696-111411151-3922474875-
讓我們假設這是一個搜索最低相對SID,只有返回'部分搜索結果'。 讓我們進一步假設的大小限制爲1000
程序然後執行以下操作: 它搜索
S-1-5-21-3188256696-111411151-3922474875- 1158之間與SID的所有對象
和
S-1-5-21-3188256696-111411151-3922474875-
然後所有之間
個
S-1-5-21-3188256696-111411151-3922474875-
和
S-1-5-21-3188256696-111411151-3922474875-
等等,直到一個的搜索返回零對象。
這種方法有幾個問題,但對我的目的來說就足夠了。
守則:
$filter = '(objectClass=Group)';
$attributes = array('objectsid','cn'); //objectsid needs to be set
$result = array();
$maxPageSize = 1000;
$searchStep = $maxPageSize-1;
$adResult = @$adConn->search($filter,$attributes); //Supress warning for first query (because it exceeds the size limit)
//Read smallest RID from the resultset
$minGroupRID = '';
for($i=0;$i<$adResult['count'];$i++){
$groupRID = unpack('V',substr($adResult[$i]['objectsid'][0],24));
if($minGroupRID == '' || $minGroupRID>$groupRID[1]){
$minGroupRID = $groupRID[1];
}
}
$sidPrefix = substr($adResult[$i-1]['objectsid'][0],0,24); //Read last objectsid and cut off the prefix
$nextStepGroupRID = $minGroupRID;
do{ //Search for all objects with a lower objectsid than minGroupRID
$adResult = $adConn->search('(&'.$filter.'(objectsid<='.preg_replace('/../','\\\\$0',bin2hex($sidPrefix.pack('V',$nextStepGroupRID))).')(objectsid>='.preg_replace('/../','\\\\$0',bin2hex($sidPrefix.pack('V',$nextStepGroupRID-$searchStep))).'))', $attributes);
for($i=0;$i<$adResult['count'];$i++){
$RID = unpack('V',substr($adResult[$i]['objectsid'][0],24)); //Extract the relative SID from the SID
$RIDs[] = $RID[1];
$resultSet = array();
foreach($attributes as $attribute){
$resultSet[$attribute] = $adResult[$i][$attribute][0];
}
$result[$RID[1]] = $resultSet;
}
$nextStepGroupRID = $nextStepGroupRID-$searchStep;
}while($adResult['count']>1);
$nextStepGroupRID = $minGroupRID;
do{ //Search for all object with a higher objectsid than minGroupRID
$adResult = $adConn->search('(&'.$filter.'(objectsid>='.preg_replace('/../','\\\\$0',bin2hex($sidPrefix.pack('V',$nextStepGroupRID))).')(objectsid<='.preg_replace('/../','\\\\$0',bin2hex($sidPrefix.pack('V',$nextStepGroupRID+$searchStep))).'))', $attributes);
for($i=0;$i<$adResult['count'];$i++){
$RID = unpack('V',substr($adResult[$i]['objectsid'][0],24)); //Extract the relative SID from the SID
$RIDs[] = $RID[1];
$resultSet = array();
foreach($attributes as $attribute){
$resultSet[$attribute] = $adResult[$i][$attribute][0];
}
$result[$RID[1]] = $resultSet;
}
$nextStepGroupRID = $nextStepGroupRID+$searchStep;
}while($adResult['count']>1);
var_dump($result);
的$ adConn->的搜索方法是這樣的:可能出現
function search($filter, $attributes = false, $base_dn = null) {
if(!isset($base_dn)){
$base_dn = $this->baseDN;
}
$entries = false;
if (is_string($filter) && $this->bind) {
if (is_array($attributes)) {
$search = ldap_search($this->resource, $base_dn, $filter, $attributes);
} else {
$search = ldap_search($this->resource, $base_dn, $filter);
}
if ($search !== false) {
$entries = ldap_get_entries($this->resource, $search);
}
}
return $entries;
}
感謝關鍵字'簡單的分頁結果'導致[此問題](http://stackoverflow.com/questions/1473075/enumerate-all-users-in-ldap-with-php),它有一個偉大的回答。似乎做到這一點的唯一方法是adoDB,好奇這是如何解決的。 – Envyrus 2011-12-27 07:23:13
你的鏈接不見了。 – MrUpsidown 2014-09-30 07:12:46