On 03/16/2015 01:35 PM, Jan Cholasta wrote:
Dne 16.3.2015 v 13:30 Martin Babinsky napsal(a):
On 03/16/2015 12:15 PM, Martin Kosek wrote:
On 03/13/2015 05:37 PM, Martin Babinsky wrote:
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.
The approach looks very good. I think that my only concern with this
patch is
this part:
+ ccache.init_creds_keytab(keytab=ktab, principal=princ)
...
+ 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))
The problem here is that this function will raise the super-generic
StandardError instead of the proper with all the context and
information about
the error that the caller can then process.
I think that
except krbV.Krb5Error as e:
if attempt == max_attempts:
log something
raise
would be better.
Yes that seems reasonable. I'm just thinking whether we should re-raise
Krb5Error or raise ipalib.errors.KerberosError? the latter options makes
more sense to me as we would not have to additionally import Krb5Error
everywhere and it would also make the resulting errors more consistent.
I am thinking about someting like this:
except krbV.Krb5Error as e:
if attempt == attempts:
# log that we have reaches maximum number of attempts
raise KerberosError(minor=str(e))
What do you think?
NACK, don't use ipalib from ipapython in new code, we are trying to get
rid of this circular dependency. Krb5Error is OK in this case.
Ok attaching updated patches.
--
Martin^3 Babinsky
From d7bae3613f39563de82952400048ad40495434f5 Mon Sep 17 00:00:00 2001
From: Martin Babinsky <mbabi...@redhat.com>
Date: Mon, 16 Mar 2015 16:28:54 +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 Krb5Error.
kinit_password wraps kinit auth using password and also supports FAST
authentication using httpd armor ccache.
---
ipapython/ipautil.py | 62 ++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 48 insertions(+), 14 deletions(-)
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 4116d974e620341119b56fad3cff1bda48af3bab..cd03e9fd17b60b8b7324d0ccd436a10f7556baf0 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -1175,27 +1175,61 @@ 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))
+ 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:
+ root_logger.debug("Attempt %d/%d: failed: %s"
+ % (attempt, attempts, e))
+ if attempt == attempts:
+ root_logger.debug("Maximum number of attempts (%d) reached"
+ % attempts)
+ raise
+ time.sleep(1)
+
+
+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 8e9f72498fabde79bd9ab236b09d1c226ff363ab Mon Sep 17 00:00:00 2001
From: Martin Babinsky <mbabi...@redhat.com>
Date: Mon, 16 Mar 2015 16:30:55 +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 host TGT from master 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 | 66 +++++++++++++++++--------------
ipa-client/man/ipa-client-install.1 | 9 +++++
2 files changed, 46 insertions(+), 29 deletions(-)
diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index ccaab5536e83b4b6ac60b81132c3455c0af19ae1..5ff668c2bad882fcb38fa3c9a96b3583548a751d 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -31,6 +31,7 @@ try:
from ConfigParser import RawConfigParser
from optparse import SUPPRESS_HELP, OptionGroup, OptionValueError
import shutil
+ from krbV import Krb5Error
import nss.nss as nss
import SSSDConfig
@@ -91,6 +92,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 +153,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 +2365,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 +2386,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 +2423,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 Krb5Error 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 +2509,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 Krb5Error 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 +2552,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 Krb5Error as 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 2d7c04afd5c611c0d8a1ecabe1ec7f248cdb93b8 Mon Sep 17 00:00:00 2001
From: Martin Babinsky <mbabi...@redhat.com>
Date: Mon, 16 Mar 2015 16:43:10 +0100
Subject: [PATCH 3/3] Adopted kinit_keytab and kinit_password for kerberos auth
Calls to ipautil.run using kinit were replaced with calls
kinit_keytab/kinit_password functions implemented in the PATCH 0015.
---
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 | 10 +++--
ipa-client/ipaclient/ipa_certupdate.py | 3 +-
ipaserver/rpcserver.py | 50 +++++++++++-----------
9 files changed, 50 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..0edd768f437c709a553094a361c79b5c317ef8b6 100755
--- a/ipa-client/ipa-install/ipa-client-automount
+++ b/ipa-client/ipa-install/ipa-client-automount
@@ -26,6 +26,7 @@ import os
import urlparse
import time
import tempfile
+from krbV import Krb5Error
import SSSDConfig
@@ -431,10 +432,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 Krb5Error as 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..6505d8a2fef133dfdb4e8a69d9a2d1f18445151e 100644
--- a/ipaserver/rpcserver.py
+++ b/ipaserver/rpcserver.py
@@ -30,6 +30,7 @@ import datetime
import urlparse
import json
import traceback
+from krbV import Krb5Error
import ldap.controls
from pyasn1.type import univ, namedtype
@@ -958,8 +959,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 +968,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 Krb5Error as 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