From: David Mulder Date: Tue, 20 Jul 2021 17:14:28 +0000 (-0600) Subject: gpo: Apply Group Policy User Scripts X-Git-Tag: ldb-2.5.0~974 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=80e3daed120b5ed71ffd58427e5d8910b6bdb3a1;p=thirdparty%2Fsamba.git gpo: Apply Group Policy User Scripts Signed-off-by: David Mulder Reviewed-by: Jeremy Allison --- diff --git a/python/samba/gp_scripts_ext.py b/python/samba/gp_scripts_ext.py index 70e668159a2..33049ff6dc0 100644 --- a/python/samba/gp_scripts_ext.py +++ b/python/samba/gp_scripts_ext.py @@ -15,8 +15,10 @@ # along with this program. If not, see . import os, re -from samba.gpclass import gp_pol_ext +from subprocess import Popen, PIPE +from samba.gpclass import gp_pol_ext, drop_privileges from base64 import b64encode +from hashlib import blake2b from tempfile import NamedTemporaryFile intro = ''' @@ -28,6 +30,9 @@ intro = ''' # to this machine. DO NOT MODIFY THIS FILE DIRECTLY. # +''' +end = ''' +### autogenerated by samba ### ''' class gp_scripts_ext(gp_pol_ext): @@ -89,9 +94,79 @@ class gp_scripts_ext(gp_pol_ext): output[key].append(e.data) return output +def fetch_crontab(username): + p = Popen(['crontab', '-l', '-u', username], stdout=PIPE, stderr=PIPE) + out, err = p.communicate() + if p.returncode != 0: + raise RuntimeError('Failed to read the crontab: %s' % err) + m = re.findall('%s(.*)%s' % (intro, end), out.decode(), re.DOTALL) + if len(m) == 1: + entries = m[0].strip().split('\n') + else: + entries = [] + m = re.findall('(.*)%s.*%s(.*)' % (intro, end), out.decode(), re.DOTALL) + if len(m) == 1: + others = '\n'.join([l.strip() for l in m[0]]) + else: + others = out.decode() + return others, entries + +def install_crontab(fname, username): + p = Popen(['crontab', fname, '-u', username], stdout=PIPE, stderr=PIPE) + _, err = p.communicate() + if p.returncode != 0: + raise RuntimeError('Failed to install crontab: %s' % err) + class gp_user_scripts_ext(gp_scripts_ext): def process_group_policy(self, deleted_gpo_list, changed_gpo_list): - pass + for guid, settings in deleted_gpo_list: + self.gp_db.set_guid(guid) + if str(self) in settings: + others, entries = fetch_crontab(self.username) + for attribute, entry in settings[str(self)].items(): + if entry in entries: + entries.remove(entry) + self.gp_db.delete(str(self), attribute) + with NamedTemporaryFile() as f: + if len(entries) > 0: + f.write('\n'.join([others, intro, + '\n'.join(entries), end]).encode()) + else: + f.write(others.encode()) + f.flush() + install_crontab(f.name, self.username) + self.gp_db.commit() + + for gpo in changed_gpo_list: + if gpo.file_sys_path: + reg_key = 'Software\\Policies\\Samba\\Unix Settings' + sections = { '%s\\Daily Scripts' % reg_key : '@daily', + '%s\\Monthly Scripts' % reg_key : '@monthly', + '%s\\Weekly Scripts' % reg_key : '@weekly', + '%s\\Hourly Scripts' % reg_key : '@hourly' } + self.gp_db.set_guid(gpo.name) + pol_file = 'USER/Registry.pol' + path = os.path.join(gpo.file_sys_path, pol_file) + pol_conf = drop_privileges('root', self.parse, path) + if not pol_conf: + continue + for e in pol_conf.entries: + if e.keyname in sections.keys() and e.data.strip(): + cron_freq = sections[e.keyname] + attribute = '%s:%s' % (e.keyname, + blake2b(e.data.encode()).hexdigest()) + old_val = self.gp_db.retrieve(str(self), attribute) + entry = '%s %s' % (cron_freq, e.data) + others, entries = fetch_crontab(self.username) + if not old_val or entry not in entries: + entries.append(entry) + with NamedTemporaryFile() as f: + f.write('\n'.join([others, intro, + '\n'.join(entries), end]).encode()) + f.flush() + install_crontab(f.name, self.username) + self.gp_db.store(str(self), attribute, entry) + self.gp_db.commit() def rsop(self, gpo): return super().rsop(gpo, target='USER') diff --git a/selftest/knownfail.d/gpo b/selftest/knownfail.d/gpo deleted file mode 100644 index 138d933edba..00000000000 --- a/selftest/knownfail.d/gpo +++ /dev/null @@ -1 +0,0 @@ -^samba.tests.gpo.samba.tests.gpo.GPOTests.test_gp_user_scripts_ext