|
0 |
- |
1 |
#!/usr/bin/python2.7 |
|
|
2 |
# coding: utf-8 |
3 |
# |
4 |
# Univention Management Console module: |
5 |
# System Diagnosis UMC module |
6 |
# |
7 |
# Copyright 2017 Univention GmbH |
8 |
# |
9 |
# http://www.univention.de/ |
10 |
# |
11 |
# All rights reserved. |
12 |
# |
13 |
# The source code of this program is made available |
14 |
# under the terms of the GNU Affero General Public License version 3 |
15 |
# (GNU AGPL V3) as published by the Free Software Foundation. |
16 |
# |
17 |
# Binary versions of this program provided by Univention to you as |
18 |
# well as other copyrighted, protected or trademarked materials like |
19 |
# Logos, graphics, fonts, specific documentations and configurations, |
20 |
# cryptographic keys etc. are subject to a license agreement between |
21 |
# you and Univention and not subject to the GNU AGPL V3. |
22 |
# |
23 |
# In the case you use this program under the terms of the GNU AGPL V3, |
24 |
# the program is provided in the hope that it will be useful, |
25 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
26 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
27 |
# GNU Affero General Public License for more details. |
28 |
# |
29 |
# You should have received a copy of the GNU Affero General Public |
30 |
# License with the Debian GNU/Linux or Univention distribution in file |
31 |
# /usr/share/common-licenses/AGPL-3; if not, see |
32 |
# <http://www.gnu.org/licenses/>. |
33 |
|
34 |
import os |
35 |
import pwd |
36 |
import grp |
37 |
import stat |
38 |
import glob |
39 |
|
40 |
import univention.config_registry |
41 |
from univention.management.console.modules.diagnostic import Warning |
42 |
|
43 |
from univention.lib.i18n import Translation |
44 |
_ = Translation('univention-management-console-module-diagnostic').translate |
45 |
|
46 |
title = _('Check file permissions') |
47 |
description = _('All files ok.') |
48 |
|
49 |
|
50 |
class CheckError(Exception): |
51 |
def __init__(self, filename): |
52 |
self.filename = filename |
53 |
|
54 |
|
55 |
class DoesNotExist(CheckError): |
56 |
def __str__(self): |
57 |
return _('File {path!r} does not exist.'.format(path=self.filename)) |
58 |
|
59 |
|
60 |
class OwnerMismatch(CheckError): |
61 |
def __init__(self, filename, expected_owner, actual_owner): |
62 |
super(OwnerMismatch, self).__init__(filename) |
63 |
self.expected_owner = expected_owner |
64 |
self.actual_owner = actual_owner |
65 |
|
66 |
def __str__(self): |
67 |
msg = _('File {path!r} has owner {actual!r} while {expected!r} was expected.') |
68 |
return msg.format(path=self.filename, |
69 |
expected=':'.join(self.expected_owner), |
70 |
actual=':'.join(self.actual_owner)) |
71 |
|
72 |
|
73 |
class PermissionMismatch(CheckError): |
74 |
def __init__(self, filename, actual_mode, expected_mode): |
75 |
super(PermissionMismatch, self).__init__(filename) |
76 |
self.actual_mode = actual_mode |
77 |
self.expected_mode = expected_mode |
78 |
|
79 |
def __str__(self): |
80 |
msg = _('File {path!r} has mode {actual:o}, {expected:o} was expected.') |
81 |
return msg.format(path=self.filename, actual=self.actual_mode, |
82 |
expected=self.expected_mode) |
83 |
|
84 |
|
85 |
def get_actual_owner(uid, gid): |
86 |
try: |
87 |
name = pwd.getpwuid(uid).pw_name |
88 |
except KeyError: |
89 |
name = str(uid) |
90 |
try: |
91 |
group = grp.getgrgid(gid).gr_name |
92 |
except KeyError: |
93 |
group = str(gid) |
94 |
return (name, group) |
95 |
|
96 |
|
97 |
def check_file(path, owner, group, mode, must_exist=False): |
98 |
try: |
99 |
file_stat = os.stat(path) |
100 |
except EnvironmentError: |
101 |
if must_exist: |
102 |
return DoesNotExist(path) |
103 |
return True |
104 |
|
105 |
expected_owner = (owner, group) |
106 |
actual_owner = get_actual_owner(file_stat.st_uid, file_stat.st_gid) |
107 |
if expected_owner != actual_owner: |
108 |
return OwnerMismatch(path, expected_owner, actual_owner) |
109 |
|
110 |
actual_mode = stat.S_IMODE(file_stat.st_mode) |
111 |
if actual_mode != mode: |
112 |
return PermissionMismatch(path, actual_mode, mode) |
113 |
|
114 |
return True |
115 |
|
116 |
|
117 |
def file_and_permission_checks(): |
118 |
configRegistry = univention.config_registry.ConfigRegistry() |
119 |
configRegistry.load() |
120 |
|
121 |
yield check_file('/etc/ldap.secret', 'root', 'DC Backup Hosts', 0640, must_exist=True) |
122 |
yield check_file('/etc/machine.secret', 'root', 'root', 0600, must_exist=True) |
123 |
yield check_file('/etc/pam_ldap.secret', 'root', 'root', 0600, must_exist=True) |
124 |
yield check_file('/etc/idp-ldap-user.secret', 'root', 'DC Backup Hosts', 0640, must_exist=True) |
125 |
yield check_file('/etc/libnss-ldap.conf', 'messagebus', 'root', 0440, must_exist=True) |
126 |
yield check_file('/var/run/slapd/ldapi', 'root', 'root', 0700) |
127 |
|
128 |
(host, domain) = (configRegistry.get('hostname'), configRegistry.get('domainname')) |
129 |
yield check_file('/etc/univention/ssl', 'root', 'DC Backup Hosts', 0755, must_exist=True) |
130 |
yield check_file('/etc/univention/ssl/openssl.cnf', 'root', 'DC Backup Hosts', 0660, must_exist=True) |
131 |
yield check_file('/etc/univention/ssl/password', 'root', 'DC Backup Hosts', 0660, must_exist=True) |
132 |
yield check_file('/etc/univention/ssl/ucsCA', 'root', 'DC Backup Hosts', 0775, must_exist=True) |
133 |
yield check_file('/etc/univention/ssl/ucs-sso.{}'.format(domain), 'root', 'DC Backup Hosts', 0750, must_exist=True) |
134 |
yield check_file('/etc/univention/ssl/{}.{}'.format(host, domain), '{}$'.format(host), 'DC Backup Hosts', 0750, must_exist=True) |
135 |
|
136 |
yield check_file('/var/lib/univention-self-service-passwordreset-umc/memcached.socket', 'self-service-umc', 'nogroup', 0600) |
137 |
yield check_file('/var/run/univention-saml/memcached.socket', 'samlcgi', 'root', 0600) |
138 |
yield check_file('/var/run/uvmm.socket', 'root', 'root', 0755) |
139 |
for path in glob.iglob('/var/run/univention-management-console/*.socket'): |
140 |
yield check_file(path, 'root', 'root', 0700) |
141 |
|
142 |
for path in glob.iglob('/var/cache/univention-*'): |
143 |
if path == '/var/cache/univention-quota': |
144 |
yield check_file(path, 'root', 'root', 0750) |
145 |
elif path == '/var/cache/univention-system-setup': |
146 |
yield check_file(path, 'root', 'root', 0700) |
147 |
else: |
148 |
yield check_file(path, 'root', 'root', 0755) |
149 |
|
150 |
for path in glob.iglob('/etc/univention/connector/*.sqlite'): |
151 |
yield check_file(path, 'root', 'root', 0644) |
152 |
|
153 |
saml_key = configRegistry.get('saml/idp/certificate/privatekey') |
154 |
if saml_key: |
155 |
yield check_file(saml_key, 'root', 'samlcgi', 0640, must_exist=True) |
156 |
|
157 |
|
158 |
def run(): |
159 |
error_descriptions = [str(error) for error in file_and_permission_checks() |
160 |
if isinstance(error, CheckError)] |
161 |
if error_descriptions: |
162 |
raise Warning(description='\n'.join(error_descriptions)) |
163 |
|
164 |
|
165 |
if __name__ == '__main__': |
166 |
run() |
167 |
from univention.management.console.modules.diagnostic import main |
168 |
main() |
1 |
(po) |
169 |
(po) |
2 |
-- |
|
|
3 |
.../umc/python/diagnostic/de.po | 26 ++++++++++++++++++++-- |
170 |
.../umc/python/diagnostic/de.po | 26 ++++++++++++++++++++-- |
4 |
1 file changed, 24 insertions(+), 2 deletions(-) |
171 |
1 file changed, 24 insertions(+), 2 deletions(-) |