def kinit(self, user, realm, password, ccache_name): # get http service ccache as an armor for FAST to enable OTP authentication armor_principal = str(krb5_format_service_principal_name( 'HTTP', self.api.env.host, realm)) keytab = paths.IPA_KEYTAB armor_name = "%sA_%s" % (krbccache_prefix, user) armor_path = os.path.join(krbccache_dir, armor_name) self.debug('Obtaining armor ccache: principal=%s keytab=%s ccache=%s', armor_principal, keytab, armor_path) try: ipautil.kinit_keytab(armor_principal, paths.IPA_KEYTAB, armor_path) except gssapi.exceptions.GSSError as e: raise CCacheError(str(e)) # Format the user as a kerberos principal principal = krb5_format_principal_name(user, realm) try: ipautil.kinit_password(principal, password, ccache_name, armor_ccache_name=armor_path) self.debug('Cleanup the armor ccache') ipautil.run( [paths.KDESTROY, '-A', '-c', armor_path], env={'KRB5CCNAME': armor_path}, raiseonerr=False) except RuntimeError as e: if ('kinit: Cannot read password while ' 'getting initial credentials') in str(e): raise PasswordExpired(principal=principal, message=unicode(e)) raise InvalidSessionPassword(principal=principal, message=unicode(e))
def change_principal(user, password, client=None, path=None, canonicalize=False, enterprise=False): if path: ccache_name = path else: ccache_name = os.path.join('/tmp', str(uuid.uuid4())) if client is None: client = api client.Backend.rpcclient.disconnect() try: with private_ccache(ccache_name): kinit_password(user, password, ccache_name, canonicalize=canonicalize, enterprise=enterprise) client.Backend.rpcclient.connect() try: yield finally: client.Backend.rpcclient.disconnect() finally: client.Backend.rpcclient.connect()
def change_principal(principal, password=None, client=None, path=None, canonicalize=False, enterprise=False, keytab=None): """Temporarily change the kerberos principal Most of the test cases run with the admin ipa user which is granted all access and exceptions from rules on some occasions. When the test needs to test for an application of some kind of a restriction it needs to authenticate as a different principal with required set of rights to the operation. The context manager changes the principal identity in two ways: * using password * using keytab If the context manager is to be used with a keytab, the keytab option must be its absolute path. The context manager can be used to authenticate with enterprise principals and aliases when given respective options. """ if path: ccache_name = path else: ccache_name = os.path.join('/tmp', str(uuid.uuid4())) if client is None: client = api client.Backend.rpcclient.disconnect() try: with private_ccache(ccache_name): if keytab: kinit_keytab(principal, keytab, ccache_name) else: kinit_password(principal, password, ccache_name, canonicalize=canonicalize, enterprise=enterprise) client.Backend.rpcclient.connect() try: yield finally: client.Backend.rpcclient.disconnect() finally: client.Backend.rpcclient.connect()
def kinit(self, principal, password): ccache_dir = tempfile.mkdtemp(prefix='krbcc') self.ccache_name = os.path.join(ccache_dir, 'ccache') current_ccache = os.environ.get('KRB5CCNAME') os.environ['KRB5CCNAME'] = self.ccache_name if principal.find('@') == -1: # pylint: disable=no-member principal = '%s@%s' % (principal, api.env.realm) try: kinit_password(principal, password, self.ccache_name) except RuntimeError as e: raise ConfigurationError("Kerberos authentication failed: %s" % e) finally: if current_ccache: os.environ['KRB5CCNAME'] = current_ccache
def kinit(self, user, realm, password, ccache_name): # get http service ccache as an armor for FAST to enable OTP authentication armor_principal = str( krb5_format_service_principal_name('HTTP', self.api.env.host, realm)) keytab = paths.IPA_KEYTAB armor_name = "%sA_%s" % (krbccache_prefix, user) armor_path = os.path.join(krbccache_dir, armor_name) self.debug('Obtaining armor ccache: principal=%s keytab=%s ccache=%s', armor_principal, keytab, armor_path) try: ipautil.kinit_keytab(armor_principal, paths.IPA_KEYTAB, armor_path) except gssapi.exceptions.GSSError as e: raise CCacheError(message=unicode(e)) # Format the user as a kerberos principal principal = krb5_format_principal_name(user, realm) try: ipautil.kinit_password(principal, password, ccache_name, armor_ccache_name=armor_path) self.debug('Cleanup the armor ccache') ipautil.run([paths.KDESTROY, '-A', '-c', armor_path], env={'KRB5CCNAME': armor_path}, raiseonerr=False) except RuntimeError as e: if ('kinit: Cannot read password while ' 'getting initial credentials') in str(e): raise PasswordExpired(principal=principal, message=unicode(e)) elif ('kinit: Client\'s entry in database' ' has expired while getting initial credentials') in str(e): raise KrbPrincipalExpired(principal=principal, message=unicode(e)) elif ('kinit: Clients credentials have been revoked ' 'while getting initial credentials') in str(e): raise UserLocked(principal=principal, message=unicode(e)) raise InvalidSessionPassword(principal=principal, message=unicode(e))
def check_creds(options, realm_name): # Check if ccache is available default_cred = None try: root_logger.debug('KRB5CCNAME set to %s' % os.environ.get('KRB5CCNAME', None)) # get default creds, will raise if none found default_cred = gssapi.creds.Credentials() principal = str(default_cred.name) except gssapi.raw.misc.GSSError as e: root_logger.debug('Failed to find default ccache: %s' % e) principal = None # Check if the principal matches the requested one (if any) if principal is not None and options.principal is not None: op = options.principal if op.find('@') == -1: op = '%s@%s' % (op, realm_name) if principal != op: root_logger.debug('Specified principal %s does not match ' 'available credentials (%s)' % (options.principal, principal)) principal = None if principal is None: (ccache_fd, ccache_name) = tempfile.mkstemp() os.close(ccache_fd) options.created_ccache_file = ccache_name if options.principal is not None: principal = options.principal else: principal = 'admin' stdin = None if principal.find('@') == -1: principal = '%s@%s' % (principal, realm_name) if options.admin_password is not None: stdin = options.admin_password else: if not options.unattended: try: stdin = getpass.getpass("Password for %s: " % principal) except EOFError: stdin = None if not stdin: root_logger.error( "Password must be provided for %s.", principal) raise ScriptError("Missing password for %s" % principal) else: if sys.stdin.isatty(): root_logger.error("Password must be provided in " + "non-interactive mode.") root_logger.info("This can be done via " + "echo password | ipa-client-install " + "... or with the -w option.") raise ScriptError("Missing password for %s" % principal) else: stdin = sys.stdin.readline() # set options.admin_password for future use options.admin_password = stdin try: ipautil.kinit_password(principal, stdin, ccache_name) except RuntimeError as e: root_logger.error("Kerberos authentication failed: %s" % e) raise ScriptError("Invalid credentials: %s" % e) os.environ['KRB5CCNAME'] = ccache_name