from samba.netcmd import gpo as gpo_user
import codecs
from samba import NTSTATUSError
+from ConfigParser import ConfigParser
+from StringIO import StringIO
class gp_ext(object):
def list(self, rootpath):
parameter to Samba4. Not registry oriented whatsoever.
'''
- def __init__(self, ldb, dn, attribute, val):
+ def __init__(self, logger, ldb, dn, attribute, val):
+ self.logger = logger
self.ldb = ldb
self.dn = dn
self.attribute = attribute
self.val = val
def ch_minPwdAge(self, val):
+ self.logger.info('KDC Minimum Password age was changed from %s to %s' % (self.ldb.get_minPwdAge(), val))
self.ldb.set_minPwdAge(val)
def ch_maxPwdAge(self, val):
+ self.logger.info('KDC Maximum Password age was changed from %s to %s' % (self.ldb.get_maxPwdAge(), val))
self.ldb.set_maxPwdAge(val)
def ch_minPwdLength(self, val):
+ self.logger.info('KDC Minimum Password length was changed from %s to %s' % (self.ldb.get_minPwdLength(), val))
self.ldb.set_minPwdLength(val)
def ch_pwdProperties(self, val):
+ self.logger.info('KDC Password Properties were changed from %s to %s' % (self.ldb.get_pwdProperties(), val))
self.ldb.set_pwdProperties(val)
def explicit(self):
count = 0
+ def __init__(self, logger):
+ self.logger = logger
+
def __str__(self):
return "Security GPO extension"
ret = False
inftable = self.populate_inf()
- policy = conn.loadfile(path).decode('utf-16')
+ policy = conn.loadfile(path.replace('/', '\\')).decode('utf-16')
current_section = None
LOG = open(attr_log, "a")
LOG.write(str(path.split('/')[2]) + '\n')
# If at any point in time a GPO was applied,
# then we return that boolean at the end.
- for line in policy.splitlines():
- line = line.strip()
- if line[0] == '[':
- section = line[1: -1]
- current_section = inftable.get(section.encode('ascii', 'ignore'))
-
- else:
- # We must be in a section
- if not current_section:
- continue
- (key, value) = line.split("=")
- key = key.strip()
+ inf_conf = ConfigParser()
+ inf_conf.optionxform=str
+ inf_conf.readfp(StringIO(policy))
+
+ for section in inf_conf.sections():
+ current_section = inftable.get(section)
+ if not current_section:
+ continue
+ for key, value in inf_conf.items(section):
if current_section.get(key):
(att, setter) = current_section.get(key)
value = value.encode('ascii', 'ignore')
ret = True
- setter(self.ldb, self.dn, att, value).update_samba()
+ setter(self.logger, self.ldb, self.dn, att, value).update_samba()
return ret
def parse(self, afile, ldb, conn, attr_log):
return None
-def scan_log(sysvol_path):
- a = open(sysvol_path, "r")
+def scan_log(sysvol_tdb):
data = {}
- for line in a.readlines():
- line = line.strip()
- (guid, version) = line.split(" ")
- data[guid] = int(version)
+ for key in sysvol_tdb.iterkeys():
+ data[key] = sysvol_tdb.get(key)
return data
import sys
import tempfile
import subprocess
+import tdb
sys.path.insert(0, "bin/python")
from samba.net import Net
from samba.dcerpc import nbt
from samba import smb
+import logging
# Finds all GPO Files ending in inf
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 lp context
lp = GPOService.Get_lp_Content()
+# Set up logging
+logger = logging.getLogger('samba_gpoupdate')
+logger.addHandler(logging.StreamHandler(sys.stdout))
+logger.setLevel(logging.CRITICAL)
+log_level = lp.log_level()
+if log_level == 1:
+ logger.setLevel(logging.ERROR)
+elif log_level == 2:
+ logger.setLevel(logging.WARNING)
+elif log_level == 3:
+ logger.setLevel(logging.INFO)
+elif log_level >= 4:
+ logger.setLevel(logging.DEBUG)
+
# 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')
+sys_log = '%s/%s' % (lp.get("path", "sysvol"), 'gpo.tdb')
attr_log = '%s/%s' % (lp.get("path", "sysvol"), 'attrlog.txt')
-BackLoggedGPO = GetBackLog(sys_log)
-BackLog = open(sys_log, "w")
+if os.path.isfile(sys_log):
+ BackLog = tdb.open(sys_log)
+else:
+ BackLog = tdb.Tdb(sys_log, 0, tdb.DEFAULT, os.O_CREAT|os.O_RDWR)
+BackLoggedGPO = scan_log(BackLog)
# We need to know writable DC to setup SMB connection
Reset_Defaults(test_ldb)
GPO_Changed = False
+BackLog.transaction_start()
for guid_eval in hierarchy_gpos:
guid = guid_eval[0]
- gp_extensions = [gp_sec_ext()]
+ gp_extensions = [gp_sec_ext(logger)]
local_path = '%s/Policies' % lp.get("realm").lower() + '/' + guid + '/'
- version = gpo.gpo_get_sysvol_gpt_version(lp.get("path", "sysvol") + '/' + local_path)[1]
+ version = int(gpo.gpo_get_sysvol_gpt_version(lp.get("path", "sysvol") + '/' + local_path)[1])
+ try:
+ old_version = int(BackLoggedGPO.get(guid))
+ except:
+ old_version = -1
gpolist = gp_path_list(local_path)
- if(version != BackLoggedGPO.get(guid)):
+ if version != old_version:
GPO_Changed = True
# If the GPO has a dn that is applicable to Samba
if guid_eval[1]:
# If it we have not read it before and is not empty
# Rewrite entire logfile here
if (version != 0) and GPO_Changed == True:
- change_backlog = gpo_parser(gpolist, test_ldb, conn, attr_log)
+ logger.info('GPO %s has changed' % guid)
+ try:
+ change_backlog = gpo_parser(gpolist, test_ldb, conn, attr_log)
+ except:
+ logger.error('Failed to parse gpo %s' % guid)
+ continue
+ BackLog.store(guid, '%i' % version)
+BackLog.transaction_commit()
+BackLog.close()
- BackLog.write('%s %i\n' % (guid, version))