mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
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>
This commit is contained in:
committed by
Jan Cholasta
parent
415a5ff372
commit
a8e30e9671
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user