From: David Mulder Date: Mon, 12 Jun 2017 22:00:38 +0000 (-0600) Subject: gpo: Always enforce policy, even if unchanged X-Git-Tag: talloc-2.1.11~449 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4a7ccbeab7656f96e2d7cadb9be44526c52910f7;p=thirdparty%2Fsamba.git gpo: Always enforce policy, even if unchanged Policies should always be enforced, even if the gpo hasn't changed. Signed-off-by: David Mulder Reviewed-by: Garming Sam Reviewed-by: Andrew Bartlett --- diff --git a/python/samba/gpclass.py b/python/samba/gpclass.py index ae06c5b361d..a73cde4c379 100644 --- a/python/samba/gpclass.py +++ b/python/samba/gpclass.py @@ -33,6 +33,15 @@ from StringIO import StringIO from abc import ABCMeta, abstractmethod import xml.etree.ElementTree as etree +try: + from enum import Enum + GPOSTATE = Enum('GPOSTATE', 'APPLY ENFORCE UNAPPLY') +except ImportError: + class GPOSTATE: + APPLY = 1 + ENFORCE = 2 + UNAPPLY = 3 + class gp_log: ''' Log settings overwritten by gpo apply The gp_log is an xml file that stores a history of gpo changes (and the original setting value). @@ -75,6 +84,7 @@ class gp_log: param gpostore - the GPOStorage obj which references the tdb which contains gp_logs param db_log - (optional) a string to initialize the gp_log ''' + self._state = GPOSTATE.APPLY self.gpostore = gpostore self.username = user if db_log: @@ -86,6 +96,26 @@ class gp_log: self.user = etree.SubElement(self.gpdb, 'user') self.user.attrib['name'] = user + def state(self, value): + ''' Policy application state + param value - APPLY, ENFORCE, or UNAPPLY + + The behavior of the gp_log depends on whether we are applying policy, enforcing policy, + or unapplying policy. During an apply, old settings are recorded in the log. During an + enforce, settings are being applied but the gp_log does not change. During an unapply, + additions to the log should be ignored (since function calls to apply settings are actually + reverting policy), but removals from the log are allowed. + ''' + # If we're enforcing, but we've unapplied, apply instead + if value == GPOSTATE.ENFORCE: + apply_log = self.user.find('applylog') + if apply_log is None or len(apply_log) == 0: + self._state = GPOSTATE.APPLY + else: + self._state = value + else: + self._state = value + def set_guid(self, guid): ''' Log to a different GPO guid param guid - guid value of the GPO from which we're applying policy @@ -94,12 +124,13 @@ class gp_log: if self.guid is None: self.guid = etree.SubElement(self.user, 'guid') self.guid.attrib['value'] = guid - apply_log = self.user.find('applylog') - if apply_log is None: - apply_log = etree.SubElement(self.user, 'applylog') - item = etree.SubElement(apply_log, 'guid') - item.attrib['count'] = '%d' % (len(apply_log)-1) - item.attrib['value'] = guid + if self._state == GPOSTATE.APPLY: + apply_log = self.user.find('applylog') + if apply_log is None: + apply_log = etree.SubElement(self.user, 'applylog') + item = etree.SubElement(apply_log, 'guid') + item.attrib['count'] = '%d' % (len(apply_log)-1) + item.attrib['value'] = guid def apply_log_pop(self): ''' Pop a GPO guid from the applylog @@ -123,6 +154,8 @@ class gp_log: param attribute - The attribute being modified param old_val - The value of the attribute prior to policy application ''' + if self._state == GPOSTATE.UNAPPLY or self._state == GPOSTATE.ENFORCE: + return None assert self.guid is not None, "gpo guid was not set" ext = self.guid.find('gp_ext[@name="%s"]' % gp_ext_name) if ext is None: diff --git a/source4/scripting/bin/samba_gpoupdate b/source4/scripting/bin/samba_gpoupdate index 721d6071bd1..568830a7461 100755 --- a/source4/scripting/bin/samba_gpoupdate +++ b/source4/scripting/bin/samba_gpoupdate @@ -68,16 +68,19 @@ def apply_gp(lp, creds, test_ldb, logger, store, gp_extensions): version = int(gpo.gpo_get_sysvol_gpt_version(os.path.join(lp.get("path", "sysvol"), local_path))[1]) if version != store.get_int(guid): logger.info('GPO %s has changed' % guid) - gp_db.set_guid(guid) - store.start() - try: - for ext in gp_extensions: - ext.parse(ext.list(local_path), test_ldb, conn, gp_db, lp) - except: - logger.error('Failed to parse gpo %s' % guid) - store.cancel() - continue - store.store(guid, '%i' % version) + gp_db.state(GPOSTATE.APPLY) + else: + gp_db.state(GPOSTATE.ENFORCE) + gp_db.set_guid(guid) + store.start() + try: + for ext in gp_extensions: + ext.parse(ext.list(local_path), test_ldb, conn, gp_db, lp) + except: + logger.error('Failed to parse gpo %s' % guid) + store.cancel() + continue + store.store(guid, '%i' % version) store.commit() def unapply_log(gp_db): @@ -90,6 +93,7 @@ def unapply_log(gp_db): def unapply_gp(lp, creds, test_ldb, logger, store, gp_extensions): gp_db = store.get_gplog(creds.get_username()) + gp_db.state(GPOSTATE.UNAPPLY) for gpo_guid in unapply_log(gp_db): gp_db.set_guid(gpo_guid) unapply_attributes = gp_db.list(gp_extensions)