# along with this program. If not, see <http://www.gnu.org/licenses/>.
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 = '''
# to this machine. DO NOT MODIFY THIS FILE DIRECTLY.
#
+'''
+end = '''
+### autogenerated by samba ###
'''
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')