View | Details | Raw Unified | Return to bug 47932 | Differences between
and this patch

Collapse All | Expand All

(-)base/univention-lib/python/admember.py (-27 / +4 lines)
 Lines 211-243   def is_domain_in_admember_mode(ucr=None): Link Here 
211
211
212
def _get_kerberos_ticket(principal, password, ucr=None):
212
def _get_kerberos_ticket(principal, password, ucr=None):
213
	# type: (str, str, Optional[ConfigRegistry]) -> None
213
	# type: (str, str, Optional[ConfigRegistry]) -> None
214
	ud.debug(ud.MODULE, ud.INFO, "running _get_kerberos_ticket")
214
	try:
215
	if not ucr:
215
		return univention.uldap.access.get_kerberos_ticket(principal, password)
216
		ucr = ConfigRegistry()
216
	except ldap.LOCAL_ERROR as exc:
217
		ucr.load()
217
		raise connectionFailed(str(exc))
218
219
	# We need to remove the target credential cache first,
220
	# otherwise kinit may use an old ticket and run into "krb5_get_init_creds: Clock skew too great".
221
	cmd1 = ("/usr/bin/kdestroy",)
222
	p1 = subprocess.Popen(cmd1, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
223
	stdout, stderr = p1.communicate()
224
	if p1.returncode != 0:
225
		ud.debug(ud.MODULE, ud.ERROR, "kdestroy failed:\n%s" % stdout.decode('UTF-8', 'replace'))
226
227
	with tempfile.NamedTemporaryFile('w+') as f:
228
		os.fchmod(f.fileno(), 0o600)
229
		f.write(password)
230
		f.flush()
231
232
		cmd2 = ("/usr/bin/kinit", "--no-addresses", "--password-file=%s" % (f.name,), principal)
233
		p1 = subprocess.Popen(cmd2, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
234
		stdout, stderr = p1.communicate()
235
		if p1.returncode != 0:
236
			msg = "kinit failed:\n%s" % (stdout.decode('UTF-8', 'replace'),)
237
			ud.debug(ud.MODULE, ud.ERROR, msg)
238
			raise connectionFailed(msg)
239
		if stdout:
240
			ud.debug(ud.MODULE, ud.WARN, "kinit output:\n%s" % stdout.decode('UTF-8', 'replace'))
241
218
242
219
243
def check_connection(ad_domain_info, username, password):
220
def check_connection(ad_domain_info, username, password):
(-)base/univention-python/modules/uldap.py (+41 lines)
 Lines 30-38    Link Here 
30
# /usr/share/common-licenses/AGPL-3; if not, see
30
# /usr/share/common-licenses/AGPL-3; if not, see
31
# <https://www.gnu.org/licenses/>.
31
# <https://www.gnu.org/licenses/>.
32
32
33
import os
33
import re
34
import re
34
from functools import wraps
35
from functools import wraps
35
import random
36
import random
37
import subprocess
38
from tempfile import NamedTemporaryFile
36
39
37
import six
40
import six
38
import ldap
41
import ldap
 Lines 319-324   class access(object): Link Here 
319
		self.binddn = self.whoami()
322
		self.binddn = self.whoami()
320
		univention.debug.debug(univention.debug.LDAP, univention.debug.INFO, 'SAML bind binddn=%s' % self.binddn)
323
		univention.debug.debug(univention.debug.LDAP, univention.debug.INFO, 'SAML bind binddn=%s' % self.binddn)
321
324
325
	@_fix_reconnect_handling
326
	def bind_sasl_gssapi(self, binddn, bindpw, credentials_cache=None):
327
		# type: (str, str, Optional[str]) -> None
328
		if credentials_cache:
329
			os.environ['KRB5CCNAME'] = credentials_cache
330
331
		self.get_kerberos_ticket()
332
		self.lo.sasl_interactive_bind_s("", ldap.sasl.gssapi(""))
333
334
	@staticmethod
335
	def get_kerberos_ticket(principal, password):
336
		# type: (str, str) -> None
337
		ud = univention.debug
338
		ud.debug(ud.MODULE, ud.INFO, "running _get_kerberos_ticket")
339
340
		# We need to remove the target credential cache first,
341
		# otherwise kinit may use an old ticket and run into "krb5_get_init_creds: Clock skew too great".
342
		cmd1 = ("/usr/bin/kdestroy",)
343
		p1 = subprocess.Popen(cmd1, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
344
		stdout, stderr = p1.communicate()
345
		if p1.returncode != 0:
346
			ud.debug(ud.MODULE, ud.ERROR, "kdestroy failed:\n%s" % stdout.decode('UTF-8', 'replace'))
347
348
		with NamedTemporaryFile('w+') as f:
349
			os.fchmod(f.fileno(), 0o600)
350
			f.write(password)
351
			f.flush()
352
353
			cmd2 = ("/usr/bin/kinit", "--no-addresses", "--password-file=%s" % (f.name,), principal)
354
			p1 = subprocess.Popen(cmd2, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
355
			stdout, stderr = p1.communicate()
356
			if p1.returncode != 0:
357
				msg = "kinit failed:\n%s" % (stdout.decode('UTF-8', 'replace'),)
358
				ud.debug(ud.MODULE, ud.ERROR, msg)
359
				raise ldap.LOCAL_ERROR(msg)
360
			if stdout:
361
				ud.debug(ud.MODULE, ud.WARN, "kinit output:\n%s" % stdout.decode('UTF-8', 'replace'))
362
322
	def unbind(self):
363
	def unbind(self):
323
		# type: () -> None
364
		# type: () -> None
324
		"""
365
		"""
(-)services/univention-ad-connector/modules/univention/connector/ad/__init__.py (-21 / +12 lines)
 Lines 42-49   import time Link Here 
42
import calendar
42
import calendar
43
import string
43
import string
44
import base64
44
import base64
45
import subprocess
46
from tempfile import NamedTemporaryFile
47
45
48
import six
46
import six
49
import ldap
47
import ldap
 Lines 665-682   class ad(univention.connector.ucs): Link Here 
665
		sid = self.samr.LookupDomain(handle, sam_domain)
663
		sid = self.samr.LookupDomain(handle, sam_domain)
666
		self.dom_handle = self.samr.OpenDomain(handle, security.SEC_FLAG_MAXIMUM_ALLOWED, sid)
664
		self.dom_handle = self.samr.OpenDomain(handle, security.SEC_FLAG_MAXIMUM_ALLOWED, sid)
667
665
668
	def get_kerberos_ticket(self):
669
		p1 = subprocess.Popen(['kdestroy', ], close_fds=True)
670
		p1.wait()
671
		with NamedTemporaryFile('w') as fd:
672
			fd.write(self.ad_ldap_bindpw)
673
			fd.flush()
674
			cmd_block = ['kinit', '--no-addresses', '--password-file=%s' % (fd.name,), self.ad_ldap_binddn]
675
			p1 = subprocess.Popen(cmd_block, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
676
			stdout, stderr = p1.communicate()
677
		if p1.returncode != 0:
678
			raise kerberosAuthenticationFailed('The following command failed: "%s" (%s): %s' % (' '.join(cmd_block), p1.returncode, stdout.decode('UTF-8', 'replace')))
679
680
	def ad_search_ext_s(self, *args, **kwargs):
666
	def ad_search_ext_s(self, *args, **kwargs):
681
		return fix_dn_in_search(self.lo_ad.lo.search_ext_s(*args, **kwargs))
667
		return fix_dn_in_search(self.lo_ad.lo.search_ext_s(*args, **kwargs))
682
668
 Lines 696-710   class ad(univention.connector.ucs): Link Here 
696
		except Exception:  # FIXME: which exception is to be caught
682
		except Exception:  # FIXME: which exception is to be caught
697
			self._debug_traceback(ud.ERROR, 'Failed to lookup AD LDAP base, using UCR value.')
683
			self._debug_traceback(ud.ERROR, 'Failed to lookup AD LDAP base, using UCR value.')
698
684
685
		self.lo_ad = univention.uldap.access(
686
			host=self.ad_ldap_host, port=int(self.ad_ldap_port),
687
			base=self.ad_ldap_base, binddn=None, bindpw=None,
688
			start_tls=tls_mode, use_ldaps=ldaps,
689
			ca_certfile=self.ad_ldap_certificate,
690
		)
691
699
		if self.configRegistry.is_true('%s/ad/ldap/kerberos' % self.CONFIGBASENAME):
692
		if self.configRegistry.is_true('%s/ad/ldap/kerberos' % self.CONFIGBASENAME):
700
			os.environ['KRB5CCNAME'] = '/var/cache/univention-ad-connector/krb5.cc'
693
			try:
701
			self.get_kerberos_ticket()
694
				self.lo_ad.bind_sasl_gssapi(self.ad_ldap_binddn, self.ad_ldap_bindpw, '/var/cache/univention-ad-connector/krb5.cc')
702
			auth = ldap.sasl.gssapi("")
695
			except ldap.LOCAL_ERROR as exc:
703
			self.lo_ad = univention.uldap.access(host=self.ad_ldap_host, port=int(self.ad_ldap_port), base=self.ad_ldap_base, binddn=None, bindpw=self.ad_ldap_bindpw, start_tls=tls_mode, use_ldaps=ldaps, ca_certfile=self.ad_ldap_certificate)
696
				raise kerberosAuthenticationFailed(str(exc))
704
			self.get_kerberos_ticket()
705
			self.lo_ad.lo.sasl_interactive_bind_s("", auth)
706
		else:
697
		else:
707
			self.lo_ad = univention.uldap.access(host=self.ad_ldap_host, port=int(self.ad_ldap_port), base=self.ad_ldap_base, binddn=self.ad_ldap_binddn, bindpw=self.ad_ldap_bindpw, start_tls=tls_mode, use_ldaps=ldaps, ca_certfile=self.ad_ldap_certificate)
698
			self.lo_ad.bind(self.ad_ldap_binddn, self.ad_ldap_bindpw)
708
699
709
		self.lo_ad.lo.set_option(ldap.OPT_REFERRALS, 0)
700
		self.lo_ad.lo.set_option(ldap.OPT_REFERRALS, 0)
710
701
(-)test/ucs-test/lib/ldap_glue.py (-11 / +3 lines)
 Lines 1-5    Link Here 
1
import os
1
import os
2
import subprocess
3
2
4
import ldap
3
import ldap
5
import ldap.dn
4
import ldap.dn
 Lines 7-12   from univention.config_registry import ConfigRegistry Link Here 
7
from ldap.controls import LDAPControl
6
from ldap.controls import LDAPControl
8
import ldap.modlist as modlist
7
import ldap.modlist as modlist
9
8
9
import univention.uldap
10
10
ucr = ConfigRegistry()
11
ucr = ConfigRegistry()
11
ucr.load()
12
ucr.load()
12
13
 Lines 72-78   class LDAPConnection(object): Link Here 
72
		try:
73
		try:
73
			if self.kerberos:
74
			if self.kerberos:
74
				os.environ['KRB5CCNAME'] = '/tmp/ucs-test-ldap-glue.cc'
75
				os.environ['KRB5CCNAME'] = '/tmp/ucs-test-ldap-glue.cc'
75
				self.get_kerberos_ticket()
76
				univention.uldap.access.get_kerberos_ticket(self.principal, open(self.pw_file).read().strip())
76
				auth = ldap.sasl.gssapi("")
77
				auth = ldap.sasl.gssapi("")
77
				self.lo.sasl_interactive_bind_s("", auth)
78
				self.lo.sasl_interactive_bind_s("", auth)
78
			else:
79
			else:
 Lines 88-102   class LDAPConnection(object): Link Here 
88
89
89
		self.lo.set_option(ldap.OPT_REFERRALS, 0)
90
		self.lo.set_option(ldap.OPT_REFERRALS, 0)
90
91
91
	def get_kerberos_ticket(self):
92
		p1 = subprocess.Popen(['kdestroy', ], close_fds=True)
93
		p1.wait()
94
		cmd_block = ['kinit', '--no-addresses', '--password-file=%s' % self.pw_file, self.principal]
95
		p1 = subprocess.Popen(cmd_block, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
96
		stdout, stderr = p1.communicate()
97
		if p1.returncode != 0:
98
			raise Exception('The following command failed: "%s" (%s): %s' % (''.join(cmd_block), p1.returncode, stdout.decode('UTF-8')))
99
100
	def exists(self, dn):
92
	def exists(self, dn):
101
		try:
93
		try:
102
			self.lo.search_ext_s(dn, ldap.SCOPE_BASE, timeout=10)
94
			self.lo.search_ext_s(dn, ldap.SCOPE_BASE, timeout=10)

Return to bug 47932