@@ -, +, @@
---
.../python/diagnostic/plugins/file_permissions.py | 168 +++++++++++++++++++++
1 file changed, 168 insertions(+)
create mode 100755 management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/file_permissions.py
--- a/management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/file_permissions.py
+++ a/management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/file_permissions.py
@@ -0,0 +1,168 @@
+#!/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 os
+import pwd
+import grp
+import stat
+import glob
+
+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 file permissions')
+description = _('All files ok.')
+
+
+class CheckError(Exception):
+ def __init__(self, filename):
+ self.filename = filename
+
+
+class DoesNotExist(CheckError):
+ def __str__(self):
+ return _('File {path!r} does not exist.'.format(path=self.filename))
+
+
+class OwnerMismatch(CheckError):
+ def __init__(self, filename, expected_owner, actual_owner):
+ super(OwnerMismatch, self).__init__(filename)
+ self.expected_owner = expected_owner
+ self.actual_owner = actual_owner
+
+ def __str__(self):
+ msg = _('File {path!r} has owner {actual!r} while {expected!r} was expected.')
+ return msg.format(path=self.filename,
+ expected=':'.join(self.expected_owner),
+ actual=':'.join(self.actual_owner))
+
+
+class PermissionMismatch(CheckError):
+ def __init__(self, filename, actual_mode, expected_mode):
+ super(PermissionMismatch, self).__init__(filename)
+ self.actual_mode = actual_mode
+ self.expected_mode = expected_mode
+
+ def __str__(self):
+ msg = _('File {path!r} has mode {actual:o}, {expected:o} was expected.')
+ return msg.format(path=self.filename, actual=self.actual_mode,
+ expected=self.expected_mode)
+
+
+def get_actual_owner(uid, gid):
+ try:
+ name = pwd.getpwuid(uid).pw_name
+ except KeyError:
+ name = str(uid)
+ try:
+ group = grp.getgrgid(gid).gr_name
+ except KeyError:
+ group = str(gid)
+ return (name, group)
+
+
+def check_file(path, owner, group, mode, must_exist=False):
+ try:
+ file_stat = os.stat(path)
+ except EnvironmentError:
+ if must_exist:
+ return DoesNotExist(path)
+ return True
+
+ expected_owner = (owner, group)
+ actual_owner = get_actual_owner(file_stat.st_uid, file_stat.st_gid)
+ if expected_owner != actual_owner:
+ return OwnerMismatch(path, expected_owner, actual_owner)
+
+ actual_mode = stat.S_IMODE(file_stat.st_mode)
+ if actual_mode != mode:
+ return PermissionMismatch(path, actual_mode, mode)
+
+ return True
+
+
+def file_and_permission_checks():
+ configRegistry = univention.config_registry.ConfigRegistry()
+ configRegistry.load()
+
+ yield check_file('/etc/ldap.secret', 'root', 'DC Backup Hosts', 0640, must_exist=True)
+ yield check_file('/etc/machine.secret', 'root', 'root', 0600, must_exist=True)
+ yield check_file('/etc/pam_ldap.secret', 'root', 'root', 0600, must_exist=True)
+ yield check_file('/etc/idp-ldap-user.secret', 'root', 'DC Backup Hosts', 0640, must_exist=True)
+ yield check_file('/etc/libnss-ldap.conf', 'messagebus', 'root', 0440, must_exist=True)
+ yield check_file('/var/run/slapd/ldapi', 'root', 'root', 0700)
+
+ (host, domain) = (configRegistry.get('hostname'), configRegistry.get('domainname'))
+ yield check_file('/etc/univention/ssl', 'root', 'DC Backup Hosts', 0755, must_exist=True)
+ yield check_file('/etc/univention/ssl/openssl.cnf', 'root', 'DC Backup Hosts', 0660, must_exist=True)
+ yield check_file('/etc/univention/ssl/password', 'root', 'DC Backup Hosts', 0660, must_exist=True)
+ yield check_file('/etc/univention/ssl/ucsCA', 'root', 'DC Backup Hosts', 0775, must_exist=True)
+ yield check_file('/etc/univention/ssl/ucs-sso.{}'.format(domain), 'root', 'DC Backup Hosts', 0750, must_exist=True)
+ yield check_file('/etc/univention/ssl/{}.{}'.format(host, domain), '{}$'.format(host), 'DC Backup Hosts', 0750, must_exist=True)
+
+ yield check_file('/var/lib/univention-self-service-passwordreset-umc/memcached.socket', 'self-service-umc', 'nogroup', 0600)
+ yield check_file('/var/run/univention-saml/memcached.socket', 'samlcgi', 'root', 0600)
+ yield check_file('/var/run/uvmm.socket', 'root', 'root', 0755)
+ for path in glob.iglob('/var/run/univention-management-console/*.socket'):
+ yield check_file(path, 'root', 'root', 0700)
+
+ for path in glob.iglob('/var/cache/univention-*'):
+ if path == '/var/cache/univention-quota':
+ yield check_file(path, 'root', 'root', 0750)
+ elif path == '/var/cache/univention-system-setup':
+ yield check_file(path, 'root', 'root', 0700)
+ else:
+ yield check_file(path, 'root', 'root', 0755)
+
+ for path in glob.iglob('/etc/univention/connector/*.sqlite'):
+ yield check_file(path, 'root', 'root', 0644)
+
+ saml_key = configRegistry.get('saml/idp/certificate/privatekey')
+ if saml_key:
+ yield check_file(saml_key, 'root', 'samlcgi', 0640, must_exist=True)
+
+
+def run():
+ error_descriptions = [str(error) for error in file_and_permission_checks()
+ if isinstance(error, CheckError)]
+ if error_descriptions:
+ raise Warning(description='\n'.join(error_descriptions))
+
+
+if __name__ == '__main__':
+ run()
+ from univention.management.console.modules.diagnostic import main
+ main()
--
(po)
---
.../umc/python/diagnostic/de.po | 26 ++++++++++++++++++++--
1 file changed, 24 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-12 17:02+0200\n"
"PO-Revision-Date: \n"
"Last-Translator: Univention GmbH \n"
"Language-Team: Univention GmbH \n"
@@ -27,6 +27,28 @@ msgstr ""
msgid "Adjust to suggested limits"
msgstr "An vorgeschlagene Limits anpassen"
+#: umc/python/diagnostic/plugins/file_permissions.py:47
+msgid "All files ok."
+msgstr "Alle Dateien in Ordnung."
+
+#: umc/python/diagnostic/plugins/file_permissions.py:46
+msgid "Check file permissions"
+msgstr "Überprüfe Datei Berechtigungen"
+
+#: umc/python/diagnostic/plugins/file_permissions.py:57
+msgid "File {path!r} does not exist."
+msgstr "Datei {path!r} existiert nicht."
+
+#: umc/python/diagnostic/plugins/file_permissions.py:80
+msgid "File {path!r} has mode {actual:o}, {expected:o} was expected."
+msgstr "Datei {path!r} hat Datei-Modus {actual:o}, {expected:o} war erwartet."
+
+#: umc/python/diagnostic/plugins/file_permissions.py:67
+msgid "File {path!r} has owner {actual!r} while {expected!r} was expected."
+msgstr ""
+"Datei {path!r} hat den Besitzer {actual!r}, während {expected!r} erwartet "
+"war."
+
#: umc/python/diagnostic/plugins/gateway.py:11
msgid "Gateway is not reachable"
msgstr "Gateway ist nicht erreichbar"
--