Attaching the next iteration of patches.
I have tried my best to reword the ipa-client-install man page bit about
the new option. Any suggestions to further improve it are welcome.
I have also slightly modified the 'kinit_keytab' function so that in
Kerberos errors are reported for each attempt and the text of the last
error is retained when finally raising exception.
--
Martin^3 Babinsky
From b6e0b91e27f041eedca4995e2ee09311d48e7168 Mon Sep 17 00:00:00 2001
From: Martin Babinsky <mbabi...@redhat.com>
Date: Fri, 13 Mar 2015 16:38:02 +0100
Subject: [PATCH 1/3] ipautil: new functions kinit_keytab and kinit_password
kinit_keytab replaces kinit_hostprincipal and performs Kerberos auth using
keytab file. Function is also able to repeat authentication multiple times
before giving up and raising StandardError.
kinit_password wraps kinit auth using password and also supports FAST
authentication using httpd armor ccache.
---
ipapython/ipautil.py | 65 +++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 51 insertions(+), 14 deletions(-)
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 4116d974e620341119b56fad3cff1bda48af3bab..7f2ca6f341907642e7acab87c89d7d46214a5646 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -1175,27 +1175,64 @@ def wait_for_open_socket(socket_name, timeout=0):
else:
raise e
-def kinit_hostprincipal(keytab, ccachedir, principal):
+
+def kinit_keytab(keytab, ccache_path, principal, attempts=1):
"""
- Given a ccache directory and a principal kinit as that user.
+ Given a ccache_path , keytab file and a principal kinit as that user.
+
+ The optional parameter 'attempts' specifies how many times the credential
+ initialization should be attempted before giving up and raising
+ StandardError.
This blindly overwrites the current CCNAME so if you need to save
it do so before calling this function.
+ This function is also not thread-safe since it modifies environment
+ variables.
+
Thus far this is used to kinit as the local host.
"""
- try:
- ccache_file = 'FILE:%s/ccache' % ccachedir
- krbcontext = krbV.default_context()
- ktab = krbV.Keytab(name=keytab, context=krbcontext)
- princ = krbV.Principal(name=principal, context=krbcontext)
- os.environ['KRB5CCNAME'] = ccache_file
- ccache = krbV.CCache(name=ccache_file, context=krbcontext, primary_principal=princ)
- ccache.init(princ)
- ccache.init_creds_keytab(keytab=ktab, principal=princ)
- return ccache_file
- except krbV.Krb5Error, e:
- raise StandardError('Error initializing principal %s in %s: %s' % (principal, keytab, str(e)))
+ root_logger.debug("Initializing principal %s using keytab %s"
+ % (principal, keytab))
+ last_exc = ""
+ for attempt in range(1, attempts + 1):
+ try:
+ krbcontext = krbV.default_context()
+ ktab = krbV.Keytab(name=keytab, context=krbcontext)
+ princ = krbV.Principal(name=principal, context=krbcontext)
+ os.environ['KRB5CCNAME'] = ccache_path
+ ccache = krbV.CCache(name=ccache_path, context=krbcontext,
+ primary_principal=princ)
+ ccache.init(princ)
+ ccache.init_creds_keytab(keytab=ktab, principal=princ)
+ root_logger.debug("Attempt %d/%d: success"
+ % (attempt, attempts))
+ return
+ except krbV.Krb5Error as e:
+ last_exc = str(e)
+ root_logger.debug("Attempt %d/%d: failed: %s"
+ % (attempt, attempts, last_exc))
+ time.sleep(1)
+
+ root_logger.debug("Maximum number of attempts (%d) reached"
+ % attempts)
+ raise StandardError("Error initializing principal %s: %s"
+ % (principal, last_exc))
+
+
+def kinit_password(principal, password, env={}, armor_ccache=""):
+ """perform interactive kinit as principal using password. Additional
+ enviroment variables can be specified using env. If using FAST for
+ web-based authentication, use armor_ccache to specify http service ccache.
+ """
+ root_logger.debug("Initializing principal %s using password" % principal)
+ args = [paths.KINIT, principal]
+ if armor_ccache:
+ root_logger.debug("Using armor ccache %s for FAST webauth"
+ % armor_ccache)
+ args.extend(['-T', armor_ccache])
+ run(args, env=env, stdin=password)
+
def dn_attribute_property(private_name):
'''
--
2.1.0
From 74fd74fdeeb746e4d6bebdc459d4401a63279b78 Mon Sep 17 00:00:00 2001
From: Martin Babinsky <mbabi...@redhat.com>
Date: Fri, 13 Mar 2015 16:39:05 +0100
Subject: [PATCH 2/3] ipa-client-install: try to get host TGT several times
before giving up
New option '--kinit-attempts' enables the host to make multiple attempts to
obtain TGT from KDC before giving up and aborting client installation.
In addition, all kinit attempts were replaced by calls to
'ipautil.kinit_keytab' and 'ipautil.kinit_password'.
https://fedorahosted.org/freeipa/ticket/4808
---
ipa-client/ipa-install/ipa-client-install | 65 +++++++++++++++++--------------
ipa-client/man/ipa-client-install.1 | 9 +++++
2 files changed, 45 insertions(+), 29 deletions(-)
diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index ccaab5536e83b4b6ac60b81132c3455c0af19ae1..dc7f2cf87dc89bee715c35bfb889dd2745ccfe25 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -91,6 +91,14 @@ def parse_options():
parser.values.ca_cert_file = value
+ def validate_kinit_attempts_option(option, opt, value, parser):
+ if value < 1 or value > sys.maxint:
+ raise OptionValueError(
+ "Option %s expects an integer in range <1,%d>"
+ % (opt, sys.maxint))
+
+ parser.values.kinit_attempts = value
+
parser = IPAOptionParser(version=version.VERSION)
basic_group = OptionGroup(parser, "basic options")
@@ -144,6 +152,11 @@ def parse_options():
help="do not modify the nsswitch.conf and PAM configuration")
basic_group.add_option("-f", "--force", dest="force", action="store_true",
default=False, help="force setting of LDAP/Kerberos conf")
+ basic_group.add_option('--kinit-attempts', dest='kinit_attempts',
+ action='callback', type='int', default=5,
+ callback=validate_kinit_attempts_option,
+ help=("number of attempts to obtain host TGT"
+ " (defaults to %default)."))
basic_group.add_option("-d", "--debug", dest="debug", action="store_true",
default=False, help="print debugging information")
basic_group.add_option("-U", "--unattended", dest="unattended",
@@ -2351,6 +2364,7 @@ def install(options, env, fstore, statestore):
root_logger.debug(
"will use principal provided as option: %s", options.principal)
+ host_principal = 'host/%s@%s' % (hostname, cli_realm)
if not options.on_master:
nolog = tuple()
# First test out the kerberos configuration
@@ -2371,7 +2385,6 @@ def install(options, env, fstore, statestore):
env['KRB5_CONFIG'] = krb_name
(ccache_fd, ccache_name) = tempfile.mkstemp()
os.close(ccache_fd)
- env['KRB5CCNAME'] = os.environ['KRB5CCNAME'] = ccache_name
join_args = [paths.SBIN_IPA_JOIN,
"-s", cli_server[0],
"-b", str(realm_to_suffix(cli_realm)),
@@ -2409,29 +2422,23 @@ def install(options, env, fstore, statestore):
else:
stdin = sys.stdin.readline()
- (stderr, stdout, returncode) = run(["kinit", principal],
- raiseonerr=False,
- stdin=stdin,
- env=env)
- if returncode != 0:
+ try:
+ ipautil.kinit_password(principal, stdin, env)
+ except CalledProcessError as e:
print_port_conf_info()
- root_logger.error("Kerberos authentication failed")
- root_logger.info("%s", stdout)
+ root_logger.error("Kerberos authentication failed: %s" % e)
return CLIENT_INSTALL_ERROR
elif options.keytab:
join_args.append("-f")
if os.path.exists(options.keytab):
- (stderr, stdout, returncode) = run(
- [paths.KINIT,'-k', '-t', options.keytab,
- 'host/%s@%s' % (hostname, cli_realm)],
- env=env,
- raiseonerr=False)
-
- if returncode != 0:
+ try:
+ ipautil.kinit_keytab(options.keytab, ccache_name,
+ host_principal,
+ attempts=options.kinit_attempts)
+ except StandardError as e:
print_port_conf_info()
- root_logger.error("Kerberos authentication failed "
- "using keytab: %s", options.keytab)
- root_logger.info("%s", stdout)
+ root_logger.error("Kerberos authentication failed: %s"
+ % e)
return CLIENT_INSTALL_ERROR
else:
root_logger.error("Keytab file could not be found: %s"
@@ -2501,12 +2508,13 @@ def install(options, env, fstore, statestore):
# only the KDC we're installing under is contacted.
# Other KDCs might not have replicated the principal yet.
# Once we have the TGT, it's usable on any server.
- env['KRB5CCNAME'] = os.environ['KRB5CCNAME'] = CCACHE_FILE
try:
- run([paths.KINIT, '-k', '-t', paths.KRB5_KEYTAB,
- 'host/%s@%s' % (hostname, cli_realm)], env=env)
- except CalledProcessError, e:
- root_logger.error("Failed to obtain host TGT.")
+ ipautil.kinit_keytab(paths.KRB5_KEYTAB, CCACHE_FILE,
+ host_principal,
+ attempts=options.kinit_attempts)
+ except StandardError as e:
+ print_port_conf_info()
+ root_logger.error("Failed to obtain host TGT: %s" % e)
# failure to get ticket makes it impossible to login and bind
# from sssd to LDAP, abort installation and rollback changes
return CLIENT_INSTALL_ERROR
@@ -2543,16 +2551,15 @@ def install(options, env, fstore, statestore):
return CLIENT_INSTALL_ERROR
root_logger.info("Configured /etc/sssd/sssd.conf")
- host_principal = 'host/%s@%s' % (hostname, cli_realm)
if options.on_master:
# If on master assume kerberos is already configured properly.
# Get the host TGT.
- os.environ['KRB5CCNAME'] = CCACHE_FILE
try:
- run([paths.KINIT, '-k', '-t', paths.KRB5_KEYTAB,
- host_principal])
- except CalledProcessError, e:
- root_logger.error("Failed to obtain host TGT.")
+ ipautil.kinit_keytab(paths.KRB5_KEYTAB, CCACHE_FILE,
+ host_principal,
+ attempts=options.kinit_attempts)
+ except StandardError, e:
+ root_logger.error("Failed to obtain host TGT: %s" % e)
return CLIENT_INSTALL_ERROR
else:
# Configure krb5.conf
diff --git a/ipa-client/man/ipa-client-install.1 b/ipa-client/man/ipa-client-install.1
index 726a6c133132dd2e3ba2fde43d8a2ec0549bfcef..050a46905d67df98f7fad5bda1a689095eb543fa 100644
--- a/ipa-client/man/ipa-client-install.1
+++ b/ipa-client/man/ipa-client-install.1
@@ -152,6 +152,15 @@ Do not use Authconfig to modify the nsswitch.conf and PAM configuration.
\fB\-f\fR, \fB\-\-force\fR
Force the settings even if errors occur
.TP
+\fB\-\-kinit\-attempts\fR=\fIKINIT_ATTEMPTS\fR
+Attempt to get Kerberos ticket for the host principal \fIKINIT_ATTEMPTS\fR
+times before giving up and aborting client installation. Useful when enrolling
+clients in heavy-load environments where KDCs may fail to respond to all
+requests at once. Default value is 5, which is less that the maximum number of
+failed auth attempts (6) before locking out principal in default FreeIPA group
+password policy. Make sure to update the policy accordingly when using higher
+values of fIKINIT_ATTEMPTS\fR.
+.TP
\fB\-d\fR, \fB\-\-debug\fR
Print debugging information to stdout
.TP
--
2.1.0
From 87f4bee9e336163a5ee13ca4121a9b60ef66a125 Mon Sep 17 00:00:00 2001
From: Martin Babinsky <mbabi...@redhat.com>
Date: Fri, 13 Mar 2015 16:39:41 +0100
Subject: [PATCH 3/3] Adopted kinit_keytab and kinit_password for kerberos auth
---
daemons/dnssec/ipa-dnskeysync-replica | 6 ++-
daemons/dnssec/ipa-dnskeysyncd | 3 +-
daemons/dnssec/ipa-ods-exporter | 5 ++-
.../certmonger/dogtag-ipa-ca-renew-agent-submit | 3 +-
install/restart_scripts/renew_ca_cert | 7 ++--
install/restart_scripts/renew_ra_cert | 4 +-
ipa-client/ipa-install/ipa-client-automount | 9 ++--
ipa-client/ipaclient/ipa_certupdate.py | 3 +-
ipaserver/rpcserver.py | 49 +++++++++++-----------
9 files changed, 48 insertions(+), 41 deletions(-)
diff --git a/daemons/dnssec/ipa-dnskeysync-replica b/daemons/dnssec/ipa-dnskeysync-replica
index d04f360e04ee018dcdd1ba9b2ca42b1844617af9..f22be9b09978ac292ea584d4c7081020b2097dda 100755
--- a/daemons/dnssec/ipa-dnskeysync-replica
+++ b/daemons/dnssec/ipa-dnskeysync-replica
@@ -139,14 +139,16 @@ log.setLevel(level=logging.DEBUG)
# Kerberos initialization
PRINCIPAL = str('%s/%s' % (DAEMONNAME, ipalib.api.env.host))
log.debug('Kerberos principal: %s', PRINCIPAL)
-ipautil.kinit_hostprincipal(paths.IPA_DNSKEYSYNCD_KEYTAB, WORKDIR, PRINCIPAL)
+ccache_filename = os.path.join(WORKDIR, 'ipa-dnskeysync-replica.ccache')
+ipautil.kinit_keytab(paths.IPA_DNSKEYSYNCD_KEYTAB, ccache_filename,
+ PRINCIPAL)
log.debug('Got TGT')
# LDAP initialization
ldap = ipalib.api.Backend[ldap2]
# fixme
log.debug('Connecting to LDAP')
-ldap.connect(ccache="%s/ccache" % WORKDIR)
+ldap.connect(ccache=ccache_filename)
log.debug('Connected')
diff --git a/daemons/dnssec/ipa-dnskeysyncd b/daemons/dnssec/ipa-dnskeysyncd
index 54a08a1e6307e89b3f52e78bddbe28cda8ac1345..cf3ecc5a5f7ac40b7f52e1dfc42367130dac926e 100755
--- a/daemons/dnssec/ipa-dnskeysyncd
+++ b/daemons/dnssec/ipa-dnskeysyncd
@@ -65,7 +65,8 @@ log = root_logger
# Kerberos initialization
PRINCIPAL = str('%s/%s' % (DAEMONNAME, api.env.host))
log.debug('Kerberos principal: %s', PRINCIPAL)
-ipautil.kinit_hostprincipal(KEYTAB_FB, WORKDIR, PRINCIPAL)
+ccache_name = os.path.join(WORKDIR, 'ipa-dnskeysyncd.ccache')
+ipautil.kinit_keytab(KEYTAB_FB, ccache_name, PRINCIPAL)
# LDAP initialization
basedn = DN(api.env.container_dns, api.env.basedn)
diff --git a/daemons/dnssec/ipa-ods-exporter b/daemons/dnssec/ipa-ods-exporter
index dc1851d3a34bb09c1a87c86d101b11afe35e49fe..4a6d387392146ea2cb48e6582bac513a36965d77 100755
--- a/daemons/dnssec/ipa-ods-exporter
+++ b/daemons/dnssec/ipa-ods-exporter
@@ -399,7 +399,8 @@ ipalib.api.finalize()
# Kerberos initialization
PRINCIPAL = str('%s/%s' % (DAEMONNAME, ipalib.api.env.host))
log.debug('Kerberos principal: %s', PRINCIPAL)
-ipautil.kinit_hostprincipal(paths.IPA_ODS_EXPORTER_KEYTAB, WORKDIR, PRINCIPAL)
+ccache_name = os.path.join(WORKDIR, 'ipa-ods-exporter.ccache')
+ipautil.kinit_keytab(paths.IPA_ODS_EXPORTER_KEYTAB, ccache_name, PRINCIPAL)
log.debug('Got TGT')
# LDAP initialization
@@ -407,7 +408,7 @@ dns_dn = DN(ipalib.api.env.container_dns, ipalib.api.env.basedn)
ldap = ipalib.api.Backend[ldap2]
# fixme
log.debug('Connecting to LDAP')
-ldap.connect(ccache="%s/ccache" % WORKDIR)
+ldap.connect(ccache=ccache_name)
log.debug('Connected')
diff --git a/install/certmonger/dogtag-ipa-ca-renew-agent-submit b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
index 7b91fc61148912c77d0ae962b3847d73e8d0720e..13d2c2a912d2fcf84053d36da5e07fc834f9cf25 100755
--- a/install/certmonger/dogtag-ipa-ca-renew-agent-submit
+++ b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
@@ -440,7 +440,8 @@ def main():
certs.renewal_lock.acquire()
try:
principal = str('host/%s@%s' % (api.env.host, api.env.realm))
- ipautil.kinit_hostprincipal(paths.KRB5_KEYTAB, tmpdir, principal)
+ ipautil.kinit_keytab(paths.KRB5_KEYTAB, os.path.join(tmpdir, 'ccache'),
+ principal)
profile = os.environ.get('CERTMONGER_CA_PROFILE')
if profile:
diff --git a/install/restart_scripts/renew_ca_cert b/install/restart_scripts/renew_ca_cert
index c7bd5d74c5b4659b3ad66d630653ff6419868d99..67156122bb75f00a4c3f612697092e5bab3723fb 100644
--- a/install/restart_scripts/renew_ca_cert
+++ b/install/restart_scripts/renew_ca_cert
@@ -73,8 +73,9 @@ def _main():
tmpdir = tempfile.mkdtemp(prefix="tmp-")
try:
principal = str('host/%s@%s' % (api.env.host, api.env.realm))
- ccache = ipautil.kinit_hostprincipal(paths.KRB5_KEYTAB, tmpdir,
- principal)
+ ccache_filename = '%s/ccache' % tmpdir
+ ipautil.kinit_keytab(paths.KRB5_KEYTAB, ccache_filename,
+ principal)
ca = cainstance.CAInstance(host_name=api.env.host, ldapi=False)
ca.update_cert_config(nickname, cert, configured_constants)
@@ -139,7 +140,7 @@ def _main():
conn = None
try:
conn = ldap2(shared_instance=False, ldap_uri=api.env.ldap_uri)
- conn.connect(ccache=ccache)
+ conn.connect(ccache=ccache_filename)
except Exception, e:
syslog.syslog(
syslog.LOG_ERR, "Failed to connect to LDAP: %s" % e)
diff --git a/install/restart_scripts/renew_ra_cert b/install/restart_scripts/renew_ra_cert
index 7dae3562380e919b2cc5f53825820291fc93fdc5..6276de78e4528dc1caa39be6628094a9d00e5988 100644
--- a/install/restart_scripts/renew_ra_cert
+++ b/install/restart_scripts/renew_ra_cert
@@ -42,8 +42,8 @@ def _main():
tmpdir = tempfile.mkdtemp(prefix="tmp-")
try:
principal = str('host/%s@%s' % (api.env.host, api.env.realm))
- ccache = ipautil.kinit_hostprincipal(paths.KRB5_KEYTAB, tmpdir,
- principal)
+ ipautil.kinit_keytab(paths.KRB5_KEYTAB, '%s/ccache' % tmpdir,
+ principal)
ca = cainstance.CAInstance(host_name=api.env.host, ldapi=False)
if ca.is_renewal_master():
diff --git a/ipa-client/ipa-install/ipa-client-automount b/ipa-client/ipa-install/ipa-client-automount
index ca56f97832159c55cb7010db1b406b52c206462f..537241828904108d3fb034a586f602529c87a535 100755
--- a/ipa-client/ipa-install/ipa-client-automount
+++ b/ipa-client/ipa-install/ipa-client-automount
@@ -431,10 +431,11 @@ def main():
os.close(ccache_fd)
try:
try:
- os.environ['KRB5CCNAME'] = ccache_name
- ipautil.run([paths.KINIT, '-k', '-t', paths.KRB5_KEYTAB, 'host/%s@%s' % (api.env.host, api.env.realm)])
- except ipautil.CalledProcessError, e:
- sys.exit("Failed to obtain host TGT.")
+ host_princ = str('host/%s@%s' % (api.env.host, api.env.realm))
+ ipautil.kinit_keytab(paths.KRB5_KEYTAB, ccache_name,
+ host_princ)
+ except StandardError, e:
+ sys.exit("Failed to obtain host TGT: %s" % e)
# Now we have a TGT, connect to IPA
try:
api.Backend.rpcclient.connect()
diff --git a/ipa-client/ipaclient/ipa_certupdate.py b/ipa-client/ipaclient/ipa_certupdate.py
index 031a34c3a54a02d43978eedcb794678a1550702b..d6f7bbb3daff3ae4dced5d69f83a0516003235ab 100644
--- a/ipa-client/ipaclient/ipa_certupdate.py
+++ b/ipa-client/ipaclient/ipa_certupdate.py
@@ -57,7 +57,8 @@ class CertUpdate(admintool.AdminTool):
tmpdir = tempfile.mkdtemp(prefix="tmp-")
try:
principal = str('host/%s@%s' % (api.env.host, api.env.realm))
- ipautil.kinit_hostprincipal(paths.KRB5_KEYTAB, tmpdir, principal)
+ ipautil.kinit_keytab(paths.KRB5_KEYTAB,
+ os.path.join(tmpdir, 'ccache'), principal)
api.Backend.rpcclient.connect()
try:
diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
index d6bc955b9d9910a24eec5df1def579310eb54786..36f16908ac8477d9982bfee613b77576853054eb 100644
--- a/ipaserver/rpcserver.py
+++ b/ipaserver/rpcserver.py
@@ -958,8 +958,8 @@ class login_password(Backend, KerberosSession, HTTP_Status):
def kinit(self, user, realm, password, ccache_name):
# get http service ccache as an armor for FAST to enable OTP authentication
- armor_principal = krb5_format_service_principal_name(
- 'HTTP', self.api.env.host, realm)
+ 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)
@@ -967,34 +967,33 @@ class login_password(Backend, KerberosSession, HTTP_Status):
self.debug('Obtaining armor ccache: principal=%s keytab=%s ccache=%s',
armor_principal, keytab, armor_path)
- (stdout, stderr, returncode) = ipautil.run(
- [paths.KINIT, '-kt', keytab, armor_principal],
- env={'KRB5CCNAME': armor_path}, raiseonerr=False)
-
- if returncode != 0:
- raise CCacheError()
+ try:
+ ipautil.kinit_keytab(paths.IPA_KEYTAB, armor_path,
+ armor_principal)
+ except StandardError, e:
+ raise CCacheError(str(e))
# Format the user as a kerberos principal
principal = krb5_format_principal_name(user, realm)
- (stdout, stderr, returncode) = ipautil.run(
- [paths.KINIT, principal, '-T', armor_path],
- env={'KRB5CCNAME': ccache_name, 'LC_ALL': 'C'},
- stdin=password, raiseonerr=False)
+ try:
+ ipautil.kinit_password(principal, password,
+ env={'KRB5CCNAME': ccache_name,
+ 'LC_ALL': 'C'},
+ armor_ccache=armor_path)
- self.debug('kinit: principal=%s returncode=%s, stderr="%s"',
- principal, returncode, stderr)
-
- self.debug('Cleanup the armor ccache')
- ipautil.run(
- [paths.KDESTROY, '-A', '-c', armor_path],
- env={'KRB5CCNAME': armor_path},
- raiseonerr=False)
-
- if returncode != 0:
- if stderr.strip() == 'kinit: Cannot read password while getting initial credentials':
- raise PasswordExpired(principal=principal, message=unicode(stderr))
- raise InvalidSessionPassword(principal=principal, message=unicode(stderr))
+ self.debug('Cleanup the armor ccache')
+ ipautil.run(
+ [paths.KDESTROY, '-A', '-c', armor_path],
+ env={'KRB5CCNAME': armor_path},
+ raiseonerr=False)
+ except ipautil.CalledProcessError, e:
+ if ('kinit: Cannot read password while '
+ 'getting initial credentials') in e.output:
+ raise PasswordExpired(principal=principal,
+ message=unicode(e.output))
+ raise InvalidSessionPassword(principal=principal,
+ message=unicode(e.output))
class change_password(Backend, HTTP_Status):
--
2.1.0
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code