From 657b1b36ed64509a16db29cbd7229f51a7a2ab78 Mon Sep 17 00:00:00 2001 From: Lukas Oyen Date: Thu, 8 Jun 2017 17:25:13 +0200 Subject: [PATCH 1/3] Bug #38238: umc-diagnostic: new check well_known_sid_check.py --- .../diagnostic/plugins/well_known_sid_check.py | 153 +++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100755 management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/well_known_sid_check.py diff --git a/management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/well_known_sid_check.py b/management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/well_known_sid_check.py new file mode 100755 index 0000000..6a58edf --- /dev/null +++ b/management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/well_known_sid_check.py @@ -0,0 +1,153 @@ +#!/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 socket + +import univention.uldap +import univention.lib.s4 as s4 +import univention.config_registry +from univention.management.console.modules.diagnostic import Warning + +from univention.lib.i18n import Translation +_ = Translation('univention-management-console-module-diagnostic').translate + +title = _('Check well known SIDs') +description = _('All SIDs exist and names are consistent.') + + +NON_EXISTENT_SIDS = set(('Power Users', 'Creator Group Server', + 'Creator Owner Server', 'Local', 'Console Logon', 'All Services', + 'Creator Authority', 'Local Authority', 'NT Authority', + 'Non-unique Authority', 'Cloneable Domain Controllers')) + + +class CheckError(Exception): + def __init__(self, sid, expected_name): + self.sid = sid + self.expected_name = expected_name + + +class SIDNotFound(CheckError): + def __str__(self): + msg = _('No user or group with SID {sid} found, expected {expected!r}.') + return msg.format(sid=self.sid, expected=self.expected_name) + + +class NameMismatch(CheckError): + def __init__(self, sid, expected_name, actual_name): + super(NameMismatch, self).__init__(sid, expected_name) + self.actual_name = actual_name + + def __str__(self): + msg = _('User or group with SID {sid} has name {actual!r}, but should be {expected!r}.') + return msg.format(sid=self.sid, actual=self.actual_name, expected=self.expected_name) + + +class LDAPConnection(object): + def __init__(self): + self._connection = univention.uldap.getMachineConnection() + self._ucr = univention.config_registry.ConfigRegistry() + self._ucr.load() + + def _map_group_name(self, name): + if name is None: + return name + return self._ucr.get('connector/s4/mapping/group/table/{}'.format(name)) or name + + def search(self, expression, attr=[]): + for (dn, attr) in self._connection.search(expression, attr=attr): + if dn is not None: + yield (dn, attr) + + def get_domain_sid(self): + for (dn, attr) in self.search('(objectClass=sambaDomain)', attr=['sambaSID']): + for sid in attr.get('sambaSID'): + return sid + raise KeyError('domain sid not found') + + def get_by_sid(self, sid): + expression = ldap.filter.filter_format('(sambaSID=%s)', (sid,)) + for (dn, attr) in self.search(expression, attr=['cn', 'uid']): + for uid in attr.get('uid', []): + return uid + for cn in attr.get('cn', []): + return self._map_group_name(cn) + raise KeyError(sid) + + +def all_sids_and_names(domain_sid): + for (sid, name) in s4.well_known_sids.iteritems(): + if name not in NON_EXISTENT_SIDS: + yield (sid, name) + + for (rid, name) in s4.well_known_domain_rids.iteritems(): + if name not in NON_EXISTENT_SIDS: + yield ('{}-{}'.format(domain_sid, rid), name) + + +def check_existence_and_consistency(): + ldap_connection = LDAPConnection() + domain_sid = ldap_connection.get_domain_sid() + for (sid, expected_name) in all_sids_and_names(domain_sid): + try: + actual_name = ldap_connection.get_by_sid(sid) + except KeyError as error: + yield SIDNotFound(error.message, expected_name) + else: + if actual_name != expected_name: + yield NameMismatch(sid, expected_name, actual_name) + + +def is_service_active(service): + lo = univention.uldap.getMachineConnection() + raw_filter = '(&(univentionService=%s)(cn=%s))' + filter_expr = ldap.filter.filter_format(raw_filter, (service, socket.gethostname())) + for (dn, _attr) in lo.search(filter_expr, attr=['cn']): + if dn is not None: + return True + return False + + +def run(): + if not is_service_active('S4 Connector'): + return + + check_errors = list(check_existence_and_consistency()) + if check_errors: + raise Warning(description='\n'.join(str(x) for x in check_errors)) + + +if __name__ == '__main__': + from univention.management.console.modules.diagnostic import main + main() -- 2.7.4 From 8da62c4caee166f45fd94606f91db155d88f89c5 Mon Sep 17 00:00:00 2001 From: Lukas Oyen Date: Thu, 8 Jun 2017 17:38:06 +0200 Subject: [PATCH 2/3] Bug #38238: umc-diagnostic: new check well_known_sid_check.py (po) --- .../umc/python/diagnostic/de.po | 25 ++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/management/univention-management-console-module-diagnostic/umc/python/diagnostic/de.po b/management/univention-management-console-module-diagnostic/umc/python/diagnostic/de.po index affad86..f9dbed7 100644 --- a/management/univention-management-console-module-diagnostic/umc/python/diagnostic/de.po +++ b/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-12 13:53+0200\n" "PO-Revision-Date: \n" "Last-Translator: Univention GmbH \n" "Language-Team: Univention GmbH \n" @@ -27,6 +27,14 @@ msgstr "" msgid "Adjust to suggested limits" msgstr "An vorgeschlagene Limits anpassen" +#: umc/python/diagnostic/plugins/well_known_sid_check.py:46 +msgid "All SIDs exist and names are consistent." +msgstr "Alle SIDs existieren und die Namen sind konsistent." + +#: umc/python/diagnostic/plugins/well_known_sid_check.py:45 +msgid "Check well known SIDs" +msgstr "Überprüfe 'Well Known' SIDs" + #: umc/python/diagnostic/plugins/gateway.py:11 msgid "Gateway is not reachable" msgstr "Gateway ist nicht erreichbar" @@ -97,6 +105,12 @@ msgstr "" msgid "Nameserver(s) are not responsive" msgstr "Nameserver sind nicht ansprechbar" +#: umc/python/diagnostic/plugins/well_known_sid_check.py:64 +msgid "No user or group with SID {sid} found, expected {expected!r}." +msgstr "" +"Kein Nutzer oder keine Gruppe mit SID {sid} gefunden, {expected!r} war " +"erwartet." + #: umc/python/diagnostic/plugins/package_status.py:11 msgid "Package status corrupt" msgstr "Paketstatus korrupt" @@ -260,6 +274,13 @@ msgstr "" "dass Authentifikations-Zugangsdaten (falls existierend) korrekt sind und die " "ACL's des Proxy-Servers nicht verbieten, Anfragen an %s zu stellen." +#: umc/python/diagnostic/plugins/well_known_sid_check.py:74 +msgid "" +"User or group with SID {sid} has name {actual!r}, but should be {expected!r}." +msgstr "" +"Der Nutzer oder die Gruppe mit der SID {sid} hat den Namen {actual!r}, " +"sollte aber {expected!r} sein." + #: umc/python/diagnostic/plugins/package_status.py:28 msgid "some" msgstr "einigen" -- 2.7.4 From 95509e37fd7995ea7406757804e423601d2b0b5c Mon Sep 17 00:00:00 2001 From: Lukas Oyen Date: Thu, 8 Jun 2017 17:26:41 +0200 Subject: [PATCH 3/3] Bug #38238: umc-diagnostic: case insensitive check in well_known_sid_check This is necessary for 'Enterprise Read-Only Domain Controllers' ('Enterprise Read-only Domain Controllers' in u.lib.s4) 'krbtgt' ('KRBTGT' in u.lib.s4). --- .../umc/python/diagnostic/plugins/well_known_sid_check.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/well_known_sid_check.py b/management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/well_known_sid_check.py index 6a58edf..902fb97 100755 --- a/management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/well_known_sid_check.py +++ b/management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/well_known_sid_check.py @@ -125,7 +125,7 @@ def check_existence_and_consistency(): except KeyError as error: yield SIDNotFound(error.message, expected_name) else: - if actual_name != expected_name: + if actual_name.lower() != expected_name.lower(): yield NameMismatch(sid, expected_name, actual_name) -- 2.7.4