[PATCH 11/23] gpo: Added BackLog for default to make it maintain hierarchy
David Mulder
dmulder at suse.com
Fri Mar 10 16:09:18 UTC 2017
From: Luke Morrison <luc785 at hotmail.com>
Signed-off-by: Garming Sam <garming at catalyst.net.nz>
Signed-off-by: Luke Morrison <luke at hubtrek.com>
---
python/samba/gpclass.py | 100 +++-------------------------------
source4/scripting/bin/samba_gpoupdate | 38 +++++++++----
2 files changed, 37 insertions(+), 101 deletions(-)
diff --git a/python/samba/gpclass.py b/python/samba/gpclass.py
index 6e17f23..04c4cd4 100755
--- a/python/samba/gpclass.py
+++ b/python/samba/gpclass.py
@@ -120,14 +120,15 @@ class gp_sec_ext(gp_ext):
}
#FIXME. EACH gpo should have a parser, and a creater. Essentially a gpo is just a file. Possibly a method and class to link it to organization unit (if that already does not exist) so that GPO's can be created arithmetically, possibly with a hashtable for certain GPO, then linked if desired. Also could store a backup folder of gpo's and then configure them without necessarily deploying it.
- def read_inf(self, path, conn):
+ def read_inf(self, path, conn, attr_log):
inftable = self.populate_inf()
- '''The inf file to be mapped'''
try:
policy = conn.loadfile(path).decode('utf-16')
except:
return None
current_section = None
+ LOG = open(attr_log, "a")
+ LOG.write(str(path.split('/')[2]) + '\n')
for line in policy.splitlines():
line = line.strip()
if line[0] == '[':
@@ -143,99 +144,16 @@ class gp_sec_ext(gp_ext):
if current_section.get(key):
(att, setter) = current_section.get(key)
value = value.encode('ascii', 'ignore')
+ # so value is the value that it contains, and the att is the attribute
+ LOG.write(att + ' ' + value + '\n')
+ # copy and paste this logic to backwalk deleted GPO
setter(self.ldb, self.dn, att, value).update_samba()
- #FIXME read registry files (.pol). Can they ever apply? Define read_registry():
- def parse(self, afile, ldb, conn):
+ def parse(self, afile, ldb, conn, attr_log):
self.ldb = ldb
self.dn = ldb.get_default_basedn()
if afile.endswith('inf'):
- self.read_inf(afile, conn)
-
-class samba4_gpo_hierarchy(object):
-
- def __init__(self, SamDB, sysvol_guid_list, DC_OU, GLOBAL_DN):
- """
- :param SamDB: An instance of the live samba database
- :param sysvol_guid_list: The complete list of all GPO GUID's listed in sysvol folder
- :param DC_OU: The respective distinguished name of the Domain Controller
- :param GLOBAL_DN: The Domain DN that Samba is a part of
- """
- self.SamDB = SamDB
- self.GUID_L = sysvol_guid_list
- self.DC_OU = DC_OU
- self.GL_DN = GLOBAL_DN
- self.sorted_containers = []
- self.sorted_full = []
- self.indexed_places = []
- self.unapplied_gpo = 0
-
- def update_unapplied_gpo(self):
- self.update_unapplied_gpo += 1
-
- '''Returns list of int indexes to where the dn changes'''
- def container_indexes(self):
- count = 0
- container_indexes = []
- while count < (len(self.GUID_L)-1):
- if self.sorted_containers[count][2] != self.sorted_containers[count+1][2]:
- container_indexes.append(count+1)
- count += 1
- container_indexes.append(len(self.sorted_containers))
- return container_indexes
-
-
- def establish_hierarchy(self):
- final_list = []
- count_unapplied_GPO = 0
- for GUID in self.GUID_L:
- container_iteration = 0
- applied = False # Assume first it is not applied
- gpo_realm = False # Realm only written on last call, if the GPO is linked to multiple places
- '''Get all of the linked information'''
- GPO_CONTAINERS = gpo_user.get_gpo_containers(self.SamDB, GUID)
- for GPO_CONTAINER in GPO_CONTAINERS:
-
- container_iteration +=1
-
- if self.DC_OU == str(GPO_CONTAINER.get('dn')):
- applied = True
- insert_gpo = [GUID, applied, str(GPO_CONTAINER.get('dn'))]
- self.sorted_containers.append(insert_gpo)
- break
-
- if self.GL_DN == str(GPO_CONTAINER.get('dn')) and (len(GPO_CONTAINERS) == 1):
- gpo_realm = True
- applied = True
-
- if self.GL_DN == str(GPO_CONTAINER.get('dn')) and (len(GPO_CONTAINERS) > 1):
- gpo_realm = True
- applied = True
-
- if container_iteration == len(GPO_CONTAINERS):
- if gpo_realm == False:
- insert_dud = [GUID, applied, str(GPO_CONTAINER.get('dn'))]
- self.sorted_containers.insert(0, insert_dud)
- self.count_unapplied_GPO()
- else :
- REALM_GPO = [GUID, applied, str(GPO_CONTAINER.get('dn'))]
- self.sorted_containers.insert(count_unapplied_GPO, REALM_GPO)
-
- '''After GPO are sorted into containers, sort the containers themselves. But first append non-applicable GPO.'''
- self.indexed_places = self.container_indexes()
- count = 0
- unapplied_gpo = []
- self.sorted_full = []
- '''Append all empties to final from first change of container'''
- while count < self.indexed_places[0]:
- unapplied_gpo.append(self.sorted_containers[count])
- count += 1
-
- count = 0
- self.sorted_full += unapplied_gpo
- while count < (len(self.indexed_places)-1): # Already accounted for one in empties
- self.sorted_full += (sort_linked(self.SamDB, self.sorted_containers, self.indexed_places[count], self.indexed_places[count + 1]))
- count += 1
+ self.read_inf(afile, conn, attr_log)
def scan_log(sysvol_path):
@@ -288,7 +206,7 @@ def sort_linked(SAMDB, guid_list, start, end):
linked_order.append(str(ldap_guid[10:48]))
count = len(linked_order) - 1
while count > 0:
- ret_list.append([linked_order[count], True, guid_list[start][2]])
+ ret_list.append([linked_order[count], guid_list[start][1], guid_list[start][2]])
count -= 1
return ret_list
diff --git a/source4/scripting/bin/samba_gpoupdate b/source4/scripting/bin/samba_gpoupdate
index e5e6507..48b5103 100755
--- a/source4/scripting/bin/samba_gpoupdate
+++ b/source4/scripting/bin/samba_gpoupdate
@@ -45,11 +45,18 @@ def gp_path_list(path):
GPO_LIST.append((ext, ext.list(path)))
return GPO_LIST
-# Reads the GPOs and sends them to their proper handlers
-def gpo_parser(GPO_LIST, ldb, conn):
+def gpo_parser(GPO_LIST, ldb, conn, attr_log):
+ '''The API method to parse the GPO
+ :param GPO_LIST:
+ :param ldb: Live instance of an LDB object AKA Samba
+ :param conn: Live instance of a CIFS connection
+ :param attr_log: backlog path for GPO and attribute to be written
+ no return except a newly updated Samba
+ '''
+
for entry in GPO_LIST:
(ext, thefile) = entry
- ext.parse(thefile, ldb, conn)
+ ext.parse(thefile, ldb, conn, attr_log)
class GPOServiceSetup:
@@ -156,6 +163,7 @@ creds = GPOService.Get_Creds()
# then open writable backLog in same location
BackLoggedGPO = None
sys_log = '%s/%s' % (lp.get("path", "sysvol"), 'syslog.txt')
+attr_log = '%s/%s' % (lp.get("path", "sysvol"), 'attrlog.txt')
BackLoggedGPO = GetBackLog(sys_log)
BackLog = open(sys_log, "w")
@@ -179,27 +187,37 @@ DC_OU = "OU=Domain Controllers" + ',' + global_dn
# Set up a List of the GUID for all GPO's
guid_list = [x['name'] for x in conn.list('%s/Policies' % lp.get("realm").lower())]
-#Establish the Hierarchy for the GPO
-hierarchy_gpos = samba4_gpo_hierarchy(test_ldb, guid_list, DC_OU, global_dn)
-hierarchy_gpos.establish_hierarchy()
+#Power through the Microsoft Hierarchy with Linking Order included
+#FIXME could be SO much more efficient if we get the dn if the DC, then use that to get all its containers
+#Then use the acquired containers of DC dn, to get all GPO in a convenient linking order with linking order already taken into account
+hierarchy_gpos = establish_hierarchy(test_ldb, guid_list, DC_OU, global_dn)
-#Write applicable GPO
+#At this point we have a list of hierarchically applied GPOS
+#Say for example a GPO was deleted, we can either
+#1)Reset ALL Defaults and then call script to apply all GPO
+#2)Find which attribute, fall back on previous attribute. THat way when we call this script, it only still applies the GPO that has changed
+#2 is more favorable because we are minimally changing Samba
-for guid_eval in hierarchy_gpos.sorted_full:
+for guid_eval in hierarchy_gpos:
guid = guid_eval[0]
gp_extensions = [gp_sec_ext()]
local_path = '%s/Policies' % lp.get("realm").lower() + '/' + guid + '/'
version = gpo.gpo_get_sysvol_gpt_version(lp.get("path", "sysvol") + '/' + local_path)[1]
gpolist = gp_path_list(local_path)
- print local_path
+
'''If an important GPO parse it. Will not parse if it has not changed, is empty, or is not in the right container'''
+ # If the GPO has a dn that is applicable to Samba
if guid_eval[1]:
+ # If it has a GPO file that could apply to Samba
if gpolist[0][1]:
+ # If it we have not read it before and is not empty
+ #We need to rewrite
if (version != BackLoggedGPO.get(guid)) and (version != 0):
print ('GPO %s has changed' % guid)
- gpo_parser(gpolist, test_ldb, conn)
+ #Apply to Samba
+ gpo_parser(gpolist, test_ldb, conn, attr_log)
BackLog.write('%s %i\n' % (guid, version))
--
2.10.2
More information about the samba-technical
mailing list