[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Thu Mar 18 20:03:01 UTC 2021


The branch, master has been updated
       via  f1a72fc63df samba-tool: Add a gpo command for removing VGP Host Access Group Policy
       via  90acb3cf991 samba-tool: Test gpo manage access remove command
       via  482046c56ba samba-tool: Add a gpo command for adding VGP Host Access Group Policy
       via  996a0bd2e46 samba-tool: Test gpo manage access add command
       via  3f3c2b5b338 samba-tool: Add a gpo command for listing VGP Host Access Group Policy
       via  76868b50f36 samba-tool: Test gpo manage access list command
       via  a6cb5b8cc57 gpo: Apply Group Policy Host Access configuration from VGP
       via  de3dbfda9c5 gpo: Test Group Policy Host Access Configuration for VGP
      from  591c9196962 smbd: free open_rec state in remove_deferred_open_message_smb2_internal()

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit f1a72fc63dfe425c9e5ed9357ecf8dfe340976c1
Author: David Mulder <dmulder at suse.com>
Date:   Wed Mar 3 14:19:01 2021 -0700

    samba-tool: Add a gpo command for removing VGP Host Access Group Policy
    
    Signed-off-by: David Mulder <dmulder at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Thu Mar 18 20:02:50 UTC 2021 on sn-devel-184

commit 90acb3cf99125f53abd2efceaf04a6f63b796a84
Author: David Mulder <dmulder at suse.com>
Date:   Wed Mar 3 12:28:07 2021 -0700

    samba-tool: Test gpo manage access remove command
    
    Signed-off-by: David Mulder <dmulder at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 482046c56ba2bbc4a464bbc518877501598e4e31
Author: David Mulder <dmulder at suse.com>
Date:   Tue Mar 2 15:05:46 2021 -0700

    samba-tool: Add a gpo command for adding VGP Host Access Group Policy
    
    Signed-off-by: David Mulder <dmulder at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 996a0bd2e46fa9e164f390561c64dd5d954eb7e2
Author: David Mulder <dmulder at suse.com>
Date:   Mon Mar 1 10:31:54 2021 -0700

    samba-tool: Test gpo manage access add command
    
    Signed-off-by: David Mulder <dmulder at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 3f3c2b5b33864ac162ed578279244be0182c42f0
Author: David Mulder <dmulder at suse.com>
Date:   Wed Feb 24 06:36:45 2021 -0700

    samba-tool: Add a gpo command for listing VGP Host Access Group Policy
    
    Signed-off-by: David Mulder <dmulder at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 76868b50f3689107e101511322dbf749c26d8342
Author: David Mulder <dmulder at suse.com>
Date:   Tue Feb 23 13:12:09 2021 -0700

    samba-tool: Test gpo manage access list command
    
    Signed-off-by: David Mulder <dmulder at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit a6cb5b8cc57a0252f27ec83645bff3791ec9aab6
Author: David Mulder <dmulder at suse.com>
Date:   Tue Feb 23 11:12:05 2021 -0700

    gpo: Apply Group Policy Host Access configuration from VGP
    
    Signed-off-by: David Mulder <dmulder at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit de3dbfda9c513bc6fdf4bf38c40e72d4f278e7e0
Author: David Mulder <dmulder at suse.com>
Date:   Mon Feb 22 15:01:04 2021 -0700

    gpo: Test Group Policy Host Access Configuration for VGP
    
    Signed-off-by: David Mulder <dmulder at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 docs-xml/manpages/samba-tool.8.xml        |  15 ++
 python/samba/netcmd/gpo.py                | 330 ++++++++++++++++++++++++++++++
 python/samba/tests/gpo.py                 | 131 ++++++++++++
 python/samba/tests/samba_tool/gpo_exts.py | 202 ++++++++++++++++++
 python/samba/vgp_access_ext.py            | 133 ++++++++++++
 source4/scripting/bin/samba-gpupdate      |   2 +
 source4/selftest/tests.py                 |   2 +
 7 files changed, 815 insertions(+)
 create mode 100644 python/samba/tests/samba_tool/gpo_exts.py
 create mode 100644 python/samba/vgp_access_ext.py


Changeset truncated at 500 lines:

diff --git a/docs-xml/manpages/samba-tool.8.xml b/docs-xml/manpages/samba-tool.8.xml
index 346143ddafe..beef6cfb265 100644
--- a/docs-xml/manpages/samba-tool.8.xml
+++ b/docs-xml/manpages/samba-tool.8.xml
@@ -974,6 +974,21 @@
 	<para>Sets a VGP Issue Group Policy to the sysvol</para>
 </refsect3>
 
+<refsect3>
+	<title>gpo manage access add</title>
+	<para>Adds a VGP Host Access Group Policy to the sysvol</para>
+</refsect3>
+
+<refsect3>
+	<title>gpo manage access list</title>
+	<para>List VGP Host Access Group Policy from the sysvol</para>
+</refsect3>
+
+<refsect3>
+	<title>gpo manage access remove</title>
+	<para>Remove a VGP Host Access Group Policy from the sysvol</para>
+</refsect3>
+
 <refsect2>
 	<title>group</title>
 	<para>Manage groups.</para>
diff --git a/python/samba/netcmd/gpo.py b/python/samba/netcmd/gpo.py
index 1b4159c4c0c..bd2db9b1ab2 100644
--- a/python/samba/netcmd/gpo.py
+++ b/python/samba/netcmd/gpo.py
@@ -3659,6 +3659,335 @@ class cmd_issue(SuperCommand):
     subcommands["list"] = cmd_list_issue()
     subcommands["set"] = cmd_set_issue()
 
+class cmd_list_access(Command):
+    """List VGP Host Access Group Policy from the sysvol
+
+This command lists host access rules from the sysvol that will be applied to winbind clients.
+
+Example:
+samba-tool gpo manage access list {31B2F340-016D-11D2-945F-00C04FB984F9}
+    """
+
+    synopsis = "%prog <gpo> [options]"
+
+    takes_optiongroups = {
+        "sambaopts": options.SambaOptions,
+        "versionopts": options.VersionOptions,
+        "credopts": options.CredentialsOptions,
+    }
+
+    takes_options = [
+        Option("-H", "--URL", help="LDB URL for database or target server", type=str,
+                metavar="URL", dest="H"),
+    ]
+
+    takes_args = ["gpo"]
+
+    def run(self, gpo, H=None, sambaopts=None, credopts=None, versionopts=None):
+        self.lp = sambaopts.get_loadparm()
+        self.creds = credopts.get_credentials(self.lp, fallback_machine=True)
+
+        # We need to know writable DC to setup SMB connection
+        if H and H.startswith('ldap://'):
+            dc_hostname = H[7:]
+            self.url = H
+        else:
+            dc_hostname = netcmd_finddc(self.lp, self.creds)
+            self.url = dc_url(self.lp, self.creds, dc=dc_hostname)
+
+        # SMB connect to DC
+        conn = smb_connection(dc_hostname,
+                              'sysvol',
+                              lp=self.lp,
+                              creds=self.creds)
+
+        realm = self.lp.get('realm')
+        vgp_xml = '\\'.join([realm.lower(), 'Policies', gpo,
+                             'MACHINE\\VGP\\VTLA\\VAS'
+                             'HostAccessControl\\Allow\\manifest.xml'])
+        try:
+            allow = ET.fromstring(conn.loadfile(vgp_xml))
+        except NTSTATUSError as e:
+            # STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_NOT_FOUND,
+            # STATUS_OBJECT_PATH_NOT_FOUND
+            if e.args[0] in [0xC0000033, 0xC0000034, 0xC000003A]:
+                allow = None # The file doesn't exist, ignore it
+            elif e.args[0] == 0xC0000022: # STATUS_ACCESS_DENIED
+                raise CommandError("The authenticated user does "
+                                   "not have sufficient privileges")
+            else:
+                raise
+
+        if allow is not None:
+            policy = allow.find('policysetting')
+            data = policy.find('data')
+            for listelement in data.findall('listelement'):
+                adobject = listelement.find('adobject')
+                name = adobject.find('name')
+                domain = adobject.find('domain')
+                self.outf.write('+:%s\\%s:ALL\n' % (domain.text, name.text))
+
+        vgp_xml = '\\'.join([realm.lower(), 'Policies', gpo,
+                             'MACHINE\\VGP\\VTLA\\VAS'
+                             'HostAccessControl\\Deny\\manifest.xml'])
+        try:
+            deny = ET.fromstring(conn.loadfile(vgp_xml))
+        except NTSTATUSError as e:
+            # STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_NOT_FOUND,
+            # STATUS_OBJECT_PATH_NOT_FOUND
+            if e.args[0] in [0xC0000033, 0xC0000034, 0xC000003A]:
+                deny = None # The file doesn't exist, ignore it
+            elif e.args[0] == 0xC0000022: # STATUS_ACCESS_DENIED
+                raise CommandError("The authenticated user does "
+                                   "not have sufficient privileges")
+            else:
+                raise
+
+        if deny is not None:
+            policy = deny.find('policysetting')
+            data = policy.find('data')
+            for listelement in data.findall('listelement'):
+                adobject = listelement.find('adobject')
+                name = adobject.find('name')
+                domain = adobject.find('domain')
+                self.outf.write('-:%s\\%s:ALL\n' % (domain.text, name.text))
+
+class cmd_add_access(Command):
+    """Adds a VGP Host Access Group Policy to the sysvol
+
+This command adds a host access setting to the sysvol for applying to winbind
+clients.
+
+Example:
+samba-tool gpo manage access add {31B2F340-016D-11D2-945F-00C04FB984F9} allow goodguy example.com
+    """
+
+    synopsis = "%prog <gpo> <allow/deny> <cn> <domain> [options]"
+
+    takes_optiongroups = {
+        "sambaopts": options.SambaOptions,
+        "versionopts": options.VersionOptions,
+        "credopts": options.CredentialsOptions,
+    }
+
+    takes_options = [
+        Option("-H", "--URL", help="LDB URL for database or target server", type=str,
+                metavar="URL", dest="H"),
+    ]
+
+    takes_args = ["gpo", "etype", "cn", "domain"]
+
+    def run(self, gpo, etype, cn, domain, H=None, sambaopts=None,
+            credopts=None, versionopts=None):
+        self.lp = sambaopts.get_loadparm()
+        self.creds = credopts.get_credentials(self.lp, fallback_machine=True)
+
+        # We need to know writable DC to setup SMB connection
+        if H and H.startswith('ldap://'):
+            dc_hostname = H[7:]
+            self.url = H
+        else:
+            dc_hostname = netcmd_finddc(self.lp, self.creds)
+            self.url = dc_url(self.lp, self.creds, dc=dc_hostname)
+
+        # SMB connect to DC
+        conn = smb_connection(dc_hostname,
+                              'sysvol',
+                              lp=self.lp,
+                              creds=self.creds)
+
+        realm = self.lp.get('realm')
+        if etype == 'allow':
+            vgp_dir = '\\'.join([realm.lower(), 'Policies', gpo,
+                                 'MACHINE\\VGP\\VTLA\\VAS'
+                                 'HostAccessControl\\Allow'])
+        elif etype == 'deny':
+            vgp_dir = '\\'.join([realm.lower(), 'Policies', gpo,
+                                 'MACHINE\\VGP\\VTLA\\VAS'
+                                 'HostAccessControl\\Deny'])
+        else:
+            raise CommandError("The entry type must be either 'allow' or "
+                               "'deny'. Unknown type '%s'" % etype)
+        vgp_xml = '\\'.join([vgp_dir, 'manifest.xml'])
+        try:
+            xml_data = ET.ElementTree(ET.fromstring(conn.loadfile(vgp_xml)))
+            policy = xml_data.getroot().find('policysetting')
+            data = policy.find('data')
+        except NTSTATUSError as e:
+            # STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_NOT_FOUND,
+            # STATUS_OBJECT_PATH_NOT_FOUND
+            if e.args[0] in [0xC0000033, 0xC0000034, 0xC000003A]:
+                # The file doesn't exist, so create the xml structure
+                xml_data = ET.ElementTree(ET.Element('vgppolicy'))
+                policysetting = ET.SubElement(xml_data.getroot(),
+                                              'policysetting')
+                pv = ET.SubElement(policysetting, 'version')
+                pv.text = '1'
+                name = ET.SubElement(policysetting, 'name')
+                name.text = 'Host Access Control'
+                description = ET.SubElement(policysetting, 'description')
+                description.text = 'Represents host access control data (pam_access)'
+                apply_mode = ET.SubElement(policysetting, 'apply_mode')
+                apply_mode.text = 'merge'
+                data = ET.SubElement(policysetting, 'data')
+            elif e.args[0] == 0xC0000022: # STATUS_ACCESS_DENIED
+                raise CommandError("The authenticated user does "
+                                   "not have sufficient privileges")
+            else:
+                raise
+
+        url = dc_url(self.lp, self.creds, dc=domain)
+        samdb = SamDB(url=url, session_info=system_session(),
+                      credentials=self.creds, lp=self.lp)
+
+        res = samdb.search(base=samdb.domain_dn(),
+                           scope=ldb.SCOPE_SUBTREE,
+                           expression="(cn=%s)" % cn,
+                           attrs=['userPrincipalName',
+                                  'samaccountname',
+                                  'objectClass'])
+        if len(res) == 0:
+            raise CommandError('Unable to find user or group "%s"' % cn)
+
+        objectclass = get_string(res[0]['objectClass'][-1])
+        if objectclass not in ['user', 'group']:
+            raise CommandError('%s is not a user or group' % cn)
+
+        listelement = ET.SubElement(data, 'listelement')
+        etype = ET.SubElement(listelement, 'type')
+        etype.text = objectclass.upper()
+        entry = ET.SubElement(listelement, 'entry')
+        if objectclass == 'user':
+            entry.text = get_string(res[0]['userPrincipalName'][-1])
+        else:
+            groupattr = ET.SubElement(data, 'groupattr')
+            groupattr.text = 'samAccountName'
+            entry.text = '%s\\%s' % (domain,
+                                     get_string(res[0]['samaccountname'][-1]))
+        adobject = ET.SubElement(listelement, 'adobject')
+        name = ET.SubElement(adobject, 'name')
+        name.text = get_string(res[0]['samaccountname'][-1])
+        domain_elm = ET.SubElement(adobject, 'domain')
+        domain_elm.text = domain
+        etype = ET.SubElement(adobject, 'type')
+        etype.text = objectclass
+
+        out = BytesIO()
+        xml_data.write(out, encoding='UTF-8', xml_declaration=True)
+        out.seek(0)
+        try:
+            create_directory_hier(conn, vgp_dir)
+            conn.savefile(vgp_xml, out.read())
+        except NTSTATUSError as e:
+            if e.args[0] == 0xC0000022: # STATUS_ACCESS_DENIED
+                raise CommandError("The authenticated user does "
+                                   "not have sufficient privileges")
+            raise
+
+class cmd_remove_access(Command):
+    """Remove a VGP Host Access Group Policy from the sysvol
+
+This command removes a host access setting from the sysvol for applying to
+winbind clients.
+
+Example:
+samba-tool gpo manage access remove {31B2F340-016D-11D2-945F-00C04FB984F9} allow goodguy example.com
+    """
+
+    synopsis = "%prog <gpo> <allow/deny> <name> <domain> [options]"
+
+    takes_optiongroups = {
+        "sambaopts": options.SambaOptions,
+        "versionopts": options.VersionOptions,
+        "credopts": options.CredentialsOptions,
+    }
+
+    takes_options = [
+        Option("-H", "--URL", help="LDB URL for database or target server", type=str,
+                metavar="URL", dest="H"),
+    ]
+
+    takes_args = ["gpo", "etype", "name", "domain"]
+
+    def run(self, gpo, etype, name, domain, H=None, sambaopts=None,
+            credopts=None, versionopts=None):
+        self.lp = sambaopts.get_loadparm()
+        self.creds = credopts.get_credentials(self.lp, fallback_machine=True)
+
+        # We need to know writable DC to setup SMB connection
+        if H and H.startswith('ldap://'):
+            dc_hostname = H[7:]
+            self.url = H
+        else:
+            dc_hostname = netcmd_finddc(self.lp, self.creds)
+            self.url = dc_url(self.lp, self.creds, dc=dc_hostname)
+
+        # SMB connect to DC
+        conn = smb_connection(dc_hostname,
+                              'sysvol',
+                              lp=self.lp,
+                              creds=self.creds)
+
+        realm = self.lp.get('realm')
+        if etype == 'allow':
+            vgp_dir = '\\'.join([realm.lower(), 'Policies', gpo,
+                                 'MACHINE\\VGP\\VTLA\\VAS'
+                                 'HostAccessControl\\Allow'])
+        elif etype == 'deny':
+            vgp_dir = '\\'.join([realm.lower(), 'Policies', gpo,
+                                 'MACHINE\\VGP\\VTLA\\VAS'
+                                 'HostAccessControl\\Deny'])
+        else:
+            raise CommandError("The entry type must be either 'allow' or "
+                               "'deny'. Unknown type '%s'" % etype)
+        vgp_xml = '\\'.join([vgp_dir, 'manifest.xml'])
+        try:
+            xml_data = ET.ElementTree(ET.fromstring(conn.loadfile(vgp_xml)))
+            policy = xml_data.getroot().find('policysetting')
+            data = policy.find('data')
+        except NTSTATUSError as e:
+            # STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_NOT_FOUND,
+            # STATUS_OBJECT_PATH_NOT_FOUND
+            if e.args[0] in [0xC0000033, 0xC0000034, 0xC000003A]:
+                raise CommandError("Cannot remove %s entry because it does "
+                                   "not exist" % etype)
+            elif e.args[0] == 0xC0000022: # STATUS_ACCESS_DENIED
+                raise CommandError("The authenticated user does "
+                                   "not have sufficient privileges")
+            else:
+                raise
+
+        for listelement in data.findall('listelement'):
+            adobject = listelement.find('adobject')
+            name_elm = adobject.find('name')
+            domain_elm = adobject.find('domain')
+            if name_elm is not None and name_elm.text == name and \
+               domain_elm is not None and domain_elm.text == domain:
+                data.remove(listelement)
+                break
+        else:
+            raise CommandError("Cannot remove %s entry because it does "
+                                   "not exist" % etype)
+
+        out = BytesIO()
+        xml_data.write(out, encoding='UTF-8', xml_declaration=True)
+        out.seek(0)
+        try:
+            create_directory_hier(conn, vgp_dir)
+            conn.savefile(vgp_xml, out.read())
+        except NTSTATUSError as e:
+            if e.args[0] == 0xC0000022: # STATUS_ACCESS_DENIED
+                raise CommandError("The authenticated user does "
+                                   "not have sufficient privileges")
+            raise
+
+class cmd_access(SuperCommand):
+    """Manage Host Access Group Policy Objects"""
+    subcommands = {}
+    subcommands["list"] = cmd_list_access()
+    subcommands["add"] = cmd_add_access()
+    subcommands["remove"] = cmd_remove_access()
+
 class cmd_manage(SuperCommand):
     """Manage Group Policy Objects"""
     subcommands = {}
@@ -3671,6 +4000,7 @@ class cmd_manage(SuperCommand):
     subcommands["scripts"] = cmd_scripts()
     subcommands["motd"] = cmd_motd()
     subcommands["issue"] = cmd_issue()
+    subcommands["access"] = cmd_access()
 
 class cmd_gpo(SuperCommand):
     """Group Policy Object (GPO) management."""
diff --git a/python/samba/tests/gpo.py b/python/samba/tests/gpo.py
index b5d195b0445..e28b117f73a 100644
--- a/python/samba/tests/gpo.py
+++ b/python/samba/tests/gpo.py
@@ -36,6 +36,7 @@ from samba.vgp_openssh_ext import vgp_openssh_ext
 from samba.vgp_startup_scripts_ext import vgp_startup_scripts_ext
 from samba.vgp_motd_ext import vgp_motd_ext
 from samba.vgp_issue_ext import vgp_issue_ext
+from samba.vgp_access_ext import vgp_access_ext
 import logging
 from samba.credentials import Credentials
 from samba.gp_msgs_ext import gp_msgs_ext
@@ -1366,3 +1367,133 @@ class GPOTests(tests.TestCase):
 
         # Unstage the manifest.xml file
         unstage_file(manifest)
+
+    def test_vgp_access(self):
+        local_path = self.lp.cache_path('gpo_cache')
+        guid = '{31B2F340-016D-11D2-945F-00C04FB984F9}'
+        allow = os.path.join(local_path, policies, guid, 'MACHINE',
+            'VGP/VTLA/VAS/HOSTACCESSCONTROL/ALLOW/MANIFEST.XML')
+        deny = os.path.join(local_path, policies, guid, 'MACHINE',
+            'VGP/VTLA/VAS/HOSTACCESSCONTROL/DENY/MANIFEST.XML')
+        logger = logging.getLogger('gpo_tests')
+        cache_dir = self.lp.get('cache directory')
+        store = GPOStorage(os.path.join(cache_dir, 'gpo.tdb'))
+
+        machine_creds = Credentials()
+        machine_creds.guess(self.lp)
+        machine_creds.set_machine_account()
+
+        # Initialize the group policy extension
+        ext = vgp_access_ext(logger, self.lp, machine_creds, store)
+
+        ads = gpo.ADS_STRUCT(self.server, self.lp, machine_creds)
+        if ads.connect():
+            gpos = ads.get_gpo_list(machine_creds.get_username())
+
+        # Stage the manifest.xml allow file
+        stage = etree.Element('vgppolicy')
+        policysetting = etree.SubElement(stage, 'policysetting')
+        version = etree.SubElement(policysetting, 'version')
+        version.text = '2'
+        apply_mode = etree.SubElement(policysetting, 'apply_mode')
+        apply_mode.text = 'merge'
+        data = etree.SubElement(policysetting, 'data')
+        # Add an allowed user
+        listelement = etree.SubElement(data, 'listelement')
+        otype = etree.SubElement(listelement, 'type')
+        otype.text = 'USER'
+        entry = etree.SubElement(listelement, 'entry')
+        entry.text = 'goodguy@%s' % realm
+        adobject = etree.SubElement(listelement, 'adobject')
+        name = etree.SubElement(adobject, 'name')
+        name.text = 'goodguy'
+        domain = etree.SubElement(adobject, 'domain')
+        domain.text = realm
+        otype = etree.SubElement(adobject, 'type')
+        otype.text = 'user'
+        # Add an allowed group
+        groupattr = etree.SubElement(data, 'groupattr')
+        groupattr.text = 'samAccountName'
+        listelement = etree.SubElement(data, 'listelement')
+        otype = etree.SubElement(listelement, 'type')
+        otype.text = 'GROUP'
+        entry = etree.SubElement(listelement, 'entry')
+        entry.text = '%s\\goodguys' % realm
+        dn = etree.SubElement(listelement, 'dn')
+        dn.text = 'CN=goodguys,CN=Users,%s' % base_dn
+        adobject = etree.SubElement(listelement, 'adobject')
+        name = etree.SubElement(adobject, 'name')
+        name.text = 'goodguys'
+        domain = etree.SubElement(adobject, 'domain')
+        domain.text = realm
+        otype = etree.SubElement(adobject, 'type')
+        otype.text = 'group'
+        ret = stage_file(allow, etree.tostring(stage))
+        self.assertTrue(ret, 'Could not create the target %s' % allow)
+
+        # Stage the manifest.xml deny file
+        stage = etree.Element('vgppolicy')
+        policysetting = etree.SubElement(stage, 'policysetting')
+        version = etree.SubElement(policysetting, 'version')
+        version.text = '2'
+        apply_mode = etree.SubElement(policysetting, 'apply_mode')
+        apply_mode.text = 'merge'
+        data = etree.SubElement(policysetting, 'data')
+        # Add a denied user
+        listelement = etree.SubElement(data, 'listelement')
+        otype = etree.SubElement(listelement, 'type')
+        otype.text = 'USER'
+        entry = etree.SubElement(listelement, 'entry')
+        entry.text = 'badguy@%s' % realm
+        adobject = etree.SubElement(listelement, 'adobject')
+        name = etree.SubElement(adobject, 'name')
+        name.text = 'badguy'
+        domain = etree.SubElement(adobject, 'domain')
+        domain.text = realm
+        otype = etree.SubElement(adobject, 'type')
+        otype.text = 'user'
+        # Add a denied group
+        groupattr = etree.SubElement(data, 'groupattr')
+        groupattr.text = 'samAccountName'
+        listelement = etree.SubElement(data, 'listelement')
+        otype = etree.SubElement(listelement, 'type')
+        otype.text = 'GROUP'
+        entry = etree.SubElement(listelement, 'entry')
+        entry.text = '%s\\badguys' % realm
+        dn = etree.SubElement(listelement, 'dn')
+        dn.text = 'CN=badguys,CN=Users,%s' % base_dn
+        adobject = etree.SubElement(listelement, 'adobject')
+        name = etree.SubElement(adobject, 'name')
+        name.text = 'badguys'
+        domain = etree.SubElement(adobject, 'domain')
+        domain.text = realm
+        otype = etree.SubElement(adobject, 'type')
+        otype.text = 'group'
+        ret = stage_file(deny, etree.tostring(stage))
+        self.assertTrue(ret, 'Could not create the target %s' % deny)
+
+        # Process all gpos, with temp output directory
+        with TemporaryDirectory() as dname:
+            ext.process_group_policy([], gpos, dname)
+            conf = os.listdir(dname)
+            self.assertEquals(len(conf), 1, 'The conf file was not created')


-- 
Samba Shared Repository



More information about the samba-cvs mailing list