Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto update vendored Samba code #878

Closed
wants to merge 1 commit into from
Closed

Conversation

github-actions[bot]
Copy link
Contributor

@github-actions github-actions bot commented Dec 18, 2023

Automated changes to vendored Samba code - fdf3656d30cedf95f4d4cccc585f98db9ba03b28

Rejected hunks:

--- python/samba/gp/gpclass.py
+++ python/samba/gp/gpclass.py
@@ -504,33 +493,6 @@ class gp_applier(object):
                     self.unapply(guid, attribute, value, **kwargs)
 
 
-class gp_misc_applier(gp_applier):
-    '''Group Policy Miscellaneous Applier/Unapplier/Modifier
-    '''
-
-    def generate_value(self, **kwargs):
-        data = etree.Element('data')
-        for k, v in kwargs.items():
-            arg = etree.SubElement(data, k)
-            arg.text = get_string(v)
-        return get_string(etree.tostring(data, 'utf-8'))
-
-    def parse_value(self, value):
-        vals = {}
-        try:
-            data = etree.fromstring(value)
-        except etree.ParseError:
-            # If parsing fails, then it's an old cache value
-            return {'old_val': value}
-        except TypeError:
-            return {}
-        itr = data.iter()
-        next(itr) # Skip the top element
-        for item in itr:
-            vals[item.tag] = item.text
-        return vals
-
-
 class gp_file_applier(gp_applier):
     '''Group Policy File Applier/Unapplier/Modifier
     Subclass of abstract class gp_applier for monitoring policy applied
@@ -600,313 +562,17 @@ def get_dc_hostname(creds, lp):
                                                           nbt.NBT_SERVER_DS))
     return cldap_ret.pdc_dns_name
 
-def get_dc_netbios_hostname(creds, lp):
-    net = Net(creds=creds, lp=lp)
-    cldap_ret = net.finddc(domain=lp.get('realm'), flags=(nbt.NBT_SERVER_LDAP |
-                                                          nbt.NBT_SERVER_DS))
-    return cldap_ret.pdc_name
-
 
 ''' Fetch a list of GUIDs for applicable GPOs '''
 
 
-def get_gpo(samdb, gpo_dn):
-    g = gpo.GROUP_POLICY_OBJECT()
-    attrs = [
-        "cn",
-        "displayName",
-        "flags",
-        "gPCFileSysPath",
-        "gPCFunctionalityVersion",
-        "gPCMachineExtensionNames",
-        "gPCUserExtensionNames",
-        "gPCWQLFilter",
-        "name",
-        "nTSecurityDescriptor",
-        "versionNumber"
-    ]
-    if gpo_dn.startswith("LDAP://"):
-        gpo_dn = gpo_dn.lstrip("LDAP://")
-
-    sd_flags = (security.SECINFO_OWNER |
-                security.SECINFO_GROUP |
-                security.SECINFO_DACL)
-    try:
-        res = samdb.search(gpo_dn, ldb.SCOPE_BASE, "(objectclass=*)", attrs,
-                           controls=['sd_flags:1:%d' % sd_flags])
-    except Exception:
-        log.error('Failed to fetch gpo object with nTSecurityDescriptor')
-        raise
-    if res.count != 1:
-        raise ldb.LdbError(ldb.ERR_NO_SUCH_OBJECT,
-                           'get_gpo: search failed')
-
-    g.ds_path = gpo_dn
-    if 'versionNumber' in res.msgs[0].keys():
-        g.version = int(res.msgs[0]['versionNumber'][0])
-    if 'flags' in res.msgs[0].keys():
-        g.options = int(res.msgs[0]['flags'][0])
-    if 'gPCFileSysPath' in res.msgs[0].keys():
-        g.file_sys_path = res.msgs[0]['gPCFileSysPath'][0].decode()
-    if 'displayName' in res.msgs[0].keys():
-        g.display_name = res.msgs[0]['displayName'][0].decode()
-    if 'name' in res.msgs[0].keys():
-        g.name = res.msgs[0]['name'][0].decode()
-    if 'gPCMachineExtensionNames' in res.msgs[0].keys():
-        g.machine_extensions = str(res.msgs[0]['gPCMachineExtensionNames'][0])
-    if 'gPCUserExtensionNames' in res.msgs[0].keys():
-        g.user_extensions = str(res.msgs[0]['gPCUserExtensionNames'][0])
-    if 'nTSecurityDescriptor' in res.msgs[0].keys():
-        g.set_sec_desc(bytes(res.msgs[0]['nTSecurityDescriptor'][0]))
-    return g
-
-class GP_LINK:
-    def __init__(self, gPLink, gPOptions):
-        self.link_names = []
-        self.link_opts = []
-        self.gpo_parse_gplink(gPLink)
-        self.gp_opts = int(gPOptions)
-
-    def gpo_parse_gplink(self, gPLink):
-        for p in gPLink.decode().split(']'):
-            if not p:
-                continue
-            log.debug('gpo_parse_gplink: processing link')
-            p = p.lstrip('[')
-            link_name, link_opt = p.split(';')
-            log.debug('gpo_parse_gplink: link: {}'.format(link_name))
-            log.debug('gpo_parse_gplink: opt: {}'.format(link_opt))
-            self.link_names.append(link_name)
-            self.link_opts.append(int(link_opt))
-
-    def num_links(self):
-        if len(self.link_names) != len(self.link_opts):
-            raise RuntimeError('Link names and opts mismatch')
-        return len(self.link_names)
-
-def find_samaccount(samdb, samaccountname):
-    attrs = ['dn', 'userAccountControl']
-    res = samdb.search(samdb.get_default_basedn(), ldb.SCOPE_SUBTREE,
-                       '(sAMAccountName={})'.format(samaccountname), attrs)
-    if res.count != 1:
-        raise ldb.LdbError(ldb.ERR_NO_SUCH_OBJECT,
-            "Failed to find samAccountName '{}'".format(samaccountname)
-        )
-    uac = int(res.msgs[0]['userAccountControl'][0])
-    dn = res.msgs[0]['dn']
-    log.info('Found dn {} for samaccountname {}'.format(dn, samaccountname))
-    return uac, dn
-
-def get_gpo_link(samdb, link_dn):
-    res = samdb.search(link_dn, ldb.SCOPE_BASE,
-                       '(objectclass=*)', ['gPLink', 'gPOptions'])
-    if res.count != 1:
-        raise ldb.LdbError(ldb.ERR_NO_SUCH_OBJECT, 'get_gpo_link: no result')
-    if 'gPLink' not in res.msgs[0]:
-        raise ldb.LdbError(ldb.ERR_NO_SUCH_ATTRIBUTE,
-            "get_gpo_link: no 'gPLink' attribute found for '{}'".format(link_dn)
-        )
-    gPLink = res.msgs[0]['gPLink'][0]
-    gPOptions = 0
-    if 'gPOptions' in res.msgs[0]:
-        gPOptions = res.msgs[0]['gPOptions'][0]
-    else:
-        log.debug("get_gpo_link: no 'gPOptions' attribute found")
-    return GP_LINK(gPLink, gPOptions)
-
-def add_gplink_to_gpo_list(samdb, gpo_list, forced_gpo_list, link_dn, gp_link,
-                           link_type, only_add_forced_gpos, token):
-    for i in range(gp_link.num_links()-1, -1, -1):
-        is_forced = (gp_link.link_opts[i] & GPLINK_OPT_ENFORCE) != 0
-        if gp_link.link_opts[i] & GPLINK_OPT_DISABLE:
-            log.debug('skipping disabled GPO')
-            continue
-
-        if only_add_forced_gpos:
-            if not is_forced:
-                log.debug("skipping nonenforced GPO link "
-                          "because GPOPTIONS_BLOCK_INHERITANCE "
-                          "has been set")
-                continue
-            else:
-                log.debug("adding enforced GPO link although "
-                          "the GPOPTIONS_BLOCK_INHERITANCE "
-                          "has been set")
-
-        try:
-            new_gpo = get_gpo(samdb, gp_link.link_names[i])
-        except ldb.LdbError as e:
-            (enum, estr) = e.args
-            log.debug("failed to get gpo: %s" % gp_link.link_names[i])
-            if enum == ldb.ERR_NO_SUCH_OBJECT:
-                log.debug("skipping empty gpo: %s" % gp_link.link_names[i])
-                continue
-            return
-        else:
-            try:
-                sec_desc = ndr_unpack(security.descriptor,
-                                      new_gpo.get_sec_desc_buf())
-                samba.security.access_check(sec_desc, token,
-                                            security.SEC_STD_READ_CONTROL |
-                                            security.SEC_ADS_LIST |
-                                            security.SEC_ADS_READ_PROP)
-            except Exception as e:
-                log.debug("skipping GPO \"%s\" as object "
-                          "has no access to it" % new_gpo.display_name)
-                continue
-
-            new_gpo.link = str(link_dn)
-            new_gpo.link_type = link_type
-
-            if is_forced:
-                forced_gpo_list.insert(0, new_gpo)
-            else:
-                gpo_list.insert(0, new_gpo)
-
-            log.debug("add_gplink_to_gpo_list: added GPLINK #%d %s "
-                      "to GPO list" % (i, gp_link.link_names[i]))
-
-def merge_with_system_token(token_1):
-    sids = token_1.sids
-    system_token = system_session().security_token
-    sids.extend(system_token.sids)
-    token_1.sids = sids
-    token_1.rights_mask |= system_token.rights_mask
-    token_1.privilege_mask |= system_token.privilege_mask
-    # There are no claims in the system token, so it is safe not to merge the claims
-    return token_1
-
-def site_dn_for_machine(samdb, dc_hostname, lp, creds, hostname):
-    # [MS-GPOL] 3.2.5.1.4 Site Search
-    config_context = samdb.get_config_basedn()
-    try:
-        c = netlogon.netlogon("ncacn_np:%s[seal]" % dc_hostname, lp, creds)
-        site_name = c.netr_DsRGetSiteName(hostname)
-        return 'CN={},CN=Sites,{}'.format(site_name, config_context)
-    except WERRORError:
-        # Fallback to the old method found in ads_site_dn_for_machine
-        nb_hostname = get_dc_netbios_hostname(creds, lp)
-        res = samdb.search(config_context, ldb.SCOPE_SUBTREE,
-                           "(cn=%s)" % nb_hostname, ['dn'])
-        if res.count != 1:
-            raise ldb.LdbError(ldb.ERR_NO_SUCH_OBJECT,
-                               'site_dn_for_machine: no result')
-        dn = res.msgs[0]['dn']
-        site_dn = dn.parent().parent()
-        return site_dn
-
 def get_gpo_list(dc_hostname, creds, lp, username):
-    '''Get the full list of GROUP_POLICY_OBJECTs for a given username.
-    Push GPOs to gpo_list so that the traversal order of the list matches
-    the order of application:
-    (L)ocal (S)ite (D)omain (O)rganizational(U)nit
-    For different domains and OUs: parent-to-child.
-    Within same level of domains and OUs: Link order.
-    Since GPOs are pushed to the front of gpo_list, GPOs have to be
-    pushed in the opposite order of application (OUs first, local last,
-    child-to-parent).
-    Forced GPOs are appended in the end since they override all others.
-    '''
-    gpo_list = []
-    forced_gpo_list = []
-    url = 'ldap://' + dc_hostname
-    samdb = SamDB(url=url,
-                  session_info=system_session(),
-                  credentials=creds, lp=lp)
-    # username is DOM\\SAM, but get_gpo_list expects SAM
-    uac, dn = find_samaccount(samdb, username.split('\\')[-1])
-    add_only_forced_gpos = False
-
-    # Fetch the security token
-    session_info_flags = (AUTH_SESSION_INFO_DEFAULT_GROUPS |
-                          AUTH_SESSION_INFO_AUTHENTICATED)
-    if url.startswith('ldap'):
-        session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES
-    session = samba.auth.user_session(samdb, lp_ctx=lp, dn=dn,
-                                      session_info_flags=session_info_flags)
-    gpo_list_machine = False
-    if uac & UF_WORKSTATION_TRUST_ACCOUNT or uac & UF_SERVER_TRUST_ACCOUNT:
-        gpo_list_machine = True
-        token = merge_with_system_token(session.security_token)
-    else:
-        token = session.security_token
-
-    # (O)rganizational(U)nit
-    parent_dn = dn.parent()
-    while True:
-        if str(parent_dn) == str(samdb.get_default_basedn().parent()):
-            break
-
-        # An account can be a member of more OUs
-        if parent_dn.get_component_name(0) == 'OU':
-            try:
-                log.debug("get_gpo_list: query OU: [%s] for GPOs" % parent_dn)
-                gp_link = get_gpo_link(samdb, parent_dn)
-            except ldb.LdbError as e:
-                (enum, estr) = e.args
-                log.debug(estr)
-            else:
-                add_gplink_to_gpo_list(samdb, gpo_list, forced_gpo_list,
-                                       parent_dn, gp_link,
-                                       gpo.GP_LINK_OU,
-                                       add_only_forced_gpos, token)
-
-                # block inheritance from now on
-                if gp_link.gp_opts & GPO_BLOCK_INHERITANCE:
-                    add_only_forced_gpos = True
-
-        parent_dn = parent_dn.parent()
-
-    # (D)omain
-    parent_dn = dn.parent()
-    while True:
-        if str(parent_dn) == str(samdb.get_default_basedn().parent()):
-            break
-
-        # An account can just be a member of one domain
-        if parent_dn.get_component_name(0) == 'DC':
-            try:
-                log.debug("get_gpo_list: query DC: [%s] for GPOs" % parent_dn)
-                gp_link = get_gpo_link(samdb, parent_dn)
-            except ldb.LdbError as e:
-                (enum, estr) = e.args
-                log.debug(estr)
-            else:
-                add_gplink_to_gpo_list(samdb, gpo_list, forced_gpo_list,
-                                       parent_dn, gp_link,
-                                       gpo.GP_LINK_DOMAIN,
-                                       add_only_forced_gpos, token)
-
-                # block inheritance from now on
-                if gp_link.gp_opts & GPO_BLOCK_INHERITANCE:
-                    add_only_forced_gpos = True
-
-        parent_dn = parent_dn.parent()
-
-    # (S)ite
-    if gpo_list_machine:
-        site_dn = site_dn_for_machine(samdb, dc_hostname, lp, creds, username)
-
-        try:
-            log.debug("get_gpo_list: query SITE: [%s] for GPOs" % site_dn)
-            gp_link = get_gpo_link(samdb, site_dn)
-        except ldb.LdbError as e:
-            (enum, estr) = e.args
-            log.debug(estr)
-        else:
-            add_gplink_to_gpo_list(samdb, gpo_list, forced_gpo_list,
-                                   site_dn, gp_link,
-                                   gpo.GP_LINK_SITE,
-                                   add_only_forced_gpos, token)
-
-    # (L)ocal
-    gpo_list.insert(0, gpo.GROUP_POLICY_OBJECT("Local Policy",
-                                               "Local Policy",
-                                               gpo.GP_LINK_LOCAL))
-
-    # Append |forced_gpo_list| at the end of |gpo_list|,
-    # so that forced GPOs are applied on top of non enforced GPOs.
-    return gpo_list+forced_gpo_list
+    gpos = []
+    ads = gpo.ADS_STRUCT(dc_hostname, lp, creds)
+    if ads.connect():
+        # username is DOM\\SAM, but get_gpo_list expects SAM
+        gpos = ads.get_gpo_list(username.split('\\')[-1])
+    return gpos
 
 
 def cache_gpo_dir(conn, cache, sub_dir):

@github-actions github-actions bot requested a review from a team as a code owner December 18, 2023 09:15
@GabrielNagy
Copy link
Contributor

Superseded by #892

@GabrielNagy GabrielNagy deleted the auto-update-samba branch January 23, 2024 15:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant