output[section] = {k: v for k, v in inf_conf.items(section)
if gp_access_ext.apply_map.get(k)}
return output
+
+class gp_privilege_rights_ext(gp_inf_ext):
+ """This class takes the .inf file parameter (essentially a GPO file mapped
+ to a GUID), hashmaps it to the Samba parameter, which then uses an ldb
+ object to update the parameter to Samba4. Not registry oriented whatsoever.
+ """
+
+ def load_ldb(self):
+ try:
+ private_dir = lp.get("private dir")
+ privilege_ldb_path = os.path.join(paths.private_dir, "privilege.ldb")
+ self.privileges_ldb = Ldb(privilege_ldb_path,
+ session_info=system_session(),
+ lp=self.lp)
+ except (NameError, LdbError):
+ raise Exception('Failed to load SamDB for assigning Group Policy')
+
+ apply_map = { 'MinimumPasswordAge': 'minPwdAge',
+ 'MaximumPasswordAge': 'maxPwdAge',
+ 'MinimumPasswordLength': 'minPwdLength',
+ 'PasswordComplexity': 'pwdProperties' }
+ def process_group_policy(self, deleted_gpo_list, changed_gpo_list):
+ if self.lp.get('server role') != 'active directory domain controller':
+ return
+ self.load_ldb()
+ inf_file = 'MACHINE/Microsoft/Windows NT/SecEdit/GptTmpl.inf'
+ for guid, settings in deleted_gpo_list:
+ self.gp_db.set_guid(guid)
+ for section in settings.keys():
+ if section == str(self):
+ for att, value in settings[section].items():
+ update_samba, _ = self.mapper().get(att)
+ update_samba(att, value)
+ self.gp_db.delete(section, att)
+ self.gp_db.commit()
+
+ for gpo in changed_gpo_list:
+ if gpo.file_sys_path:
+ self.gp_db.set_guid(gpo.name)
+ path = os.path.join(gpo.file_sys_path, inf_file)
+ inf_conf = self.parse(path)
+ if not inf_conf:
+ continue
+ for section in inf_conf.sections():
+ if section == str(self):
+ for key, value in inf_conf.items(section):
+ if key not in gp_access_ext.apply_map:
+ continue
+ att = gp_access_ext.apply_map[key]
+ (update_samba, value_func) = self.mapper().get(att)
+ update_samba(att, value_func(value))
+ self.gp_db.commit()
+
+ def ch_minPwdAge(self, attribute, val):
+ old_val = self.ldb.get_minPwdAge()
+ log.info('KDC Minimum Password age was changed from %s to %s'
+ % (old_val, val))
+ self.gp_db.store(str(self), attribute, str(old_val))
+ self.ldb.set_minPwdAge(val)
+
+ def ch_maxPwdAge(self, attribute, val):
+ old_val = self.ldb.get_maxPwdAge()
+ log.info('KDC Maximum Password age was changed from %s to %s'
+ % (old_val, val))
+ self.gp_db.store(str(self), attribute, str(old_val))
+ self.ldb.set_maxPwdAge(val)
+
+ def ch_minPwdLength(self, attribute, val):
+ old_val = self.ldb.get_minPwdLength()
+ log.info('KDC Minimum Password length was changed from %s to %s'
+ % (old_val, val))
+ self.gp_db.store(str(self), attribute, str(old_val))
+ self.ldb.set_minPwdLength(val)
+
+ def ch_pwdProperties(self, attribute, val):
+ old_val = self.ldb.get_pwdProperties()
+ log.info('KDC Password Properties were changed from %s to %s'
+ % (old_val, val))
+ self.gp_db.store(str(self), attribute, str(old_val))
+ self.ldb.set_pwdProperties(val)
+
+ def mapper(self):
+ """ldap value : samba setter"""
+ return {"minPwdAge": (self.ch_minPwdAge, days2rel_nttime),
+ "maxPwdAge": (self.ch_maxPwdAge, days2rel_nttime),
+ # Could be none, but I like the method assignment in
+ # update_samba
+ "minPwdLength": (self.ch_minPwdLength, lambda val: val),
+ "pwdProperties": (self.ch_pwdProperties, lambda val: val),
+
+ }
+
+ def __str__(self):
+ return 'Privilege Rights'
+
+ def rsop(self, gpo):
+ output = {}
+ if self.lp.get('server role') != 'active directory domain controller':
+ return output
+ inf_file = 'MACHINE/Microsoft/Windows NT/SecEdit/GptTmpl.inf'
+ if gpo.file_sys_path:
+ path = os.path.join(gpo.file_sys_path, inf_file)
+ inf_conf = self.parse(path)
+ if not inf_conf:
+ return output
+ if str(self) in inf_conf.sections():
+ section = str(self)
+ output[section] = {k: v for k, v in inf_conf.items(section)
+ if gp_access_ext.apply_map.get(k)}
+ return output