选择AD ntSecurityDescriptor属性作为非管理员 [英] Selecting the AD ntSecurityDescriptor Attribute as a Non-Admin

查看:189
本文介绍了选择AD ntSecurityDescriptor属性作为非管理员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为Active Directory ACL/ACE设计SDDL/安全描述符解析器.我快要完成了,使用管理帐户连接到LDAP时一切正常.

I'm working on a SDDL/Security Descriptor parser for Active Directory ACLs/ACEs. I'm nearly complete, everything works fine when I connect to LDAP using an administrative account.

但是,当我尝试以非管理帐户查询ntSecurityDescriptor时,它不返回任何值.用户帐户本身有权读取属性.当我开始调查此问题时,我遇到了以下LDAP服务器控件:

However, when I try to query the ntSecurityDescriptor as a non-administrative account it returns no values. The user account itself has rights to read the attribute. When I started to investigate this I ran across the following LDAP server control:

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

LDAP_SERVER_SD_FLAGS_OID控件与LDAP搜索一起使用 请求控制Windows安全描述符的一部分以 取回. DC仅返回安全性的指定部分 描述符.它还与LDAP添加和修​​改请求一起使用,以 控制Windows安全描述符的一部分进行修改. DC 仅修改安全描述符的指定部分.

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. The DC returns only the specified portion of the security descriptors. It is also used with LDAP Add and Modify requests to control the portion of a Windows security descriptor to modify. The DC modifies only the specified portion of the security descriptor.

将此控件发送到DC时,controlValue字段设置为 以下ASN.1结构的BER编码.

When sending this control to the DC, the controlValue field is set to the BER encoding of the following ASN.1 structure.

 SDFlagsRequestValue ::= SEQUENCE {
     Flags    INTEGER
 }

Flags值具有以big-endian字节表示的以下格式 命令. X表示客户端应将未使用的位设置为0,并且 必须由服务器忽略.

The Flags value has the following format presented in big-endian byte order. X denotes unused bits that SHOULD be set to 0 by the client and that MUST be ignored by the server.

指定未设置任何标志或不使用LDAP_SERVER_SD_FLAGS_OID控件的标志等同于将标志设置为(OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION).将此控件发送到DC不会导致服务器在其响应中包含任何控件.

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). Sending this control to the DC does not cause the server to include any controls in its response.

文档中该语句的最后一部分似乎是不正确的,至少在非管理用户的上下文中是不正确的.

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.

我的问题:我应该如何使用标准PHP LDAP库函数将此控件发送到LDAP?我知道我必须设置服务器控件,但是我不确定如何对值进行编码.我将范围缩小到最简单的示例:

My question: how am I supposed to send this control to LDAP using the standard PHP LDAP library functions? 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);

我知道控件的值需要进行BER编码,但是我不确定如何实现文档中定义的值.我能够找到以下Java示例:

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. I was able to find the following Java example:

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

但是我一直无法将正在发生的事情翻译成PHP.有什么想法吗?

But I have been unable to translate what's going on there to PHP. Any ideas?

推荐答案

问题似乎是非特权AD用户帐户无法访问安全描述符的SACL.要解决此问题并仍然检索ntSecurityDescriptor(减去SACL),请向控件发送设置了所有其他标志的值(该值为7):

The issue appears to be that non-privileged AD user accounts will not have access to the SACL of the security descriptor. 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):

// 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的默认值是要设置的 all 标志(包括SACL).由于大多数普通帐户无法访问该SACL,因此AD可能决定不返回安全描述符的任何部分,因此即使您选择了查询,也不会返回ntSecurityDescriptor值.

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). 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.

另一个重要说明,如果您正在使用LDAP分页,则似乎会干扰此控件.您不能同时使用分页和此控件.我不确定这是否总体上是此控件的副作用,还是在PHP的LDAP模块中如何完成服务器控件的问题.

Another important note, if you are using LDAP paging it seems to interfere with this control. 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.

这篇关于选择AD ntSecurityDescriptor属性作为非管理员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆