diff --git a/roles/ipaclient/library/ipaclient_join.py b/roles/ipaclient/library/ipaclient_join.py index a11f3f257421500a4eccee4fa81163ace0ab4efc..7057b5f6959d9908879a9cf951809b693e5c6b47 100644 --- a/roles/ipaclient/library/ipaclient_join.py +++ b/roles/ipaclient/library/ipaclient_join.py @@ -60,6 +60,9 @@ options: password: description: The password to use if not using Kerberos to authenticate. required: false + admin_keytab: + description: The path to a local admin keytab. + required: false keytab: description: The path to a backed-up host keytab from previous enrollment. required: false @@ -138,6 +141,7 @@ def main(): principal=dict(required=False), password=dict(required=False, no_log=True), keytab=dict(required=False), + admin_keytab=dict(required=False), ca_cert_file=dict(required=False), force_join=dict(required=False, type='bool'), kinit_attempts=dict(required=False, type='int', default=5), @@ -157,6 +161,7 @@ def main(): principal = module.params.get('principal') password = module.params.get('password') keytab = module.params.get('keytab') + admin_keytab = module.params.get('admin_keytab') ca_cert_file = module.params.get('ca_cert_file') kinit_attempts = module.params.get('kinit_attempts') debug = module.params.get('debug') @@ -164,6 +169,9 @@ def main(): if password is not None and keytab is not None: module.fail_json(msg="Password and keytab cannot be used together") + if password is None and admin_keytab is None: + module.fail_json(msg="Password or admin_keytab is needed") + client_domain = hostname[hostname.find(".")+1:] nolog = tuple() env = {'PATH': SECURE_PATH} @@ -209,12 +217,29 @@ def main(): if principal is not None: if principal.find('@') == -1: principal = '%s@%s' % (principal, realm) - try: - kinit_password(principal, password, ccache_name, - config=krb_name) - except RuntimeError as e: - module.fail_json( - msg="Kerberos authentication failed: {}".format(e)) + if admin_keytab: + join_args.append("-f") + if not os.path.exists(admin_keytab): + module.fail_json( + msg="Keytab file could not be found: %s" % \ + admin_keytab) + try: + kinit_keytab(principal, + admin_keytab, + ccache_name, + config=krb_name, + attempts=kinit_attempts) + except GSSError as e: + module.fail_json( + msg="Kerberos authentication failed: %s" % str(e)) + else: + try: + kinit_password(principal, password, ccache_name, + config=krb_name) + except RuntimeError as e: + module.fail_json( + msg="Kerberos authentication failed: {}".format(e)) + elif keytab: join_args.append("-f") if os.path.exists(keytab): diff --git a/roles/ipaclient/tasks/install.yml b/roles/ipaclient/tasks/install.yml index 74b3ea1450a481069aac0666931a429836493bbf..72864fe394ec2d4793b27aef4797304744ef30a2 100644 --- a/roles/ipaclient/tasks/install.yml +++ b/roles/ipaclient/tasks/install.yml @@ -156,6 +156,7 @@ fail: msg="At least one of password or keytabs must be specified" when: not result_ipaclient_test_keytab.krb5_keytab_ok and ipaadmin_password is undefined + and ipaadmin_keytab is undefined and ipaclient_keytab is undefined when: not ipaclient_on_master | bool @@ -190,6 +191,7 @@ ipaclient_keytab is not defined else omit }}" password: "{{ ipaadmin_password | default(omit) }}" keytab: "{{ ipaclient_keytab | default(omit) }}" + admin_keytab: "{{ ipaadmin_keytab if not ipaclient_use_otp | bool and ipaadmin_keytab else omit }}" # ca_cert_file: "{{ ipaclient_ca_cert_file | default(omit) }}" kinit_attempts: "{{ ipaclient_kinit_attempts | default(omit) }}" register: result_ipaclient_join