我尝试nTSecurityDescriptor
使用 ldapsearch (或其他东西)作为普通域用户从 linux 机器上读取。
搜索其他东西有效,但我找不到nTSecurityDescriptor
.
此 KB可能是相关的,但以域管理员身份运行不是服务的选项。
那么我怎样才能阅读这些信息呢?我知道我可以阅读 DACL,但问题是如何阅读。
我尝试nTSecurityDescriptor
使用 ldapsearch (或其他东西)作为普通域用户从 linux 机器上读取。
搜索其他东西有效,但我找不到nTSecurityDescriptor
.
此 KB可能是相关的,但以域管理员身份运行不是服务的选项。
那么我怎样才能阅读这些信息呢?我知道我可以阅读 DACL,但问题是如何阅读。
我为 Windows ntSecurityDescriptor 管理创建了一个新的 Java (JNDI) 库(Apache2 许可证)。从http://blog.tirasa.net/ntsecuritydescripto-management.html开始阅读介绍。
查看库 ( https://github.com/Tirasa/ADSDDL ) 集成测试以获取任何帮助。以下示例将“用户无法更改密码”ACE 添加到 DACL。
final SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
controls.setReturningAttributes(new String[] { "nTSecurityDescriptor" });
ctx.setRequestControls(new Control[] { new SDFlagsControl(0x00000004) });
NamingEnumeration<SearchResult> results =
ctx.search(baseContext, searchFilter, controls);
SearchResult res = results.next();
final String dn = res.getNameInNamespace();
byte[] orig = (byte[]) res.getAttributes().get("nTSecurityDescriptor").get();
SDDL sddl = new SDDL(orig);
results.close();
final List<ACE> toBeChanged = new ArrayList<>();
for (ACE ace : sddl.getDacl().getAces()) {
if ((ace.getType() == AceType.ACCESS_ALLOWED_OBJECT_ACE_TYPE
|| ace.getType() == AceType.ACCESS_DENIED_OBJECT_ACE_TYPE)
&& ace.getObjectFlags().getFlags().contains(
AceObjectFlags.Flag.ACE_OBJECT_TYPE_PRESENT)) {
if (GUID.getGuidAsString(ace.getObjectType()).equals(
UCP_OBJECT_GUID)) {
final SID sid = ace.getSid();
if (sid.getSubAuthorities().size() == 1
&& ((Arrays.equals(sid.getIdentifierAuthority(),
new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 })
&& Arrays.equals(sid.getSubAuthorities().get(0),
new byte[] { 0x00, 0x00, 0x00, 0x00 }))
|| (Arrays.equals(sid.getIdentifierAuthority(),
new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x05 })
&& Arrays.equals(sid.getSubAuthorities().get(0),
new byte[] { 0x00, 0x00, 0x00, 0x0a })))) {
toBeChanged.add(ace);
}
}
}
}
if (toBeChanged.isEmpty()) {
// prepare aces
ACE self = ACE.newInstance(AceType.ACCESS_DENIED_OBJECT_ACE_TYPE);
self.setObjectFlags(new AceObjectFlags(
AceObjectFlags.Flag.ACE_OBJECT_TYPE_PRESENT));
self.setObjectType(GUID.getGuidAsByteArray(UCP_OBJECT_GUID));
self.setRights(new AceRights().addOjectRight(AceRights.ObjectRight.CR));
SID sd = SID.newInstance(NumberFacility.getBytes(0x000000000001));
sd.addSubAuthority(NumberFacility.getBytes(0));
self.setSid(sd);
ACE all = ACE.newInstance(AceType.ACCESS_DENIED_OBJECT_ACE_TYPE);
all.setObjectFlags(new AceObjectFlags(
AceObjectFlags.Flag.ACE_OBJECT_TYPE_PRESENT));
all.setObjectType(GUID.getGuidAsByteArray(UCP_OBJECT_GUID));
all.setRights(new AceRights().addOjectRight(AceRights.ObjectRight.CR));
sd = SID.newInstance(NumberFacility.getBytes(0x000000000005));
sd.addSubAuthority(NumberFacility.getBytes(0x0A));
all.setSid(sd);
sddl.getDacl().getAces().add(self);
sddl.getDacl().getAces().add(all);
} else {
for (ACE ace : toBeChanged) {
ace.setType(AceType.ACCESS_DENIED_OBJECT_ACE_TYPE);
}
}
final Attribute ntSecurityDescriptor = new BasicAttribute(
"ntSecurityDescriptor", sddl.toByteArray());
final ModificationItem[] mods = new ModificationItem[1];
mods[0] = new ModificationItem(
DirContext.REPLACE_ATTRIBUTE, ntSecurityDescriptor);
ctx.modifyAttributes(dn, mods);
// .....
要选择ntSecurityDescriptor
非特权帐户,您需要使用LDAP_SERVER_SD_FLAGS_OID
值为 7 的服务器控件。这表示您希望安全描述符的所有部分都减去 SACL。默认值(包括 SACL)似乎是导致属性不返回的原因,因为大多数非特权帐户将无权访问 SACL,因此 AD 似乎什么也不返回。
此问题/答案中的更多详细信息:
看起来,这是不可能的。
不幸的是,微软产品使用的底层 API(COM API 等)不是开源的,所以我什至不知道它是如何实现的。
但是我可以通过 windows 上的 windows API 调用来获取安全描述符GetSecurityInfo
。