[PATCH 24/26] Adderd modularity to samba_gpoupdate

abartlet at samba.org abartlet at samba.org
Thu Jun 5 04:07:29 MDT 2014


From: Luke Morrison <luc785 at hotmail.com>

---
 source4/scripting/bin/samba_gpoupdate | 229 ++++++++++++++++++++++------------
 1 file changed, 150 insertions(+), 79 deletions(-)

diff --git a/source4/scripting/bin/samba_gpoupdate b/source4/scripting/bin/samba_gpoupdate
index 875d154..9e394b0 100755
--- a/source4/scripting/bin/samba_gpoupdate
+++ b/source4/scripting/bin/samba_gpoupdate
@@ -1,5 +1,8 @@
 #!/usr/bin/env python
-# Copyright Luke Morrison <luc785 at .hotmail.com> 2013
+# Copyright Luke Morrison <luc785 at .hotmail.com> July 2013
+# Co-Edited by Matthieu Pattou July 2013 from original August 2013
+# Edited by Garwing Sam Feb. 2014
+# Edited by Luke Morrison April 2014
 '''This script reads log file of previous GPO, gets all GPO from sysvol, sorts them by container, and applies the ones that have not been applied, have changed, or is in the right container'''
 import os
 import fcntl
@@ -17,7 +20,14 @@ from samba.net import Net
 from samba.dcerpc import nbt
 from samba import smb
 
-# Finds all GPO Files ending in inf
+
+"""Do I needs this?
+schemadn = test_ldb.get_schema_basedn()
+basedn = test_ldb.get_default_basedn()
+
+#guid_list = os.listdir(path)
+#guid_list = establish_hierarchy(test_ldb, guid_list, DC_OU, global_dn)
+"""
 def gp_path_list(path):
 
     GPO_LIST = []
@@ -25,103 +35,164 @@ def gp_path_list(path):
         GPO_LIST.append((ext, ext.list(path)))
     return GPO_LIST
 
-#lReads the GPOs and sends them to their proper handlers
 def gpo_parser(GPO_LIST, ldb, conn):
     for entry in GPO_LIST:
         (ext, thefile) = entry
         ext.parse(thefile, ldb, conn)
 
-parser = optparse.OptionParser("testsearchdn [options]")
-
-sambaopts = options.SambaOptions(parser)
-
-parser.add_option_group(sambaopts)
-parser.add_option_group(options.VersionOptions(parser))
-
-credopts = options.CredentialsOptions(parser)
-
-parser.add_option("-H", dest = "url", help="URL for the samdb")
-
-parser.add_option_group(credopts)
-
-opts, args = parser.parse_args()
-lp = sambaopts.get_loadparm()
-
-smbconf = lp.configfile
-creds = credopts.get_credentials(lp, fallback_machine=True)
-
-session = system_session()
-
-if not opts.url:
-    url = lp.samdb_url()
-else:
-    url = opts.url
-
-#########################
-#Inialize Samba Database#
-#########################
-
-test_ldb = SamDB(url, session_info=session,
-                 credentials=creds,lp=lp)
-
-schemadn = test_ldb.get_schema_basedn()
-
-basedn = test_ldb.get_default_basedn()
-
-'''Will need sysvol to write a basic GUID version dynamic log file'''
-#path = '%s/%s/%s' % (lp.get("path", "sysvol"), lp.get("realm").lower(), 'Policies')
-path = '%s/Policies' % lp.get("realm").lower()
+class GPOServiceSetup:
+	def __init__(self):
+		"""Initialize all components necessary to return instances of
+		a Samba lp context (smb.conf) and Samba LDB context"""
+		self.parser = optparse.OptionParser("testsearchdn [options]")
+		self.sambaopts = options.SambaOptions(self.parser)
+		self.credopts = None
+		self.opts = None
+		self.args = None
+		self.lp = None
+		self.smbconf = None
+		self.creds = None
+		self.url = None
+
+	#Initializers
+	def init_parser(self):
+		'''Get the command line options'''
+		self.parser.add_option_group(self.sambaopts)
+		self.parser.add_option_group(options.VersionOptions(self.parser))
+		self.init_credopts()
+		self.parser.add_option("-H", dest = "url", help="URL for the samdb")
+		self.parser.add_option_group(self.credopts)
+
+	def init_argsopts(self):
+		'''Set the options and the arguments'''
+		(opts, args) = self.parser.parse_args()
+
+		self.opts = opts
+		self.args = args
+
+	def init_credopts(self):
+		'''Set Credential operations'''
+		self.credopts = options.CredentialsOptions(self.parser)
+
+	def init_lp(self):
+		'''Set the loadparm context'''
+		self.lp = self.sambaopts.get_loadparm()
+		self.smbconf = self.lp.configfile
+		if (not self.opts.url):
+			#Compiler says it needs another indent. Weird
+			self.url = self.lp.samdb_url()
+		else:
+			self.url = self.opts.url
+
+	def init_session(self):
+		'''Initialize the session'''
+		self.creds = self.credopts.get_credentials(self.lp, fallback_machine=True)
+		self.session = system_session()
+
+	def InitializeService(self):
+		'''Inializer for the thread'''
+		self.init_parser()
+		self.init_argsopts()
+		self.init_lp()
+		self.init_session()
+	#Getters
+	def Get_LDB(self):
+		'''Return a live instance of Samba'''
+		SambaDB = SamDB(self.url, session_info = self.session, credentials = self.creds, lp = self.lp)
+		return SambaDB
+
+	def Get_lp_Content(self):
+		'''Return an instance of a local lp context'''
+		return self.lp
+
+	def Get_Creds(self):
+		'''Return an instance of a local creds'''
+		return self.creds
+
+def GetBackLog(sys_log):
+	"""Reads BackLog and makes thread aware of which GPO are unchanged or empty
+	:param String sys_log: path to BackLog
+	:return Dictionary previous_scanned_version: {Unedited GPO : Version Number}
+	*NOTE on Version below
+	"""
+	previous_scanned_version = {}
+	if os.path.isfile(sys_log):
+		previous_scanned_version = scan_log(sys_log)
+		return previous_scanned_version
+	else:
+		return None
+
+#Set up the GPO service
+GPOService = GPOServiceSetup()
+GPOService.InitializeService()
+
+#Get the Samba Instance
+test_ldb = GPOService.Get_LDB()
+
+#Get The lp context
+lp = GPOService.Get_lp_Content()
+
+#Get the CREDS
+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')
+BackLoggedGPO  = GetBackLog(sys_log)
+BackLog = open(sys_log, "w")
 
-'''Returns dict from previous logfile, then scraps the logfile '''
-previous_scanned_version = {'a' : 4}
-if os.path.isfile(sys_log):
-    previous_scanned_version = scan_log(sys_log)
-sys_log = open(sys_log, "w")
-
-'''Establishes the hierarchy TODO - insert the link fom Microsoft and vouch why we dont care about site or local'''
-specific_ou = "OU=Domain Controllers"
-'''TODO Definitely get DC from Samba'''
-global_dn = test_ldb.domain_dn()
-print 'The global DN for this domain is ' + global_dn
-DC_OU = specific_ou + ',' + global_dn
 
-net = Net(creds=creds, lp=lp)
 
 # We need to know writable DC to setup SMB connection
-flags = (nbt.NBT_SERVER_LDAP |
+net = Net(creds=creds, lp=lp)
+'''flags = (nbt.NBT_SERVER_LDAP |
+	 nbt.NBT_SERVER_DS |
+	 nbt.NBT_SERVER_WRITABLE)'''
+cldap_ret = net.finddc(domain=lp.get('realm'), flags=(nbt.NBT_SERVER_LDAP |
 	 nbt.NBT_SERVER_DS |
-	 nbt.NBT_SERVER_WRITABLE)
-cldap_ret = net.finddc(domain=lp.get('realm'), flags=flags)
+	 nbt.NBT_SERVER_WRITABLE))
 dc_hostname = cldap_ret.pdc_dns_name
-
 try:
     conn = smb.SMB(dc_hostname, 'sysvol', lp=lp, creds=creds)
 except Exception, e:
     raise Exception("Error connecting to '%s' using SMB" % dc_hostname, e)
 
-guid_list = [x['name'] for x in conn.list(path)]
-#guid_list = os.listdir(path)
-#guid_list = establish_hierarchy(test_ldb, guid_list, DC_OU, global_dn)
+#Get the dn of the domain, and the dn of readable/writable DC
+global_dn = test_ldb.domain_dn()
+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()
 
 
+#TODO Make this a method in itself
+#Write applicable GPO
+
 for guid_eval in hierarchy_gpos.sorted_full:
-    guid = guid_eval[0]
-    gp_extensions = [gp_sec_ext()]
-    local_path = path + '/' + 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 guid_eval[1]:
-        if gpolist[0][1]:
-            if (version != previous_scanned_version.get(guid)) and (version != 0):
-                print ('GPO %s has changed' % guid)
-                gpo_parser(gpolist, test_ldb, conn)
-
-    sys_log.write('%s %i\n' % (guid,version))
+	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 guid_eval[1]:
+	    if gpolist[0][1]:
+	        if (version != BackLoggedGPO.get(guid)) and (version != 0):
+	            print ('GPO %s has changed' % guid)
+	            gpo_parser(gpolist, test_ldb, conn)
+
+	BackLog.write('%s %i\n' % (guid,version))
+
+
+#NOTE Version: *A GPO will :
+	#1)Change Version Number if edited content (policy added or removed)
+	#2)Have a Version Number = 0 if Completely empty of content
+#Obviously we will only Apply GPO that do not fall either of these catagories
-- 
1.9.3



More information about the samba-technical mailing list