[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Sun Feb 14 00:54:01 UTC 2021


The branch, master has been updated
       via  09a8f409e59 samba-tool: Replace gpo command for removing Sudoers Group Policy
       via  430e065fa92 samba-tool: Test gpo manage vgp sudoers remove command
       via  30e0ba2ed89 samba-tool: Replace gpo command for adding Sudoers Group Policy
       via  7f3c2b69bef samba-tool: Test VGP sudoers add command
       via  777173923c3 samba-tool: Replace gpo command for listing Sudoers Group Policy
       via  ca60a0cb175 samba-tool: Test gpo manage vgp sudoers list command
       via  35cf85d2134 gpo: VGP Sudoers policy must handle group principals
       via  7c2f2d31c39 gpo: Test that VGP Sudoers policy handles group principals
      from  d05ecd26b94 vfs: update status of SMB_VFS_READLINKAT()

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


- Log -----------------------------------------------------------------
commit 09a8f409e598e94e3595843c52912b6906c73a84
Author: David Mulder <dmulder at suse.com>
Date:   Wed Dec 23 08:09:32 2020 -0700

    samba-tool: Replace gpo command for removing Sudoers Group Policy
    
    Replace it with the VGP command for removing
    sudoers entries from an xml file.
    
    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): Sun Feb 14 00:53:41 UTC 2021 on sn-devel-184

commit 430e065fa92b742c2ba7eb5f55f1da54678a3a2c
Author: David Mulder <dmulder at suse.com>
Date:   Tue Dec 22 15:36:59 2020 -0700

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

commit 30e0ba2ed893d53f2dd4c64a03e4a55c942095f4
Author: David Mulder <dmulder at suse.com>
Date:   Tue Dec 22 13:34:19 2020 -0700

    samba-tool: Replace gpo command for adding Sudoers Group Policy
    
    Replace it with the VGP command for adding
    sudoers entries in an xml file.
    
    Signed-off-by: David Mulder <dmulder at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 7f3c2b69befb60fc18586d4dc1bd941c220fc6da
Author: David Mulder <dmulder at suse.com>
Date:   Tue Dec 22 11:23:34 2020 -0700

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

commit 777173923c3fafcddf4516f13434924707ef8bc7
Author: David Mulder <dmulder at suse.com>
Date:   Mon Dec 21 14:57:27 2020 -0700

    samba-tool: Replace gpo command for listing Sudoers Group Policy
    
    Replace it with the VGP command for listing
    sudoers entries in an xml file.
    
    Signed-off-by: David Mulder <dmulder at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit ca60a0cb1751788d8cc688ad70f690ad099b2193
Author: David Mulder <dmulder at suse.com>
Date:   Mon Dec 21 13:14:41 2020 -0700

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

commit 35cf85d213418f8f153306dd2d3f1207b959d122
Author: David Mulder <dmulder at suse.com>
Date:   Mon Dec 21 16:48:55 2020 -0700

    gpo: VGP Sudoers policy must handle group principals
    
    Signed-off-by: David Mulder <dmulder at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 7c2f2d31c396e18ccce326ad3f5619619973738d
Author: David Mulder <dmulder at suse.com>
Date:   Mon Dec 21 16:47:51 2020 -0700

    gpo: Test that VGP Sudoers policy handles group principals
    
    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           | 157 ++++++++++++++++++++++++++---------
 python/samba/tests/gpo.py            |   6 +-
 python/samba/tests/samba_tool/gpo.py | 121 ++++++++++++++-------------
 python/samba/vgp_sudoers_ext.py      |  18 +++-
 5 files changed, 217 insertions(+), 100 deletions(-)


Changeset truncated at 500 lines:

diff --git a/docs-xml/manpages/samba-tool.8.xml b/docs-xml/manpages/samba-tool.8.xml
index ea1f5f8d0e7..e7ac7dd625a 100644
--- a/docs-xml/manpages/samba-tool.8.xml
+++ b/docs-xml/manpages/samba-tool.8.xml
@@ -924,6 +924,21 @@
 	<para>Sets a VGP OpenSSH Group Policy to the sysvol</para>
 </refsect3>
 
+<refsect3>
+	<title>gpo manage sudoers add</title>
+	<para>Adds a Samba Sudoers Group Policy to the sysvol.</para>
+</refsect3>
+
+<refsect3>
+	<title>gpo manage sudoers list</title>
+	<para>List Samba Sudoers Group Policy from the sysvol.</para>
+</refsect3>
+
+<refsect3>
+	<title>gpo manage sudoers remove</title>
+	<para>Removes a Samba Sudoers 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 33069200a44..24ecf664ecf 100644
--- a/python/samba/netcmd/gpo.py
+++ b/python/samba/netcmd/gpo.py
@@ -1674,11 +1674,22 @@ class cmd_add_sudoers(Command):
 
 This command adds a sudo rule to the sysvol for applying to winbind clients.
 
+The command argument indicates the final field in the sudo rule.
+The user argument indicates the user specified in the parentheses.
+The users and groups arguments are comma separated lists, which are combined to
+form the first field in the sudo rule.
+The --passwd argument specifies whether the sudo entry will require a password
+be specified. The default is False, meaning the NOPASSWD field will be
+specified in the sudo entry.
+
 Example:
-samba-tool gpo manage sudoers add {31B2F340-016D-11D2-945F-00C04FB984F9} 'fakeu ALL=(ALL) NOPASSWD: ALL'
+samba-tool gpo manage sudoers add {31B2F340-016D-11D2-945F-00C04FB984F9} ALL ALL fakeu fakeg
+
+The example command will generate the following sudoers entry:
+fakeu,fakeg% ALL=(ALL) NOPASSWD: ALL
     """
 
-    synopsis = "%prog <gpo> <entry> [options]"
+    synopsis = "%prog <gpo> <command> <user> <users> [groups] [options]"
 
     takes_optiongroups = {
         "sambaopts": options.SambaOptions,
@@ -1689,11 +1700,14 @@ samba-tool gpo manage sudoers add {31B2F340-016D-11D2-945F-00C04FB984F9} 'fakeu
     takes_options = [
         Option("-H", "--URL", help="LDB URL for database or target server", type=str,
                 metavar="URL", dest="H"),
+        Option("--passwd", action='store_true', default=False,
+               help="Specify to indicate that sudo entry must provide a password")
     ]
 
-    takes_args = ["gpo", "entry"]
+    takes_args = ["gpo", "command", "user", "users", "groups?"]
 
-    def run(self, gpo, entry, H=None, sambaopts=None, credopts=None, versionopts=None):
+    def run(self, gpo, command, user, users, groups=None, passwd=None,
+            H=None, sambaopts=None, credopts=None, versionopts=None):
         self.lp = sambaopts.get_loadparm()
         self.creds = credopts.get_credentials(self.lp, fallback_machine=True)
 
@@ -1712,33 +1726,63 @@ samba-tool gpo manage sudoers add {31B2F340-016D-11D2-945F-00C04FB984F9} 'fakeu
                               creds=self.creds)
 
         realm = self.lp.get('realm')
-        pol_dir = '\\'.join([realm.lower(), 'Policies', gpo, 'MACHINE'])
-        pol_file = '\\'.join([pol_dir, 'Registry.pol'])
+        vgp_dir = '\\'.join([realm.lower(), 'Policies', gpo,
+                             'MACHINE\\VGP\\VTLA\\Sudo',
+                             'SudoersConfiguration'])
+        vgp_xml = '\\'.join([vgp_dir, 'manifest.xml'])
         try:
-            pol_data = ndr_unpack(preg.file, conn.loadfile(pol_file))
+            xml_data = ET.ElementTree(ET.fromstring(conn.loadfile(vgp_xml)))
+            policysetting = xml_data.getroot().find('policysetting')
+            data = policysetting.find('data')
         except NTSTATUSError as e:
-            # STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_NOT_FOUND
-            if e.args[0] in [0xC0000033, 0xC0000034]:
-                pol_data = preg.file() # The file doesn't exist
+            # 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 = 'Sudo Policy'
+                description = ET.SubElement(policysetting, 'description')
+                description.text = 'Sudoers File Configuration Policy'
+                apply_mode = ET.SubElement(policysetting, 'apply_mode')
+                apply_mode.text = 'merge'
+                data = ET.SubElement(policysetting, 'data')
+                load_plugin = ET.SubElement(data, 'load_plugin')
+                load_plugin.text = 'true'
             elif e.args[0] == 0xC0000022: # STATUS_ACCESS_DENIED
                 raise CommandError("The authenticated user does "
                                    "not have sufficient privileges")
             else:
                 raise
 
-        e = preg.entry()
-        e.keyname = b'Software\\Policies\\Samba\\Unix Settings\\Sudo Rights'
-        e.valuename = b'Software\\Policies\\Samba\\Unix Settings'
-        e.type = 1
-        e.data = get_bytes(entry)
-        entries = list(pol_data.entries)
-        entries.append(e)
-        pol_data.entries = entries
-        pol_data.num_entries = len(entries)
+        sudoers_entry = ET.SubElement(data, 'sudoers_entry')
+        if passwd:
+            ET.SubElement(sudoers_entry, 'password')
+        command_elm = ET.SubElement(sudoers_entry, 'command')
+        command_elm.text = command
+        user_elm = ET.SubElement(sudoers_entry, 'user')
+        user_elm.text = user
+        listelement = ET.SubElement(sudoers_entry, 'listelement')
+        for u in users.split(','):
+            principal = ET.SubElement(listelement, 'principal')
+            principal.text = u
+            principal.attrib['type'] = 'user'
+        if groups is not None:
+            for g in groups.split():
+                principal = ET.SubElement(listelement, 'principal')
+                principal.text = g
+                principal.attrib['type'] = 'group'
 
+        out = BytesIO()
+        xml_data.write(out, encoding='UTF-8', xml_declaration=True)
+        out.seek(0)
         try:
-            create_directory_hier(conn, pol_dir)
-            conn.savefile(pol_file, ndr_pack(pol_data))
+            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 "
@@ -1788,22 +1832,36 @@ samba-tool gpo manage sudoers list {31B2F340-016D-11D2-945F-00C04FB984F9}
                               creds=self.creds)
 
         realm = self.lp.get('realm')
-        pol_file = '\\'.join([realm.lower(), 'Policies', gpo,
-                                'MACHINE\\Registry.pol'])
+        vgp_xml = '\\'.join([realm.lower(), 'Policies', gpo,
+                                'MACHINE\\VGP\\VTLA\\Sudo',
+                                'SudoersConfiguration\\manifest.xml'])
         try:
-            pol_data = ndr_unpack(preg.file, conn.loadfile(pol_file))
+            xml_data = ET.fromstring(conn.loadfile(vgp_xml))
         except NTSTATUSError as e:
-            if e.args[0] == 0xC0000033: # STATUS_OBJECT_NAME_INVALID
+            # STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_NOT_FOUND,
+            # STATUS_OBJECT_PATH_NOT_FOUND
+            if e.args[0] in [0xC0000033, 0xC0000034, 0xC000003A]:
                 return # The file doesn't exist, so there is nothing to list
             if e.args[0] == 0xC0000022: # STATUS_ACCESS_DENIED
                 raise CommandError("The authenticated user does "
                                    "not have sufficient privileges")
             raise
 
-        keyname = b'Software\\Policies\\Samba\\Unix Settings\\Sudo Rights'
-        for entry in pol_data.entries:
-            if get_bytes(entry.keyname) == keyname:
-                self.outf.write('%s\n' % entry.data)
+        policy = xml_data.find('policysetting')
+        data = policy.find('data')
+        for entry in data.findall('sudoers_entry'):
+            command = entry.find('command').text
+            user = entry.find('user').text
+            principals = entry.find('listelement').findall('principal')
+            if len(principals) > 0:
+                uname = ','.join([u.text if u.attrib['type'] == 'user' \
+                    else '%s%%' % u.text for u in principals])
+            else:
+                uname = 'ALL'
+            nopassword = entry.find('password') == None
+            np_entry = ' NOPASSWD:' if nopassword else ''
+            p = '%s ALL=(%s)%s %s' % (uname, user, np_entry, command)
+            self.outf.write('%s\n' % p)
 
 class cmd_remove_sudoers(Command):
     """Removes a Samba Sudoers Group Policy from the sysvol
@@ -1848,28 +1906,51 @@ samba-tool gpo manage sudoers remove {31B2F340-016D-11D2-945F-00C04FB984F9} 'fak
                               creds=self.creds)
 
         realm = self.lp.get('realm')
-        pol_file = '\\'.join([realm.lower(), 'Policies', gpo,
-                                'MACHINE\\Registry.pol'])
+        vgp_dir = '\\'.join([realm.lower(), 'Policies', gpo,
+                             'MACHINE\\VGP\\VTLA\\Sudo',
+                             'SudoersConfiguration'])
+        vgp_xml = '\\'.join([vgp_dir, 'manifest.xml'])
         try:
-            pol_data = ndr_unpack(preg.file, conn.loadfile(pol_file))
+            xml_data = ET.ElementTree(ET.fromstring(conn.loadfile(vgp_xml)))
+            policysetting = xml_data.getroot().find('policysetting')
+            data = policysetting.find('data')
         except NTSTATUSError as e:
-            if e.args[0] == 0xC0000033: # STATUS_OBJECT_NAME_INVALID
+            # STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_NOT_FOUND,
+            # STATUS_OBJECT_PATH_NOT_FOUND
+            if e.args[0] in [0xC0000033, 0xC0000034, 0xC000003A]:
                 raise CommandError("The specified entry does not exist")
             elif e.args[0] == 0xC0000022: # STATUS_ACCESS_DENIED
                 raise CommandError("The authenticated user does "
                                    "not have sufficient privileges")
             raise
 
-        if entry not in [e.data for e in pol_data.entries]:
+        entries = {}
+        for e in data.findall('sudoers_entry'):
+            command = e.find('command').text
+            user = e.find('user').text
+            principals = e.find('listelement').findall('principal')
+            if len(principals) > 0:
+                uname = ','.join([u.text if u.attrib['type'] == 'user' \
+                    else '%s%%' % u.text for u in principals])
+            else:
+                uname = 'ALL'
+            nopassword = e.find('password') == None
+            np_entry = ' NOPASSWD:' if nopassword else ''
+            p = '%s ALL=(%s)%s %s' % (uname, user, np_entry, command)
+            entries[p] = e
+
+        if entry not in entries.keys():
             raise CommandError("Cannot remove '%s' because it does not exist" %
                                 entry)
 
-        entries = [e for e in pol_data.entries if e.data != entry]
-        pol_data.num_entries = len(entries)
-        pol_data.entries = entries
+        data.remove(entries[entry])
 
+        out = BytesIO()
+        xml_data.write(out, encoding='UTF-8', xml_declaration=True)
+        out.seek(0)
         try:
-            conn.savefile(pol_file, ndr_pack(pol_data))
+            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 "
diff --git a/python/samba/tests/gpo.py b/python/samba/tests/gpo.py
index ba0e91bde79..e3b500868ec 100644
--- a/python/samba/tests/gpo.py
+++ b/python/samba/tests/gpo.py
@@ -484,7 +484,11 @@ class GPOTests(tests.TestCase):
         principal = etree.Element('principal')
         principal.text = 'fakeu'
         principal.attrib['type'] = 'user'
+        group = etree.Element('principal')
+        group.text = 'fakeg'
+        group.attrib['type'] = 'group'
         principal_list.append(principal)
+        principal_list.append(group)
         sudoers_entry.append(principal_list)
         data.append(sudoers_entry)
         policysetting.append(data)
@@ -492,7 +496,7 @@ class GPOTests(tests.TestCase):
         self.assertTrue(ret, 'Could not create the target %s' % manifest)
 
         # Process all gpos, with temp output directory
-        data = 'fakeu ALL=(ALL) NOPASSWD: ALL'
+        data = 'fakeu,fakeg% ALL=(ALL) NOPASSWD: ALL'
         with TemporaryDirectory() as dname:
             ext.process_group_policy([], gpos, dname)
             sudoers = os.listdir(dname)
diff --git a/python/samba/tests/samba_tool/gpo.py b/python/samba/tests/samba_tool/gpo.py
index 588c63a703c..c57c6786d79 100644
--- a/python/samba/tests/samba_tool/gpo.py
+++ b/python/samba/tests/samba_tool/gpo.py
@@ -727,28 +727,32 @@ class GpoCmdTestCase(SambaToolCmdTest):
 
         self.assertFalse(inf_data.has_section('Kerberos Policy'))
 
-    def test_sudoers_remove(self):
-        lp = LoadParm()
-        lp.load(os.environ['SERVERCONFFILE'])
-        local_path = lp.get('path', 'sysvol')
-        reg_pol = os.path.join(local_path, lp.get('realm').lower(), 'Policies',
-                               self.gpo_guid, 'Machine/Registry.pol')
+    def test_sudoers_add(self):
+        (result, out, err) = self.runsublevelcmd("gpo", ("manage",
+                                                 "sudoers", "add"),
+                                                 self.gpo_guid, 'ALL', 'ALL',
+                                                 'fakeu', 'fakeg', "-H",
+                                                 "ldap://%s" %
+                                                 os.environ["SERVER"],
+                                                 "-U%s%%%s" %
+                                                 (os.environ["USERNAME"],
+                                                 os.environ["PASSWORD"]))
+        self.assertCmdSuccess(result, out, err, 'Sudoers add failed')
 
-        # Stage the Registry.pol file with test data
-        stage = preg.file()
-        e = preg.entry()
-        e.keyname = b'Software\\Policies\\Samba\\Unix Settings\\Sudo Rights'
-        e.valuename = b'Software\\Policies\\Samba\\Unix Settings'
-        e.type = 1
-        e.data = b'fakeu  ALL=(ALL) NOPASSWD: ALL'
-        stage.num_entries = 1
-        stage.entries = [e]
-        ret = stage_file(reg_pol, ndr_pack(stage))
-        self.assertTrue(ret, 'Could not create the target %s' % reg_pol)
+        sudoer = 'fakeu,fakeg% ALL=(ALL) NOPASSWD: ALL'
+        (result, out, err) = self.runsublevelcmd("gpo", ("manage",
+                                                 "sudoers", "list"),
+                                                 self.gpo_guid, "-H",
+                                                 "ldap://%s" %
+                                                 os.environ["SERVER"],
+                                                 "-U%s%%%s" %
+                                                 (os.environ["USERNAME"],
+                                                 os.environ["PASSWORD"]))
+        self.assertIn(sudoer, out, 'The test entry was not found!')
 
-        (result, out, err) = self.runsublevelcmd("gpo", ("manage", "sudoers",
-                                                 "remove"), self.gpo_guid,
-                                                 get_string(e.data),
+        (result, out, err) = self.runsublevelcmd("gpo", ("manage",
+                                                 "sudoers", "remove"),
+                                                 self.gpo_guid, sudoer,
                                                  "-H", "ldap://%s" %
                                                  os.environ["SERVER"],
                                                  "-U%s%%%s" %
@@ -756,59 +760,62 @@ class GpoCmdTestCase(SambaToolCmdTest):
                                                  os.environ["PASSWORD"]))
         self.assertCmdSuccess(result, out, err, 'Sudoers remove failed')
 
-    def test_sudoers_add(self):
-        lp = LoadParm()
-        lp.load(os.environ['SERVERCONFFILE'])
-        local_path = lp.get('path', 'sysvol')
-        reg_pol = os.path.join(local_path, lp.get('realm').lower(), 'Policies',
-                               self.gpo_guid, 'Machine/Registry.pol')
-
-        entry = 'fakeu  ALL=(ALL) NOPASSWD: ALL'
-        (result, out, err) = self.runsublevelcmd("gpo", ("manage", "sudoers",
-                                                 "add"), self.gpo_guid, entry,
-                                                 "-H", "ldap://%s" %
+        (result, out, err) = self.runsublevelcmd("gpo", ("manage",
+                                                 "sudoers", "list"),
+                                                 self.gpo_guid, "-H",
+                                                 "ldap://%s" %
                                                  os.environ["SERVER"],
                                                  "-U%s%%%s" %
                                                  (os.environ["USERNAME"],
                                                  os.environ["PASSWORD"]))
-        self.assertCmdSuccess(result, out, err, 'Sudoers add failed')
-
-        self.assertTrue(os.path.exists(reg_pol),
-                        'The Registry.pol does not exist')
-        reg_data = ndr_unpack(preg.file, open(reg_pol, 'rb').read())
-        self.assertTrue(any([get_string(e.data) == entry for e in reg_data.entries]),
-                        'The sudoers entry was not added')
+        self.assertNotIn(sudoer, out, 'The test entry was still found!')
 
     def test_sudoers_list(self):
         lp = LoadParm()
         lp.load(os.environ['SERVERCONFFILE'])
         local_path = lp.get('path', 'sysvol')
-        reg_pol = os.path.join(local_path, lp.get('realm').lower(), 'Policies',
-                               self.gpo_guid, 'Machine/Registry.pol')
+        vgp_xml = os.path.join(local_path, lp.get('realm').lower(), 'Policies',
+                               self.gpo_guid, 'Machine/VGP/VTLA/Sudo',
+                               'SudoersConfiguration/manifest.xml')
 
-        # Stage the Registry.pol file with test data
-        stage = preg.file()
-        e = preg.entry()
-        e.keyname = b'Software\\Policies\\Samba\\Unix Settings\\Sudo Rights'
-        e.valuename = b'Software\\Policies\\Samba\\Unix Settings'
-        e.type = 1
-        e.data = b'fakeu  ALL=(ALL) NOPASSWD: ALL'
-        stage.num_entries = 1
-        stage.entries = [e]
-        ret = stage_file(reg_pol, ndr_pack(stage))
-        self.assertTrue(ret, 'Could not create the target %s' % reg_pol)
+        stage = etree.Element('vgppolicy')
+        policysetting = etree.SubElement(stage, 'policysetting')
+        pv = etree.SubElement(policysetting, 'version')
+        pv.text = '1'
+        name = etree.SubElement(policysetting, 'name')
+        name.text = 'Sudo Policy'
+        description = etree.SubElement(policysetting, 'description')
+        description.text = 'Sudoers File Configuration Policy'
+        apply_mode = etree.SubElement(policysetting, 'apply_mode')
+        apply_mode.text = 'merge'
+        data = etree.SubElement(policysetting, 'data')
+        load_plugin = etree.SubElement(data, 'load_plugin')
+        load_plugin.text = 'true'
+        sudoers_entry = etree.SubElement(data, 'sudoers_entry')
+        command = etree.SubElement(sudoers_entry, 'command')
+        command.text = 'ALL'
+        user = etree.SubElement(sudoers_entry, 'user')
+        user.text = 'ALL'
+        listelement = etree.SubElement(sudoers_entry, 'listelement')
+        principal = etree.SubElement(listelement, 'principal')
+        principal.text = 'fakeu'
+        principal.attrib['type'] = 'user'
+        ret = stage_file(vgp_xml, etree.tostring(stage, 'utf-8'))
+        self.assertTrue(ret, 'Could not create the target %s' % vgp_xml)
 
-        (result, out, err) = self.runsublevelcmd("gpo", ("manage", "sudoers",
-                                                 "list"), self.gpo_guid,
-                                                 "-H", "ldap://%s" %
+        sudoer = 'fakeu ALL=(ALL) NOPASSWD: ALL'
+        (result, out, err) = self.runsublevelcmd("gpo", ("manage",
+                                                 "sudoers", "list"),
+                                                 self.gpo_guid, "-H",
+                                                 "ldap://%s" %
                                                  os.environ["SERVER"],
                                                  "-U%s%%%s" %
                                                  (os.environ["USERNAME"],
                                                  os.environ["PASSWORD"]))
-        self.assertIn(e.data, out, 'The test entry was not found!')
+        self.assertIn(sudoer, out, 'The test entry was not found!')
 
-        # Unstage the Registry.pol file
-        unstage_file(reg_pol)
+        # Unstage the manifest.xml file
+        unstage_file(vgp_xml)
 
     def test_symlink_list(self):
         lp = LoadParm()
diff --git a/python/samba/vgp_sudoers_ext.py b/python/samba/vgp_sudoers_ext.py
index 278f3558cc2..573ec9fb4d1 100644
--- a/python/samba/vgp_sudoers_ext.py
+++ b/python/samba/vgp_sudoers_ext.py
@@ -49,10 +49,15 @@ class vgp_sudoers_ext(gp_xml_ext):
                 for entry in data.findall('sudoers_entry'):
                     command = entry.find('command').text
                     user = entry.find('user').text
-                    principals = [p.text for p in entry.find('listelement').findall('principal')]
+                    principals = entry.find('listelement').findall('principal')
+                    if len(principals) > 0:
+                        uname = ','.join([u.text if u.attrib['type'] == 'user' \
+                            else '%s%%' % u.text for u in principals])
+                    else:
+                        uname = 'ALL'
                     nopassword = entry.find('password') == None
                     np_entry = ' NOPASSWD:' if nopassword else ''
-                    p = '%s ALL=(%s)%s %s' % (','.join(principals), user, np_entry, command)
+                    p = '%s ALL=(%s)%s %s' % (uname, user, np_entry, command)
                     attribute = b64encode(p.encode()).decode()
                     old_val = self.gp_db.retrieve(str(self), attribute)
                     if not old_val:
@@ -91,10 +96,15 @@ class vgp_sudoers_ext(gp_xml_ext):
             for entry in data.findall('sudoers_entry'):
                 command = entry.find('command').text
                 user = entry.find('user').text
-                principals = [p.text for p in entry.find('listelement').findall('principal')]
+                principals = entry.find('listelement').findall('principal')
+                if len(principals) > 0:
+                    uname = ','.join([u.text if u.attrib['type'] == 'user' \
+                        else '%s%%' % u.text for u in principals])
+                else:
+                    uname = 'ALL'
                 nopassword = entry.find('password') == None
                 np_entry = ' NOPASSWD:' if nopassword else ''
-                p = '%s ALL=(%s)%s %s' % (','.join(principals), user, np_entry, command)
+                p = '%s ALL=(%s)%s %s' % (uname, user, np_entry, command)
                 if str(self) not in output.keys():
                     output[str(self)] = []
                 output[str(self)].append(p)


-- 
Samba Shared Repository



More information about the samba-cvs mailing list