[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Wed Dec 21 03:06:01 UTC 2022


The branch, master has been updated
       via  94b70d1ed92 gp: Don't hide managed/recommended directories
       via  0a1778cde01 gp: Ensure rsop is tested for every CSE
       via  c435c105c51 gp: Fix rsop when final value isn't a str
       via  74598eeef72 gp: Enable gpupdate output when testing
       via  6710c50f540 gp: Ensure policy changes don't leave files behind
       via  e6156b13502 gp: Re-create files if manually removed
       via  d170d8cfbb4 gp: Test that files are re-created if manually removed
       via  5037d402a54 gp: Modify Chromium CSE to use new files applier
       via  f36542b50c7 gp: Modify Cert Auto Enroll CSE to use new applier
       via  acdc7fbe898 gp: Modify Centrify Crontab compatible CSE to use new files applier
       via  f20ca1a7db2 gp: Modify Startup Scripts CSE to use new files applier
       via  fb512e06803 gp: Modify GNOME Settings CSE to use new files applier
       via  f3e24a325ea gp: Modify Machine Scripts CSE to use new files applier
       via  64f4930dc0d gp: Modify Files CSE to use new files applier
       via  2953329ba07 gp: Modify Sudoers CSEs to use new files applier
       via  81dbcae9dfb gp: Modify OpenSSH CSE to use new files applier
       via  50f4c3d44e1 gp: Modify PAM Access CSE to use new files applier
       via  3f7105894c1 gp: Modify Symlink CSE to use new files applier
       via  5715281918f gp: Implement appliers for monitoring policy changes
      from  5b19288949e s3:params:lp_do_section - protect against NULL deref

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


- Log -----------------------------------------------------------------
commit 94b70d1ed92a6fac4a679ccc959c63c49d918349
Author: David Mulder <dmulder at samba.org>
Date:   Mon Dec 12 10:05:16 2022 -0700

    gp: Don't hide managed/recommended directories
    
    Making these variables hidden prevents the parent
    class gp_chromium_ext from reading them when
    subclassed in gp_chrome_ext. This caused the
    chrome policies to be installed in the chromium
    directories.
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Wed Dec 21 03:05:46 UTC 2022 on sn-devel-184

commit 0a1778cde011fecb000f5b7e6f43920f5ab59da0
Author: David Mulder <dmulder at samba.org>
Date:   Fri Dec 9 10:31:49 2022 -0700

    gp: Ensure rsop is tested for every CSE
    
    A bug cropped up in the rsop that was causing a
    crash because this wasn't being tested.
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit c435c105c511bd984b6d1bda3964100ad5ec2c31
Author: David Mulder <dmulder at samba.org>
Date:   Fri Dec 9 09:40:34 2022 -0700

    gp: Fix rsop when final value isn't a str
    
    The output must be a string value, or it will
    crash. Chromium policies output integers, which
    was causing the parser to crash.
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 74598eeef72e6b260393df7451c957d7fde1f59a
Author: David Mulder <dmulder at samba.org>
Date:   Thu Dec 8 15:15:15 2022 -0700

    gp: Enable gpupdate output when testing
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 6710c50f54025d8174aacd17515d58ff50e6d28a
Author: David Mulder <dmulder at samba.org>
Date:   Wed Dec 7 10:17:38 2022 -0700

    gp: Ensure policy changes don't leave files behind
    
    This test exercises the gp_file_applier and
    ensures that when a policy is modified, no old
    policy is left behind.
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit e6156b135021db5a6335bb8779acefff2f6a0bd3
Author: David Mulder <dmulder at samba.org>
Date:   Wed Dec 7 09:51:12 2022 -0700

    gp: Re-create files if manually removed
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit d170d8cfbb4571af8b66f1dcd7355a598b0abd1f
Author: David Mulder <dmulder at samba.org>
Date:   Wed Dec 7 09:49:53 2022 -0700

    gp: Test that files are re-created if manually removed
    
    Currently applied files which are manually
    removed do not get re-applied.
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 5037d402a54a0010382cc7825e6fba4322ba18b4
Author: David Mulder <dmulder at samba.org>
Date:   Tue Dec 6 11:12:34 2022 -0700

    gp: Modify Chromium CSE to use new files applier
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit f36542b50c70de74144b9e2e94e91944e8536421
Author: David Mulder <dmulder at samba.org>
Date:   Tue Dec 6 08:56:24 2022 -0700

    gp: Modify Cert Auto Enroll CSE to use new applier
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit acdc7fbe8985a16d41075b72f54a96f217c3f884
Author: David Mulder <dmulder at samba.org>
Date:   Mon Dec 5 10:41:27 2022 -0700

    gp: Modify Centrify Crontab compatible CSE to use new files applier
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit f20ca1a7db29ec2ccf3ef5de58a578aa7dfc4964
Author: David Mulder <dmulder at samba.org>
Date:   Fri Dec 2 15:42:58 2022 -0700

    gp: Modify Startup Scripts CSE to use new files applier
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit fb512e068033b49b7e8bc6baa6040b032d6b99c1
Author: David Mulder <dmulder at samba.org>
Date:   Fri Dec 2 14:51:27 2022 -0700

    gp: Modify GNOME Settings CSE to use new files applier
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit f3e24a325ea6d2d574f42f0e7f9f1e1fb040366c
Author: David Mulder <dmulder at samba.org>
Date:   Tue Nov 29 14:01:13 2022 -0700

    gp: Modify Machine Scripts CSE to use new files applier
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 64f4930dc0d46c21fefd8a798534b58670036faa
Author: David Mulder <dmulder at samba.org>
Date:   Tue Nov 29 08:04:35 2022 -0700

    gp: Modify Files CSE to use new files applier
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 2953329ba07cb7de6c8df1718779b7c9045d3910
Author: David Mulder <dmulder at samba.org>
Date:   Mon Nov 28 13:37:52 2022 -0700

    gp: Modify Sudoers CSEs to use new files applier
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 81dbcae9dfba2f2dd7b5e7e04f9ababca02ed49b
Author: David Mulder <dmulder at samba.org>
Date:   Fri Nov 18 15:03:41 2022 -0700

    gp: Modify OpenSSH CSE to use new files applier
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 50f4c3d44e1c99210e754c5aeff85f7c9ac9ed2b
Author: David Mulder <dmulder at samba.org>
Date:   Fri Nov 18 14:22:17 2022 -0700

    gp: Modify PAM Access CSE to use new files applier
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 3f7105894c1b65cb4b26702d1111a9fb35bb561c
Author: David Mulder <dmulder at samba.org>
Date:   Fri Nov 18 14:04:13 2022 -0700

    gp: Modify Symlink CSE to use new files applier
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 5715281918fc10a4840f682a9c314e0e0ae84ee3
Author: David Mulder <dmulder at samba.org>
Date:   Fri Nov 18 13:59:32 2022 -0700

    gp: Implement appliers for monitoring policy changes
    
    This is currently a significant drawback of Samba
    Group Policy. CSEs MUST be aware of policy changes
    such as modification, removal, etc. This is a
    complex process, and is easy to mess up. Here I
    add 'appliers' (the first being for files), which
    handle the complexty transparently to ensure this
    is done correctly.
    
    Signed-off-by: David Mulder <dmulder at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

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

Summary of changes:
 python/samba/gp/gp_centrify_crontab_ext.py |   38 +-
 python/samba/gp/gp_centrify_sudoers_ext.py |   51 +-
 python/samba/gp/gp_cert_auto_enroll_ext.py |  114 +-
 python/samba/gp/gp_chromium_ext.py         |  132 +-
 python/samba/gp/gp_gnome_settings_ext.py   |  176 +--
 python/samba/gp/gp_scripts_ext.py          |   54 +-
 python/samba/gp/gp_sudoers_ext.py          |   69 +-
 python/samba/gp/gpclass.py                 |  212 ++-
 python/samba/gp/vgp_access_ext.py          |   48 +-
 python/samba/gp/vgp_files_ext.py           |   54 +-
 python/samba/gp/vgp_openssh_ext.py         |   48 +-
 python/samba/gp/vgp_startup_scripts_ext.py |   53 +-
 python/samba/gp/vgp_sudoers_ext.py         |   51 +-
 python/samba/gp/vgp_symlink_ext.py         |   28 +-
 python/samba/tests/gpo.py                  | 2266 ++--------------------------
 15 files changed, 812 insertions(+), 2582 deletions(-)


Changeset truncated at 500 lines:

diff --git a/python/samba/gp/gp_centrify_crontab_ext.py b/python/samba/gp/gp_centrify_crontab_ext.py
index 220feb776a5..414cd90aaf7 100644
--- a/python/samba/gp/gp_centrify_crontab_ext.py
+++ b/python/samba/gp/gp_centrify_crontab_ext.py
@@ -16,7 +16,7 @@
 
 import os, re
 from subprocess import Popen, PIPE
-from samba.gp.gpclass import gp_pol_ext, drop_privileges
+from samba.gp.gpclass import gp_pol_ext, drop_privileges, gp_file_applier
 from hashlib import blake2b
 from tempfile import NamedTemporaryFile
 
@@ -34,43 +34,47 @@ end = '''
 ### autogenerated by samba ###
 '''
 
-class gp_centrify_crontab_ext(gp_pol_ext):
+class gp_centrify_crontab_ext(gp_pol_ext, gp_file_applier):
     def __str__(self):
         return 'Centrify/CrontabEntries'
 
     def process_group_policy(self, deleted_gpo_list, changed_gpo_list,
                              cdir=None):
         for guid, settings in deleted_gpo_list:
-            self.gp_db.set_guid(guid)
             if str(self) in settings:
                 for attribute, script in settings[str(self)].items():
-                    if os.path.exists(script):
-                        os.unlink(script)
-                    self.gp_db.delete(str(self), attribute)
-            self.gp_db.commit()
+                    self.unapply(guid, attribute, script)
 
         for gpo in changed_gpo_list:
             if gpo.file_sys_path:
                 section = \
                     'Software\\Policies\\Centrify\\UnixSettings\\CrontabEntries'
-                self.gp_db.set_guid(gpo.name)
                 pol_file = 'MACHINE/Registry.pol'
                 path = os.path.join(gpo.file_sys_path, pol_file)
                 pol_conf = self.parse(path)
                 if not pol_conf:
                     continue
+                entries = []
                 for e in pol_conf.entries:
                     if e.keyname == section and e.data.strip():
                         cron_dir = '/etc/cron.d' if not cdir else cdir
-                        attribute = blake2b(e.data.encode()).hexdigest()
-                        old_val = self.gp_db.retrieve(str(self), attribute)
-                        if not old_val:
-                            with NamedTemporaryFile(prefix='gp_', mode="w+",
-                                    delete=False, dir=cron_dir) as f:
-                                contents = '%s\n%s\n%s' % (intro, e.data, end)
-                                f.write(contents)
-                                self.gp_db.store(str(self), attribute, f.name)
-                        self.gp_db.commit()
+                        entries.append(e.data)
+                def applier_func(entries):
+                    with NamedTemporaryFile(prefix='gp_', mode="w+",
+                            delete=False, dir=cron_dir) as f:
+                        contents = intro
+                        for entry in entries:
+                            contents += '%s\n' % entry
+                        contents += end
+                        f.write(contents)
+                        return [f.name]
+                attribute = self.generate_attribute(gpo.name)
+                value_hash = self.generate_value_hash(*entries)
+                self.apply(gpo.name, attribute, value_hash, applier_func,
+                           entries)
+
+                # Remove scripts for this GPO which are no longer applied
+                self.clean(gpo.name, keep=attribute)
 
     def rsop(self, gpo, target='MACHINE'):
         output = {}
diff --git a/python/samba/gp/gp_centrify_sudoers_ext.py b/python/samba/gp/gp_centrify_sudoers_ext.py
index 2d03a4871a4..3de4fb871ea 100644
--- a/python/samba/gp/gp_centrify_sudoers_ext.py
+++ b/python/samba/gp/gp_centrify_sudoers_ext.py
@@ -15,11 +15,8 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import os
-from samba.gp.gpclass import gp_pol_ext
-from base64 import b64encode
-from tempfile import NamedTemporaryFile
-from subprocess import Popen, PIPE
-from samba.gp.gp_sudoers_ext import visudo, intro
+from samba.gp.gpclass import gp_pol_ext, gp_file_applier
+from samba.gp.gp_sudoers_ext import sudo_applier_func
 from samba.gp.util.logging import log
 
 def ext_enabled(entries):
@@ -29,57 +26,41 @@ def ext_enabled(entries):
             return e.data == 1
     return False
 
-class gp_centrify_sudoers_ext(gp_pol_ext):
+class gp_centrify_sudoers_ext(gp_pol_ext, gp_file_applier):
     def __str__(self):
         return 'Centrify/Sudo Rights'
 
     def process_group_policy(self, deleted_gpo_list, changed_gpo_list,
             sdir='/etc/sudoers.d'):
         for guid, settings in deleted_gpo_list:
-            self.gp_db.set_guid(guid)
             if str(self) in settings:
                 for attribute, sudoers in settings[str(self)].items():
-                    if os.path.exists(sudoers):
-                        os.unlink(sudoers)
-                    self.gp_db.delete(str(self), attribute)
-            self.gp_db.commit()
+                    self.unapply(guid, attribute, sudoers)
 
         for gpo in changed_gpo_list:
             if gpo.file_sys_path:
                 section = 'Software\\Policies\\Centrify\\UnixSettings\\SuDo'
-                self.gp_db.set_guid(gpo.name)
                 pol_file = 'MACHINE/Registry.pol'
                 path = os.path.join(gpo.file_sys_path, pol_file)
                 pol_conf = self.parse(path)
                 if not pol_conf or not ext_enabled(pol_conf.entries):
                     continue
+                sudo_entries = []
                 for e in pol_conf.entries:
                     if e.keyname == section and e.data.strip():
                         if '**delvals.' in e.valuename:
                             continue
-                        attribute = b64encode(e.data.encode()).decode()
-                        old_val = self.gp_db.retrieve(str(self), attribute)
-                        if not old_val:
-                            contents = intro
-                            contents += '%s\n' % e.data
-                            with NamedTemporaryFile() as f:
-                                with open(f.name, 'w') as w:
-                                    w.write(contents)
-                                sudo_validation = \
-                                        Popen([visudo, '-c', '-f', f.name],
-                                            stdout=PIPE, stderr=PIPE).wait()
-                            if sudo_validation == 0:
-                                with NamedTemporaryFile(prefix='gp_',
-                                                        delete=False,
-                                                        dir=sdir) as f:
-                                    with open(f.name, 'w') as w:
-                                        w.write(contents)
-                                    self.gp_db.store(str(self),
-                                                     attribute,
-                                                     f.name)
-                            else:
-                                log.error('Sudoers apply failed', e.data)
-                        self.gp_db.commit()
+                        sudo_entries.append(e.data)
+                # Each GPO applies only one set of sudoers, in a
+                # set of files, so the attribute does not need uniqueness.
+                attribute = self.generate_attribute(gpo.name, *sudo_entries)
+                # The value hash is generated from the sudo_entries, ensuring
+                # any changes to this GPO will cause the files to be rewritten.
+                value_hash = self.generate_value_hash(*sudo_entries)
+                self.apply(gpo.name, attribute, value_hash, sudo_applier_func,
+                           sdir, sudo_entries)
+                # Cleanup any old entries that are no longer part of the policy
+                self.clean(gpo.name, keep=[attribute])
 
     def rsop(self, gpo):
         output = {}
diff --git a/python/samba/gp/gp_cert_auto_enroll_ext.py b/python/samba/gp/gp_cert_auto_enroll_ext.py
index f1dcf6bbafb..3be8931bf1e 100644
--- a/python/samba/gp/gp_cert_auto_enroll_ext.py
+++ b/python/samba/gp/gp_cert_auto_enroll_ext.py
@@ -17,7 +17,7 @@
 import os
 import operator
 import requests
-from samba.gp.gpclass import gp_pol_ext
+from samba.gp.gpclass import gp_pol_ext, gp_applier, GPOSTATE
 from samba import Ldb
 from ldb import SCOPE_SUBTREE, SCOPE_BASE
 from samba.auth import system_session
@@ -39,6 +39,7 @@ except ModuleNotFoundError:
 from cryptography.hazmat.primitives.serialization import Encoding
 from cryptography.x509 import load_der_x509_certificate
 from cryptography.hazmat.backends import default_backend
+from samba.common import get_string
 
 cert_wrap = b"""
 -----BEGIN CERTIFICATE-----
@@ -153,9 +154,9 @@ def fetch_certification_authorities(ldb):
     if len(res) == 0:
         return result
     for es in res:
-        data = { 'name': es['cn'][0],
-                 'hostname': es['dNSHostName'][0],
-                 'cACertificate': es['cACertificate'][0]
+        data = { 'name': get_string(es['cn'][0]),
+                 'hostname': get_string(es['dNSHostName'][0]),
+                 'cACertificate': get_string(es['cACertificate'][0])
                }
         result.append(data)
     return result
@@ -171,7 +172,7 @@ def fetch_template_attrs(ldb, name, attrs=['msPKI-Minimal-Key-Size']):
         return {'msPKI-Minimal-Key-Size': ['2048']}
 
 def format_root_cert(cert):
-    cert = base64.b64encode(cert)
+    cert = base64.b64encode(cert.encode())
     return cert_wrap % re.sub(b"(.{64})", b"\\1\n", cert, 0, re.DOTALL)
 
 def find_cepces_submit():
@@ -248,7 +249,7 @@ def getca(ca, url, trust_dir):
 
 def cert_enroll(ca, ldb, trust_dir, private_dir, auth='Kerberos'):
     """Install the root certificate chain."""
-    data = {'files': [], 'templates': []}
+    data = dict({'files': [], 'templates': []}, **ca)
     url = 'http://%s/CertSrv/mscep/mscep.dll/pkiclient.exe?' % ca['hostname']
     root_certs = getca(ca, url, trust_dir)
     data['files'].extend(root_certs)
@@ -311,10 +312,42 @@ def cert_enroll(ca, ldb, trust_dir, private_dir, auth='Kerberos'):
                  'certificate auto enrollment to work')
     return json.dumps(data)
 
-class gp_cert_auto_enroll_ext(gp_pol_ext):
+class gp_cert_auto_enroll_ext(gp_pol_ext, gp_applier):
     def __str__(self):
         return 'Cryptography\AutoEnrollment'
 
+    def unapply(self, guid, attribute, value):
+        ca_cn = base64.b64decode(attribute)
+        data = json.loads(value)
+        getcert = which('getcert')
+        if getcert is not None:
+            Popen([getcert, 'remove-ca', '-c', ca_cn]).wait()
+            for nickname in data['templates']:
+                Popen([getcert, 'stop-tracking', '-i', nickname]).wait()
+        for f in data['files']:
+            if os.path.exists(f):
+                if os.path.exists(f):
+                    os.unlink(f)
+        self.cache_remove_attribute(guid, attribute)
+
+    def apply(self, guid, ca, applier_func, *args, **kwargs):
+        attribute = base64.b64encode(ca['name'].encode()).decode()
+        # If the policy has changed, unapply, then apply new policy
+        old_val = self.cache_get_attribute_value(guid, attribute)
+        old_data = json.loads(old_val) if old_val is not None else {}
+        if all([(ca[k] == old_data[k] if k in old_data else False) \
+                    for k in ca.keys()]) or \
+                self.cache_get_apply_state() == GPOSTATE.ENFORCE:
+            self.unapply(guid, attribute, old_val)
+        # If policy is already applied, skip application
+        if old_val is not None and \
+                self.cache_get_apply_state() != GPOSTATE.ENFORCE:
+            return
+
+        # Apply the policy and log the changes
+        data = applier_func(*args, **kwargs)
+        self.cache_add_attribute(guid, attribute, data)
+
     def process_group_policy(self, deleted_gpo_list, changed_gpo_list,
                              trust_dir=None, private_dir=None):
         if trust_dir is None:
@@ -327,27 +360,13 @@ class gp_cert_auto_enroll_ext(gp_pol_ext):
             os.mkdir(private_dir, mode=0o700)
 
         for guid, settings in deleted_gpo_list:
-            self.gp_db.set_guid(guid)
             if str(self) in settings:
                 for ca_cn_enc, data in settings[str(self)].items():
-                    ca_cn = base64.b64decode(ca_cn_enc)
-                    data = json.loads(data)
-                    getcert = which('getcert')
-                    if getcert is not None:
-                        Popen([getcert, 'remove-ca', '-c', ca_cn]).wait()
-                        for nickname in data['templates']:
-                            Popen([getcert, 'stop-tracking',
-                                   '-i', nickname]).wait()
-                    for f in data['files']:
-                        if os.path.exists(f):
-                            os.unlink(f)
-                    self.gp_db.delete(str(self), ca_cn_enc)
-            self.gp_db.commit()
+                    self.unapply(guid, ca_cn_enc, data)
 
         for gpo in changed_gpo_list:
             if gpo.file_sys_path:
                 section = 'Software\Policies\Microsoft\Cryptography\AutoEnrollment'
-                self.gp_db.set_guid(gpo.name)
                 pol_file = 'MACHINE/Registry.pol'
                 path = os.path.join(gpo.file_sys_path, pol_file)
                 pol_conf = self.parse(path)
@@ -362,11 +381,22 @@ class gp_cert_auto_enroll_ext(gp_pol_ext):
                         manage = e.data & 0x2 == 0x2
                         retrive_pending = e.data & 0x4 == 0x4
                         if enroll:
-                            self.__enroll(pol_conf.entries, trust_dir,
-                                          private_dir)
-                        self.gp_db.commit()
+                            ca_names = self.__enroll(gpo.name,
+                                                     pol_conf.entries,
+                                                     trust_dir, private_dir)
+
+                            # Cleanup any old CAs that have been removed
+                            ca_attrs = [base64.b64encode(n.encode()).decode() \
+                                    for n in ca_names]
+                            self.clean(gpo.name, keep=ca_attrs)
+                        else:
+                            # If enrollment has been disabled for this GPO,
+                            # remove any existing policy
+                            ca_attrs = \
+                                self.cache_get_all_attribute_values(gpo.name)
+                            self.clean(gpo.name, remove=ca_attrs)
 
-    def __read_cep_data(self, ldb, end_point_information,
+    def __read_cep_data(self, guid, ldb, end_point_information,
                         trust_dir, private_dir):
         """Read CEP Data.
 
@@ -414,42 +444,44 @@ class gp_cert_auto_enroll_ext(gp_pol_ext):
 
             # For each CertificateEnrollmentPolicyEndPoint instance for that
             # group:
+            ca_names = []
             for ca in end_point_group:
                 # If EndPoint.URI equals "LDAP":
                 if ca['URL'] == 'LDAP:':
                     # This is a basic configuration.
                     cas = fetch_certification_authorities(ldb)
                     for _ca in cas:
-                        data = cert_enroll(_ca, ldb, trust_dir, private_dir)
-                        self.gp_db.store(str(self),
-                                         base64.b64encode(_ca['name']).decode(),
-                                         data)
+                        self.apply(guid, _ca, cert_enroll, _ca, ldb, trust_dir,
+                                   private_dir)
+                        ca_names.append(_ca['name'])
                 # If EndPoint.URI starts with "HTTPS//":
                 elif ca['URL'].lower().startswith('https://'):
-                    data = cert_enroll(ca, ldb, trust_dir,
-                                       private_dir, auth=ca['auth'])
-                    self.gp_db.store(str(self),
-                        base64.b64encode(ca['name'].encode()).decode(),
-                        data)
+                    self.apply(guid, ca, cert_enroll, ca, ldb, trust_dir,
+                               private_dir, auth=ca['auth'])
+                    ca_names.append(ca['name'])
                 else:
                     edata = { 'endpoint': ca['URL'] }
                     log.error('Unrecognized endpoint', edata)
+            return ca_names
 
-    def __enroll(self, entries, trust_dir, private_dir):
+    def __enroll(self, guid, entries, trust_dir, private_dir):
         url = 'ldap://%s' % get_dc_hostname(self.creds, self.lp)
         ldb = Ldb(url=url, session_info=system_session(),
                   lp=self.lp, credentials=self.creds)
 
+        ca_names = []
         end_point_information = obtain_end_point_information(entries)
         if len(end_point_information) > 0:
-            self.__read_cep_data(ldb, end_point_information,
-                                 trust_dir, private_dir)
+            ca_names.extend(self.__read_cep_data(guid, ldb,
+                                                 end_point_information,
+                                                 trust_dir, private_dir))
         else:
             cas = fetch_certification_authorities(ldb)
             for ca in cas:
-                data = cert_enroll(ca, ldb, trust_dir, private_dir)
-                self.gp_db.store(str(self),
-                                 base64.b64encode(ca['name']).decode(), data)
+                self.apply(guid, ca, cert_enroll, ca, ldb, trust_dir,
+                           private_dir)
+                ca_names.append(ca['name'])
+        return ca_names
 
     def rsop(self, gpo):
         output = {}
diff --git a/python/samba/gp/gp_chromium_ext.py b/python/samba/gp/gp_chromium_ext.py
index ae4bc8a7a80..5e54f0f469d 100644
--- a/python/samba/gp/gp_chromium_ext.py
+++ b/python/samba/gp/gp_chromium_ext.py
@@ -16,10 +16,11 @@
 
 import os
 import json
-from samba.gp.gpclass import gp_pol_ext
+from samba.gp.gpclass import gp_pol_ext, gp_file_applier
 from samba.dcerpc import misc
 from samba.common import get_string
 from samba.gp.util.logging import log
+from tempfile import NamedTemporaryFile
 
 def parse_entry_data(name, e):
     dict_entries = ['VirtualKeyboardFeatures',
@@ -365,7 +366,9 @@ def assign_entry(policies, e):
         name = e.valuename
         policies[name] = parse_entry_data(name, e)
 
-def convert_pol_to_json(managed, recommended, section, entries):
+def convert_pol_to_json(section, entries):
+    managed = {}
+    recommended = {}
     recommended_section = '\\'.join([section, 'Recommended'])
     for e in entries:
         if '**delvals.' in e.valuename:
@@ -376,98 +379,77 @@ def convert_pol_to_json(managed, recommended, section, entries):
             assign_entry(managed, e)
     return managed, recommended
 
-class gp_chromium_ext(gp_pol_ext):
-    __managed_policies_path = '/etc/chromium/policies/managed'
-    __recommended_policies_path = '/etc/chromium/policies/recommended'
+class gp_chromium_ext(gp_pol_ext, gp_file_applier):
+    managed_policies_path = '/etc/chromium/policies/managed'
+    recommended_policies_path = '/etc/chromium/policies/recommended'
 
     def __str__(self):
         return 'Google/Chromium'
 
-    def set_managed_machine_policy(self, managed):
-        try:
-            managed_policies = os.path.join(self.__managed_policies_path,
-                                            'policies.json')
-            os.makedirs(self.__managed_policies_path, exist_ok=True)
-            with open(managed_policies, 'w') as f:
-                json.dump(managed, f)
-                log.debug('Wrote Chromium preferences', managed_policies)
-        except PermissionError:
-            log.debug('Failed to write Chromium preferences',
-                      managed_policies)
-
-
-    def set_recommended_machine_policy(self, recommended):
-        try:
-            recommended_policies = os.path.join(self.__recommended_policies_path,
-                                                'policies.json')
-            os.makedirs(self.__recommended_policies_path, exist_ok=True)
-            with open(recommended_policies, 'w') as f:
-                json.dump(recommended, f)
-                log.debug('Wrote Chromium preferences', recommended_policies)
-        except PermissionError:
-            log.debug('Failed to write Chromium preferences',
-                      recommended_policies)
-
-    def get_managed_machine_policy(self):
-        managed_policies = os.path.join(self.__managed_policies_path,
-                                        'policies.json')
-        if os.path.exists(managed_policies):
-            with open(managed_policies, 'r') as r:
-                managed = json.load(r)
-                log.debug('Read Chromium preferences', managed_policies)
-        else:
-            managed = {}
-        return managed
-
-    def get_recommended_machine_policy(self):
-        recommended_policies = os.path.join(self.__recommended_policies_path,
-                                            'policies.json')
-        if os.path.exists(recommended_policies):
-            with open(recommended_policies, 'r') as r:
-                recommended = json.load(r)
-                log.debug('Read Chromium preferences', recommended_policies)
-        else:
-            recommended = {}
-        return recommended
-
     def process_group_policy(self, deleted_gpo_list, changed_gpo_list,
                              policy_dir=None):
         if policy_dir is not None:
-            self.__recommended_policies_path = os.path.join(policy_dir,
+            self.recommended_policies_path = os.path.join(policy_dir,
                                                             'recommended')
-            self.__managed_policies_path = os.path.join(policy_dir, 'managed')
+            self.managed_policies_path = os.path.join(policy_dir, 'managed')
+        # Create the policy directories if necessary
+        if not os.path.exists(self.recommended_policies_path):
+            os.makedirs(self.recommended_policies_path, mode=0o755,
+                        exist_ok=True)
+        if not os.path.exists(self.managed_policies_path):
+            os.makedirs(self.managed_policies_path, mode=0o755,
+                        exist_ok=True)
         for guid, settings in deleted_gpo_list:
-            self.gp_db.set_guid(guid)
             if str(self) in settings:
                 for attribute, policies in settings[str(self)].items():
-                    if attribute == 'managed':
-                        self.set_managed_machine_policy(json.loads(policies))
-                    elif attribute == 'recommended':
-                        self.set_recommended_machine_policy(json.loads(policies))
-                    self.gp_db.delete(str(self), attribute)
-            self.gp_db.commit()
+                    try:
+                        json.loads(policies)
+                    except json.decoder.JSONDecodeError:
+                        self.unapply(guid, attribute, policies)
+                    else:
+                        # Policies were previously stored all in one file, but
+                        # the Chromium documentation says this is not


-- 
Samba Shared Repository



More information about the samba-cvs mailing list