簡體   English   中英

選擇AD ntSecurityDescriptor屬性作為非管理員

[英]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示例:

https://github.com/Tirasa/ADSDDL/blob/master/src/main/java/net/tirasa/adsddl/ntsd/controls/SDFlagsControl.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM