Blame 0001-Implement-adcli-testjoin.patch

8fc58f6
From 6fd99ff6c5dd6ef0be8d942989b1c6dcee3102d9 Mon Sep 17 00:00:00 2001
8fc58f6
From: Sumit Bose <sbose@redhat.com>
8fc58f6
Date: Fri, 22 Mar 2019 12:37:39 +0100
8fc58f6
Subject: [PATCH] Implement 'adcli testjoin'
8fc58f6
8fc58f6
By calling adcli testjoin it will be checked if the host credentials
8fc58f6
stored in the keytab are still valid.
8fc58f6
8fc58f6
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1622583
8fc58f6
---
8fc58f6
 doc/adcli.xml    | 34 +++++++++++++++++++++++
8fc58f6
 tools/computer.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++
8fc58f6
 tools/tools.c    |  1 +
8fc58f6
 tools/tools.h    |  4 +++
8fc58f6
 4 files changed, 111 insertions(+)
8fc58f6
8fc58f6
diff --git a/doc/adcli.xml b/doc/adcli.xml
8fc58f6
index af73433..9605b4a 100644
8fc58f6
--- a/doc/adcli.xml
8fc58f6
+++ b/doc/adcli.xml
8fc58f6
@@ -43,6 +43,9 @@
8fc58f6
 	<cmdsynopsis>
8fc58f6
 		<command>adcli update</command>
8fc58f6
 	</cmdsynopsis>
8fc58f6
+	<cmdsynopsis>
8fc58f6
+		<command>adcli testjoin</command>
8fc58f6
+	</cmdsynopsis>
8fc58f6
 	<cmdsynopsis>
8fc58f6
 		<command>adcli create-user</command>
8fc58f6
 		<arg choice="opt">--domain=domain.example.com</arg>
8fc58f6
@@ -474,6 +477,37 @@ $ adcli update --login-ccache=/tmp/krbcc_123
8fc58f6
 
8fc58f6
 </refsect1>
8fc58f6
 
8fc58f6
+<refsect1 id='testjoin'>
8fc58f6
+	<title>Testing if the machine account password is valid</title>
8fc58f6
+
8fc58f6
+	<para><command>adcli testjoin</command> uses the current credentials in
8fc58f6
+	the keytab and tries to authenticate with the machine account to the AD
8fc58f6
+	domain. If this works the machine account password and the join are
8fc58f6
+	still valid. If it fails the machine account password or the whole
8fc58f6
+	machine account have to be refreshed with
8fc58f6
+	<command>adcli join</command> or <command>adcli update</command>.
8fc58f6
+	</para>
8fc58f6
+
8fc58f6
+<programlisting>
8fc58f6
+$ adcli testjoin
8fc58f6
+</programlisting>
8fc58f6
+
8fc58f6
+	<para>Only the global options not related to authentication are
8fc58f6
+	available, additionally you can specify the following options to
8fc58f6
+	control how this operation is done.</para>
8fc58f6
+
8fc58f6
+	<variablelist>
8fc58f6
+		<varlistentry>
8fc58f6
+			<term><option>-K, --host-keytab=<parameter>/path/to/keytab</parameter></option></term>
8fc58f6
+			<listitem><para>Specify the path to the host keytab where
8fc58f6
+			current host credentials are stored and the new ones
8fc58f6
+			will be written to.  If not specified, the default
8fc58f6
+			location will be used, usually
8fc58f6
+			<filename>/etc/krb5.keytab</filename>.</para></listitem>
8fc58f6
+		</varlistentry>
8fc58f6
+	</variablelist>
8fc58f6
+</refsect1>
8fc58f6
+
8fc58f6
 <refsect1 id='create_user'>
8fc58f6
 	<title>Creating a User</title>
8fc58f6
 
8fc58f6
diff --git a/tools/computer.c b/tools/computer.c
8fc58f6
index 112340e..610ed2b 100644
8fc58f6
--- a/tools/computer.c
8fc58f6
+++ b/tools/computer.c
8fc58f6
@@ -566,6 +566,78 @@ adcli_tool_computer_update (adcli_conn *conn,
8fc58f6
 	return 0;
8fc58f6
 }
8fc58f6
 
8fc58f6
+int
8fc58f6
+adcli_tool_computer_testjoin (adcli_conn *conn,
8fc58f6
+                              int argc,
8fc58f6
+                              char *argv[])
8fc58f6
+{
8fc58f6
+	adcli_enroll *enroll;
8fc58f6
+	adcli_result res;
8fc58f6
+	const char *ktname;
8fc58f6
+	int opt;
8fc58f6
+
8fc58f6
+	struct option options[] = {
8fc58f6
+		{ "domain", required_argument, NULL, opt_domain },
8fc58f6
+		{ "domain-controller", required_argument, NULL, opt_domain_controller },
8fc58f6
+		{ "host-keytab", required_argument, 0, opt_host_keytab },
8fc58f6
+		{ "verbose", no_argument, NULL, opt_verbose },
8fc58f6
+		{ "help", no_argument, NULL, 'h' },
8fc58f6
+		{ 0 },
8fc58f6
+	};
8fc58f6
+
8fc58f6
+	static adcli_tool_desc usages[] = {
8fc58f6
+		{ 0, "usage: adcli testjoin" },
8fc58f6
+		{ 0 },
8fc58f6
+	};
8fc58f6
+
8fc58f6
+	enroll = adcli_enroll_new (conn);
8fc58f6
+	if (enroll == NULL)
8fc58f6
+		errx (-1, "unexpected memory problems");
8fc58f6
+
8fc58f6
+	while ((opt = adcli_tool_getopt (argc, argv, options)) != -1) {
8fc58f6
+		switch (opt) {
8fc58f6
+		case 'h':
8fc58f6
+		case '?':
8fc58f6
+		case ':':
8fc58f6
+			adcli_tool_usage (options, usages);
8fc58f6
+			adcli_tool_usage (options, common_usages);
8fc58f6
+			adcli_enroll_unref (enroll);
8fc58f6
+			return opt == 'h' ? 0 : 2;
8fc58f6
+		default:
8fc58f6
+			parse_option ((Option)opt, optarg, conn, enroll);
8fc58f6
+			break;
8fc58f6
+		}
8fc58f6
+	}
8fc58f6
+
8fc58f6
+	/* Force use of a keytab to test the join/machine account password */
8fc58f6
+	adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_COMPUTER_ACCOUNT);
8fc58f6
+	ktname = adcli_enroll_get_keytab_name (enroll);
8fc58f6
+	adcli_conn_set_login_keytab_name (conn, ktname ? ktname : "");
8fc58f6
+
8fc58f6
+	res = adcli_enroll_load (enroll);
8fc58f6
+	if (res != ADCLI_SUCCESS) {
8fc58f6
+		adcli_enroll_unref (enroll);
8fc58f6
+		adcli_conn_unref (conn);
8fc58f6
+		errx (-res, "couldn't lookup domain info from keytab: %s",
8fc58f6
+		      adcli_get_last_error ());
8fc58f6
+	}
8fc58f6
+
8fc58f6
+	res = adcli_conn_connect (conn);
8fc58f6
+	if (res != ADCLI_SUCCESS) {
8fc58f6
+		adcli_enroll_unref (enroll);
8fc58f6
+		adcli_conn_unref (conn);
8fc58f6
+		errx (-res, "couldn't connect to %s domain: %s",
8fc58f6
+		      adcli_conn_get_domain_name (conn),
8fc58f6
+		      adcli_get_last_error ());
8fc58f6
+	}
8fc58f6
+
8fc58f6
+	printf ("Sucessfully validated join to domain %s\n",
8fc58f6
+	        adcli_conn_get_domain_name (conn));
8fc58f6
+
8fc58f6
+	adcli_enroll_unref (enroll);
8fc58f6
+
8fc58f6
+	return 0;
8fc58f6
+}
8fc58f6
 
8fc58f6
 int
8fc58f6
 adcli_tool_computer_preset (adcli_conn *conn,
8fc58f6
diff --git a/tools/tools.c b/tools/tools.c
8fc58f6
index 915130e..c4e2851 100644
8fc58f6
--- a/tools/tools.c
8fc58f6
+++ b/tools/tools.c
8fc58f6
@@ -55,6 +55,7 @@ struct {
8fc58f6
 	{ "info", adcli_tool_info, "Print information about a domain", CONNECTION_LESS },
8fc58f6
 	{ "join", adcli_tool_computer_join, "Join this machine to a domain", },
8fc58f6
 	{ "update", adcli_tool_computer_update, "Update machine membership in a domain", },
8fc58f6
+	{ "testjoin", adcli_tool_computer_testjoin, "Test if machine account password is valid", },
8fc58f6
 	{ "preset-computer", adcli_tool_computer_preset, "Pre setup computers accounts", },
8fc58f6
 	{ "reset-computer", adcli_tool_computer_reset, "Reset a computer account", },
8fc58f6
 	{ "delete-computer", adcli_tool_computer_delete, "Delete a computer account", },
8fc58f6
diff --git a/tools/tools.h b/tools/tools.h
8fc58f6
index 6c97ccf..8cebbf9 100644
8fc58f6
--- a/tools/tools.h
8fc58f6
+++ b/tools/tools.h
8fc58f6
@@ -70,6 +70,10 @@ int       adcli_tool_computer_update   (adcli_conn *conn,
8fc58f6
                                         int argc,
8fc58f6
                                         char *argv[]);
8fc58f6
 
8fc58f6
+int       adcli_tool_computer_testjoin (adcli_conn *conn,
8fc58f6
+                                        int argc,
8fc58f6
+                                        char *argv[]);
8fc58f6
+
8fc58f6
 int       adcli_tool_computer_delete   (adcli_conn *conn,
8fc58f6
                                         int argc,
8fc58f6
                                         char *argv[]);
8fc58f6
-- 
8fc58f6
2.20.1
8fc58f6