From ac24f9c067ae9b9dfe8219630da45f5d39886547 Mon Sep 17 00:00:00 2001
From: Thomas Woerner <twoerner@redhat.com>
Date: Fri, 14 Jun 2019 17:30:53 +0200
Subject: [PATCH] ipaclient_join: Support to use ipaadmin_keytab without
 ipaclient_use_otp

ipaadmin_keytab has been supported only with with ipaclient_use_otp. But
it can also be used without for ipa-join.

Important is that ipaadmin_keytab needs to be placed on the cliend node
and ipaadmin_keytab needs to be a full path. Otherwise the file will not
be found.
---
 roles/ipaclient/library/ipaclient_join.py | 37 +++++++++++++++++++----
 roles/ipaclient/tasks/install.yml         |  2 ++
 2 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/roles/ipaclient/library/ipaclient_join.py b/roles/ipaclient/library/ipaclient_join.py
index a11f3f25..7057b5f6 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 74b3ea14..72864fe3 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
-- 
GitLab