@@ -, +, @@
`inconsistent_policies.py`
---
.../diagnostic/plugins/inconsistent_policies.py | 184 +++++++++++++++++++++
1 file changed, 184 insertions(+)
create mode 100755 management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/inconsistent_policies.py
--- a/management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/inconsistent_policies.py
+++ a/management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/inconsistent_policies.py
@@ -0,0 +1,184 @@
+#!/usr/bin/python2.7
+# coding: utf-8
+#
+# Univention Management Console module:
+# System Diagnosis UMC module
+#
+# Copyright 2017 Univention GmbH
+#
+# http://www.univention.de/
+#
+# All rights reserved.
+#
+# The source code of this program is made available
+# under the terms of the GNU Affero General Public License version 3
+# (GNU AGPL V3) as published by the Free Software Foundation.
+#
+# Binary versions of this program provided by Univention to you as
+# well as other copyrighted, protected or trademarked materials like
+# Logos, graphics, fonts, specific documentations and configurations,
+# cryptographic keys etc. are subject to a license agreement between
+# you and Univention and not subject to the GNU AGPL V3.
+#
+# In the case you use this program under the terms of the GNU AGPL V3,
+# the program is provided in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public
+# License with the Debian GNU/Linux or Univention distribution in file
+# /usr/share/common-licenses/AGPL-3; if not, see
+# .
+
+import ldap
+
+import univention.uldap
+import univention.admin.uldap
+import univention.admin.modules as udm_modules
+from univention.management.console.modules.diagnostic import Warning
+
+from univention.lib.i18n import Translation
+_ = Translation('univention-management-console-module-diagnostic').translate
+
+title = _('Check password policy inconsistencies')
+description = _('No problems found.')
+
+
+def fix_policies():
+ for mismatch in check_policies():
+ mismatch.fix()
+ return run()
+
+
+actions = {
+ 'fix_policies': fix_policies,
+}
+
+
+class PolicyMismatch(Exception):
+ def __init__(self, policy, mismatches):
+ super(PolicyMismatch, self).__init__(policy.dn)
+ self.policy = policy
+ self.mismatches = mismatches
+
+ def __str__(self):
+ msg = _('In policy {name!r} (see {{udm:policies/policy}}):')
+ messages = [msg.format(name=self.policy.get('name'))]
+ empty_tmpl = _('Attribute {attr} should be empty.')
+ mismatch_tmpl = _('Attribute {attr} should have value {value}.')
+ properties = udm_modules.get(self.policy.module).property_descriptions
+
+ for (attr, value) in self.mismatches:
+ template = empty_tmpl if value is None else mismatch_tmpl
+ attr_desc = properties.get(attr).short_description
+ messages.append(template.format(attr=attr_desc, value=value))
+ return '\n'.join(messages)
+
+ def module(self):
+ return {
+ 'module': 'udm',
+ 'flavor': 'policies/policy',
+ 'props': {
+ 'openObject': {
+ 'objectDN': self.policy.dn,
+ 'objectType': 'policies/pwhistory'
+ }
+ }
+ }
+
+ def fix(self):
+ for (attr, value) in self.mismatches:
+ self.policy[attr] = value
+ self.policy.modify()
+
+
+def get_samba_domain(ldap_connection, position):
+ module = udm_modules.get('settings/sambadomain')
+ udm_modules.init(ldap_connection, position, module)
+ for sambadomain in module.lookup(None, ldap_connection, ''):
+ sambadomain.open()
+ return sambadomain
+
+
+def policy_used(ldap_connection, dn):
+ filter_expr = ldap.filter.filter_format('(univentionPolicyReference=%s)', (dn,))
+ search = ldap_connection.search(filter=filter_expr, sizelimit=3, attr=['dn'])
+ return any(dn is not None for (dn, attr) in search)
+
+
+def get_pw_policies(ldap_connection, position):
+ module = udm_modules.get('policies/pwhistory')
+ udm_modules.init(ldap_connection, position, module)
+ for policy in module.lookup(None, ldap_connection, ''):
+ if policy_used(ldap_connection, policy.dn):
+ policy.open()
+ yield policy
+
+
+def to_days(unix_time_interval, default_unit='seconds'):
+ if unix_time_interval is None:
+ return None
+
+ try:
+ (value, unit) = unix_time_interval
+ except ValueError:
+ (value, unit) = (unix_time_interval, default_unit)
+
+ try:
+ as_int = int(value)
+ except ValueError:
+ as_int = 0
+
+ if unit == 'days':
+ return str(as_int)
+ elif unit == 'hours':
+ return str(as_int / 24)
+ elif unit == 'minutes':
+ return str(as_int / (24 * 60))
+ return str(as_int / (24 * 60 * 60))
+
+
+def policy_mismatch(samba_domain, pw_policy):
+ def compare(policy_attr, domain_attr, convert=lambda x: x):
+ (policy_value, domain_value) = (pw_policy.get(policy_attr), samba_domain.get(domain_attr))
+ converted_domain_value = convert(domain_value)
+ if policy_value != converted_domain_value:
+ yield (policy_attr, converted_domain_value)
+
+ for result in compare('length', 'passwordHistory'):
+ yield result
+ for result in compare('pwLength', 'passwordLength'):
+ yield result
+ for result in compare('expiryInterval', 'maxPasswordAge', to_days):
+ yield result
+
+
+def check_policies():
+ (ldap_connection, position) = univention.admin.uldap.getAdminConnection()
+ samba_domain = get_samba_domain(ldap_connection, position)
+ for policy in get_pw_policies(ldap_connection, position):
+ mismatch = list(policy_mismatch(samba_domain, policy))
+ if mismatch:
+ yield PolicyMismatch(policy, mismatch)
+
+
+def run():
+ univention.admin.modules.update()
+ problems = list(check_policies())
+ error = _('There are inconsistencies between the Univention policies and the Samba settings.')
+ buttons = [{
+ 'action': 'fix_policies',
+ 'label': _('Fix password policies'),
+ }]
+
+ if problems:
+ ed = [error, '']
+ ed.extend(str(error) for error in problems)
+ umc_modules = [e.module() for e in problems]
+ raise Warning(description='\n'.join(ed), umc_modules=umc_modules, buttons=buttons)
+
+
+if __name__ == '__main__':
+ from univention.management.console.modules.diagnostic import main
+ main()
--
`inconsistent_policies.py` (po)
---
.../umc/python/diagnostic/de.po | 36 ++++++++++++++++++++--
1 file changed, 34 insertions(+), 2 deletions(-)
--- a/management/univention-management-console-module-diagnostic/umc/python/diagnostic/de.po
+++ a/management/univention-management-console-module-diagnostic/umc/python/diagnostic/de.po
@@ -2,8 +2,8 @@
msgid ""
msgstr ""
"Project-Id-Version: univention-management-console-module-diagnostic\n"
-"Report-Msgid-Bugs-To: packages@univention.de\n"
-"POT-Creation-Date: 2016-01-14 12:19+0100\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2017-06-29 14:47+0200\n"
"PO-Revision-Date: \n"
"Last-Translator: Univention GmbH \n"
"Language-Team: Univention GmbH \n"
@@ -27,6 +27,22 @@ msgstr ""
msgid "Adjust to suggested limits"
msgstr "An vorgeschlagene Limits anpassen"
+#: umc/python/diagnostic/plugins/inconsistent_policies.py:69
+msgid "Attribute {attr} should be empty."
+msgstr "Attribut {attr} sollte nicht gesetzt sein."
+
+#: umc/python/diagnostic/plugins/inconsistent_policies.py:70
+msgid "Attribute {attr} should have value {value}."
+msgstr "Attribut {attr} sollte den Wert {value} haben."
+
+#: umc/python/diagnostic/plugins/inconsistent_policies.py:44
+msgid "Check password policy inconsistencies"
+msgstr "Überprüfe Password Richtlinien"
+
+#: umc/python/diagnostic/plugins/inconsistent_policies.py:171
+msgid "Fix password policies"
+msgstr "Berichtige Password Richtlinien"
+
#: umc/python/diagnostic/plugins/gateway.py:11
msgid "Gateway is not reachable"
msgstr "Gateway ist nicht erreichbar"
@@ -49,6 +65,10 @@ msgid "If these settings are correct the problem relies in the gateway itself:"
msgstr ""
"Wenn diese Einstellungen richtig sind liegt das Problem im Gateway selbst:"
+#: umc/python/diagnostic/plugins/inconsistent_policies.py:66
+msgid "In policy {name!r} (see {{udm:policies/policy}}):"
+msgstr "In der Richtlinie {name!r} (siehe {{udm:policies/policy}}):"
+
#: umc/python/diagnostic/plugins/security_limits.py:19
#, python-brace-format
msgid ""
@@ -97,6 +117,10 @@ msgstr ""
msgid "Nameserver(s) are not responsive"
msgstr "Nameserver sind nicht ansprechbar"
+#: umc/python/diagnostic/plugins/inconsistent_policies.py:45
+msgid "No problems found."
+msgstr "Keine Probleme gefunden."
+
#: umc/python/diagnostic/plugins/package_status.py:11
msgid "Package status corrupt"
msgstr "Paketstatus korrupt"
@@ -231,6 +255,14 @@ msgstr ""
"Der SSH Host-Key des entfernten Rechners hat sich geändert (vielleicht wurde "
"der Rechner neu installiert). "
+#: umc/python/diagnostic/plugins/inconsistent_policies.py:168
+msgid ""
+"There are inconsistencies between the Univention policies and the Samba "
+"settings."
+msgstr ""
+"Es gibt Widersprüche in den Univention Password Richtlinien und den Samba "
+"Einstellungen."
+
#: umc/python/diagnostic/plugins/proxy.py:16
msgid ""
"There was an error using the proxy server. The {setup:network} can be used "
--