Php 选择AD ntSecurityDescriptor属性作为非管理员
我正在为Active Directory ACL/ACE开发SDDL/安全描述符解析器。我几乎完成了,当我使用管理帐户连接到LDAP时,一切正常 但是,当我尝试将Php 选择AD ntSecurityDescriptor属性作为非管理员,php,active-directory,ldap,Php,Active Directory,Ldap,我正在为Active Directory ACL/ACE开发SDDL/安全描述符解析器。我几乎完成了,当我使用管理帐户连接到LDAP时,一切正常 但是,当我尝试将ntSecurityDescriptor作为非管理帐户查询时,它不会返回任何值。用户帐户本身具有读取属性的权限。当我开始对此进行调查时,我遇到了以下LDAP服务器控件: LDAP_服务器_SD_FLAGS_OID控件用于LDAP搜索 请求控制要删除的Windows安全描述符部分 检索DC仅返回证券的指定部分 描述符。它还与LDAP添加
ntSecurityDescriptor
作为非管理帐户查询时,它不会返回任何值。用户帐户本身具有读取属性的权限。当我开始对此进行调查时,我遇到了以下LDAP服务器控件:
LDAP_服务器_SD_FLAGS_OID控件用于LDAP搜索
请求控制要删除的Windows安全描述符部分
检索DC仅返回证券的指定部分
描述符。它还与LDAP添加和修改请求一起使用,以
控制要修改的Windows安全描述符部分。DC
仅修改安全描述符的指定部分
将此控件发送到DC时,controlValue字段设置为
以下ASN.1结构的BER编码
SDFlagsRequestValue ::= SEQUENCE {
Flags INTEGER
}
Flags值的格式如下,以big-endian字节表示
秩序。X表示未使用的位,客户端和
服务器必须忽略的
指定未设置位的标志,或不使用LDAP_服务器_SD_标志_OID控件,相当于将标志设置为(所有者|安全|信息|组|安全|信息| SACL |安全|信息)。将此控件发送到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)的控件:
我的猜测是MS文档没有错,LDAP\u SERVER\u SD\u FLAGS\u OID
的默认值是要设置的所有标志(包括SACL)。由于大多数普通帐户没有访问该SACL的权限,AD可能决定不返回安全描述符的任何部分,因此即使您选择了它,也不会从查询返回任何ntSecurityDescriptor
值
另一个重要的注意事项是,如果您使用LDAP分页,它似乎会干扰此控件。不能同时使用分页和此控件。我不确定这是该控件的一个副作用,还是PHP的LDAP模块中服务器控件的执行方式问题
// 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";
}