[PATCH 25/26] Added BackLog for default WIP make it maintain hierarchy
abartlet at samba.org
abartlet at samba.org
Thu Jun 5 04:07:30 MDT 2014
From: Luke Morrison <luc785 at hotmail.com>
---
Sdfsdfs | 0
python/samba/gpclass.py | 131 +++++++---------------------------
source4/scripting/bin/samba_gpoupdate | 40 +++++++----
3 files changed, 54 insertions(+), 117 deletions(-)
create mode 100644 Sdfsdfs
diff --git a/Sdfsdfs b/Sdfsdfs
new file mode 100644
index 0000000..e69de29
diff --git a/python/samba/gpclass.py b/python/samba/gpclass.py
index 59b6402..c728045 100755
--- a/python/samba/gpclass.py
+++ b/python/samba/gpclass.py
@@ -117,15 +117,18 @@ 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:
policy = conn.loadfile(path).decode('utf-16')
except:
return None
current_section = None
+ print attr_log
+ #LOG2 = open(attr_log, "w")
+ LOG = open(attr_log, "a")
+ print path.split('/')[2]
+ LOG.write(str(path.split('/')[2]) + '\n')
for line in policy.splitlines():
line = line.strip()
if line[0] == '[':
@@ -141,102 +144,27 @@ 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
+ #Fixing the bug where only some Linux Boxes Capitalize MACHINE
+ blist = afile.split('/')
+
+ bfile = blist[0] + '/' + blist[1] + '/' + 'Machine' + '/Microsoft/Windows NT/SecEdit/GptTmpl.inf'
+ if bfile.endswith('inf'):
+ self.read_inf(bfile, conn, attr_log)
+ bfile = blist[0] + '/' + blist[1] + '/' + 'machine' + '/Microsoft/Windows NT/SecEdit/GptTmpl.inf'
+ if bfile.endswith('inf'):
+ self.read_inf(bfile, conn, attr_log)
+
+ if afile.endswith('inf'):
+ self.read_inf(afile, conn, attr_log)
def scan_log(sysvol_path):
a = open(sysvol_path, "r")
@@ -263,13 +191,14 @@ def container_indexes(GUID_LIST):
return container_indexes
'''So GPO in same level need to have link level. This takes a container and sorts it'''
+#Small small problem, it is backwards
def sort_linked(SAMDB, guid_list, start, end):
containers = gpo_user.get_gpo_containers(SAMDB, guid_list[start][0])
for right_container in containers:
if right_container.get('dn') == guid_list[start][2]:
break
- print 'the container is %s' % (right_container.get('dn'))
gplink = str(right_container.get('gPLink'))
+ #print str(right_container.get('gPLink'))
gplink_split = gplink.split('[')
linked_order = []
ret_list = []
@@ -277,24 +206,16 @@ 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
-
'''Takes a list of GUID from gpo, and sorts them based on OU, and realm. See http://msdn.microsoft.com/en-us/library/windows/desktop/aa374155%28v=vs.85%29.aspx'''
def establish_hierarchy(SamDB, GUID_LIST, DC_OU, global_dn):
final_list = []
count_unapplied_GPO = 0
for GUID in GUID_LIST:
+
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
diff --git a/source4/scripting/bin/samba_gpoupdate b/source4/scripting/bin/samba_gpoupdate
index 9e394b0..d41d8e5 100755
--- a/source4/scripting/bin/samba_gpoupdate
+++ b/source4/scripting/bin/samba_gpoupdate
@@ -34,11 +34,18 @@ def gp_path_list(path):
for ext in gp_extensions:
GPO_LIST.append((ext, ext.list(path)))
return GPO_LIST
+'''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
+'''
+def gpo_parser(GPO_LIST, ldb, conn, attr_log):
-def gpo_parser(GPO_LIST, ldb, conn):
for entry in GPO_LIST:
(ext, thefile) = entry
- ext.parse(thefile, ldb, conn)
+ ext.parse(thefile, ldb, conn, attr_log)
class GPOServiceSetup:
def __init__(self):
@@ -138,11 +145,13 @@ creds = GPOService.Get_Creds()
#Read the Readable BackLog into a Hashmap 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")
+
# We need to know writable DC to setup SMB connection
net = Net(creds=creds, lp=lp)
'''flags = (nbt.NBT_SERVER_LDAP |
@@ -164,30 +173,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() )]
-##############################3UP UNTIL LAST EDITING
-#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)
-#TODO Make this a method in itself
-#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))
--
1.9.3
More information about the samba-technical
mailing list