简体   繁体   English

选择AD ntSecurityDescriptor属性作为非管理员

[英]Selecting the AD ntSecurityDescriptor Attribute as a Non-Admin

I'm working on a SDDL/Security Descriptor parser for Active Directory ACLs/ACEs. 我正在为Active Directory ACL / ACE设计SDDL /安全描述符解析器。 I'm nearly complete, everything works fine when I connect to LDAP using an administrative account. 我快要完成了,使用管理帐户连接到LDAP时一切正常。

However, when I try to query the ntSecurityDescriptor as a non-administrative account it returns no values. 但是,当我尝试以非管理帐户查询ntSecurityDescriptor ,它不返回任何值。 The user account itself has rights to read the attribute. 用户帐户本身有权读取属性。 When I started to investigate this I ran across the following LDAP server control: 当我开始调查此问题时,我遇到了以下LDAP服务器控件:

https://msdn.microsoft.com/en-us/library/cc223323.aspx https://msdn.microsoft.com/en-us/library/cc223323.aspx

The LDAP_SERVER_SD_FLAGS_OID control is used with an LDAP Search request to control the portion of a Windows security descriptor to retrieve. LDAP_SERVER_SD_FLAGS_OID控件与LDAP搜索请求一起使用,以控制要检索的Windows安全描述符的一部分。 The DC returns only the specified portion of the security descriptors. DC仅返回安全描述符的指定部分。 It is also used with LDAP Add and Modify requests to control the portion of a Windows security descriptor to modify. 它还与LDAP添加和修​​改请求一起使用,以控制要修改的Windows安全描述符的一部分。 The DC modifies only the specified portion of the security descriptor. DC仅修改安全描述符的指定部分。

When sending this control to the DC, the controlValue field is set to the BER encoding of the following ASN.1 structure. 当将此控件发送到DC时,controlValue字段将设置为以下ASN.1结构的BER编码。

  SDFlagsRequestValue ::= SEQUENCE { Flags INTEGER } 

The Flags value has the following format presented in big-endian byte order. Flags值具有以big-endian字节顺序显示的以下格式。 X denotes unused bits that SHOULD be set to 0 by the client and that MUST be ignored by the server. X表示客户端应将未使用的比特设置为0,并且服务器必须将其忽略。

Specifying Flags with no bits set, or not using the LDAP_SERVER_SD_FLAGS_OID control, is equivalent to setting Flags to (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION). 指定未设置任何位的标志,或者不使用LDAP_SERVER_SD_FLAGS_OID控件,等同于将标志设置为(OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION)。 Sending this control to the DC does not cause the server to include any controls in its response. 将此控件发送到DC不会导致服务器在其响应中包含任何控件。

The last part of that statement from the docs does not appear to be correct, at least not when under the context of a non-administrative user. 来自该文档的该陈述的最后一部分似乎是不正确的,至少在非管理用户的情况下至少如此。

My question: how am I supposed to send this control to LDAP using the standard PHP LDAP library functions? 我的问题:我应该如何使用标准PHP LDAP库函数将此控件发送到LDAP? I know I have to set the server controls, but I'm not sure how to encode the value. 我知道我必须设置服务器控件,但是我不确定如何对值进行编码。 I have narrowed this down to the simplest possible example: 我将范围缩小到最简单的示例:

$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);

I know the value for the control needs to be BER encoded, but I'm not sure how to achieve that for the value as it is defined in the docs. 我知道控件的值需要进行BER编码,但是我不确定如何实现文档中定义的值。 I was able to find the following Java example: 我能够找到以下Java示例:

https://github.com/Tirasa/ADSDDL/blob/master/src/main/java/net/tirasa/adsddl/ntsd/controls/SDFlagsControl.java https://github.com/Tirasa/ADSDDL/blob/master/src/main/java/net/tirasa/adsddl/ntsd/controls/SDFlagsControl.java

But I have been unable to translate what's going on there to PHP. 但是我一直无法将正在发生的事情翻译成PHP。 Any ideas? 有任何想法吗?

The issue appears to be that non-privileged AD user accounts will not have access to the SACL of the security descriptor. 问题似乎是非特权AD用户帐户将无权访问安全描述符的SACL。 To get around this and still retrieve the ntSecurityDescriptor (minus the SACL), send the control with a value of all other flags set (which would be a value of 7): 要解决此问题并仍然检索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";
}

My guess is that the MS docs are not wrong, the default value of the LDAP_SERVER_SD_FLAGS_OID is for all flags to be set (which includes the SACL). 我的猜测是MS文档没有错, LDAP_SERVER_SD_FLAGS_OID的默认值是设置所有标志(包括SACL)。 Since most normal accounts do not have access to that SACL, AD probably decides to return no portion of the security descriptor, and thus no ntSecurityDescriptor value is returned from a query even though you select it. 由于大多数普通帐户无法访问该SACL,因此AD可能决定不返回安全描述符的任何部分,因此即使您选择了该查询,也不会从查询中返回ntSecurityDescriptor值。

Another important note, if you are using LDAP paging it seems to interfere with this control. 另一个重要说明,如果您正在使用LDAP分页,它似乎会干扰此控件。 You cannot use paging and this control at the same time. 您不能同时使用分页和此控件。 I'm not sure if this is a side-effect of this control in general, or an issue with how server controls are done in PHP's LDAP module. 我不确定这是否总体上是此控件的副作用,还是在PHP的LDAP模块中如何完成服务器控件的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM