|
32 |
# <http://www.gnu.org/licenses/>. |
32 |
# <http://www.gnu.org/licenses/>. |
33 |
|
33 |
|
34 |
import subprocess |
34 |
import subprocess |
|
|
35 |
import contextlib |
35 |
|
36 |
|
36 |
import univention.config_registry |
37 |
import univention.config_registry |
37 |
from univention.management.console.modules.diagnostic import Critical |
38 |
from univention.management.console.modules.diagnostic import Critical |
Lines 39-85
from univention.management.console.modules.diagnostic import Critical
|
Link Here
|
---|
|
39 |
from univention.lib.i18n import Translation |
40 |
from univention.lib.i18n import Translation |
40 |
_ = Translation('univention-management-console-module-diagnostic').translate |
41 |
_ = Translation('univention-management-console-module-diagnostic').translate |
41 |
|
42 |
|
42 |
title = _('Check for Kerberos-authenticated DNS Updates') |
43 |
title = _('Check kerberos authenticated DNS updates') |
43 |
description = _('The check for updating DNS-Records with Kerberos Authentication was successful.') |
44 |
description = _('No errors occured.') |
|
|
45 |
|
46 |
|
47 |
class UpdateError(Exception): |
48 |
pass |
49 |
|
50 |
|
51 |
class KinitError(UpdateError): |
52 |
def __init__(self, principal, keytab, password_file): |
53 |
super(KinitError, self).__init__(principal, keytab, password_file) |
54 |
self.principal = principal |
55 |
self.keytab = keytab |
56 |
self.password_file = password_file |
57 |
|
58 |
def __str__(self): |
59 |
if self.keytab: |
60 |
msg = _('`kinit` for principal {princ} with keytab {tab} failed.') |
61 |
else: |
62 |
msg = _('`kinit` for principal {princ} with password file {file} failed.') |
63 |
return msg.format(princ=self.principal, tab=self.keytab, file=self.password_file) |
64 |
|
65 |
|
66 |
class NSUpdateError(UpdateError): |
67 |
def __init__(self, hostname, domainname): |
68 |
super(NSUpdateError, self).__init__(hostname, domainname) |
69 |
self.hostname = hostname |
70 |
self.domainname = domainname |
71 |
|
72 |
def __str__(self): |
73 |
msg = _('`nsupdate` existence check for domain {domain} failed.') |
74 |
return msg.format(domain=self.domainname) |
75 |
|
76 |
|
77 |
@contextlib.contextmanager |
78 |
def kinit(principal, keytab=None, password_file=None): |
79 |
auth = '--keytab={tab}' if keytab else '--password-file={file}' |
80 |
cmd = ('kinit', auth.format(tab=keytab, file=password_file), principal) |
81 |
try: |
82 |
subprocess.check_call(cmd) |
83 |
except subprocess.CalledProcessError: |
84 |
raise KinitError(principal, keytab, password_file) |
85 |
else: |
86 |
yield |
87 |
subprocess.call(('kdestroy',)) |
88 |
|
89 |
|
90 |
def nsupdate(hostname, domainname): |
91 |
process = subprocess.Popen(('nsupdate', '-g'), stdin=subprocess.PIPE, |
92 |
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
93 |
cmd = 'server {host}.{domain}\nprereq yxdomain {domain}\n' |
94 |
_ = process.communicate(cmd.format(host=hostname, domain=domainname)) |
95 |
if process.poll() != 0: |
96 |
raise NSUpdateError(hostname, domainname) |
97 |
|
98 |
|
99 |
def check_dns_machine_principal(hostname, domainname): |
100 |
with kinit('{}$'.format(hostname), password_file='/etc/machine.secret'): |
101 |
nsupdate(hostname, domainname) |
102 |
|
103 |
|
104 |
def check_dns_server_principal(hostname, domainname): |
105 |
with kinit('dns-{}'.format(hostname), keytab='/var/lib/samba/private/dns.keytab'): |
106 |
nsupdate(hostname, domainname) |
107 |
|
108 |
|
109 |
def check_nsupdate(hostname, domainname, is_dc=False): |
110 |
try: |
111 |
check_dns_machine_principal(hostname, domainname) |
112 |
except UpdateError as error: |
113 |
yield error |
114 |
|
115 |
if is_dc: |
116 |
try: |
117 |
check_dns_server_principal(hostname, domainname) |
118 |
except UpdateError as error: |
119 |
yield error |
44 |
|
120 |
|
45 |
|
121 |
|
46 |
def run(): |
122 |
def run(): |
47 |
config_registry = univention.config_registry.ConfigRegistry() |
123 |
config_registry = univention.config_registry.ConfigRegistry() |
48 |
config_registry.load() |
124 |
config_registry.load() |
49 |
|
125 |
|
50 |
pwdpath = config_registry.get("umc/module/diagnostic/umc_password") |
126 |
hostname = config_registry.get('hostname') |
51 |
hostname = config_registry.get("umc/module/diagnostic/umc_user") |
127 |
domainname = config_registry.get('domainname') |
52 |
domainname = config_registry.get("domainname") |
128 |
is_dc = config_registry.get('samba4/role') == 'DC' |
53 |
kerberos_realm = config_registry.get("kerberos/realm") |
129 |
|
54 |
process = subprocess.Popen(['testparm', '-sv'], stdout=subprocess.PIPE, |
130 |
problems = list(check_nsupdate(hostname, domainname, is_dc)) |
55 |
stderr=subprocess.STDOUT) |
131 |
if problems: |
56 |
stdout, stderr = process.communicate() |
132 |
ed = [_('Errors occured while running `kinit` or `nsupdate`.')] |
57 |
samba_server_role = utils.get_string_between_strings(stdout, "server role = ", "\n") |
133 |
ed.extend(str(error) for error in problems) |
58 |
|
134 |
raise Critical(description='\n'.join(ed)) |
59 |
if not samba_server_role == "active directory domain controller": |
135 |
|
60 |
return |
|
|
61 |
|
62 |
kinit = ['kinit', '--password-file=%s' % (pwdpath), '%s@%s' % (hostname, kerberos_realm)] |
63 |
process = subprocess.Popen(kinit, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
64 |
if process.returncode: |
65 |
description = _('Kinit with machine account failed') |
66 |
raise Critical('\n'.join([ |
67 |
description, |
68 |
"Returncode of process: %s" % (process.returncode) |
69 |
])) |
70 |
stdout, stderr = process.communicate() |
71 |
nsupdate_process = subprocess.Popen(['nsupdate', '-g'], |
72 |
stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT) |
73 |
nsupdate_process.stdin.write('prereq yxdomain %s\nsend\nquit\n' % (domainname)) |
74 |
stdout, stderr = nsupdate_process.communicate() |
75 |
if nsupdate_process.returncode != 0: |
76 |
description = _('nsupdate -g failed') |
77 |
raise Critical('\n'.join([ |
78 |
description, |
79 |
"Returncode of process: %s" % (nsupdate_process.returncode), |
80 |
"stdout: %s" % (stdout), |
81 |
"stderr: %s" % (stderr) |
82 |
])) |
83 |
|
136 |
|
84 |
if __name__ == '__main__': |
137 |
if __name__ == '__main__': |
85 |
from univention.management.console.modules.diagnostic import main |
138 |
from univention.management.console.modules.diagnostic import main |
86 |
- |
|
|
87 |
`kerberos_ddns_update.py` (po) |
139 |
`kerberos_ddns_update.py` (po) |
88 |
-- |
|
|
89 |
.../umc/python/diagnostic/de.po | 36 ++++++++++++++++++++-- |
140 |
.../umc/python/diagnostic/de.po | 36 ++++++++++++++++++++-- |
90 |
1 file changed, 34 insertions(+), 2 deletions(-) |
141 |
1 file changed, 34 insertions(+), 2 deletions(-) |