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_current_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, 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, krberr: # kerberos error on one server is likely on all raise errors.KerberosError(major=str(krberr), minor='')
def create_connection(self, ccache=None, verbose=False, fallback=True, delegate=False): try: xmlrpc_uri = self.env.xmlrpc_uri principal = get_current_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: xmlrpc_uri = self.apply_session_cookie(xmlrpc_uri) except ValueError: # No session key, do full Kerberos auth pass urls = self.get_url_list(xmlrpc_uri) serverproxy = None for url in urls: kw = dict(allow_none=True, encoding='UTF-8') kw['verbose'] = verbose if url.startswith('https://'): if delegate: kw['transport'] = DelegatedKerbTransport() else: kw['transport'] = KerbTransport() else: kw['transport'] = LanguageAwareTransport() self.log.info('trying %s' % url) setattr(context, 'request_url', url) serverproxy = ServerProxy(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, e: e = decode_fault(e) if e.faultCode in self.__errors: error = self.__errors[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, krberr: # kerberos error on one server is likely on all raise errors.KerberosError(major=str(krberr), minor='')
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 = util.get_current_principal() if current_principal == normalize_principal(principal): return None else: return MAGIC_VALUE
class passwd(Command): __doc__ = _("Set a user's password.") takes_args = ( Str( 'principal', validate_principal, cli_name='user', label=_('User name'), primary_key=True, autofill=True, default_from=lambda: util.get_current_principal(), normalizer=lambda value: normalize_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, sortorder=-1, ), ) has_output = output.standard_value msg_summary = _('Changed password for "%(value)s"') def execute(self, principal, password, current_password): """ 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 (dn, 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 self.log.warn( 'User attempted to change password using magic value') raise errors.ACIError(info=_('Invalid credentials')) if current_password == MAGIC_VALUE: ldap.modify_password(dn, password) else: ldap.modify_password(dn, password, current_password) return dict( result=True, value=principal, )