diff options
author | Martin Babinsky <mbabinsk@redhat.com> | 2015-03-16 16:30:55 +0100 |
---|---|---|
committer | Jan Cholasta <jcholast@redhat.com> | 2015-04-20 08:27:35 +0000 |
commit | a8e30e96716992e4160abdb7ac5995bb75e54eae (patch) | |
tree | 40163905452de8fb15b05708970a3bc7ec964e97 /ipa-client | |
parent | 415a5ff372fccee38a799cae37fb170145222107 (diff) | |
download | freeipa-a8e30e96716992e4160abdb7ac5995bb75e54eae.tar.gz freeipa-a8e30e96716992e4160abdb7ac5995bb75e54eae.tar.xz freeipa-a8e30e96716992e4160abdb7ac5995bb75e54eae.zip |
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
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
Reviewed-By: Simo Sorce <ssorce@redhat.com>
Reviewed-By: Petr Spacek <pspacek@redhat.com>
Diffstat (limited to 'ipa-client')
-rwxr-xr-x | ipa-client/ipa-install/ipa-client-install | 69 | ||||
-rw-r--r-- | ipa-client/man/ipa-client-install.1 | 8 |
2 files changed, 48 insertions, 29 deletions
diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install index 1590a0860..47f1c128c 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 kinit_attempts_callback(option, opt, value, parser): + if value < 1: + raise OptionValueError( + "Option %s expects an integer greater than 0." + % opt) + + 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=kinit_attempts_callback, + 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", @@ -2354,6 +2368,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 @@ -2374,7 +2389,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)), @@ -2412,29 +2426,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, ccache_name) + except RuntimeError 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(host_principal, options.keytab, + ccache_name, + 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" @@ -2460,6 +2468,7 @@ def install(options, env, fstore, statestore): join_args.append(password) nolog = (password,) + env['KRB5CCNAME'] = os.environ['KRB5CCNAME'] = ccache_name # Get the CA certificate try: os.environ['KRB5_CONFIG'] = env['KRB5_CONFIG'] @@ -2504,12 +2513,14 @@ 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(host_principal, paths.KRB5_KEYTAB, + CCACHE_FILE, + attempts=options.kinit_attempts) + env['KRB5CCNAME'] = os.environ['KRB5CCNAME'] = CCACHE_FILE + 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 @@ -2546,16 +2557,16 @@ 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(host_principal, paths.KRB5_KEYTAB, + CCACHE_FILE, + attempts=options.kinit_attempts) + os.environ['KRB5CCNAME'] = CCACHE_FILE + 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 726a6c133..985cfb064 100644 --- a/ipa-client/man/ipa-client-install.1 +++ b/ipa-client/man/ipa-client-install.1 @@ -152,6 +152,14 @@ 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 +In case of unresponsive KDC (e.g. when enrolling multiple hosts at once in a +heavy load environment) repeat the request for host Kerberos ticket up to a +total number of \fIKINIT_ATTEMPTS\fR times before giving up and aborting client +installation. Default number of attempts is 5. The request is not repeated when +there is a problem with host credentials themselves (e.g. wrong keytab format +or invalid principal) so using this option will not lead to account lockouts. +.TP \fB\-d\fR, \fB\-\-debug\fR Print debugging information to stdout .TP |