[PATCH 11/18] gpo: Added BackLog for default to make it maintain hierarchy

David Mulder dmulder at suse.com
Thu Feb 23 20:22:03 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               | 113 +++-------------------------------
 source4/scripting/bin/samba_gpoupdate |  38 +++++++++---
 2 files changed, 38 insertions(+), 113 deletions(-)

diff --git a/python/samba/gpclass.py b/python/samba/gpclass.py
index b7f6e34..adebcb5 100755
--- a/python/samba/gpclass.py
+++ b/python/samba/gpclass.py
@@ -120,15 +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'''
-        #policy = codecs.open(path, encoding='utf-16')
-	try:
+        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] == '[':
@@ -144,101 +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
-                    #REALM_GPO = [GUID, applied, str(GPO_CONTAINER.get('dn'))]
-                    #final_list.insert(count_unapplied_GPO, REALM_GPO)
-
-                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):
@@ -291,18 +206,10 @@ 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
 
-   # Accepts sysvol parameters to return a hierarchically sorted list, with application flag indicators.
-
-
-#A GPO may have a single or multiple links. Get all of the containers (OU, SITE, etc..) and return them'''
-    #def get_gpo_containers( ) :
-    #   return gpo_netcmd_user.get_gpo_containers(self.SamDB, self.GUID)
-
-  #  def
 
 def establish_hierarchy(SamDB, GUID_LIST, DC_OU, global_dn):
     '''Takes a list of GUID from gpo, and sorts them based on OU, and realm.
diff --git a/source4/scripting/bin/samba_gpoupdate b/source4/scripting/bin/samba_gpoupdate
index 008ff60..1388bf7 100755
--- a/source4/scripting/bin/samba_gpoupdate
+++ b/source4/scripting/bin/samba_gpoupdate
@@ -32,11 +32,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:
@@ -143,6 +150,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")
 
@@ -166,27 +174,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