mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
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. 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
e4930b3235
commit
415a5ff372
@@ -1185,27 +1185,64 @@ def wait_for_open_socket(socket_name, timeout=0):
|
|||||||
else:
|
else:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
def kinit_hostprincipal(keytab, ccachedir, principal):
|
|
||||||
"""
|
|
||||||
Given a ccache directory and a principal kinit as that user.
|
|
||||||
|
|
||||||
This blindly overwrites the current CCNAME so if you need to save
|
def kinit_keytab(principal, keytab, ccache_name, attempts=1):
|
||||||
it do so before calling this function.
|
|
||||||
|
|
||||||
Thus far this is used to kinit as the local host.
|
|
||||||
"""
|
"""
|
||||||
|
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 in case of non-responsive KDC.
|
||||||
|
"""
|
||||||
|
errors_to_retry = {krbV.KRB5KDC_ERR_SVC_UNAVAILABLE,
|
||||||
|
krbV.KRB5_KDC_UNREACH}
|
||||||
|
root_logger.debug("Initializing principal %s using keytab %s"
|
||||||
|
% (principal, keytab))
|
||||||
|
root_logger.debug("using ccache %s" % ccache_name)
|
||||||
|
for attempt in range(1, attempts + 1):
|
||||||
try:
|
try:
|
||||||
ccache_file = 'FILE:%s/ccache' % ccachedir
|
|
||||||
krbcontext = krbV.default_context()
|
krbcontext = krbV.default_context()
|
||||||
ktab = krbV.Keytab(name=keytab, context=krbcontext)
|
ktab = krbV.Keytab(name=keytab, context=krbcontext)
|
||||||
princ = krbV.Principal(name=principal, context=krbcontext)
|
princ = krbV.Principal(name=principal, context=krbcontext)
|
||||||
os.environ['KRB5CCNAME'] = ccache_file
|
ccache = krbV.CCache(name=ccache_name, context=krbcontext,
|
||||||
ccache = krbV.CCache(name=ccache_file, context=krbcontext, primary_principal=princ)
|
primary_principal=princ)
|
||||||
ccache.init(princ)
|
ccache.init(princ)
|
||||||
ccache.init_creds_keytab(keytab=ktab, principal=princ)
|
ccache.init_creds_keytab(keytab=ktab, principal=princ)
|
||||||
return ccache_file
|
root_logger.debug("Attempt %d/%d: success"
|
||||||
except krbV.Krb5Error, e:
|
% (attempt, attempts))
|
||||||
raise StandardError('Error initializing principal %s in %s: %s' % (principal, keytab, str(e)))
|
return
|
||||||
|
except krbV.Krb5Error as e:
|
||||||
|
if e.args[0] not in errors_to_retry:
|
||||||
|
raise
|
||||||
|
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
|
||||||
|
root_logger.debug("Waiting 5 seconds before next retry")
|
||||||
|
time.sleep(5)
|
||||||
|
|
||||||
|
|
||||||
|
def kinit_password(principal, password, ccache_name, armor_ccache_name=None):
|
||||||
|
"""
|
||||||
|
perform interactive kinit as principal using password. If using FAST for
|
||||||
|
web-based authentication, use armor_ccache_path to specify http service
|
||||||
|
ccache.
|
||||||
|
"""
|
||||||
|
root_logger.debug("Initializing principal %s using password" % principal)
|
||||||
|
args = [paths.KINIT, principal, '-c', ccache_name]
|
||||||
|
if armor_ccache_name is not None:
|
||||||
|
root_logger.debug("Using armor ccache %s for FAST webauth"
|
||||||
|
% armor_ccache_name)
|
||||||
|
args.extend(['-T', armor_ccache_name])
|
||||||
|
|
||||||
|
# this workaround enables us to capture stderr and put it
|
||||||
|
# into the raised exception in case of unsuccessful authentication
|
||||||
|
(stdout, stderr, retcode) = run(args, stdin=password, env={'LC_ALL': 'C'},
|
||||||
|
raiseonerr=False)
|
||||||
|
if retcode:
|
||||||
|
raise RuntimeError(stderr)
|
||||||
|
|
||||||
|
|
||||||
def dn_attribute_property(private_name):
|
def dn_attribute_property(private_name):
|
||||||
'''
|
'''
|
||||||
|
|||||||
Reference in New Issue
Block a user