TODO gp_privilege_rights_ext
authorStefan Metzmacher <metze@samba.org>
Mon, 22 Apr 2024 16:23:56 +0000 (18:23 +0200)
committerStefan Metzmacher <metze@samba.org>
Mon, 22 Apr 2024 16:23:56 +0000 (18:23 +0200)
python/samba/gp/gp_sec_ext.py
source4/scripting/bin/samba-gpupdate

index 39b9cdced83c5ca3e86f9f144079eafbd58c6ac4..283d4643cb44781761f8fbad9a5d433644e85c21 100644 (file)
@@ -219,3 +219,113 @@ class gp_access_ext(gp_inf_ext):
                 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
index 0f1c9a11aaa0c6fc12dab3141996c6d69df48517..e7cd5c9ab72438d9032b9233a44bd6bced33e9d2 100755 (executable)
@@ -101,6 +101,7 @@ if __name__ == "__main__":
     gp_extensions = []
     if opts.target == 'Computer':
         gp_extensions.append(gp_access_ext)
+        gp_extensions.append(gp_privilege_rights_ext)
         gp_extensions.append(gp_krb_ext)
         gp_extensions.append(gp_scripts_ext)
         gp_extensions.append(gp_sudoers_ext)