mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
ipaldap: merge IPAdmin to LDAPClient
* move IPAdmin methods to LDAPClient
* add extra arguments (cacert, sasl_nocanon) to LDAPClient.__init__()
* add host, port, _protocol to LDAPClient (parsed from ldap_uri)
* create get_ldap_uri() method to create ldap_uri from former
IPAdmin.__init__() arguments
* replace IPAdmin with LDAPClient + get_ldap_uri()
* remove ununsed function argument hostname from
enable_replication_version_checking()
https://fedorahosted.org/freeipa/ticket/6461
Reviewed-By: Martin Basti <mbasti@redhat.com>
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
This commit is contained in:
committed by
Martin Basti
parent
4f1a6a1776
commit
5b81dbfda1
@@ -27,6 +27,7 @@ import contextlib
|
||||
import collections
|
||||
import os
|
||||
import pwd
|
||||
from urlparse import urlparse
|
||||
|
||||
import ldap
|
||||
import ldap.sasl
|
||||
@@ -705,7 +706,8 @@ class LDAPClient(object):
|
||||
size_limit = 0 # unlimited
|
||||
|
||||
def __init__(self, ldap_uri, start_tls=False, force_schema_updates=False,
|
||||
no_schema=False, decode_attrs=True):
|
||||
no_schema=False, decode_attrs=True, cacert=None,
|
||||
sasl_nocanon=False):
|
||||
"""Create LDAPClient object.
|
||||
|
||||
:param ldap_uri: The LDAP URI to connect to
|
||||
@@ -727,6 +729,16 @@ class LDAPClient(object):
|
||||
self._force_schema_updates = force_schema_updates
|
||||
self._no_schema = no_schema
|
||||
self._decode_attrs = decode_attrs
|
||||
self._cacert = cacert
|
||||
self._sasl_nocanon = sasl_nocanon
|
||||
|
||||
self.host = 'localhost'
|
||||
self.port = None
|
||||
url_data = urlparse(ldap_uri)
|
||||
self._protocol = url_data.scheme
|
||||
if self._protocol in ('ldap', 'ldaps'):
|
||||
self.host = url_data.hostname
|
||||
self.port = url_data.port
|
||||
|
||||
self.log = log_mgr.get_logger(self)
|
||||
self._has_schema = False
|
||||
@@ -734,6 +746,36 @@ class LDAPClient(object):
|
||||
|
||||
self._conn = self._connect()
|
||||
|
||||
def __str__(self):
|
||||
return self.ldap_uri
|
||||
|
||||
def do_bind(self, dm_password="", autobind=AUTOBIND_AUTO):
|
||||
if dm_password:
|
||||
self.simple_bind(bind_dn=DIRMAN_DN,
|
||||
bind_password=dm_password)
|
||||
return
|
||||
if (autobind != AUTOBIND_DISABLED and os.getegid() == 0 and
|
||||
self._protocol == 'ldapi'):
|
||||
try:
|
||||
# autobind
|
||||
self.external_bind()
|
||||
return
|
||||
except errors.NotFound:
|
||||
if autobind == AUTOBIND_ENABLED:
|
||||
# autobind was required and failed, raise
|
||||
# exception that it failed
|
||||
raise
|
||||
|
||||
# fall back
|
||||
self.gssapi_bind()
|
||||
|
||||
def modify_s(self, dn, modlist):
|
||||
# FIXME: for backwards compatibility only
|
||||
assert isinstance(dn, DN)
|
||||
dn = str(dn)
|
||||
modlist = [(a, self.encode(b), self.encode(c)) for a, b, c in modlist]
|
||||
return self.conn.modify_s(dn, modlist)
|
||||
|
||||
@property
|
||||
def conn(self):
|
||||
return self._conn
|
||||
@@ -1066,6 +1108,14 @@ class LDAPClient(object):
|
||||
with self.error_handler():
|
||||
conn = ldap.initialize(self.ldap_uri)
|
||||
|
||||
if self._start_tls or self._protocol == 'ldaps':
|
||||
ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, self._cacert)
|
||||
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, True)
|
||||
conn.set_option(ldap.OPT_X_TLS_DEMAND, True)
|
||||
|
||||
if self._sasl_nocanon:
|
||||
conn.set_option(ldap.OPT_X_SASL_NOCANON, ldap.OPT_ON)
|
||||
|
||||
if self._start_tls:
|
||||
conn.start_tls_s()
|
||||
|
||||
@@ -1559,99 +1609,22 @@ class LDAPClient(object):
|
||||
return True
|
||||
|
||||
|
||||
class IPAdmin(LDAPClient):
|
||||
def get_ldap_uri(host='', port=389, cacert=None, ldapi=False, realm=None,
|
||||
protocol=None):
|
||||
if protocol is None:
|
||||
if ldapi:
|
||||
protocol = 'ldapi'
|
||||
elif cacert is not None:
|
||||
protocol = 'ldaps'
|
||||
else:
|
||||
protocol = 'ldap'
|
||||
|
||||
def __get_ldap_uri(self, protocol):
|
||||
if protocol == 'ldaps':
|
||||
return 'ldaps://%s' % format_netloc(self.host, self.port)
|
||||
return 'ldaps://%s' % format_netloc(host, port)
|
||||
elif protocol == 'ldapi':
|
||||
return 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % (
|
||||
"-".join(self.realm.split(".")))
|
||||
"-".join(realm.split(".")))
|
||||
elif protocol == 'ldap':
|
||||
return 'ldap://%s' % format_netloc(self.host, self.port)
|
||||
return 'ldap://%s' % format_netloc(host, port)
|
||||
else:
|
||||
raise ValueError('Protocol %r not supported' % protocol)
|
||||
|
||||
|
||||
def __guess_protocol(self):
|
||||
"""Return the protocol to use based on flags passed to the constructor
|
||||
|
||||
Only used when "protocol" is not specified explicitly.
|
||||
|
||||
If a CA certificate is provided then it is assumed that we are
|
||||
doing SSL client authentication with proxy auth.
|
||||
|
||||
If a CA certificate is not present then it is assumed that we are
|
||||
using a forwarded kerberos ticket for SASL auth. SASL provides
|
||||
its own encryption.
|
||||
"""
|
||||
if self.cacert is not None:
|
||||
return 'ldaps'
|
||||
elif self.ldapi:
|
||||
return 'ldapi'
|
||||
else:
|
||||
return 'ldap'
|
||||
|
||||
def __init__(self, host='', port=389, cacert=None, debug=None, ldapi=False,
|
||||
realm=None, protocol=None, force_schema_updates=True,
|
||||
start_tls=False, ldap_uri=None, no_schema=False,
|
||||
decode_attrs=True, sasl_nocanon=False, demand_cert=False):
|
||||
self._conn = None
|
||||
log_mgr.get_logger(self, True)
|
||||
if debug and debug.lower() == "on":
|
||||
ldap.set_option(ldap.OPT_DEBUG_LEVEL,255)
|
||||
if cacert is not None:
|
||||
ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, cacert)
|
||||
|
||||
self.port = port
|
||||
self.host = host
|
||||
self.cacert = cacert
|
||||
self.ldapi = ldapi
|
||||
self.realm = realm
|
||||
self.suffixes = {}
|
||||
|
||||
if not ldap_uri:
|
||||
ldap_uri = self.__get_ldap_uri(protocol or self.__guess_protocol())
|
||||
|
||||
super(IPAdmin, self).__init__(
|
||||
ldap_uri, force_schema_updates=force_schema_updates,
|
||||
no_schema=no_schema, decode_attrs=decode_attrs)
|
||||
|
||||
with self.error_handler():
|
||||
if demand_cert:
|
||||
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, True)
|
||||
self.conn.set_option(ldap.OPT_X_TLS_DEMAND, True)
|
||||
|
||||
if sasl_nocanon:
|
||||
self.conn.set_option(ldap.OPT_X_SASL_NOCANON, ldap.OPT_ON)
|
||||
|
||||
if start_tls:
|
||||
self.conn.start_tls_s()
|
||||
|
||||
def __str__(self):
|
||||
return self.host + ":" + str(self.port)
|
||||
|
||||
def do_bind(self, dm_password="", autobind=AUTOBIND_AUTO):
|
||||
if dm_password:
|
||||
self.simple_bind(bind_dn=DIRMAN_DN, bind_password=dm_password)
|
||||
return
|
||||
if autobind != AUTOBIND_DISABLED and os.getegid() == 0 and self.ldapi:
|
||||
try:
|
||||
# autobind
|
||||
self.external_bind()
|
||||
return
|
||||
except errors.NotFound:
|
||||
if autobind == AUTOBIND_ENABLED:
|
||||
# autobind was required and failed, raise
|
||||
# exception that it failed
|
||||
raise
|
||||
|
||||
#fall back
|
||||
self.gssapi_bind()
|
||||
|
||||
def modify_s(self, dn, modlist):
|
||||
# FIXME: for backwards compatibility only
|
||||
assert isinstance(dn, DN)
|
||||
dn = str(dn)
|
||||
modlist = [(a, self.encode(b), self.encode(c)) for a, b, c in modlist]
|
||||
return self.conn.modify_s(dn, modlist)
|
||||
|
||||
Reference in New Issue
Block a user