From: Joseph Sutton Date: Mon, 21 Feb 2022 01:56:45 +0000 (+1300) Subject: samba-tool delegation: Add function to display security descriptor for RBCD X-Git-Tag: tevent-0.12.0~233 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e4ea06ec242e6f26a5d997d0ba992bc0d2437cba;p=thirdparty%2Fsamba.git samba-tool delegation: Add function to display security descriptor for RBCD We also check some features of the security descriptor, and display warnings if they are not as expected. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14954 Signed-off-by: Joseph Sutton Reviewed-by: Andrew Bartlett --- diff --git a/python/samba/netcmd/delegation.py b/python/samba/netcmd/delegation.py index 54ba71bdf41..b1166598361 100644 --- a/python/samba/netcmd/delegation.py +++ b/python/samba/netcmd/delegation.py @@ -24,6 +24,7 @@ from samba import provision from samba import dsdb from samba.samdb import SamDB from samba.auth import system_session +from samba.dcerpc import security from samba.netcmd.common import _get_user_realm_domain from samba.netcmd import ( Command, @@ -51,6 +52,82 @@ class cmd_delegation_show(Command): takes_args = ["accountname"] + def show_security_descriptor(self, sam, security_descriptor): + dacl = security_descriptor.dacl + desc_type = security_descriptor.type + + warning_info = ('Security Descriptor of attribute ' + 'msDS-AllowedToActOnBehalfOfOtherIdentity') + + if dacl is None or not desc_type & security.SEC_DESC_DACL_PRESENT: + self.errf.write(f'Warning: DACL not present in {warning_info}!\n') + return + + if not desc_type & security.SEC_DESC_SELF_RELATIVE: + self.errf.write(f'Warning: DACL in {warning_info} lacks ' + f'SELF_RELATIVE flag!\n') + return + + for ace in dacl.aces: + trustee = ace.trustee + + # Convert the trustee SID into a DN if we can. + try: + res = sam.search(f'', + scope=ldb.SCOPE_BASE) + except ldb.LdbError as err: + num, _ = err.args + if num != ldb.ERR_NO_SUCH_OBJECT: + raise + else: + if len(res) == 1: + trustee = res[0].dn + + ignore = False + + if (ace.type == security.SEC_ACE_TYPE_ACCESS_DENIED + or ace.type == security.SEC_ACE_TYPE_ACCESS_DENIED_OBJECT): + self.errf.write(f'Warning: ACE in {warning_info} denies ' + f'access for trustee {trustee}!\n') + # Ignore the ACE if it denies access + ignore = True + elif (ace.type != security.SEC_ACE_TYPE_ACCESS_ALLOWED + and ace.type != security.SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT): + # Ignore the ACE if it doesn't explicitly allow access + ignore = True + + inherit_only = ace.flags & security.SEC_ACE_FLAG_INHERIT_ONLY + object_inherit = ace.flags & security.SEC_ACE_FLAG_OBJECT_INHERIT + container_inherit = ( + ace.flags & security.SEC_ACE_FLAG_CONTAINER_INHERIT) + inherited_ace = ace.flags & security.SEC_ACE_FLAG_INHERITED_ACE + + if inherit_only and not object_inherit and not container_inherit: + # Ignore the ACE if it is propagated only to child objects, but + # neither of the object and container inherit flags are set. + ignore = True + else: + if container_inherit: + self.errf.write(f'Warning: ACE for trustee {trustee} has ' + f'unexpected CONTAINER_INHERIT flag set in ' + f'{warning_info}!\n') + ignore = True + + if inherited_ace: + self.errf.write(f'Warning: ACE for trustee {trustee} has ' + f'unexpected INHERITED_ACE flag set in ' + f'{warning_info}!\n') + ignore = True + + if not ace.access_mask: + # Ignore the ACE if it doesn't grant any permissions. + ignore = True + + if not ignore: + self.outf.write(f'msDS-AllowedToActOnBehalfOfOtherIdentity: ' + f'{trustee}\n') + + def run(self, accountname, H=None, credopts=None, sambaopts=None, versionopts=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp)