def _gssapi_cred(self): try: return get_principal() except Exception: self.logger.error( "Unable to get principal from GSSAPI. Are you missing a " "TGT or valid Kerberos keytab?") raise
def get_current_password(principal): """ If the user is changing their own password then return None so the current password is prompted for, otherwise return a fixed value to be ignored later. """ current_principal = krb_utils.get_principal() if current_principal == unicode(normalize_user_principal(principal)): return None else: return MAGIC_VALUE
def get_current_password(principal): """ If the user is changing their own password then return None so the current password is prompted for, otherwise return a fixed value to be ignored later. """ current_principal = krb_utils.get_principal() if current_principal == normalize_principal(principal): return None else: return MAGIC_VALUE
def create_connection(self, ccache=None, bind_dn=None, bind_pw='', cacert=None, autobind=AUTOBIND_AUTO, serverctrls=None, clientctrls=None, time_limit=_missing, size_limit=_missing): """ Connect to LDAP server. Keyword arguments: ldapuri -- the LDAP server to connect to ccache -- Kerberos ccache name bind_dn -- dn used to bind to the server bind_pw -- password used to bind to the server debug_level -- LDAP debug level option cacert -- TLS CA certificate filename autobind - autobind as the current user time_limit, size_limit -- maximum time and size limit for LDAP possible options: - value - sets the given value - None - reads value from ipaconfig - _missing - keeps previously configured settings (unlimited set by default in constructor) Extends backend.Connectible.create_connection. """ if bind_dn is None: bind_dn = DN(('cn', 'directory manager')) assert isinstance(bind_dn, DN) if cacert is None: cacert = paths.IPA_CA_CRT if time_limit is not _missing: object.__setattr__(self, 'time_limit', time_limit) if size_limit is not _missing: object.__setattr__(self, 'size_limit', size_limit) client = LDAPClient(self.ldap_uri, force_schema_updates=self._force_schema_updates, cacert=cacert) conn = client._conn with client.error_handler(): minssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MIN) maxssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MAX) # Always connect with at least an SSF of 56, confidentiality # This also protects us from a broken ldap.conf if minssf < 56: minssf = 56 conn.set_option(_ldap.OPT_X_SASL_SSF_MIN, minssf) if maxssf < minssf: conn.set_option(_ldap.OPT_X_SASL_SSF_MAX, minssf) ldapi = self.ldap_uri.startswith('ldapi://') if bind_pw: client.simple_bind(bind_dn, bind_pw, server_controls=serverctrls, client_controls=clientctrls) elif autobind != AUTOBIND_DISABLED and os.getegid() == 0 and ldapi: try: client.external_bind(server_controls=serverctrls, client_controls=clientctrls) except errors.NotFound: if autobind == AUTOBIND_ENABLED: # autobind was required and failed, raise # exception that it failed raise else: if ldapi: with client.error_handler(): conn.set_option(_ldap.OPT_HOST_NAME, self.api.env.host) if ccache is None: os.environ.pop('KRB5CCNAME', None) else: os.environ['KRB5CCNAME'] = ccache principal = krb_utils.get_principal(ccache_name=ccache) client.gssapi_bind(server_controls=serverctrls, client_controls=clientctrls) setattr(context, 'principal', principal) return conn
def create_connection(self, ccache=None, verbose=None, fallback=None, delegate=None, ca_certfile=None): if verbose is None: verbose = self.api.env.verbose if fallback is None: fallback = self.api.env.fallback if delegate is None: delegate = self.api.env.delegate if ca_certfile is None: ca_certfile = self.api.env.tls_ca_cert context.ca_certfile = ca_certfile rpc_uri = self.env[self.env_rpc_uri_key] try: principal = get_principal(ccache_name=ccache) stored_principal = getattr(context, 'principal', None) if principal != stored_principal: try: delattr(context, 'session_cookie') except AttributeError: pass setattr(context, 'principal', principal) # We have a session cookie, try using the session URI to see if it # is still valid if not delegate: rpc_uri = self.apply_session_cookie(rpc_uri) except (errors.CCacheError, ValueError): # No session key, do full Kerberos auth pass urls = self.get_url_list(rpc_uri) proxy_kw = { 'allow_none': True, 'encoding': 'UTF-8', 'verbose': verbose } for url in urls: # should we get ProtocolError (=> error in HTTP response) and # 401 (=> Unauthorized), we'll be re-trying with new session # cookies several times for _try_num in range(0, 5): if url.startswith('https://'): if delegate: transport_class = DelegatedKerbTransport else: transport_class = KerbTransport else: transport_class = LanguageAwareTransport proxy_kw['transport'] = transport_class(protocol=self.protocol, service='HTTP', ccache=ccache) logger.info('trying %s', url) setattr(context, 'request_url', url) serverproxy = self.server_proxy_class(url, **proxy_kw) if len(urls) == 1: # if we have only 1 server and then let the # main requester handle any errors. This also means it # must handle a 401 but we save a ping. return serverproxy try: command = getattr(serverproxy, 'ping') try: command([], {}) except Fault as e: e = decode_fault(e) if e.faultCode in errors_by_code: error = errors_by_code[e.faultCode] raise error(message=e.faultString) else: raise UnknownError( code=e.faultCode, error=e.faultString, server=url, ) # We don't care about the response, just that we got one return serverproxy except errors.KerberosError: # kerberos error on one server is likely on all raise except ProtocolError as e: if hasattr(context, 'session_cookie') and e.errcode == 401: # Unauthorized. Remove the session and try again. delattr(context, 'session_cookie') try: delete_persistent_client_session_data(principal) except Exception: # This shouldn't happen if we have a session but # it isn't fatal. pass # try the same url once more with a new session cookie continue if not fallback: raise else: logger.info('Connection to %s failed with %s', url, e) # try the next url break except Exception as e: if not fallback: raise else: logger.info('Connection to %s failed with %s', url, e) # try the next url break # finished all tries but no serverproxy was found raise NetworkError(uri=_('any of the configured servers'), error=', '.join(urls))
class passwd(Command): __doc__ = _("Set a user's password.") takes_args = ( Principal( 'principal', validate_realm, cli_name='user', label=_('User name'), primary_key=True, autofill=True, default_from=lambda: kerberos.Principal(krb_utils.get_principal()), normalizer=lambda value: normalize_user_principal(value), ), Password( 'password', label=_('New Password'), ), Password( 'current_password', label=_('Current Password'), confirm=False, default_from=lambda principal: get_current_password(principal), autofill=True, ), ) takes_options = (Password( 'otp?', label=_('OTP'), doc=_('The OTP if the user has a token configured'), confirm=False, ), ) has_output = output.simple_value msg_summary = _('Changed password for "%(value)s"') def execute(self, principal, password, current_password, **options): """ Execute the passwd operation. The dn should not be passed as a keyword argument as it is constructed by this method. Returns the entry :param principal: The login name or principal of the user :param password: the new password :param current_password: the existing password, if applicable """ ldap = self.api.Backend.ldap2 principal = unicode(principal) entry_attrs = ldap.find_entry_by_attr( 'krbprincipalname', principal, 'posixaccount', [''], DN(api.env.container_user, api.env.basedn)) if principal == getattr(context, 'principal') and \ current_password == MAGIC_VALUE: # No cheating logger.warning('User attempted to change password using magic ' 'value') raise errors.ACIError(info=_('Invalid credentials')) if current_password == MAGIC_VALUE: ldap.modify_password(entry_attrs.dn, password) else: otp = options.get('otp') ldap.modify_password(entry_attrs.dn, password, current_password, otp) return dict( result=True, value=principal, )
def create_connection( self, ccache=None, bind_dn=None, bind_pw='', cacert=None, autobind=AUTOBIND_AUTO, serverctrls=None, clientctrls=None, time_limit=_missing, size_limit=_missing): """ Connect to LDAP server. Keyword arguments: ldapuri -- the LDAP server to connect to ccache -- Kerberos ccache name bind_dn -- dn used to bind to the server bind_pw -- password used to bind to the server debug_level -- LDAP debug level option cacert -- TLS CA certificate filename autobind - autobind as the current user time_limit, size_limit -- maximum time and size limit for LDAP possible options: - value - sets the given value - None - reads value from ipaconfig - _missing - keeps previously configured settings (unlimited set by default in constructor) Extends backend.Connectible.create_connection. """ if bind_dn is None: bind_dn = DN(('cn', 'directory manager')) assert isinstance(bind_dn, DN) if cacert is None: cacert = constants.CACERT if time_limit is not _missing: self.time_limit = time_limit if size_limit is not _missing: self.size_limit = size_limit client = LDAPClient(self.ldap_uri, force_schema_updates=self._force_schema_updates, cacert=cacert) conn = client._conn with client.error_handler(): minssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MIN) maxssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MAX) # Always connect with at least an SSF of 56, confidentiality # This also protects us from a broken ldap.conf if minssf < 56: minssf = 56 conn.set_option(_ldap.OPT_X_SASL_SSF_MIN, minssf) if maxssf < minssf: conn.set_option(_ldap.OPT_X_SASL_SSF_MAX, minssf) ldapi = self.ldap_uri.startswith('ldapi://') if bind_pw: client.simple_bind(bind_dn, bind_pw, server_controls=serverctrls, client_controls=clientctrls) elif autobind != AUTOBIND_DISABLED and os.getegid() == 0 and ldapi: try: client.external_bind(server_controls=serverctrls, client_controls=clientctrls) except errors.NotFound: if autobind == AUTOBIND_ENABLED: # autobind was required and failed, raise # exception that it failed raise else: if ldapi: with client.error_handler(): conn.set_option(_ldap.OPT_HOST_NAME, self.api.env.host) if ccache is None: os.environ.pop('KRB5CCNAME', None) else: os.environ['KRB5CCNAME'] = ccache principal = krb_utils.get_principal(ccache_name=ccache) client.gssapi_bind(server_controls=serverctrls, client_controls=clientctrls) setattr(context, 'principal', principal) return conn
def create_connection(self, ccache=None, verbose=None, fallback=None, delegate=None, nss_dir=None): if verbose is None: verbose = self.api.env.verbose if fallback is None: fallback = self.api.env.fallback if delegate is None: delegate = self.api.env.delegate if nss_dir is None: nss_dir = self.api.env.nss_dir try: rpc_uri = self.env[self.env_rpc_uri_key] principal = get_principal() setattr(context, "principal", principal) # We have a session cookie, try using the session URI to see if it # is still valid if not delegate: rpc_uri = self.apply_session_cookie(rpc_uri) except (errors.CCacheError, ValueError): # No session key, do full Kerberos auth pass context.nss_dir = nss_dir urls = self.get_url_list(rpc_uri) serverproxy = None for url in urls: kw = dict(allow_none=True, encoding="UTF-8") kw["verbose"] = verbose if url.startswith("https://"): if delegate: transport_class = DelegatedKerbTransport else: transport_class = KerbTransport else: transport_class = LanguageAwareTransport kw["transport"] = transport_class(protocol=self.protocol) self.log.info("trying %s" % url) setattr(context, "request_url", url) serverproxy = self.server_proxy_class(url, **kw) if len(urls) == 1: # if we have only 1 server and then let the # main requester handle any errors. This also means it # must handle a 401 but we save a ping. return serverproxy try: command = getattr(serverproxy, "ping") try: command([], {}) except Fault as e: e = decode_fault(e) if e.faultCode in errors_by_code: error = errors_by_code[e.faultCode] raise error(message=e.faultString) else: raise UnknownError(code=e.faultCode, error=e.faultString, server=url) # We don't care about the response, just that we got one break except KerberosError as krberr: # kerberos error on one server is likely on all raise errors.KerberosError(message=unicode(krberr)) except ProtocolError as e: if hasattr(context, "session_cookie") and e.errcode == 401: # Unauthorized. Remove the session and try again. delattr(context, "session_cookie") try: delete_persistent_client_session_data(principal) except Exception as e: # This shouldn't happen if we have a session but it isn't fatal. pass return self.create_connection(ccache, verbose, fallback, delegate) if not fallback: raise serverproxy = None except Exception as e: if not fallback: raise else: self.log.info("Connection to %s failed with %s", url, e) serverproxy = None if serverproxy is None: raise NetworkError(uri=_("any of the configured servers"), error=", ".join(urls)) return serverproxy
def create_connection(self, ccache=None, bind_dn=None, bind_pw='', tls_cacertfile=None, tls_certfile=None, tls_keyfile=None, debug_level=0, autobind=AUTOBIND_AUTO, serverctrls=None, clientctrls=None, time_limit=None, size_limit=None): """ Connect to LDAP server. Keyword arguments: ldapuri -- the LDAP server to connect to ccache -- Kerberos ccache name bind_dn -- dn used to bind to the server bind_pw -- password used to bind to the server debug_level -- LDAP debug level option tls_cacertfile -- TLS CA certificate filename tls_certfile -- TLS certificate filename tls_keyfile - TLS bind key filename autobind - autobind as the current user Extends backend.Connectible.create_connection. """ if bind_dn is None: bind_dn = DN() assert isinstance(bind_dn, DN) if tls_cacertfile is not None: _ldap.set_option(_ldap.OPT_X_TLS_CACERTFILE, tls_cacertfile) if tls_certfile is not None: _ldap.set_option(_ldap.OPT_X_TLS_CERTFILE, tls_certfile) if tls_keyfile is not None: _ldap.set_option(_ldap.OPT_X_TLS_KEYFILE, tls_keyfile) if time_limit is not None: self.time_limit = time_limit if size_limit is not None: self.size_limit = size_limit if debug_level: _ldap.set_option(_ldap.OPT_DEBUG_LEVEL, debug_level) client = LDAPClient(self.ldap_uri, force_schema_updates=self._force_schema_updates) conn = client._conn with client.error_handler(): minssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MIN) maxssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MAX) # Always connect with at least an SSF of 56, confidentiality # This also protects us from a broken ldap.conf if minssf < 56: minssf = 56 conn.set_option(_ldap.OPT_X_SASL_SSF_MIN, minssf) if maxssf < minssf: conn.set_option(_ldap.OPT_X_SASL_SSF_MAX, minssf) ldapi = self.ldap_uri.startswith('ldapi://') if bind_pw: client.simple_bind(bind_dn, bind_pw, server_controls=serverctrls, client_controls=clientctrls) elif autobind != AUTOBIND_DISABLED and os.getegid() == 0 and ldapi: try: pw_name = pwd.getpwuid(os.geteuid()).pw_name client.external_bind(pw_name, server_controls=serverctrls, client_controls=clientctrls) except errors.NotFound: if autobind == AUTOBIND_ENABLED: # autobind was required and failed, raise # exception that it failed raise else: if ldapi: with client.error_handler(): conn.set_option(_ldap.OPT_HOST_NAME, self.api.env.host) if ccache is None: os.environ.pop('KRB5CCNAME', None) else: os.environ['KRB5CCNAME'] = ccache principal = krb_utils.get_principal(ccache_name=ccache) client.gssapi_bind(server_controls=serverctrls, client_controls=clientctrls) setattr(context, 'principal', principal) return conn
def create_connection(self, ccache=None, verbose=None, fallback=None, delegate=None, ca_certfile=None): if verbose is None: verbose = self.api.env.verbose if fallback is None: fallback = self.api.env.fallback if delegate is None: delegate = self.api.env.delegate if ca_certfile is None: ca_certfile = self.api.env.tls_ca_cert context.ca_certfile = ca_certfile rpc_uri = self.env[self.env_rpc_uri_key] try: principal = get_principal(ccache_name=ccache) stored_principal = getattr(context, 'principal', None) if principal != stored_principal: try: delattr(context, 'session_cookie') except AttributeError: pass setattr(context, 'principal', principal) # We have a session cookie, try using the session URI to see if it # is still valid if not delegate: rpc_uri = self.apply_session_cookie(rpc_uri) except (errors.CCacheError, ValueError): # No session key, do full Kerberos auth pass urls = self.get_url_list(rpc_uri) proxy_kw = { 'allow_none': True, 'encoding': 'UTF-8', 'verbose': verbose } for url in urls: # should we get ProtocolError (=> error in HTTP response) and # 401 (=> Unauthorized), we'll be re-trying with new session # cookies several times for _try_num in range(0, 5): if url.startswith('https://'): if delegate: transport_class = DelegatedKerbTransport else: transport_class = KerbTransport else: transport_class = LanguageAwareTransport proxy_kw['transport'] = transport_class( protocol=self.protocol, service='HTTP', ccache=ccache) logger.debug('trying %s', url) setattr(context, 'request_url', url) serverproxy = self.server_proxy_class(url, **proxy_kw) if len(urls) == 1: # if we have only 1 server and then let the # main requester handle any errors. This also means it # must handle a 401 but we save a ping. return serverproxy try: command = getattr(serverproxy, 'ping') try: command([], {}) except Fault as e: e = decode_fault(e) if e.faultCode in errors_by_code: error = errors_by_code[e.faultCode] raise error(message=e.faultString) else: raise UnknownError( code=e.faultCode, error=e.faultString, server=url, ) # We don't care about the response, just that we got one return serverproxy except errors.KerberosError: # kerberos error on one server is likely on all raise except ProtocolError as e: if hasattr(context, 'session_cookie') and e.errcode == 401: # Unauthorized. Remove the session and try again. delattr(context, 'session_cookie') try: delete_persistent_client_session_data(principal) except Exception: # This shouldn't happen if we have a session but # it isn't fatal. pass # try the same url once more with a new session cookie continue if not fallback: raise else: logger.info( 'Connection to %s failed with %s', url, e) # try the next url break except Exception as e: if not fallback: raise else: logger.info( 'Connection to %s failed with %s', url, e) # try the next url break # finished all tries but no serverproxy was found raise NetworkError(uri=_('any of the configured servers'), error=', '.join(urls))
def create_connection(self, ccache=None, verbose=None, fallback=None, delegate=None, ca_certfile=None): if verbose is None: verbose = self.api.env.verbose if fallback is None: fallback = self.api.env.fallback if delegate is None: delegate = self.api.env.delegate if ca_certfile is None: ca_certfile = self.api.env.tls_ca_cert try: rpc_uri = self.env[self.env_rpc_uri_key] principal = get_principal(ccache_name=ccache) stored_principal = getattr(context, 'principal', None) if principal != stored_principal: try: delattr(context, 'session_cookie') except AttributeError: pass setattr(context, 'principal', principal) # We have a session cookie, try using the session URI to see if it # is still valid if not delegate: rpc_uri = self.apply_session_cookie(rpc_uri) except (errors.CCacheError, ValueError): # No session key, do full Kerberos auth pass context.ca_certfile = ca_certfile urls = self.get_url_list(rpc_uri) serverproxy = None for url in urls: kw = dict(allow_none=True, encoding='UTF-8') kw['verbose'] = verbose if url.startswith('https://'): if delegate: transport_class = DelegatedKerbTransport else: transport_class = KerbTransport else: transport_class = LanguageAwareTransport kw['transport'] = transport_class(protocol=self.protocol, service='HTTP', ccache=ccache) self.log.info('trying %s' % url) setattr(context, 'request_url', url) serverproxy = self.server_proxy_class(url, **kw) if len(urls) == 1: # if we have only 1 server and then let the # main requester handle any errors. This also means it # must handle a 401 but we save a ping. return serverproxy try: command = getattr(serverproxy, 'ping') try: command([], {}) except Fault as e: e = decode_fault(e) if e.faultCode in errors_by_code: error = errors_by_code[e.faultCode] raise error(message=e.faultString) else: raise UnknownError( code=e.faultCode, error=e.faultString, server=url, ) # We don't care about the response, just that we got one break except KerberosError as krberr: # kerberos error on one server is likely on all raise errors.KerberosError(message=unicode(krberr)) except ProtocolError as e: if hasattr(context, 'session_cookie') and e.errcode == 401: # Unauthorized. Remove the session and try again. delattr(context, 'session_cookie') try: delete_persistent_client_session_data(principal) except Exception as e: # This shouldn't happen if we have a session but it isn't fatal. pass return self.create_connection(ccache, verbose, fallback, delegate) if not fallback: raise serverproxy = None except Exception as e: if not fallback: raise else: self.log.info('Connection to %s failed with %s', url, e) serverproxy = None if serverproxy is None: raise NetworkError(uri=_('any of the configured servers'), error=', '.join(urls)) return serverproxy
def create_connection(self, ccache=None, verbose=0, fallback=True, delegate=False, nss_dir=None): try: rpc_uri = self.env[self.env_rpc_uri_key] principal = get_principal() setattr(context, 'principal', principal) # We have a session cookie, try using the session URI to see if it # is still valid if not delegate: rpc_uri = self.apply_session_cookie(rpc_uri) except ValueError: # No session key, do full Kerberos auth pass # This might be dangerous. Use at your own risk! if nss_dir: context.nss_dir = nss_dir urls = self.get_url_list(rpc_uri) serverproxy = None for url in urls: kw = dict(allow_none=True, encoding='UTF-8') kw['verbose'] = verbose if url.startswith('https://'): if delegate: transport_class = DelegatedKerbTransport else: transport_class = KerbTransport else: transport_class = LanguageAwareTransport kw['transport'] = transport_class(protocol=self.protocol) self.log.info('trying %s' % url) setattr(context, 'request_url', url) serverproxy = self.server_proxy_class(url, **kw) if len(urls) == 1: # if we have only 1 server and then let the # main requester handle any errors. This also means it # must handle a 401 but we save a ping. return serverproxy try: command = getattr(serverproxy, 'ping') try: response = command([], {}) except Fault as e: e = decode_fault(e) if e.faultCode in errors_by_code: error = errors_by_code[e.faultCode] raise error(message=e.faultString) else: raise UnknownError( code=e.faultCode, error=e.faultString, server=url, ) # We don't care about the response, just that we got one break except KerberosError as krberr: # kerberos error on one server is likely on all raise errors.KerberosError(major=str(krberr), minor='') except ProtocolError as e: if hasattr(context, 'session_cookie') and e.errcode == 401: # Unauthorized. Remove the session and try again. delattr(context, 'session_cookie') try: delete_persistent_client_session_data(principal) except Exception as e: # This shouldn't happen if we have a session but it isn't fatal. pass return self.create_connection(ccache, verbose, fallback, delegate) if not fallback: raise serverproxy = None except Exception as e: if not fallback: raise else: self.log.info('Connection to %s failed with %s', url, e) serverproxy = None if serverproxy is None: raise NetworkError(uri=_('any of the configured servers'), error=', '.join(urls)) return serverproxy
def create_connection(self, ccache=None, bind_dn=None, bind_pw='', tls_cacertfile=None, tls_certfile=None, tls_keyfile=None, debug_level=0, autobind=AUTOBIND_AUTO, serverctrls=None, clientctrls=None): """ Connect to LDAP server. Keyword arguments: ldapuri -- the LDAP server to connect to ccache -- Kerberos ccache name bind_dn -- dn used to bind to the server bind_pw -- password used to bind to the server debug_level -- LDAP debug level option tls_cacertfile -- TLS CA certificate filename tls_certfile -- TLS certificate filename tls_keyfile - TLS bind key filename autobind - autobind as the current user Extends backend.Connectible.create_connection. """ if bind_dn is None: bind_dn = DN() assert isinstance(bind_dn, DN) if tls_cacertfile is not None: _ldap.set_option(_ldap.OPT_X_TLS_CACERTFILE, tls_cacertfile) if tls_certfile is not None: _ldap.set_option(_ldap.OPT_X_TLS_CERTFILE, tls_certfile) if tls_keyfile is not None: _ldap.set_option(_ldap.OPT_X_TLS_KEYFILE, tls_keyfile) if debug_level: _ldap.set_option(_ldap.OPT_DEBUG_LEVEL, debug_level) LDAPClient._connect(self) conn = self._conn with self.error_handler(): minssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MIN) maxssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MAX) # Always connect with at least an SSF of 56, confidentiality # This also protects us from a broken ldap.conf if minssf < 56: minssf = 56 conn.set_option(_ldap.OPT_X_SASL_SSF_MIN, minssf) if maxssf < minssf: conn.set_option(_ldap.OPT_X_SASL_SSF_MAX, minssf) ldapi = self.ldap_uri.startswith('ldapi://') if bind_pw: self.simple_bind(bind_dn, bind_pw, server_controls=serverctrls, client_controls=clientctrls) elif autobind != AUTOBIND_DISABLED and os.getegid() == 0 and ldapi: try: pw_name = pwd.getpwuid(os.geteuid()).pw_name self.external_bind(pw_name, server_controls=serverctrls, client_controls=clientctrls) except errors.NotFound: if autobind == AUTOBIND_ENABLED: # autobind was required and failed, raise # exception that it failed raise else: if ldapi: with self.error_handler(): conn.set_option(_ldap.OPT_HOST_NAME, self.api.env.host) if ccache is None: os.environ.pop('KRB5CCNAME', None) else: os.environ['KRB5CCNAME'] = ccache principal = krb_utils.get_principal(ccache_name=ccache) self.gssapi_bind(server_controls=serverctrls, client_controls=clientctrls) setattr(context, 'principal', principal) return conn