[英]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.