PHP Conference Japan 2024

ldap_get_values_len

(PHP 4, PHP 5, PHP 7, PHP 8)

ldap_get_values_len從結果條目取得所有二進位值

描述

ldap_get_values_len(LDAP\Connection $ldap, LDAP\ResultEntry $entry, string $attribute): array|false

讀取結果中條目中屬性的所有值。

此函式的使用方式與 ldap_get_values() 完全相同,差別在於它處理的是二進位資料而非字串資料。

參數

ldap

ldap_connect() 傳回的 LDAP\Connection 實例。

entry

LDAP\ResultEntry 實例。

attribute

傳回值

成功時傳回屬性的值陣列,錯誤時傳回 false。個別值可透過陣列中的整數索引存取。第一個索引為 0。值的數量可透過索引結果陣列中的 "count" 來找到。

變更記錄

版本 描述
8.1.0 ldap 參數現在需要 LDAP\Connection 實例;先前需要有效的 ldap link 資源
8.1.0 entry 參數現在需要 LDAP\ResultEntry 實例;先前需要有效的 ldap result entry 資源

參見

新增註解

使用者提供的註解 9 則註解

gizmotronic at gmail dot com
9 年前
再次探討將二進位 objectGUID 轉換為字串的問題,有一個更簡單的方法,不需要大量的字串操作

function GUIDtoStr($binary_guid) {
$unpacked = unpack('Va/v2b/n2c/Nd', $binary_guid);
return sprintf('%08X-%04X-%04X-%04X-%04X%08X', $unpacked['a'], $unpacked['b1'], $unpacked['b2'], $unpacked['c1'], $unpacked['c2'], $unpacked['d']);
}

如果您喜歡小寫的十六進位數字,您當然可以在 sprintf 格式字串中將 "X" 替換為 "x"。
ashwini at majestik dot net
11 年前
關於 "objectGUID" 欄位,僅對下方來自 "jhgustafsson" 的註解進行小更新...

更進一步來說,有時將此 GUID 顯示為字串很有用,而 Microsoft 有一篇支援文章和腳本詳細說明如何將 objectGUID 從十六進位轉換為字串。該文章位於此: http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B325649

下方是一個 PHP 函式,它與 Microsoft 的 VB 腳本執行相同的操作,它採用二進位格式的 objectGUID 輸入,並將其格式化為字串傳回(在轉換為十六進位作為中間步驟之後)。這將傳回在 ADUC 中為任何 Active Directory 物件顯示的確切 "objectGUID" 值。

範例輸出:3f79048f-42cd-4c77-8426-835cd9f8a3ad

function GUIDtoStr($binary_guid) {
$hex_guid = unpack("H*hex", $binary_guid);
$hex = $hex_guid["hex"];

$hex1 = substr($hex, -26, 2) . substr($hex, -28, 2) . substr($hex, -30, 2) . substr($hex, -32, 2);
$hex2 = substr($hex, -22, 2) . substr($hex, -24, 2);
$hex3 = substr($hex, -18, 2) . substr($hex, -20, 2);
$hex4 = substr($hex, -16, 4);
$hex5 = substr($hex, -12, 12);

$guid_str = $hex1 . "-" . $hex2 . "-" . $hex3 . "-" . $hex4 . "-" . $hex5;

return $guid_str;
}
Stav
13 年前
我在使用 ldap_get_values_len() 時遇到許多解碼錯誤的問題,並且在許多論壇上發現許多未解決的求助呼叫。

錯誤訊息是 - 警告:ldap_get_values():無法在 xxx.php 中取得屬性解碼錯誤的值。

似乎這個錯誤涵蓋了許多問題,包括屬性名稱中的簡單拼寫錯誤。

在使用 PHP 列出特定記錄的屬性之後,我注意到屬性 userCertificate 並未簡單地列為 userCertificate,而是列為 userCertificate;binary。我將其寫入我的程式碼,所有問題都已解決。

所以我的程式碼如下。

<?php
if (!$val = @ldap_get_values_len($con, $entry, "$attribute;binary"))
die (
'擷取值時發生錯誤 (' . ldap_error($con) . ')');
?>

我希望這能為那些在 Google 上苦苦搜尋答案的人省去痛苦。
derek dot ethier at gmail dot com
17 年前
為了詳細說明 rcrow 的文章,如果您想要將 objectSID 值轉換為可用的字串(來自 Active Directory),下列函式會執行此操作(這是從手冊的另一個章節借來的,只是想把它加在這裡)

// 傳回文字 SID
function bin_to_str_sid($binsid) {
$hex_sid = bin2hex($binsid);
$rev = hexdec(substr($hex_sid, 0, 2));
$subcount = hexdec(substr($hex_sid, 2, 2));
$auth = hexdec(substr($hex_sid, 4, 12));
$result = "$rev-$auth";

for ($x=0;$x < $subcount; $x++) {
$subauth[$x] =
hexdec($this->little_endian(substr($hex_sid, 16 + ($x * 8), 8)));
$result .= "-" . $subauth[$x];
}

// 透過附加 S- 來作弊
return 'S-' . $result;
}

// 將小端序的十六進位數字轉換為 hexdec 可以轉換的數字
function little_endian($hex) {
for ($x = strlen($hex) - 2; $x >= 0; $x = $x - 2) {
$result .= substr($hex, $x, 2);
}
return $result;
}

此函式與 ldap_get_values_len 函式無關,但如果您想要將 objectGUID 二進位值轉換為字串格式(從 Richard Mueller 提供的一些 vbscript 轉換而來),它仍然很有幫助。

// 此函式會將二進位值的 GUID 轉換為有效的字串。
function bin_to_str_guid($object_guid) {
$hex_guid = bin2hex($object_guid);
$hex_guid_to_guid_str = '';
for($k = 1; $k <= 4; ++$k) {
$hex_guid_to_guid_str .= substr($hex_guid, 8 - 2 * $k, 2);
}
$hex_guid_to_guid_str .= '-';
for($k = 1; $k <= 2; ++$k) {
$hex_guid_to_guid_str .= substr($hex_guid, 12 - 2 * $k, 2);
}
$hex_guid_to_guid_str .= '-';
for($k = 1; $k <= 2; ++$k) {
$hex_guid_to_guid_str .= substr($hex_guid, 16 - 2 * $k, 2);
}
$hex_guid_to_guid_str .= '-' . substr($hex_guid, 16, 4);
$hex_guid_to_guid_str .= '-' . substr($hex_guid, 20);

return strtoupper($hex_guid_to_guid_str);
}

以下是如何同時使用兩者的範例

$filter="samaccountname=".$username;
$fields=array("objectguid","objectsid");

// 建立連線並先指定 base_dn。手冊中有很多這方面的範例

$sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields);
$entries = ldap_get_entries($this->_conn, $sr);

if (in_array("objectguid", $fields)) {
$entries[0]["objectguid"][0]=
$this->bin_to_str_guid($entries[0]["objectguid"][0]);
}

if (in_array("objectsid", $fields)) {
$entry = ldap_first_entry($this->_conn, $sr);
$objectsid_binary = ldap_get_values_len($this->_conn, $entry, "objectsid");
$entries[0]["objectsid"][0] = $this->bin_to_str_sid($objectsid_binary[0]);
}

希望這對某些人有幫助!
jhgustafsson at gmail dot com
15 年前
嘗試了幾種不同的方法來執行此操作,但這個方法似乎最有效

<?php
$info
= ldap_first_entry($ds,$sr);

// 取得二進位安全的值。
$bin_guid = ldap_get_values_len($ds,$info,"objectguid");

// 轉換為十六進位,bin2hex 在這裡對我來說失敗了。但是 Unpack() 似乎有效。
$hex_guid = unpack("H*hex", $bin_guid[0]);
?>
m1tk0123123 at abv dot bg
8 年前

這是 WINDOWS objectsid 的解決方案
// LIB .............................
class LDAP_OBJECT_SID {

public function toString($SID_BINARY) {

$split = str_split($SID_BINARY, 8);
$hexArray = array();
foreach ($split as $key => $byte) {
$hexArray[$key] = strToUpper(substr('0'.dechex(bindec($byte)), -2));
}

$BLOCK_COUNT = hexdec($hexArray[1]);
$DEC_GROUP['SUB-ID-BLOCKS'] = array();
for ($i=0; $i<$BLOCK_COUNT; $i++) {
$offset = 8 + (4 * $i);
$DEC_GROUP['SUB-ID-BLOCKS'][$i] = array();
$DEC_GROUP['SUB-ID-BLOCKS'][$i][1] = hexdec($hexArray[$offset+3]);
$DEC_GROUP['SUB-ID-BLOCKS'][$i][2] = hexdec($hexArray[$offset+2]);
$DEC_GROUP['SUB-ID-BLOCKS'][$i][3] = hexdec($hexArray[$offset+1]);
$DEC_GROUP['SUB-ID-BLOCKS'][$i][4] = hexdec($hexArray[$offset]);

}
$SID = 'S-'.hexdec($hexArray[0]).'-'.$this->byte6ToLong(
hexdec($hexArray[2]),
hexdec($hexArray[3]),
hexdec($hexArray[4]),
hexdec($hexArray[5]),
hexdec($hexArray[6]),
hexdec($hexArray[7])
);
foreach ($DEC_GROUP['SUB-ID-BLOCKS'] as $BLOCK) {
$SID .= '-'.$this->byte4ToLong(
$BLOCK[1],
$BLOCK[2],
$BLOCK[3],
$BLOCK[4]
);
}
return $SID;

}

private function byte6ToLong($b1, $b2, $b3, $b4, $b5, $b6) {
$byte6ToLong = $b1;
$byte6ToLong = $byte6ToLong*256 + $b2;
$byte6ToLong = $byte6ToLong*256 + $b3;
$byte6ToLong = $byte6ToLong*256 + $b4;
$byte6ToLong = $byte6ToLong*256 + $b5;
$byte6ToLong = $byte6ToLong*256 + $b6;
return $byte6ToLong;
}

private function byte4ToLong($b1, $b2, $b3, $b4) {
$byte4ToLong = $b1;
$byte4ToLong = $byte4ToLong*256 + $b2;
$byte4ToLong = $byte4ToLong*256 + $b3;
$byte4ToLong = $byte4ToLong*256 + $b4;
return $byte4ToLong;
}

}

TEST

$sr=ldap_search($conn, $base_dn, $filter,$fields);
$entry = ldap_first_entry($conn, $sr);
$objectsid_binary = ldap_get_values_len($conn, $entry, "objectsid");

$Obj = new LDAP_OBJECT_SID();
echo $Obj->toString($objectsid_binary[0]);
alexey_baranov at inbox dot ru
15 年前
不再需要使用 ldap_get_values_len()。ldap_get_attributes() 現在運作良好。

<?php
$attrs
= ldap_get_attributes($this->cid, $this->re);
$hex_Sid= bin2hex($attrs['objectSid'][0]); //傳回 010500000000000515000000c94d7d363d787b17e77b80109d060000
$hex_GUID= bin2hex($attrs['objectGUID'][0]); //傳回 710234bbc2abc148ade8c1f9b4567b24
?>
derek dot ethier at gmail dot com
17 年前
再新增一個函式,以補充我在下面發布的 bin_to_str_guid 函式

// 此函式會將字串 GUID 值轉換為十六進位值,以搜尋 AD。
function str_to_hex_guid($str_guid) {
$str_guid = str_replace('-', '', $str_guid);

$octet_str = substr($str_guid, 6, 2);
$octet_str .= substr($str_guid, 4, 2);
$octet_str .= substr($str_guid, 2, 2);
$octet_str .= substr($str_guid, 0, 2);
$octet_str .= substr($str_guid, 10, 2);
$octet_str .= substr($str_guid, 8, 2);
$octet_str .= substr($str_guid, 14, 2);
$octet_str .= substr($str_guid, 12, 2);
$octet_str .= substr($str_guid, 16, strlen($str_guid));

return $octet_str;
}

如果您想將字串 GUID 轉換回十六進位格式(如果想根據 GUID 字串搜尋 AD,則需要此格式,請確保在搜尋時使用雙反斜線跳脫十六進位字串,例如 \\AE\\0F\\88...)。
rcrow at NOSPAM dot laptv dot com
20 年前
如果您嘗試存取二進位資料,例如 LDAP 中的 ObjectSID,您必須先取得個別的條目,如 ldap_get_values() 函式所述:「此呼叫需要 result_entry_identifier,因此需要先執行其中一個 ldap 搜尋呼叫,以及其中一個取得個別條目的呼叫。」

以下程式碼片段將取得特定使用者的 LDAP objectSID。

<?php
/* 取得二進位 objectsid 條目 */
/* 請確定您已在 ldap_search 中包含二進位欄位。 */
$criteria = "samaccountname=$ldapUser";
$justthese = array("memberOf", "objectsid");

$ldapSearchResult = ldap_search($ldapConnectionResult, $ldapBase, $criteria, $justthese);

if (
ldap_count_entries($ldapConnectionResult, $ldapSearchResult)){
$ldapResults = ldap_get_entries($ldapConnectionResult, $ldapSearchResult);

$entry = ldap_first_entry($ldapConnectionResult, $ldapSearchResult);
$ldapBinary = ldap_get_values_len ($ldapConnectionResult, $entry, "objectsid");

/* 您的程式碼在這裡 */

}
?>

然後,您可以使用類似 bin2hex 的方式將資料轉換為更可用的形式。
To Top