예제 #1
0
 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
예제 #2
0
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
예제 #3
0
파일: passwd.py 프로젝트: icute1349/freeipa
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
예제 #4
0
파일: ldap2.py 프로젝트: yangmulang/freeipa
    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
예제 #5
0
    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))
예제 #6
0
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,
        )
예제 #7
0
    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
예제 #8
0
파일: rpc.py 프로젝트: apophys/freeipa
    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
예제 #9
0
    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
예제 #10
0
파일: rpc.py 프로젝트: stlaz/freeipa
    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))
예제 #11
0
    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
예제 #12
0
파일: rpc.py 프로젝트: msrb/freeipa
    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
예제 #13
0
파일: ldap2.py 프로젝트: pspacek/freeipa
    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