[英]Selecting the AD ntSecurityDescriptor Attribute as a Non-Admin
我正在為Active Directory ACL / ACE設計SDDL /安全描述符解析器。 我快要完成了,使用管理帳戶連接到LDAP時一切正常。
但是,當我嘗試以非管理帳戶查詢ntSecurityDescriptor
,它不返回任何值。 用戶帳戶本身有權讀取屬性。 當我開始調查此問題時,我遇到了以下LDAP服務器控件:
https://msdn.microsoft.com/en-us/library/cc223323.aspx
LDAP_SERVER_SD_FLAGS_OID控件與LDAP搜索請求一起使用,以控制要檢索的Windows安全描述符的一部分。 DC僅返回安全描述符的指定部分。 它還與LDAP添加和修改請求一起使用,以控制要修改的Windows安全描述符的一部分。 DC僅修改安全描述符的指定部分。
當將此控件發送到DC時,controlValue字段將設置為以下ASN.1結構的BER編碼。
SDFlagsRequestValue ::= SEQUENCE { Flags INTEGER }
Flags值具有以big-endian字節順序顯示的以下格式。 X表示客戶端應將未使用的比特設置為0,並且服務器必須將其忽略。
指定未設置任何位的標志,或者不使用LDAP_SERVER_SD_FLAGS_OID控件,等同於將標志設置為(OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION)。 將此控件發送到DC不會導致服務器在其響應中包含任何控件。
來自該文檔的該陳述的最后一部分似乎是不正確的,至少在非管理用戶的情況下至少如此。
我的問題:我應該如何使用標准PHP LDAP庫函數將此控件發送到LDAP? 我知道我必須設置服務器控件,但是我不確定如何對值進行編碼。 我將范圍縮小到最簡單的示例:
$user = 'user@example.local';
$pass = 'secret';
$server = 'dc1.example.local';
$ldap = ldap_connect($server);
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
ldap_bind($ldap, $user, $pass);
$ctrl1 = array(
"oid" => "1.2.840.113556.1.4.801",
"iscritical" => true,
// How should this value be set???
"value" => sprintf("%c%c%c%c%c", 48, 3, 2, 1, 15)
);
if (!ldap_set_option($ldap, LDAP_OPT_SERVER_CONTROLS, array($ctrl1))) {
echo "Failed to set server controls";
}
$searchUser = "user";
$dn = "dc=example,dc=local";
$filter="(sAMAccountName=$searchUser)";
$attr = array("ntsecuritydescriptor");
$sr = ldap_search($ldap, $dn, $filter, $attr);
$info = ldap_get_entries($ldap, $sr);
// Should contain ntSecurityDescriptor...but it does not.
var_dump($info);
我知道控件的值需要進行BER編碼,但是我不確定如何實現文檔中定義的值。 我能夠找到以下Java示例:
但是我一直無法將正在發生的事情翻譯成PHP。 有任何想法嗎?
問題似乎是非特權AD用戶帳戶將無權訪問安全描述符的SACL。 要解決此問題並仍然檢索ntSecurityDescriptor
(減去SACL),請向控件發送設置了所有其他標志的值(該值為7):
// OWNER_SECURITY_INFORMATION + GROUP_SECURITY_INFORMATION + DACL_SECURITY_INFORMATION
$sdFlags = 7;
$ctrl1 = array(
"oid" => "1.2.840.113556.1.4.801",
"iscritical" => true,
"value" => sprintf("%c%c%c%c%c", 48, 3, 2, 1, $sdFlags)
);
if (!ldap_set_option($ldap, LDAP_OPT_SERVER_CONTROLS, array($ctrl1))) {
echo "Failed to set server controls";
}
我的猜測是MS文檔沒有錯, LDAP_SERVER_SD_FLAGS_OID
的默認值是設置所有標志(包括SACL)。 由於大多數普通帳戶無法訪問該SACL,因此AD可能決定不返回安全描述符的任何部分,因此即使您選擇了該查詢,也不會從查詢中返回ntSecurityDescriptor
值。
另一個重要說明,如果您正在使用LDAP分頁,它似乎會干擾此控件。 您不能同時使用分頁和此控件。 我不確定這是否總體上是此控件的副作用,還是在PHP的LDAP模塊中如何完成服務器控件的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.