解决golang 普通用户权限无法获取nTSecurityDescriptor属性

当我们需要通过代码去查询对象的ACL信息时需要通过LDAP去获取对象的nTSecurityDescriptor属性。

默认通过LDAP查询对象的nTSecurityDescriptor 属性的话通常返回空内容,很多人认为这需要管理员权限才能查到,其实是可以通过普通用户权限获得。

nTSecurityDescriptor属性存储着DACL和SACL还有其他信息,当我们查询该属性时默认检索安全描述符的所有内容,然而当前查询用户可能没有访问全部安全描述符的信息权限,尤其是SACL系统ACL。所以当我们的权限不足以查询这些信息时,AD就会返回空内容。解决这个问题其实很简单,我们只需要告诉AD只查询DACL就行。

要想指定获取DACL就要通过LDAP控件来指定不需要SACL,这个控件就是LDAP_SERVER_SD_FLAGS_OID。

LDAP_SERVER_SD_FLAGS_OID控件与LDAP搜索请求一起使用,以控制要检索的Windows安全描述符部分。DC只返回安全描述符的指定部分。它还与LDAP Modify requests2一起使用,以控制要修改的Windows安全描述符部分。DC仅修改安全描述符的指定部分。

当将该控制发送到DC时,controlValue字段被设置为以下ASN.1结构的BER编码。

代码如下:省略ldap连接部分,构造controls

import(
    ber "github.com/go-asn1-ber/asn1-ber"
)
type ControlInteger struct {
	ControlType  string
	Criticality  bool
	ControlValue int64
}

func main(){
    ....
    
	var controls []ldap.Control

	sdcontrol := &ControlInteger{
		ControlType:  "1.2.840.113556.1.4.801",
		Criticality:  true,
		ControlValue: int64(7),
	}
	controls = append(controls, sdcontrol)

	fmt.Println(sdcontrol)
	searchRequest := ldap.NewSearchRequest(
		"dc=test,dc=com",
		ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
		filter,
		[]string{"dn", "cn", "nTSecurityDescriptor"},
		controls,
	)
	sr, err := client.Search(searchRequest)
}







// GetControlType rturns the OID
func (c *ControlInteger) GetControlType() string {
	return c.ControlType
}

// Encode returns the ber packet representation
func (c *ControlInteger) Encode() *ber.Packet {
	packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
	packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, c.ControlType, "Control Type ("+c.ControlType+")"))
	if c.Criticality {
		packet.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, c.Criticality, "Criticality"))
	}

	// p2 ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Control Value")
	p2 := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Control Value")
	value := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control Value Sequence")
	value.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, c.ControlValue, "Integer"))
	p2.AppendChild(value)
	packet.AppendChild(p2)

	return packet
}

// String returns a human-readable description
func (c *ControlInteger) String() string {
	return fmt.Sprintf("Control Type: %v  Critiality: %t  Control Value: %v", c.ControlType, c.Criticality, c.ControlValue)
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值