Reputation: 15172
I try to read the nTSecurityDescriptor
from a linux machine with ldapsearch (or something else) as normal domain user.
Searching for other things works, but I can not find the nTSecurityDescriptor
.
This KB is probably related, but running as domain admin is not an option for a service.
So how can I read this info? I know that I can read the DACL, but the question is HOW.
Upvotes: 2
Views: 11363
Reputation: 2869
To select the ntSecurityDescriptor
as a non-privileged account you need to use the LDAP_SERVER_SD_FLAGS_OID
server control with a value of 7. That indicates you want all portions of the security descriptor minus the SACL. The default value (which includes the SACL) seems to be what causes the attribute not to be returned, as most non-privileged accounts will not have access to the SACL, and because of this AD seems to just return nothing.
More details in this question/answer:
Selecting the AD ntSecurityDescriptor Attribute as a Non-Admin
Upvotes: 4
Reputation: 51
I created a new Java (JNDI) library (Apache2 license) for Windows ntSecurityDescriptor management. Start reading from http://blog.tirasa.net/ntsecuritydescripto-management.html for intro.
Take a look at the library (https://github.com/Tirasa/ADSDDL) integration tests for any help. Following an example to add 'user cannot change password' ACE into 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);
// .....
Upvotes: 5
Reputation: 15172
As it looks, it is not possible.
Unfortunately the underlying API that the Microsoft products use (COM API etc.) is not open source, so I don't even know how it can be done.
But I can get the security descriptor with the windows API call GetSecurityInfo
on windows.
Upvotes: 2