import adcli-0.8.2-3.el8

This commit is contained in:
CentOS Sources 2019-11-05 17:01:42 -05:00 committed by Andrew Lukoshko
parent 95ad1e7b0d
commit fa9446a71a
27 changed files with 3023 additions and 30 deletions

View File

@ -0,0 +1,43 @@
From 3c93c96eb6ea2abd3869921ee4c89e1a4d9e4c44 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 14 Aug 2018 13:08:52 +0200
Subject: [PATCH] Fix for issues found by Coverity
---
library/adenroll.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/library/adenroll.c b/library/adenroll.c
index 02bd9e3..de2242a 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -1575,7 +1575,7 @@ load_host_keytab (adcli_enroll *enroll)
}
krb5_free_context (k5);
- return ADCLI_SUCCESS;
+ return res;
}
typedef struct {
@@ -1756,12 +1756,12 @@ add_principal_to_keytab (adcli_enroll *enroll,
enroll->kvno, &password, enctypes, &salts[*which_salt]);
free_principal_salts (k5, salts);
+ }
- if (code != 0) {
- _adcli_err ("Couldn't add keytab entries: %s: %s",
- enroll->keytab_name, krb5_get_error_message (k5, code));
- return ADCLI_ERR_FAIL;
- }
+ if (code != 0) {
+ _adcli_err ("Couldn't add keytab entries: %s: %s",
+ enroll->keytab_name, krb5_get_error_message (k5, code));
+ return ADCLI_ERR_FAIL;
}
--
2.21.0

View File

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

View File

@ -0,0 +1,32 @@
From 5cf1723c308e21cdbe9b98ed2aaa42cb997456fb Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 15 Mar 2019 14:31:12 +0100
Subject: [PATCH] Increment kvno after password change with user creds
Originally only the host credential part was fixed in the context of
https://bugs.freedesktop.org/show_bug.cgi?id=91185. This patch adds the
fix to the case when user credentials are used.
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1642546
---
library/adenroll.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/library/adenroll.c b/library/adenroll.c
index e02f403..58362c2 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -1057,6 +1057,10 @@ set_password_with_user_creds (adcli_enroll *enroll)
#endif
} else {
_adcli_info ("Set computer password");
+ if (enroll->kvno > 0) {
+ enroll->kvno++;
+ _adcli_info ("kvno incremented to %d", enroll->kvno);
+ }
res = ADCLI_SUCCESS;
}
--
2.20.1

View File

@ -0,0 +1,80 @@
From 341974aae7d0755fc32a0b7e2b34d8e1ef60d195 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 20 Dec 2018 21:05:35 +0100
Subject: [PATCH 1/4] adenroll: make sure only allowed enctypes are used in
FIPS mode
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1717355
---
library/adenroll.c | 36 +++++++++++++++++++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/library/adenroll.c b/library/adenroll.c
index 52aa8a8..f617f28 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -41,11 +41,19 @@
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#ifndef SAMBA_DATA_TOOL
#define SAMBA_DATA_TOOL "/usr/bin/net"
#endif
+static krb5_enctype v60_later_enctypes_fips[] = {
+ ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+ ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+ 0
+};
+
static krb5_enctype v60_later_enctypes[] = {
ENCTYPE_AES256_CTS_HMAC_SHA1_96,
ENCTYPE_AES128_CTS_HMAC_SHA1_96,
@@ -2594,6 +2602,28 @@ adcli_enroll_set_keytab_name (adcli_enroll *enroll,
enroll->keytab_name_is_krb5 = 0;
}
+#define PROC_SYS_FIPS "/proc/sys/crypto/fips_enabled"
+
+static bool adcli_fips_enabled (void)
+{
+ int fd;
+ ssize_t len;
+ char buf[8];
+
+ fd = open (PROC_SYS_FIPS, O_RDONLY);
+ if (fd != -1) {
+ len = read (fd, buf, sizeof (buf));
+ close (fd);
+ /* Assume FIPS in enabled if PROC_SYS_FIPS contains a
+ * non-0 value. */
+ if ( ! (len == 2 && buf[0] == '0' && buf[1] == '\n')) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
krb5_enctype *
adcli_enroll_get_keytab_enctypes (adcli_enroll *enroll)
{
@@ -2602,7 +2632,11 @@ adcli_enroll_get_keytab_enctypes (adcli_enroll *enroll)
return enroll->keytab_enctypes;
if (adcli_conn_server_has_capability (enroll->conn, ADCLI_CAP_V60_OID))
- return v60_later_enctypes;
+ if (adcli_fips_enabled ()) {
+ return v60_later_enctypes_fips;
+ } else {
+ return v60_later_enctypes;
+ }
else
return v51_earlier_enctypes;
}
--
2.21.0

View File

@ -0,0 +1,134 @@
From 85d127fd52a8469f9f3ce0d1130fe17e756fdd75 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 16 Nov 2018 13:32:33 +0100
Subject: [PATCH 1/2] adutil: add _adcli_strv_add_unique
_adcli_strv_add_unique checks is the new value already exists in the
strv before adding it. Check can be done case-sensitive or not.
Related to https://gitlab.freedesktop.org/realmd/adcli/issues/16
---
library/adprivate.h | 5 ++++
library/adutil.c | 65 ++++++++++++++++++++++++++++++++++++++-------
2 files changed, 61 insertions(+), 9 deletions(-)
diff --git a/library/adprivate.h b/library/adprivate.h
index bc9df6d..0806430 100644
--- a/library/adprivate.h
+++ b/library/adprivate.h
@@ -111,6 +111,11 @@ char ** _adcli_strv_add (char **strv,
char *string,
int *length) GNUC_WARN_UNUSED;
+char ** _adcli_strv_add_unique (char **strv,
+ char *string,
+ int *length,
+ bool case_sensitive) GNUC_WARN_UNUSED;
+
void _adcli_strv_remove_unsorted (char **strv,
const char *string,
int *length);
diff --git a/library/adutil.c b/library/adutil.c
index 17d2caa..76ea158 100644
--- a/library/adutil.c
+++ b/library/adutil.c
@@ -221,6 +221,34 @@ _adcli_strv_add (char **strv,
return seq_push (strv, length, string);
}
+static int
+_adcli_strv_has_ex (char **strv,
+ const char *str,
+ int (* compare) (const char *match, const char*value))
+{
+ int i;
+
+ for (i = 0; strv && strv[i] != NULL; i++) {
+ if (compare (strv[i], str) == 0)
+ return 1;
+ }
+
+ return 0;
+}
+
+char **
+_adcli_strv_add_unique (char **strv,
+ char *string,
+ int *length,
+ bool case_sensitive)
+{
+ if (_adcli_strv_has_ex (strv, string, case_sensitive ? strcmp : strcasecmp) == 1) {
+ return strv;
+ }
+
+ return _adcli_strv_add (strv, string, length);
+}
+
#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
void
@@ -241,19 +269,11 @@ _adcli_strv_remove_unsorted (char **strv,
(seq_compar)strcasecmp, free);
}
-
int
_adcli_strv_has (char **strv,
const char *str)
{
- int i;
-
- for (i = 0; strv && strv[i] != NULL; i++) {
- if (strcmp (strv[i], str) == 0)
- return 1;
- }
-
- return 0;
+ return _adcli_strv_has_ex (strv, str, strcmp);
}
void
@@ -704,6 +724,32 @@ test_strv_add_free (void)
_adcli_strv_free (strv);
}
+static void
+test_strv_add_unique_free (void)
+{
+ char **strv = NULL;
+
+ strv = _adcli_strv_add_unique (strv, strdup ("one"), NULL, false);
+ strv = _adcli_strv_add_unique (strv, strdup ("one"), NULL, false);
+ strv = _adcli_strv_add_unique (strv, strdup ("two"), NULL, false);
+ strv = _adcli_strv_add_unique (strv, strdup ("two"), NULL, false);
+ strv = _adcli_strv_add_unique (strv, strdup ("tWo"), NULL, false);
+ strv = _adcli_strv_add_unique (strv, strdup ("three"), NULL, false);
+ strv = _adcli_strv_add_unique (strv, strdup ("three"), NULL, false);
+ strv = _adcli_strv_add_unique (strv, strdup ("TWO"), NULL, true);
+
+ assert_num_eq (_adcli_strv_len (strv), 4);
+
+ assert_str_eq (strv[0], "one");
+ assert_str_eq (strv[1], "two");
+ assert_str_eq (strv[2], "three");
+ assert_str_eq (strv[3], "TWO");
+ assert (strv[4] == NULL);
+
+ _adcli_strv_free (strv);
+}
+
+
static void
test_strv_dup (void)
{
@@ -856,6 +902,7 @@ main (int argc,
char *argv[])
{
test_func (test_strv_add_free, "/util/strv_add_free");
+ test_func (test_strv_add_unique_free, "/util/strv_add_unique_free");
test_func (test_strv_dup, "/util/strv_dup");
test_func (test_strv_count, "/util/strv_count");
test_func (test_check_nt_time_string_lifetime, "/util/check_nt_time_string_lifetime");
--
2.20.1

View File

@ -0,0 +1,71 @@
From 1457b4a7623a8ae58fb8d6a652d1cc44904b8863 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 18 Mar 2019 11:02:57 +0100
Subject: [PATCH 1/2] create-user: add nis-domain option
Related to https://gitlab.freedesktop.org/realmd/adcli/issues/2
---
doc/adcli.xml | 8 ++++++++
tools/entry.c | 6 ++++++
2 files changed, 14 insertions(+)
diff --git a/doc/adcli.xml b/doc/adcli.xml
index 4722c3a..18620c0 100644
--- a/doc/adcli.xml
+++ b/doc/adcli.xml
@@ -531,6 +531,14 @@ $ adcli create-user Fry --domain=domain.example.com \
the new created user account, which should be the user's
numeric primary user id.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--nis-domain=<parameter>nis_domain</parameter></option></term>
+ <listitem><para>Set the <code>msSFU30NisDomain</code> attribute of
+ the new created user account, which should be the user's
+ NIS domain is the NIS/YP service of Active Directory's Services for Unix (SFU)
+ are used. This is needed to let the 'UNIX attributes' tab of older Active
+ Directoy versions show the set UNIX specific attributes.</para></listitem>
+ </varlistentry>
</variablelist>
</refsect1>
diff --git a/tools/entry.c b/tools/entry.c
index 7b6a200..69ce62c 100644
--- a/tools/entry.c
+++ b/tools/entry.c
@@ -52,6 +52,7 @@ typedef enum {
opt_unix_uid,
opt_unix_gid,
opt_unix_shell,
+ opt_nis_domain,
} Option;
static adcli_tool_desc common_usages[] = {
@@ -62,6 +63,7 @@ static adcli_tool_desc common_usages[] = {
{ opt_unix_uid, "unix uid number" },
{ opt_unix_gid, "unix gid number" },
{ opt_unix_shell, "unix shell" },
+ { opt_nis_domain, "NIS domain" },
{ opt_domain, "active directory domain name" },
{ opt_domain_realm, "kerberos realm for the domain" },
{ opt_domain_controller, "domain directory server to connect to" },
@@ -159,6 +161,7 @@ adcli_tool_user_create (adcli_conn *conn,
{ "unix-uid", required_argument, NULL, opt_unix_uid },
{ "unix-gid", required_argument, NULL, opt_unix_gid },
{ "unix-shell", required_argument, NULL, opt_unix_shell },
+ { "nis-domain", required_argument, NULL, opt_nis_domain },
{ "domain-ou", required_argument, NULL, opt_domain_ou },
{ "domain", required_argument, NULL, opt_domain },
{ "domain-realm", required_argument, NULL, opt_domain_realm },
@@ -200,6 +203,9 @@ adcli_tool_user_create (adcli_conn *conn,
case opt_unix_shell:
adcli_attrs_add (attrs, "loginShell", optarg, NULL);
break;
+ case opt_nis_domain:
+ adcli_attrs_add (attrs, "msSFU30NisDomain", optarg, NULL);
+ break;
case opt_domain_ou:
ou = optarg;
break;
--
2.20.1

View File

@ -0,0 +1,72 @@
From 3a84c2469c31967bc22c0490456f07723ef5fc86 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 20 Mar 2019 11:01:50 +0100
Subject: [PATCH 1/4] ensure_keytab_principals: do not leak memory when called
twice
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1630187
---
library/adenroll.c | 32 +++++++++++++++++++++-----------
1 file changed, 21 insertions(+), 11 deletions(-)
diff --git a/library/adenroll.c b/library/adenroll.c
index d1f746c..48cb4cf 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -413,6 +413,25 @@ ensure_service_principals (adcli_result res,
return res;
}
+static void enroll_clear_keytab_principals (adcli_enroll *enroll)
+{
+ krb5_context k5;
+ size_t c;
+
+ if (enroll->keytab_principals) {
+ k5 = adcli_conn_get_krb5_context (enroll->conn);
+ return_if_fail (k5 != NULL);
+
+ for (c = 0; enroll->keytab_principals[c] != NULL; c++)
+ krb5_free_principal (k5, enroll->keytab_principals[c]);
+
+ free (enroll->keytab_principals);
+ enroll->keytab_principals = NULL;
+ }
+
+ return;
+}
+
static adcli_result
ensure_keytab_principals (adcli_result res,
adcli_enroll *enroll)
@@ -430,6 +449,7 @@ ensure_keytab_principals (adcli_result res,
k5 = adcli_conn_get_krb5_context (enroll->conn);
return_unexpected_if_fail (k5 != NULL);
+ enroll_clear_keytab_principals (enroll);
enroll->keytab_principals = calloc (count + 3, sizeof (krb5_principal));
return_unexpected_if_fail (enroll->keytab_principals != NULL);
at = 0;
@@ -1860,18 +1880,8 @@ static void
enroll_clear_state (adcli_enroll *enroll)
{
krb5_context k5;
- int i;
-
- if (enroll->keytab_principals) {
- k5 = adcli_conn_get_krb5_context (enroll->conn);
- return_if_fail (k5 != NULL);
-
- for (i = 0; enroll->keytab_principals[i] != NULL; i++)
- krb5_free_principal (k5, enroll->keytab_principals[i]);
- free (enroll->keytab_principals);
- enroll->keytab_principals = NULL;
- }
+ enroll_clear_keytab_principals (enroll);
if (enroll->keytab) {
k5 = adcli_conn_get_krb5_context (enroll->conn);
--
2.20.1

View File

@ -0,0 +1,86 @@
From cd296bf24e7cc56fb8d00bad7e9a56c539894309 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 19 Mar 2019 20:44:36 +0100
Subject: [PATCH 1/2] join: always add service principals
If currently --service-name is given during the join only the service
names given by this option are added as service principal names. As a
result the default 'host' service principal name might be missing which
might cause issues e.g. with SSSD and sshd.
The patch makes sure the default service principals 'host' and
'RestrictedKrbHost' are always added during join.
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1644311
---
library/adenroll.c | 36 ++++++++++++++++++++++++++++++------
1 file changed, 30 insertions(+), 6 deletions(-)
diff --git a/library/adenroll.c b/library/adenroll.c
index 58362c2..d1f746c 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -288,16 +288,23 @@ ensure_computer_password (adcli_result res,
}
static adcli_result
-ensure_service_names (adcli_result res,
- adcli_enroll *enroll)
+ensure_default_service_names (adcli_enroll *enroll)
{
int length = 0;
- if (res != ADCLI_SUCCESS)
- return res;
+ if (enroll->service_names != NULL) {
+ length = seq_count (enroll->service_names);
- if (enroll->service_names || enroll->service_principals)
- return ADCLI_SUCCESS;
+ /* Make sure there is no entry with an unexpected case. AD
+ * would not care but since the client side is case-sensitive
+ * we should make sure we use the expected spelling. */
+ seq_remove_unsorted (enroll->service_names,
+ &length, "host",
+ (seq_compar)strcasecmp, free);
+ seq_remove_unsorted (enroll->service_names,
+ &length, "RestrictedKrbHost",
+ (seq_compar)strcasecmp, free);
+ }
/* The default ones specified by MS */
enroll->service_names = _adcli_strv_add (enroll->service_names,
@@ -307,6 +314,19 @@ ensure_service_names (adcli_result res,
return ADCLI_SUCCESS;
}
+static adcli_result
+ensure_service_names (adcli_result res,
+ adcli_enroll *enroll)
+{
+ if (res != ADCLI_SUCCESS)
+ return res;
+
+ if (enroll->service_names || enroll->service_principals)
+ return ADCLI_SUCCESS;
+
+ return ensure_default_service_names (enroll);
+}
+
static adcli_result
add_service_names_to_service_principals (adcli_enroll *enroll)
{
@@ -2039,6 +2059,10 @@ adcli_enroll_join (adcli_enroll *enroll,
if (res != ADCLI_SUCCESS)
return res;
+ res = ensure_default_service_names (enroll);
+ if (res != ADCLI_SUCCESS)
+ return res;
+
res = adcli_enroll_prepare (enroll, flags);
if (res != ADCLI_SUCCESS)
return res;
--
2.20.1

View File

@ -0,0 +1,34 @@
From a64cce9830c2e9c26e120f671b247ee71b45c888 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 12 Apr 2019 17:31:41 +0200
Subject: [PATCH] library: add missing strdup
In add_server_side_service_principals _adcli_strv_add_unique is called
which only adds a string to a list without copying to. Since the
original list will be freed later the value must be copied.
This issue was introduce with 972f1a2f35829ed89f5353bd204683aa9ad6a2d2
and hence
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1630187
---
library/adenroll.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/library/adenroll.c b/library/adenroll.c
index 1cce86a..52aa8a8 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -1987,7 +1987,8 @@ add_server_side_service_principals (adcli_enroll *enroll)
_adcli_info ("Checking %s", spn_list[c]);
if (!_adcli_strv_has_ex (enroll->service_principals_to_remove, spn_list[c], strcasecmp)) {
enroll->service_principals = _adcli_strv_add_unique (enroll->service_principals,
- spn_list[c], &length, false);
+ strdup (spn_list[c]),
+ &length, false);
assert (enroll->service_principals != NULL);
_adcli_info (" Added %s", spn_list[c]);
}
--
2.20.1

View File

@ -0,0 +1,92 @@
From 85b835f8258a57e3b23de47a255dddd822d5bfb3 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 15 Mar 2019 17:33:44 +0100
Subject: [PATCH] library: use getaddrinfo with AI_CANONNAME to find a FQDN
Currently adcli creates service principals only with a short name if the
hostname of the client is a short name. This would fail is
Kerberos/GSSAPI clients will use the fully-qualified domain name (FQDN)
to access the host.
With this patch adcli tries to expand the short name by calling
getaddrinfo with the AI_CANONNAME hint.
Related to https://gitlab.freedesktop.org/realmd/adcli/issues/1
---
doc/adcli.xml | 6 +++++-
library/adconn.c | 30 +++++++++++++++++++++++++++++-
2 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/doc/adcli.xml b/doc/adcli.xml
index 97dec08..4722c3a 100644
--- a/doc/adcli.xml
+++ b/doc/adcli.xml
@@ -228,7 +228,11 @@ Password for Administrator:
<term><option>-H, --host-fqdn=<parameter>host</parameter></option></term>
<listitem><para>Override the local machine's fully qualified
domain name. If not specified, the local machine's hostname
- will be retrieved via <function>gethostname()</function>.</para></listitem>
+ will be retrieved via <function>gethostname()</function>.
+ If <function>gethostname()</function> only returns a short name
+ <function>getaddrinfo()</function> with the AI_CANONNAME hint
+ is called to expand the name to a fully qualified domain
+ name.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-K, --host-keytab=<parameter>/path/to/keytab</parameter></option></term>
diff --git a/library/adconn.c b/library/adconn.c
index e2250e3..f6c23d3 100644
--- a/library/adconn.c
+++ b/library/adconn.c
@@ -86,11 +86,36 @@ struct _adcli_conn_ctx {
krb5_keytab keytab;
};
+static char *try_to_get_fqdn (const char *host_name)
+{
+ int ret;
+ char *fqdn = NULL;
+ struct addrinfo *res;
+ struct addrinfo hints;
+
+ memset (&hints, 0, sizeof (struct addrinfo));
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = AI_CANONNAME;
+
+ ret = getaddrinfo (host_name, NULL, &hints, &res);
+ if (ret != 0) {
+ _adcli_err ("Failed to find FQDN: %s", gai_strerror (ret));
+ return NULL;
+ }
+
+ fqdn = strdup (res->ai_canonname);
+
+ freeaddrinfo (res);
+
+ return fqdn;
+}
+
static adcli_result
ensure_host_fqdn (adcli_result res,
adcli_conn *conn)
{
char hostname[HOST_NAME_MAX + 1];
+ char *fqdn = NULL;
int ret;
if (res != ADCLI_SUCCESS)
@@ -107,7 +132,10 @@ ensure_host_fqdn (adcli_result res,
return ADCLI_ERR_UNEXPECTED;
}
- conn->host_fqdn = strdup (hostname);
+ if (strchr (hostname, '.') == NULL) {
+ fqdn = try_to_get_fqdn (hostname);
+ }
+ conn->host_fqdn = fqdn != NULL ? fqdn : strdup (hostname);
return_unexpected_if_fail (conn->host_fqdn != NULL);
return ADCLI_SUCCESS;
}
--
2.20.1

View File

@ -0,0 +1,328 @@
From fa7926c7a9d92bc7c42c610ba6f1706c635aa901 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 15 Apr 2019 17:54:27 +0200
Subject: [PATCH 1/7] tools: remove errx from computer commands
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1588596
---
tools/computer.c | 166 ++++++++++++++++++++++++++++++-----------------
1 file changed, 107 insertions(+), 59 deletions(-)
diff --git a/tools/computer.c b/tools/computer.c
index bee695c..9cbbb28 100644
--- a/tools/computer.c
+++ b/tools/computer.c
@@ -379,8 +379,10 @@ adcli_tool_computer_join (adcli_conn *conn,
};
enroll = adcli_enroll_new (conn);
- if (enroll == NULL)
- errx (-1, "unexpected memory problems");
+ if (enroll == NULL) {
+ warnx ("unexpected memory problems");
+ return -1;
+ }
while ((opt = adcli_tool_getopt (argc, argv, options)) != -1) {
switch (opt) {
@@ -415,21 +417,28 @@ adcli_tool_computer_join (adcli_conn *conn,
if (argc == 1)
adcli_conn_set_domain_name (conn, argv[0]);
- else if (argc > 1)
- errx (2, "extra arguments specified");
+ else if (argc > 1) {
+ warnx ("extra arguments specified");
+ adcli_enroll_unref (enroll);
+ return 2;
+ }
res = adcli_conn_connect (conn);
if (res != ADCLI_SUCCESS) {
- errx (-res, "couldn't connect to %s domain: %s",
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("couldn't connect to %s domain: %s",
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_enroll_unref (enroll);
+ return -res;
}
res = adcli_enroll_join (enroll, flags);
if (res != ADCLI_SUCCESS) {
- errx (-res, "joining domain %s failed: %s",
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("joining domain %s failed: %s",
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_enroll_unref (enroll);
+ return -res;
}
if (details)
@@ -486,8 +495,10 @@ adcli_tool_computer_update (adcli_conn *conn,
};
enroll = adcli_enroll_new (conn);
- if (enroll == NULL)
- errx (-1, "unexpected memory problems");
+ if (enroll == NULL) {
+ warnx ("unexpected memory problems");
+ return -1;
+ }
while ((opt = adcli_tool_getopt (argc, argv, options)) != -1) {
switch (opt) {
@@ -525,22 +536,28 @@ adcli_tool_computer_update (adcli_conn *conn,
res = adcli_enroll_load (enroll);
if (res != ADCLI_SUCCESS) {
- errx (-res, "couldn't lookup domain info from keytab: %s",
- adcli_get_last_error ());
+ warnx ("couldn't lookup domain info from keytab: %s",
+ adcli_get_last_error ());
+ adcli_enroll_unref (enroll);
+ return -res;
}
res = adcli_conn_connect (conn);
if (res != ADCLI_SUCCESS) {
- errx (-res, "couldn't connect to %s domain: %s",
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("couldn't connect to %s domain: %s",
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_enroll_unref (enroll);
+ return -res;
}
res = adcli_enroll_update (enroll, flags);
if (res != ADCLI_SUCCESS) {
- errx (-res, "updating membership with domain %s failed: %s",
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("updating membership with domain %s failed: %s",
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_enroll_unref (enroll);
+ return -res;
}
if (details)
@@ -578,8 +595,10 @@ adcli_tool_computer_testjoin (adcli_conn *conn,
};
enroll = adcli_enroll_new (conn);
- if (enroll == NULL)
- errx (-1, "unexpected memory problems");
+ if (enroll == NULL) {
+ warnx ("unexpected memory problems");
+ return -1;
+ }
while ((opt = adcli_tool_getopt (argc, argv, options)) != -1) {
switch (opt) {
@@ -604,18 +623,18 @@ adcli_tool_computer_testjoin (adcli_conn *conn,
res = adcli_enroll_load (enroll);
if (res != ADCLI_SUCCESS) {
adcli_enroll_unref (enroll);
- adcli_conn_unref (conn);
- errx (-res, "couldn't lookup domain info from keytab: %s",
- adcli_get_last_error ());
+ warnx ("couldn't lookup domain info from keytab: %s",
+ adcli_get_last_error ());
+ return -res;
}
res = adcli_conn_connect (conn);
if (res != ADCLI_SUCCESS) {
adcli_enroll_unref (enroll);
- adcli_conn_unref (conn);
- errx (-res, "couldn't connect to %s domain: %s",
+ warnx ("couldn't connect to %s domain: %s",
adcli_conn_get_domain_name (conn),
adcli_get_last_error ());
+ return -res;
}
printf ("Sucessfully validated join to domain %s\n",
@@ -665,8 +684,10 @@ adcli_tool_computer_preset (adcli_conn *conn,
};
enroll = adcli_enroll_new (conn);
- if (enroll == NULL)
- errx (-1, "unexpected memory problems");
+ if (enroll == NULL) {
+ warnx ("unexpected memory problems");
+ return -1;
+ }
flags = ADCLI_ENROLL_NO_KEYTAB;
while ((opt = adcli_tool_getopt (argc, argv, options)) != -1) {
@@ -694,17 +715,22 @@ adcli_tool_computer_preset (adcli_conn *conn,
argc -= optind;
argv += optind;
- if (argc < 1)
- errx (EUSAGE, "specify one or more host names of computer accounts to preset");
+ if (argc < 1) {
+ warnx ("specify one or more host names of computer accounts to preset");
+ adcli_enroll_unref (enroll);
+ return EUSAGE;
+ }
adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT);
reset_password = (adcli_enroll_get_computer_password (enroll) == NULL);
res = adcli_conn_connect (conn);
if (res != ADCLI_SUCCESS) {
- errx (-res, "couldn't connect to %s domain: %s",
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("couldn't connect to %s domain: %s",
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_enroll_unref (enroll);
+ return -res;
}
for (i = 0; i < argc; i++) {
@@ -715,9 +741,11 @@ adcli_tool_computer_preset (adcli_conn *conn,
res = adcli_enroll_join (enroll, flags);
if (res != ADCLI_SUCCESS) {
- errx (-res, "presetting %s in %s domain failed: %s", argv[i],
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("presetting %s in %s domain failed: %s", argv[i],
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_enroll_unref (enroll);
+ return -res;
}
printf ("computer-name: %s\n", adcli_enroll_get_computer_name (enroll));
@@ -758,8 +786,10 @@ adcli_tool_computer_reset (adcli_conn *conn,
};
enroll = adcli_enroll_new (conn);
- if (enroll == NULL)
- errx (-1, "unexpected memory problems");
+ if (enroll == NULL) {
+ warnx ("unexpected memory problems");
+ return -1;
+ }
while ((opt = adcli_tool_getopt (argc, argv, options)) != -1) {
switch (opt) {
@@ -779,14 +809,19 @@ adcli_tool_computer_reset (adcli_conn *conn,
argc -= optind;
argv += optind;
- if (argc != 1)
- errx (EUSAGE, "specify one host name of computer account to reset");
+ if (argc != 1) {
+ warnx ("specify one host name of computer account to reset");
+ adcli_enroll_unref (enroll);
+ return EUSAGE;
+ }
res = adcli_conn_connect (conn);
if (res != ADCLI_SUCCESS) {
- errx (-res, "couldn't connect to %s domain: %s",
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("couldn't connect to %s domain: %s",
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_enroll_unref (enroll);
+ return -res;
}
parse_fqdn_or_name (enroll, argv[0]);
@@ -794,9 +829,11 @@ adcli_tool_computer_reset (adcli_conn *conn,
res = adcli_enroll_password (enroll, 0);
if (res != ADCLI_SUCCESS) {
- errx (-res, "resetting %s in %s domain failed: %s", argv[0],
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("resetting %s in %s domain failed: %s", argv[0],
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_enroll_unref (enroll);
+ return -res;
}
adcli_enroll_unref (enroll);
@@ -832,8 +869,10 @@ adcli_tool_computer_delete (adcli_conn *conn,
};
enroll = adcli_enroll_new (conn);
- if (enroll == NULL)
- errx (-1, "unexpected memory problems");
+ if (enroll == NULL) {
+ warnx ("unexpected memory problems");
+ return -1;
+ }
while ((opt = adcli_tool_getopt (argc, argv, options)) != -1) {
switch (opt) {
@@ -853,22 +892,29 @@ adcli_tool_computer_delete (adcli_conn *conn,
argc -= optind;
argv += optind;
- if (argc > 1)
- errx (EUSAGE, "specify one host name of computer account to delete");
+ if (argc > 1) {
+ warnx ("specify one host name of computer account to delete");
+ adcli_enroll_unref (enroll);
+ return EUSAGE;
+ }
adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT);
res = adcli_enroll_load (enroll);
if (res != ADCLI_SUCCESS) {
- errx (-res, "couldn't lookup domain info from keytab: %s",
- adcli_get_last_error ());
+ warnx ("couldn't lookup domain info from keytab: %s",
+ adcli_get_last_error ());
+ adcli_enroll_unref (enroll);
+ return -res;
}
res = adcli_conn_connect (conn);
if (res != ADCLI_SUCCESS) {
- errx (-res, "couldn't connect to %s domain: %s",
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("couldn't connect to %s domain: %s",
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_enroll_unref (enroll);
+ return -res;
}
if (argc == 1)
@@ -876,9 +922,11 @@ adcli_tool_computer_delete (adcli_conn *conn,
res = adcli_enroll_delete (enroll, 0);
if (res != ADCLI_SUCCESS) {
- errx (-res, "deleting %s in %s domain failed: %s", argv[0],
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("deleting %s in %s domain failed: %s", argv[0],
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_enroll_unref (enroll);
+ return -res;
}
adcli_enroll_unref (enroll);
--
2.20.1

View File

@ -0,0 +1,52 @@
From 2fc259a88be618871cea8ff8b8a13bd3e040aea4 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 13 Jun 2019 17:23:47 +0200
Subject: [PATCH 2/4] adconn: add adcli_conn_set_krb5_context
Related to https://gitlab.freedesktop.org/realmd/adcli/issues/3
---
library/adconn.c | 13 +++++++++++++
library/adconn.h | 3 +++
2 files changed, 16 insertions(+)
diff --git a/library/adconn.c b/library/adconn.c
index f6c23d3..bcaced8 100644
--- a/library/adconn.c
+++ b/library/adconn.c
@@ -1406,6 +1406,19 @@ adcli_conn_get_krb5_context (adcli_conn *conn)
return conn->k5;
}
+void
+adcli_conn_set_krb5_context (adcli_conn *conn,
+ krb5_context k5)
+{
+ return_if_fail (conn != NULL);
+
+ if (conn->k5 != NULL) {
+ krb5_free_context (conn->k5);
+ }
+
+ conn->k5 = k5;
+}
+
const char *
adcli_conn_get_login_user (adcli_conn *conn)
{
diff --git a/library/adconn.h b/library/adconn.h
index 13cfd32..1ad5715 100644
--- a/library/adconn.h
+++ b/library/adconn.h
@@ -97,6 +97,9 @@ LDAP * adcli_conn_get_ldap_connection (adcli_conn *conn);
krb5_context adcli_conn_get_krb5_context (adcli_conn *conn);
+void adcli_conn_set_krb5_context (adcli_conn *conn,
+ krb5_context k5);
+
const char * adcli_conn_get_computer_name (adcli_conn *conn);
void adcli_conn_set_computer_name (adcli_conn *conn,
--
2.21.0

View File

@ -0,0 +1,83 @@
From 0c027538f398b3823bedbfbf5f388ad97784a0ec Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 16 Nov 2018 13:32:59 +0100
Subject: [PATCH 2/2] adenroll: use _adcli_strv_add_unique for service
principals
Check if service principals is already in the list before adding it.
Related to https://gitlab.freedesktop.org/realmd/adcli/issues/16
---
library/adenroll.c | 31 ++++++++-----------------------
1 file changed, 8 insertions(+), 23 deletions(-)
diff --git a/library/adenroll.c b/library/adenroll.c
index de2242a..e02f403 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -313,7 +313,6 @@ add_service_names_to_service_principals (adcli_enroll *enroll)
char *name;
int length = 0;
int i;
- size_t c;
if (enroll->service_principals != NULL) {
length = seq_count (enroll->service_principals);
@@ -322,28 +321,14 @@ add_service_names_to_service_principals (adcli_enroll *enroll)
for (i = 0; enroll->service_names[i] != NULL; i++) {
if (asprintf (&name, "%s/%s", enroll->service_names[i], enroll->computer_name) < 0)
return_unexpected_if_reached ();
- for (c = 0; enroll->service_principals != NULL && enroll->service_principals[c] != NULL; c++) {
- if (strcmp (name, enroll->service_principals[c]) == 0) {
- break;
- }
- }
- if (enroll->service_principals == NULL || enroll->service_principals[c] == NULL) {
- enroll->service_principals = _adcli_strv_add (enroll->service_principals,
- name, &length);
- }
+ enroll->service_principals = _adcli_strv_add_unique (enroll->service_principals,
+ name, &length, false);
if (enroll->host_fqdn) {
if (asprintf (&name, "%s/%s", enroll->service_names[i], enroll->host_fqdn) < 0)
return_unexpected_if_reached ();
- for (c = 0; enroll->service_principals != NULL && enroll->service_principals[c] != NULL; c++) {
- if (strcmp (name, enroll->service_principals[c]) == 0) {
- break;
- }
- }
- if (enroll->service_principals == NULL || enroll->service_principals[c] == NULL) {
- enroll->service_principals = _adcli_strv_add (enroll->service_principals,
- name, &length);
- }
+ enroll->service_principals = _adcli_strv_add_unique (enroll->service_principals,
+ name, &length, false);
}
}
@@ -364,9 +349,9 @@ add_and_remove_service_principals (adcli_enroll *enroll)
list = adcli_enroll_get_service_principals_to_add (enroll);
if (list != NULL) {
for (c = 0; list[c] != NULL; c++) {
- enroll->service_principals = _adcli_strv_add (enroll->service_principals,
- strdup (list[c]),
- &length);
+ enroll->service_principals = _adcli_strv_add_unique (enroll->service_principals,
+ strdup (list[c]),
+ &length, false);
if (enroll->service_principals == NULL) {
return ADCLI_ERR_UNEXPECTED;
}
@@ -1525,7 +1510,7 @@ load_keytab_entry (krb5_context k5,
value = strdup (name);
return_val_if_fail (value != NULL, FALSE);
_adcli_info ("Found service principal in keytab: %s", value);
- enroll->service_principals = _adcli_strv_add (enroll->service_principals, value, NULL);
+ enroll->service_principals = _adcli_strv_add_unique (enroll->service_principals, value, NULL, false);
}
}
--
2.20.1

View File

@ -0,0 +1,147 @@
From 408880a11879b1a57a450e25c77ef2e310bdffd5 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 18 Mar 2019 16:45:54 +0100
Subject: [PATCH 2/2] create-user: try to find NIS domain if needed
Related to https://gitlab.freedesktop.org/realmd/adcli/issues/2
---
doc/adcli.xml | 4 +++-
library/adentry.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
library/adentry.h | 2 ++
tools/entry.c | 16 ++++++++++++++++
4 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/doc/adcli.xml b/doc/adcli.xml
index 18620c0..af73433 100644
--- a/doc/adcli.xml
+++ b/doc/adcli.xml
@@ -537,7 +537,9 @@ $ adcli create-user Fry --domain=domain.example.com \
the new created user account, which should be the user's
NIS domain is the NIS/YP service of Active Directory's Services for Unix (SFU)
are used. This is needed to let the 'UNIX attributes' tab of older Active
- Directoy versions show the set UNIX specific attributes.</para></listitem>
+ Directoy versions show the set UNIX specific attributes. If not specified
+ adcli will try to determine the NIS domain automatically if needed.
+ </para></listitem>
</varlistentry>
</variablelist>
diff --git a/library/adentry.c b/library/adentry.c
index 9b9e1c6..1cc0518 100644
--- a/library/adentry.c
+++ b/library/adentry.c
@@ -484,3 +484,47 @@ adcli_entry_new_group (adcli_conn *conn,
return_val_if_fail (sam_name != NULL, NULL);
return entry_new (conn, "group", group_entry_builder, sam_name);
}
+
+adcli_result
+adcli_get_nis_domain (adcli_entry *entry,
+ adcli_attrs *attrs)
+{
+ LDAP *ldap;
+ const char *ldap_attrs[] = { "cn", NULL };
+ LDAPMessage *results;
+ LDAPMessage *ldap_entry;
+ char *base;
+ const char *filter = "objectClass=msSFU30DomainInfo";
+ char *cn;
+ int ret;
+
+ ldap = adcli_conn_get_ldap_connection (entry->conn);
+ return_unexpected_if_fail (ldap != NULL);
+
+ if (asprintf (&base, "CN=ypservers,CN=ypServ30,CN=RpcServices,CN=System,%s",
+ adcli_conn_get_default_naming_context (entry->conn)) < 0) {
+ return_unexpected_if_reached ();
+ }
+
+ ret = ldap_search_ext_s (ldap, base, LDAP_SCOPE_SUB, filter, (char **)ldap_attrs,
+ 0, NULL, NULL, NULL, -1, &results);
+
+ free (base);
+
+ if (ret != LDAP_SUCCESS) {
+ /* No NIS domain available */
+ ldap_msgfree (results);
+ return ADCLI_SUCCESS;
+ }
+
+ ldap_entry = ldap_first_entry (ldap, results);
+ if (ldap_entry != NULL) {
+ cn = _adcli_ldap_parse_value (ldap, ldap_entry, "cn");
+ return_unexpected_if_fail (cn != NULL);
+
+ adcli_attrs_add (attrs, "msSFU30NisDomain", cn, NULL);
+ }
+ ldap_msgfree (results);
+
+ return ADCLI_SUCCESS;
+}
diff --git a/library/adentry.h b/library/adentry.h
index eb8bc00..ae90689 100644
--- a/library/adentry.h
+++ b/library/adentry.h
@@ -58,4 +58,6 @@ const char * adcli_entry_get_sam_name (adcli_entry *entry);
const char * adcli_entry_get_dn (adcli_entry *entry);
+adcli_result adcli_get_nis_domain (adcli_entry *entry,
+ adcli_attrs *attrs);
#endif /* ADENTRY_H_ */
diff --git a/tools/entry.c b/tools/entry.c
index 69ce62c..de56586 100644
--- a/tools/entry.c
+++ b/tools/entry.c
@@ -153,6 +153,8 @@ adcli_tool_user_create (adcli_conn *conn,
adcli_attrs *attrs;
const char *ou = NULL;
int opt;
+ bool has_unix_attr = false;
+ bool has_nis_domain = false;
struct option options[] = {
{ "display-name", required_argument, NULL, opt_display_name },
@@ -193,18 +195,23 @@ adcli_tool_user_create (adcli_conn *conn,
break;
case opt_unix_home:
adcli_attrs_add (attrs, "unixHomeDirectory", optarg, NULL);
+ has_unix_attr = true;
break;
case opt_unix_uid:
adcli_attrs_add (attrs, "uidNumber", optarg, NULL);
+ has_unix_attr = true;
break;
case opt_unix_gid:
adcli_attrs_add (attrs, "gidNumber", optarg, NULL);
+ has_unix_attr = true;
break;
case opt_unix_shell:
adcli_attrs_add (attrs, "loginShell", optarg, NULL);
+ has_unix_attr = true;
break;
case opt_nis_domain:
adcli_attrs_add (attrs, "msSFU30NisDomain", optarg, NULL);
+ has_nis_domain = true;
break;
case opt_domain_ou:
ou = optarg;
@@ -242,6 +249,15 @@ adcli_tool_user_create (adcli_conn *conn,
adcli_get_last_error ());
}
+ if (has_unix_attr && !has_nis_domain) {
+ res = adcli_get_nis_domain (entry, attrs);
+ if (res != ADCLI_SUCCESS) {
+ adcli_entry_unref (entry);
+ adcli_attrs_free (attrs);
+ errx (-res, "couldn't get NIS domain");
+ }
+ }
+
res = adcli_entry_create (entry, attrs);
if (res != ADCLI_SUCCESS) {
errx (-res, "creating user %s in domain %s failed: %s",
--
2.20.1

View File

@ -0,0 +1,42 @@
From e1b45e66bc185f5db4c252e1f3fb1b4400b4538e Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 22 Mar 2019 10:36:38 +0100
Subject: [PATCH 2/4] library: make _adcli_strv_has_ex public
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1630187
---
library/adprivate.h | 4 ++++
library/adutil.c | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/library/adprivate.h b/library/adprivate.h
index 0806430..55e6234 100644
--- a/library/adprivate.h
+++ b/library/adprivate.h
@@ -125,6 +125,10 @@ void _adcli_strv_free (char **strv);
int _adcli_strv_has (char **strv,
const char *str);
+int _adcli_strv_has_ex (char **strv,
+ const char *str,
+ int (* compare) (const char *match, const char*value));
+
char ** _adcli_strv_dup (char **strv) GNUC_WARN_UNUSED;
char * _adcli_strv_join (char **strv,
diff --git a/library/adutil.c b/library/adutil.c
index 76ea158..9b0c47f 100644
--- a/library/adutil.c
+++ b/library/adutil.c
@@ -221,7 +221,7 @@ _adcli_strv_add (char **strv,
return seq_push (strv, length, string);
}
-static int
+int
_adcli_strv_has_ex (char **strv,
const char *str,
int (* compare) (const char *match, const char*value))
--
2.20.1

View File

@ -0,0 +1,35 @@
From 4987a21f4839ab7ea50e932c72df05075efb89b3 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 21 Mar 2019 15:05:33 +0100
Subject: [PATCH 2/2] library: return error if no matching key was found
To avoid a misleading debug message indicating success a proper erro
code should be returned the no matching key was found when trying to
copy an keytab entry for a new principal.
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1644311
---
library/adkrb5.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/library/adkrb5.c b/library/adkrb5.c
index 033c181..7f77373 100644
--- a/library/adkrb5.c
+++ b/library/adkrb5.c
@@ -298,11 +298,10 @@ _adcli_krb5_keytab_copy_entries (krb5_context k5,
code = _adcli_krb5_get_keyblock (k5, keytab, &entry.key,
match_enctype_and_kvno, &closure);
- if (code != 0) {
- return code;
+ if (code != 0 || closure.matched == 0) {
+ return code != 0 ? code : ENOKEY;
}
-
entry.principal = principal;
entry.vno = kvno;
--
2.20.1

View File

@ -0,0 +1,398 @@
From cac0fa9df8888245399f2db187e05e31f93d1471 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 15 Apr 2019 17:56:37 +0200
Subject: [PATCH 2/7] tools: remove errx from user and group commands
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1588596
---
tools/entry.c | 232 +++++++++++++++++++++++++++++++++-----------------
1 file changed, 154 insertions(+), 78 deletions(-)
diff --git a/tools/entry.c b/tools/entry.c
index de56586..97ec6e7 100644
--- a/tools/entry.c
+++ b/tools/entry.c
@@ -232,21 +232,30 @@ adcli_tool_user_create (adcli_conn *conn,
argc -= optind;
argv += optind;
- if (argc != 1)
- errx (2, "specify one user name to create");
+ if (argc != 1) {
+ warnx ("specify one user name to create");
+ adcli_attrs_free (attrs);
+ return 2;
+ }
entry = adcli_entry_new_user (conn, argv[0]);
- if (entry == NULL)
- errx (-1, "unexpected memory problems");
+ if (entry == NULL) {
+ warnx ("unexpected memory problems");
+ adcli_attrs_free (attrs);
+ return -1;
+ }
adcli_entry_set_domain_ou (entry, ou);
adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT);
res = adcli_conn_connect (conn);
if (res != ADCLI_SUCCESS) {
- errx (-res, "couldn't connect to %s domain: %s",
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("couldn't connect to %s domain: %s",
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_entry_unref (entry);
+ adcli_attrs_free (attrs);
+ return -res;
}
if (has_unix_attr && !has_nis_domain) {
@@ -254,16 +263,20 @@ adcli_tool_user_create (adcli_conn *conn,
if (res != ADCLI_SUCCESS) {
adcli_entry_unref (entry);
adcli_attrs_free (attrs);
- errx (-res, "couldn't get NIS domain");
+ warnx ("couldn't get NIS domain");
+ return -res;
}
}
res = adcli_entry_create (entry, attrs);
if (res != ADCLI_SUCCESS) {
- errx (-res, "creating user %s in domain %s failed: %s",
- adcli_entry_get_sam_name (entry),
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("creating user %s in domain %s failed: %s",
+ adcli_entry_get_sam_name (entry),
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_entry_unref (entry);
+ adcli_attrs_free (attrs);
+ return -res;
}
adcli_entry_unref (entry);
@@ -317,28 +330,36 @@ adcli_tool_user_delete (adcli_conn *conn,
argc -= optind;
argv += optind;
- if (argc != 1)
- errx (2, "specify one user name to delete");
+ if (argc != 1) {
+ warnx ("specify one user name to delete");
+ return 2;
+ }
entry = adcli_entry_new_user (conn, argv[0]);
- if (entry == NULL)
- errx (-1, "unexpected memory problems");
+ if (entry == NULL) {
+ warnx ("unexpected memory problems");
+ return -1;
+ }
adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT);
res = adcli_conn_connect (conn);
if (res != ADCLI_SUCCESS) {
- errx (-res, "couldn't connect to %s domain: %s",
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("couldn't connect to %s domain: %s",
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_entry_unref (entry);
+ return -res;
}
res = adcli_entry_delete (entry);
if (res != ADCLI_SUCCESS) {
- errx (-res, "deleting user %s in domain %s failed: %s",
- adcli_entry_get_sam_name (entry),
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("deleting user %s in domain %s failed: %s",
+ adcli_entry_get_sam_name (entry),
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_entry_unref (entry);
+ return -res;
}
adcli_entry_unref (entry);
@@ -404,29 +425,41 @@ adcli_tool_group_create (adcli_conn *conn,
argc -= optind;
argv += optind;
- if (argc != 1)
- errx (2, "specify one group to create");
+ if (argc != 1) {
+ warnx ("specify one group to create");
+ adcli_attrs_free (attrs);
+ return 2;
+ }
entry = adcli_entry_new_group (conn, argv[0]);
- if (entry == NULL)
- errx (-1, "unexpected memory problems");
+ if (entry == NULL) {
+ warnx ("unexpected memory problems");
+ adcli_attrs_free (attrs);
+ return -1;
+ }
adcli_entry_set_domain_ou (entry, ou);
adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT);
res = adcli_conn_connect (conn);
if (res != ADCLI_SUCCESS) {
- errx (-res, "couldn't connect to domain %s: %s",
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("couldn't connect to domain %s: %s",
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_entry_unref (entry);
+ adcli_attrs_free (attrs);
+ return -res;
}
res = adcli_entry_create (entry, attrs);
if (res != ADCLI_SUCCESS) {
- errx (-res, "creating group %s in domain %s failed: %s",
- adcli_entry_get_sam_name (entry),
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("creating group %s in domain %s failed: %s",
+ adcli_entry_get_sam_name (entry),
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_entry_unref (entry);
+ adcli_attrs_free (attrs);
+ return -res;
}
adcli_entry_unref (entry);
@@ -480,28 +513,36 @@ adcli_tool_group_delete (adcli_conn *conn,
argc -= optind;
argv += optind;
- if (argc != 1)
- errx (2, "specify one group name to delete");
+ if (argc != 1) {
+ warnx ("specify one group name to delete");
+ return 2;
+ }
entry = adcli_entry_new_group (conn, argv[0]);
- if (entry == NULL)
- errx (-1, "unexpected memory problems");
+ if (entry == NULL) {
+ warnx ("unexpected memory problems");
+ return -1;
+ }
adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT);
res = adcli_conn_connect (conn);
if (res != ADCLI_SUCCESS) {
- errx (-res, "couldn't connect to %s domain: %s",
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("couldn't connect to %s domain: %s",
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_entry_unref (entry);
+ return -res;
}
res = adcli_entry_delete (entry);
if (res != ADCLI_SUCCESS) {
- errx (-res, "deleting group %s in domain %s failed: %s",
- adcli_entry_get_sam_name (entry),
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("deleting group %s in domain %s failed: %s",
+ adcli_entry_get_sam_name (entry),
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_entry_unref (entry);
+ return -res;
}
adcli_entry_unref (entry);
@@ -509,7 +550,7 @@ adcli_tool_group_delete (adcli_conn *conn,
return 0;
}
-static void
+static int
expand_user_dn_as_member (adcli_conn *conn,
adcli_attrs *attrs,
const char *user,
@@ -523,16 +564,19 @@ expand_user_dn_as_member (adcli_conn *conn,
res = adcli_entry_load (entry);
if (res != ADCLI_SUCCESS) {
- errx (-res, "couldn't lookup user %s in domain %s: %s",
- user, adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("couldn't lookup user %s in domain %s: %s",
+ user, adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_entry_unref (entry);
+ return -res;
}
dn = adcli_entry_get_dn (entry);
if (dn == NULL) {
- errx (-ADCLI_ERR_CONFIG,
- "couldn't found user %s in domain %s",
- user, adcli_conn_get_domain_name (conn));
+ warnx ("couldn't found user %s in domain %s",
+ user, adcli_conn_get_domain_name (conn));
+ adcli_entry_unref (entry);
+ return -ADCLI_ERR_CONFIG;
}
if (adding)
@@ -541,6 +585,8 @@ expand_user_dn_as_member (adcli_conn *conn,
adcli_attrs_delete1 (attrs, "member", dn);
adcli_entry_unref (entry);
+
+ return ADCLI_SUCCESS;
}
int
@@ -590,33 +636,48 @@ adcli_tool_member_add (adcli_conn *conn,
argc -= optind;
argv += optind;
- if (argc < 2)
- errx (2, "specify a group name and a user to add");
+ if (argc < 2) {
+ warnx ("specify a group name and a user to add");
+ return 2;
+ }
entry = adcli_entry_new_group (conn, argv[0]);
- if (entry == NULL)
- errx (-1, "unexpected memory problems");
+ if (entry == NULL) {
+ warnx ("unexpected memory problems");
+ return -1;
+ }
adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT);
res = adcli_conn_connect (conn);
if (res != ADCLI_SUCCESS) {
- errx (-res, "couldn't connect to %s domain: %s",
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("couldn't connect to %s domain: %s",
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_entry_unref (entry);
+ return -res;
}
attrs = adcli_attrs_new ();
- for (i = 1; i < argc; i++)
- expand_user_dn_as_member (conn, attrs, argv[i], 1);
+ for (i = 1; i < argc; i++) {
+ res = expand_user_dn_as_member (conn, attrs, argv[i], 1);
+ if (res != ADCLI_SUCCESS) {
+ adcli_attrs_free (attrs);
+ adcli_entry_unref (entry);
+ return res;
+ }
+ }
res = adcli_entry_modify (entry, attrs);
if (res != ADCLI_SUCCESS) {
- errx (-res, "adding member(s) to group %s in domain %s failed: %s",
- adcli_entry_get_sam_name (entry),
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("adding member(s) to group %s in domain %s failed: %s",
+ adcli_entry_get_sam_name (entry),
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_attrs_free (attrs);
+ adcli_entry_unref (entry);
+ return -res;
}
adcli_attrs_free (attrs);
@@ -672,33 +733,48 @@ adcli_tool_member_remove (adcli_conn *conn,
argc -= optind;
argv += optind;
- if (argc < 2)
- errx (2, "specify a group name and a user to remove");
+ if (argc < 2) {
+ warnx ("specify a group name and a user to remove");
+ return 2;
+ }
entry = adcli_entry_new_group (conn, argv[0]);
- if (entry == NULL)
- errx (-1, "unexpected memory problems");
+ if (entry == NULL) {
+ warnx ("unexpected memory problems");
+ return -1;
+ }
adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT);
res = adcli_conn_connect (conn);
if (res != ADCLI_SUCCESS) {
- errx (-res, "couldn't connect to %s domain: %s",
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("couldn't connect to %s domain: %s",
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_entry_unref (entry);
+ return -res;
}
attrs = adcli_attrs_new ();
- for (i = 1; i < argc; i++)
- expand_user_dn_as_member (conn, attrs, argv[i], 0);
+ for (i = 1; i < argc; i++) {
+ res = expand_user_dn_as_member (conn, attrs, argv[i], 0);
+ if (res != ADCLI_SUCCESS) {
+ adcli_attrs_free (attrs);
+ adcli_entry_unref (entry);
+ return res;
+ }
+ }
res = adcli_entry_modify (entry, attrs);
if (res != ADCLI_SUCCESS) {
- errx (-res, "adding member(s) to group %s in domain %s failed: %s",
- adcli_entry_get_sam_name (entry),
- adcli_conn_get_domain_name (conn),
- adcli_get_last_error ());
+ warnx ("adding member(s) to group %s in domain %s failed: %s",
+ adcli_entry_get_sam_name (entry),
+ adcli_conn_get_domain_name (conn),
+ adcli_get_last_error ());
+ adcli_attrs_free (attrs);
+ adcli_entry_unref (entry);
+ return -res;
}
adcli_attrs_free (attrs);
--
2.20.1

View File

@ -0,0 +1,196 @@
From 0c09070e8beec734e3f0c70e14b0a04788077b73 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 13 Jun 2019 17:25:52 +0200
Subject: [PATCH 3/4] adenroll: add adcli_enroll_get_permitted_keytab_enctypes
with tests
The new call does not only return the current encryption types set in AD
or a default list but filters them with the list of permitted encryption
types on the client. This makes sure the client can create and use the
keys.
Related to https://gitlab.freedesktop.org/realmd/adcli/issues/3
---
library/Makefile.am | 5 ++
library/adenroll.c | 124 ++++++++++++++++++++++++++++++++++++++++++++
library/adenroll.h | 2 +
3 files changed, 131 insertions(+)
diff --git a/library/Makefile.am b/library/Makefile.am
index 39e8fd1..4829555 100644
--- a/library/Makefile.am
+++ b/library/Makefile.am
@@ -40,6 +40,7 @@ check_PROGRAMS = \
test-util \
test-ldap \
test-attrs \
+ test-adenroll \
$(NULL)
test_seq_SOURCES = seq.c test.c test.h
@@ -56,6 +57,10 @@ test_attrs_SOURCES = adattrs.c $(test_ldap_SOURCES)
test_attrs_CFLAGS = -DATTRS_TESTS
test_attrs_LDADD = $(test_ldap_LDADD)
+test_adenroll_SOURCES = adenroll.c $(test_ldap_SOURCES)
+test_adenroll_CFLAGS = -DADENROLL_TESTS
+test_adenroll_LDADD = $(KRB5_LIBS)
+
TESTS = $(check_PROGRAMS)
MEMCHECK_ENV = $(TEST_RUNNER) valgrind --error-exitcode=80 --quiet --trace-children=yes
diff --git a/library/adenroll.c b/library/adenroll.c
index f617f28..95c07cd 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -2641,6 +2641,50 @@ adcli_enroll_get_keytab_enctypes (adcli_enroll *enroll)
return v51_earlier_enctypes;
}
+krb5_enctype *
+adcli_enroll_get_permitted_keytab_enctypes (adcli_enroll *enroll)
+{
+ krb5_enctype *cur_enctypes;
+ krb5_enctype *permitted_enctypes;
+ krb5_enctype *new_enctypes;
+ krb5_error_code code;
+ krb5_context k5;
+ size_t c;
+ size_t p;
+ size_t n;
+
+ return_val_if_fail (enroll != NULL, NULL);
+ cur_enctypes = adcli_enroll_get_keytab_enctypes (enroll);
+
+ k5 = adcli_conn_get_krb5_context (enroll->conn);
+ return_val_if_fail (k5 != NULL, NULL);
+
+ code = krb5_get_permitted_enctypes (k5, &permitted_enctypes);
+ return_val_if_fail (code == 0, NULL);
+
+ for (c = 0; cur_enctypes[c] != 0; c++);
+
+ new_enctypes = calloc (c + 1, sizeof (krb5_enctype));
+ return_val_if_fail (new_enctypes != NULL, NULL);
+
+ n = 0;
+ for (c = 0; cur_enctypes[c] != 0; c++) {
+ for (p = 0; permitted_enctypes[p] != 0; p++) {
+ if (cur_enctypes[c] == permitted_enctypes[p]) {
+ new_enctypes[n++] = cur_enctypes[c];
+ break;
+ }
+ }
+ if (permitted_enctypes[p] == 0) {
+ _adcli_info ("Encryption type [%d] not permitted.", cur_enctypes[c]);
+ }
+ }
+
+ krb5_free_enctypes (k5, permitted_enctypes);
+
+ return new_enctypes;
+}
+
void
adcli_enroll_set_keytab_enctypes (adcli_enroll *enroll,
krb5_enctype *value)
@@ -2833,3 +2877,83 @@ adcli_enroll_add_service_principal_to_remove (adcli_enroll *enroll,
strdup (value), NULL);
return_if_fail (enroll->service_principals_to_remove != NULL);
}
+
+#ifdef ADENROLL_TESTS
+
+#include "test.h"
+
+static void
+test_adcli_enroll_get_permitted_keytab_enctypes (void)
+{
+ krb5_enctype *enctypes;
+ krb5_error_code code;
+ krb5_enctype *permitted_enctypes;
+ krb5_enctype check_enctypes[3] = { 0 };
+ adcli_conn *conn;
+ adcli_enroll *enroll;
+ adcli_result res;
+ krb5_context k5;
+ size_t c;
+
+ conn = adcli_conn_new ("test.dom");
+ assert_ptr_not_null (conn);
+
+ enroll = adcli_enroll_new (conn);
+ assert_ptr_not_null (enroll);
+
+ enctypes = adcli_enroll_get_permitted_keytab_enctypes (NULL);
+ assert_ptr_eq (enctypes, NULL);
+
+ /* krb5 context missing */
+ enctypes = adcli_enroll_get_permitted_keytab_enctypes (enroll);
+ assert_ptr_eq (enctypes, NULL);
+
+ /* check that all permitted enctypes can pass */
+ res = _adcli_krb5_init_context (&k5);
+ assert_num_eq (res, ADCLI_SUCCESS);
+
+ adcli_conn_set_krb5_context (conn, k5);
+
+ code = krb5_get_permitted_enctypes (k5, &permitted_enctypes);
+ assert_num_eq (code, 0);
+ assert_ptr_not_null (permitted_enctypes);
+ assert_num_cmp (permitted_enctypes[0], !=, 0);
+
+ adcli_enroll_set_keytab_enctypes (enroll, permitted_enctypes);
+
+ enctypes = adcli_enroll_get_permitted_keytab_enctypes (enroll);
+ assert_ptr_not_null (enctypes);
+ for (c = 0; permitted_enctypes[c] != 0; c++) {
+ assert_num_eq (enctypes[c], permitted_enctypes[c]);
+ }
+ assert_num_eq (enctypes[c], 0);
+ krb5_free_enctypes (k5, enctypes);
+
+ /* check that ENCTYPE_UNKNOWN is filtered out */
+ check_enctypes[0] = permitted_enctypes[0];
+ check_enctypes[1] = ENCTYPE_UNKNOWN;
+ check_enctypes[2] = 0;
+ adcli_enroll_set_keytab_enctypes (enroll, check_enctypes);
+
+ enctypes = adcli_enroll_get_permitted_keytab_enctypes (enroll);
+ assert_ptr_not_null (enctypes);
+ assert_num_eq (enctypes[0], permitted_enctypes[0]);
+ assert_num_eq (enctypes[1], 0);
+ krb5_free_enctypes (k5, enctypes);
+
+ krb5_free_enctypes (k5, permitted_enctypes);
+
+ adcli_enroll_unref (enroll);
+ adcli_conn_unref (conn);
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ test_func (test_adcli_enroll_get_permitted_keytab_enctypes,
+ "/attrs/adcli_enroll_get_permitted_keytab_enctypes");
+ return test_run (argc, argv);
+}
+
+#endif /* ADENROLL_TESTS */
diff --git a/library/adenroll.h b/library/adenroll.h
index abbbfd4..1d5d00d 100644
--- a/library/adenroll.h
+++ b/library/adenroll.h
@@ -138,6 +138,8 @@ krb5_enctype * adcli_enroll_get_keytab_enctypes (adcli_enroll *enroll);
void adcli_enroll_set_keytab_enctypes (adcli_enroll *enroll,
krb5_enctype *enctypes);
+krb5_enctype * adcli_enroll_get_permitted_keytab_enctypes (adcli_enroll *enroll);
+
const char * adcli_enroll_get_os_name (adcli_enroll *enroll);
void adcli_enroll_set_os_name (adcli_enroll *enroll,
--
2.21.0

View File

@ -0,0 +1,42 @@
From 10a4dbb5978b6f05cf75f820d97da908e735ace8 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 22 Mar 2019 10:37:11 +0100
Subject: [PATCH 3/4] library: _adcli_krb5_build_principal allow principals as
names
Make _adcli_krb5_build_principal a bit more robust by checking if the
given name already contains a realm suffix.
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1630187
---
library/adkrb5.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/library/adkrb5.c b/library/adkrb5.c
index 7f77373..da835d7 100644
--- a/library/adkrb5.c
+++ b/library/adkrb5.c
@@ -41,12 +41,16 @@ _adcli_krb5_build_principal (krb5_context k5,
krb5_principal *principal)
{
krb5_error_code code;
- char *name;
+ char *name = NULL;
- if (asprintf (&name, "%s@%s", user, realm) < 0)
- return_val_if_reached (ENOMEM);
+ /* Use user if user contains a @-character and add @realm otherwise */
+ if (strchr (user, '@') == NULL) {
+ if (asprintf (&name, "%s@%s", user, realm) < 0) {
+ return_val_if_reached (ENOMEM);
+ }
+ }
- code = krb5_parse_name (k5, name, principal);
+ code = krb5_parse_name (k5, name != NULL ? name : user, principal);
return_val_if_fail (code == 0, code);
free (name);
--
2.20.1

View File

@ -0,0 +1,53 @@
From 4794812cc98c8783921f534d20dae8b44f3826d2 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 15 Apr 2019 17:57:37 +0200
Subject: [PATCH 3/7] tools: remove errx from info commands
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1588596
---
tools/info.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/tools/info.c b/tools/info.c
index e7e20ad..c63e0ff 100644
--- a/tools/info.c
+++ b/tools/info.c
@@ -162,21 +162,28 @@ adcli_tool_info (adcli_conn *unused,
if (argc == 1)
domain = argv[0];
- else if (argc != 0)
- errx (2, "specify one user name to create");
+ else if (argc != 0) {
+ warnx ("specify one user name to create");
+ return 2;
+ }
if (server) {
adcli_disco_host (server, &disco);
- if (disco == NULL)
- errx (1, "couldn't discover domain controller: %s", server);
+ if (disco == NULL) {
+ warnx ("couldn't discover domain controller: %s", server);
+ return 1;
+ }
for_host = 1;
} else if (domain) {
adcli_disco_domain (domain, &disco);
- if (disco == NULL)
- errx (1, "couldn't discover domain: %s", domain);
+ if (disco == NULL) {
+ warnx ("couldn't discover domain: %s", domain);
+ return 1;
+ }
for_host = 0;
} else {
- errx (2, "specify a domain to discover");
+ warnx ("specify a domain to discover");
+ return 2;
}
print_info (disco, for_host);
--
2.20.1

View File

@ -0,0 +1,103 @@
From cc3ef52884a48863a81acbfc741735fe09cd85f7 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 13 Jun 2019 18:27:49 +0200
Subject: [PATCH 4/4] adenroll: use only enctypes permitted by Kerberos config
Realted to https://gitlab.freedesktop.org/realmd/adcli/issues/3
---
doc/adcli.xml | 10 ++++++++++
library/adenroll.c | 22 +++++++++++++++++++---
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/doc/adcli.xml b/doc/adcli.xml
index 9605b4a..094f577 100644
--- a/doc/adcli.xml
+++ b/doc/adcli.xml
@@ -342,6 +342,11 @@ Password for Administrator:
</varlistentry>
</variablelist>
+ <para>If supported on the AD side the
+ <option>msDS-supportedEncryptionTypes</option> attribute will be set as
+ well. Either the current value or the default list of AD's supported
+ encryption types filtered by the permitted encryption types of the
+ client's Kerberos configuration are written.</para>
</refsect1>
<refsect1 id='updating'>
@@ -475,6 +480,11 @@ $ adcli update --login-ccache=/tmp/krbcc_123
</varlistentry>
</variablelist>
+ <para>If supported on the AD side the
+ <option>msDS-supportedEncryptionTypes</option> attribute will be set as
+ well. Either the current value or the default list of AD's supported
+ encryption types filtered by the permitted encryption types of the
+ client's Kerberos configuration are written.</para>
</refsect1>
<refsect1 id='testjoin'>
diff --git a/library/adenroll.c b/library/adenroll.c
index 95c07cd..53cd812 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -639,6 +639,7 @@ calculate_enctypes (adcli_enroll *enroll, char **enctype)
{
char *value = NULL;
krb5_enctype *read_enctypes;
+ krb5_enctype *new_enctypes;
char *new_value = NULL;
int is_2008_or_later;
LDAP *ldap;
@@ -685,7 +686,14 @@ calculate_enctypes (adcli_enroll *enroll, char **enctype)
value = _adcli_krb5_format_enctypes (v51_earlier_enctypes);
}
- new_value = _adcli_krb5_format_enctypes (adcli_enroll_get_keytab_enctypes (enroll));
+ new_enctypes = adcli_enroll_get_permitted_keytab_enctypes (enroll);
+ if (new_enctypes == NULL) {
+ _adcli_warn ("No permitted encryption type found.");
+ return ADCLI_ERR_UNEXPECTED;
+ }
+
+ new_value = _adcli_krb5_format_enctypes (new_enctypes);
+ krb5_free_enctypes (adcli_conn_get_krb5_context (enroll->conn), new_enctypes);
if (new_value == NULL) {
free (value);
_adcli_warn ("The encryption types desired are not available in active directory");
@@ -1758,7 +1766,11 @@ add_principal_to_keytab (adcli_enroll *enroll,
enroll->keytab_name);
}
- enctypes = adcli_enroll_get_keytab_enctypes (enroll);
+ enctypes = adcli_enroll_get_permitted_keytab_enctypes (enroll);
+ if (enctypes == NULL) {
+ _adcli_warn ("No permitted encryption type found.");
+ return ADCLI_ERR_UNEXPECTED;
+ }
if (flags & ADCLI_ENROLL_PASSWORD_VALID) {
code = _adcli_krb5_keytab_copy_entries (k5, enroll->keytab, principal,
@@ -1774,7 +1786,10 @@ add_principal_to_keytab (adcli_enroll *enroll,
*/
salts = build_principal_salts (enroll, k5, principal);
- return_unexpected_if_fail (salts != NULL);
+ if (salts == NULL) {
+ krb5_free_enctypes (k5, enctypes);
+ return ADCLI_ERR_UNEXPECTED;
+ }
if (*which_salt < 0) {
code = _adcli_krb5_keytab_discover_salt (k5, principal, enroll->kvno, &password,
@@ -1794,6 +1809,7 @@ add_principal_to_keytab (adcli_enroll *enroll,
free_principal_salts (k5, salts);
}
+ krb5_free_enctypes (k5, enctypes);
if (code != 0) {
_adcli_err ("Couldn't add keytab entries: %s: %s",
--
2.21.0

View File

@ -0,0 +1,82 @@
From 972f1a2f35829ed89f5353bd204683aa9ad6a2d2 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 22 Mar 2019 10:37:57 +0100
Subject: [PATCH 4/4] library: make sure server side SPNs are preserved
adcli should not delete service principal names (SPNs) unexpectedly. If
a SPN was added on the server while presetting a host or updating an
existing entry and upcoming adcli join or update should preserver this
change.
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1630187
---
library/adenroll.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/library/adenroll.c b/library/adenroll.c
index 48cb4cf..1cce86a 100644
--- a/library/adenroll.c
+++ b/library/adenroll.c
@@ -1961,6 +1961,47 @@ adcli_enroll_prepare (adcli_enroll *enroll,
return res;
}
+static adcli_result
+add_server_side_service_principals (adcli_enroll *enroll)
+{
+ char **spn_list;
+ LDAP *ldap;
+ size_t c;
+ int length = 0;
+ adcli_result res;
+
+ ldap = adcli_conn_get_ldap_connection (enroll->conn);
+ assert (ldap != NULL);
+
+ spn_list = _adcli_ldap_parse_values (ldap, enroll->computer_attributes,
+ "servicePrincipalName");
+ if (spn_list == NULL) {
+ return ADCLI_SUCCESS;
+ }
+
+ if (enroll->service_principals != NULL) {
+ length = seq_count (enroll->service_principals);
+ }
+
+ for (c = 0; spn_list[c] != NULL; c++) {
+ _adcli_info ("Checking %s", spn_list[c]);
+ if (!_adcli_strv_has_ex (enroll->service_principals_to_remove, spn_list[c], strcasecmp)) {
+ enroll->service_principals = _adcli_strv_add_unique (enroll->service_principals,
+ spn_list[c], &length, false);
+ assert (enroll->service_principals != NULL);
+ _adcli_info (" Added %s", spn_list[c]);
+ }
+ }
+ _adcli_strv_free (spn_list);
+
+ res = ensure_keytab_principals (ADCLI_SUCCESS, enroll);
+ if (res != ADCLI_SUCCESS) {
+ return res;
+ }
+
+ return ADCLI_SUCCESS;
+}
+
static adcli_result
enroll_join_or_update_tasks (adcli_enroll *enroll,
adcli_enroll_flags flags)
@@ -2019,6 +2060,11 @@ enroll_join_or_update_tasks (adcli_enroll *enroll,
update_and_calculate_enctypes (enroll);
update_computer_account (enroll);
+ res = add_server_side_service_principals (enroll);
+ if (res != ADCLI_SUCCESS) {
+ return res;
+ }
+
/* service_names is only set from input on the command line, so no
* additional check for explicit is needed here */
if (enroll->service_names != NULL) {
--
2.20.1

View File

@ -0,0 +1,42 @@
From 251d7d0c71226afb8e51f7bc5794a7a3164f5a20 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 15 Apr 2019 17:59:17 +0200
Subject: [PATCH 4/7] tools: remove errx from adcli_read_password_func
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1588596
---
tools/tools.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/tools/tools.c b/tools/tools.c
index c4e2851..bdf6d38 100644
--- a/tools/tools.c
+++ b/tools/tools.c
@@ -247,7 +247,9 @@ adcli_read_password_func (adcli_login_type login_type,
if (res < 0) {
if (errno == EAGAIN || errno == EINTR)
continue;
- err (EFAIL, "couldn't read password from stdin");
+ warn ("couldn't read password from stdin");
+ free (buffer);
+ return NULL;
} else if (res == 0) {
buffer[offset] = '\0';
@@ -261,8 +263,11 @@ adcli_read_password_func (adcli_login_type login_type,
return buffer;
} else {
- if (memchr (buffer + offset, 0, res))
- errx (EUSAGE, "unsupported null character present in password");
+ if (memchr (buffer + offset, 0, res)) {
+ warnx ("unsupported null character present in password");
+ free (buffer);
+ return NULL;
+ }
offset += res;
}
}
--
2.20.1

View File

@ -0,0 +1,63 @@
From b8f5d995d30c17eb8bec3ac5e0777ea94f5b76c3 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 15 Apr 2019 18:00:52 +0200
Subject: [PATCH 5/7] tools: remove errx from setup_krb5_conf_directory
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1588596
---
tools/tools.c | 38 ++++++++++++++++++++++++--------------
1 file changed, 24 insertions(+), 14 deletions(-)
diff --git a/tools/tools.c b/tools/tools.c
index bdf6d38..fc9fa9a 100644
--- a/tools/tools.c
+++ b/tools/tools.c
@@ -327,21 +327,31 @@ setup_krb5_conf_directory (adcli_conn *conn)
}
if (asprintf (&directory, "%s%sadcli-krb5-XXXXXX", parent,
- (parent[0] && parent[strlen(parent) - 1] == '/') ? "" : "/") < 0)
- errx (1, "unexpected: out of memory");
-
- if (mkdtemp (directory) == NULL) {
- errn = errno;
+ (parent[0] && parent[strlen(parent) - 1] == '/') ? "" : "/") < 0) {
+ warnx ("unexpected: out of memory");
+ directory = NULL; /* content is undefined */
failed = 1;
- warnx ("couldn't create temporary directory in: %s: %s",
- parent, strerror (errn));
- } else {
- if (asprintf (&filename, "%s/krb5.conf", directory) < 0 ||
- asprintf (&snippets, "%s/krb5.d", directory) < 0 ||
- asprintf (&contents, "includedir %s\n%s%s\n", snippets,
- krb5_conf ? "include " : "",
- krb5_conf ? krb5_conf : "") < 0)
- errx (1, "unexpected: out of memory");
+ }
+
+ if (!failed) {
+ if (mkdtemp (directory) == NULL) {
+ errn = errno;
+ failed = 1;
+ warnx ("couldn't create temporary directory in: %s: %s",
+ parent, strerror (errn));
+ } else {
+ if (asprintf (&filename, "%s/krb5.conf", directory) < 0 ||
+ asprintf (&snippets, "%s/krb5.d", directory) < 0 ||
+ asprintf (&contents, "includedir %s\n%s%s\n", snippets,
+ krb5_conf ? "include " : "",
+ krb5_conf ? krb5_conf : "") < 0) {
+ warnx ("unexpected: out of memory");
+ filename = NULL; /* content is undefined */
+ snippets = NULL; /* content is undefined */
+ contents = NULL; /* content is undefined */
+ failed = 1;
+ }
+ }
}
if (!failed) {
--
2.20.1

View File

@ -0,0 +1,175 @@
From d9912e19e48ec482351b9c384140ad71922ec5c0 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 8 Apr 2019 17:22:00 +0200
Subject: [PATCH 6/7] tools: entry - remove errx from parse_option
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1588596
---
tools/entry.c | 70 ++++++++++++++++++++++++++++++++++-----------------
1 file changed, 47 insertions(+), 23 deletions(-)
diff --git a/tools/entry.c b/tools/entry.c
index 97ec6e7..f361845 100644
--- a/tools/entry.c
+++ b/tools/entry.c
@@ -81,7 +81,7 @@ static adcli_tool_desc common_usages[] = {
{ 0 },
};
-static void
+static int
parse_option (Option opt,
const char *optarg,
adcli_conn *conn)
@@ -93,54 +93,58 @@ parse_option (Option opt,
switch (opt) {
case opt_login_ccache:
adcli_conn_set_login_ccache_name (conn, optarg);
- return;
+ return ADCLI_SUCCESS;
case opt_login_user:
adcli_conn_set_login_user (conn, optarg);
- return;
+ return ADCLI_SUCCESS;
case opt_domain:
adcli_conn_set_domain_name (conn, optarg);
- return;
+ return ADCLI_SUCCESS;
case opt_domain_realm:
adcli_conn_set_domain_realm (conn, optarg);
- return;
+ return ADCLI_SUCCESS;
case opt_domain_controller:
adcli_conn_set_domain_controller (conn, optarg);
- return;
+ return ADCLI_SUCCESS;
case opt_no_password:
if (stdin_password || prompt_password) {
- errx (EUSAGE, "cannot use --no-password argument with %s",
- stdin_password ? "--stdin-password" : "--prompt-password");
+ warnx ("cannot use --no-password argument with %s",
+ stdin_password ? "--stdin-password" : "--prompt-password");
+ return EUSAGE;
} else {
adcli_conn_set_password_func (conn, NULL, NULL, NULL);
no_password = 1;
}
- return;
+ return ADCLI_SUCCESS;
case opt_prompt_password:
if (stdin_password || no_password) {
- errx (EUSAGE, "cannot use --prompt-password argument with %s",
- stdin_password ? "--stdin-password" : "--no-password");
+ warnx ("cannot use --prompt-password argument with %s",
+ stdin_password ? "--stdin-password" : "--no-password");
+ return EUSAGE;
} else {
adcli_conn_set_password_func (conn, adcli_prompt_password_func, NULL, NULL);
prompt_password = 1;
}
- return;
+ return ADCLI_SUCCESS;
case opt_stdin_password:
if (prompt_password || no_password) {
- errx (EUSAGE, "cannot use --stdin-password argument with %s",
- prompt_password ? "--prompt-password" : "--no-password");
+ warnx ("cannot use --stdin-password argument with %s",
+ prompt_password ? "--prompt-password" : "--no-password");
+ return EUSAGE;
} else {
adcli_conn_set_password_func (conn, adcli_read_password_func, NULL, NULL);
stdin_password = 1;
}
- return;
+ return ADCLI_SUCCESS;
case opt_verbose:
- return;
+ return ADCLI_SUCCESS;
default:
assert (0 && "not reached");
break;
}
- errx (EUSAGE, "failure to parse option '%c'", opt);
+ warnx ("failure to parse option '%c'", opt);
+ return EUSAGE;
}
int
@@ -224,7 +228,11 @@ adcli_tool_user_create (adcli_conn *conn,
adcli_attrs_free (attrs);
return opt == 'h' ? 0 : 2;
default:
- parse_option ((Option)opt, optarg, conn);
+ res = parse_option ((Option)opt, optarg, conn);
+ if (res != ADCLI_SUCCESS) {
+ adcli_attrs_free (attrs);
+ return res;
+ }
break;
}
}
@@ -322,7 +330,10 @@ adcli_tool_user_delete (adcli_conn *conn,
adcli_tool_usage (options, common_usages);
return opt == 'h' ? 0 : 2;
default:
- parse_option ((Option)opt, optarg, conn);
+ res = parse_option ((Option)opt, optarg, conn);
+ if (res != ADCLI_SUCCESS) {
+ return res;
+ }
break;
}
}
@@ -417,7 +428,11 @@ adcli_tool_group_create (adcli_conn *conn,
adcli_attrs_free (attrs);
return opt == 'h' ? 0 : 2;
default:
- parse_option ((Option)opt, optarg, conn);
+ res = parse_option ((Option)opt, optarg, conn);
+ if (res != ADCLI_SUCCESS) {
+ adcli_attrs_free (attrs);
+ return res;
+ }
break;
}
}
@@ -505,7 +520,10 @@ adcli_tool_group_delete (adcli_conn *conn,
adcli_tool_usage (options, common_usages);
return opt == 'h' ? 0 : 2;
default:
- parse_option ((Option)opt, optarg, conn);
+ res = parse_option ((Option)opt, optarg, conn);
+ if (res != ADCLI_SUCCESS) {
+ return res;
+ }
break;
}
}
@@ -628,7 +646,10 @@ adcli_tool_member_add (adcli_conn *conn,
adcli_tool_usage (options, common_usages);
return opt == 'h' ? 0 : 2;
default:
- parse_option ((Option)opt, optarg, conn);
+ res = parse_option ((Option)opt, optarg, conn);
+ if (res != ADCLI_SUCCESS) {
+ return res;
+ }
break;
}
}
@@ -725,7 +746,10 @@ adcli_tool_member_remove (adcli_conn *conn,
adcli_tool_usage (options, common_usages);
return opt == 'h' ? 0 : 2;
default:
- parse_option ((Option)opt, optarg, conn);
+ res = parse_option ((Option)opt, optarg, conn);
+ if (res != ADCLI_SUCCESS) {
+ return res;
+ }
break;
}
}
--
2.20.1

View File

@ -0,0 +1,294 @@
From f127ddef23a532cd9763190527bf79b4e47fa2ab Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 8 Apr 2019 17:33:17 +0200
Subject: [PATCH 7/7] tools: computer - remove errx from parse_option
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1588596
---
tools/computer.c | 128 +++++++++++++++++++++++++++++------------------
1 file changed, 80 insertions(+), 48 deletions(-)
diff --git a/tools/computer.c b/tools/computer.c
index 9cbbb28..ac8a203 100644
--- a/tools/computer.c
+++ b/tools/computer.c
@@ -159,7 +159,7 @@ static adcli_tool_desc common_usages[] = {
{ 0 },
};
-static void
+static int
parse_option (Option opt,
const char *optarg,
adcli_conn *conn,
@@ -175,132 +175,139 @@ parse_option (Option opt,
switch (opt) {
case opt_login_ccache:
adcli_conn_set_login_ccache_name (conn, optarg ? optarg : "");
- return;
+ return ADCLI_SUCCESS;
case opt_login_user:
if (adcli_conn_get_allowed_login_types (conn) & ADCLI_LOGIN_USER_ACCOUNT) {
adcli_conn_set_login_user (conn, optarg);
adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT);
} else {
- errx (EUSAGE, "cannot set --user if --login-type not set to 'user'");
+ warnx ("cannot set --user if --login-type not set to 'user'");
+ return EUSAGE;
}
- return;
+ return ADCLI_SUCCESS;
case opt_login_type:
if (optarg && strcmp (optarg, "computer") == 0) {
- if (adcli_conn_get_login_user (conn) != NULL)
- errx (EUSAGE, "cannot set --login-type to 'computer' if --user is set");
- else
+ if (adcli_conn_get_login_user (conn) != NULL) {
+ warnx ("cannot set --login-type to 'computer' if --user is set");
+ return EUSAGE;
+ } else
adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_COMPUTER_ACCOUNT);
} else if (optarg && strcmp (optarg, "user") == 0) {
adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT);
} else {
- errx (EUSAGE, "unknown login type '%s'", optarg);
+ warnx ("unknown login type '%s'", optarg);
+ return EUSAGE;
}
- return;
+ return ADCLI_SUCCESS;
case opt_host_fqdn:
adcli_conn_set_host_fqdn (conn, optarg);
- return;
+ return ADCLI_SUCCESS;
case opt_host_keytab:
adcli_enroll_set_keytab_name (enroll, optarg);
- return;
+ return ADCLI_SUCCESS;
case opt_computer_name:
adcli_conn_set_computer_name (conn, optarg);
adcli_enroll_set_computer_name (enroll, optarg);
- return;
+ return ADCLI_SUCCESS;
case opt_domain:
adcli_conn_set_domain_name (conn, optarg);
- return;
+ return ADCLI_SUCCESS;
case opt_domain_realm:
adcli_conn_set_domain_realm (conn, optarg);
- return;
+ return ADCLI_SUCCESS;
case opt_domain_controller:
adcli_conn_set_domain_controller (conn, optarg);
- return;
+ return ADCLI_SUCCESS;
case opt_domain_ou:
adcli_enroll_set_domain_ou (enroll, optarg);
- return;
+ return ADCLI_SUCCESS;
case opt_service_name:
adcli_enroll_add_service_name (enroll, optarg);
- return;
+ return ADCLI_SUCCESS;
case opt_no_password:
if (stdin_password || prompt_password) {
- errx (EUSAGE, "cannot use --no-password argument with %s",
- stdin_password ? "--stdin-password" : "--prompt-password");
+ warnx ("cannot use --no-password argument with %s",
+ stdin_password ? "--stdin-password" : "--prompt-password");
+ return EUSAGE;
} else {
adcli_conn_set_password_func (conn, NULL, NULL, NULL);
no_password = 1;
}
- return;
+ return ADCLI_SUCCESS;
case opt_prompt_password:
if (stdin_password || no_password) {
- errx (EUSAGE, "cannot use --prompt-password argument with %s",
- stdin_password ? "--stdin-password" : "--no-password");
+ warnx ("cannot use --prompt-password argument with %s",
+ stdin_password ? "--stdin-password" : "--no-password");
+ return EUSAGE;
} else {
adcli_conn_set_password_func (conn, adcli_prompt_password_func, NULL, NULL);
prompt_password = 1;
}
- return;
+ return ADCLI_SUCCESS;
case opt_stdin_password:
if (prompt_password || no_password) {
- errx (EUSAGE, "cannot use --stdin-password argument with %s",
- prompt_password ? "--prompt-password" : "--no-password");
+ warnx ("cannot use --stdin-password argument with %s",
+ prompt_password ? "--prompt-password" : "--no-password");
+ return EUSAGE;
} else {
adcli_conn_set_password_func (conn, adcli_read_password_func, NULL, NULL);
stdin_password = 1;
}
- return;
+ return ADCLI_SUCCESS;
case opt_os_name:
adcli_enroll_set_os_name (enroll, optarg);
- return;
+ return ADCLI_SUCCESS;
case opt_os_version:
adcli_enroll_set_os_version (enroll, optarg);
- return;
+ return ADCLI_SUCCESS;
case opt_os_service_pack:
adcli_enroll_set_os_service_pack (enroll, optarg);
- return;
+ return ADCLI_SUCCESS;
case opt_user_principal:
if (optarg && optarg[0])
adcli_enroll_set_user_principal (enroll, optarg);
else
adcli_enroll_auto_user_principal (enroll);
- return;
+ return ADCLI_SUCCESS;
case opt_computer_password_lifetime:
errno = 0;
lifetime = strtoul (optarg, &endptr, 10);
if (errno != 0 || *endptr != '\0' || endptr == optarg) {
- errx (EUSAGE,
- "failure to parse value '%s' of option 'computer-password-lifetime'; "
- "expecting non-negative integer indicating the lifetime in days",
- optarg);
+ warnx ("failure to parse value '%s' of option 'computer-password-lifetime'; "
+ "expecting non-negative integer indicating the lifetime in days",
+ optarg);
+ return EUSAGE;
}
adcli_enroll_set_computer_password_lifetime (enroll, lifetime);
- return;
+ return ADCLI_SUCCESS;
case opt_samba_data_tool:
errno = 0;
ret = access (optarg, X_OK);
if (ret != 0) {
ret = errno;
- errx (EUSAGE, "Failed to access tool to add Samba data: %s", strerror (ret));
+ warnx ("Failed to access tool to add Samba data: %s", strerror (ret));
+ return EUSAGE;
} else {
adcli_enroll_set_samba_data_tool (enroll, optarg);
}
- return;
+ return ADCLI_SUCCESS;
case opt_trusted_for_delegation:
if (strcasecmp (optarg, "true") == 0 || strcasecmp (optarg, "yes") == 0) {
adcli_enroll_set_trusted_for_delegation (enroll, true);
} else {
adcli_enroll_set_trusted_for_delegation (enroll, false);
}
- return;
+ return ADCLI_SUCCESS;
case opt_add_service_principal:
adcli_enroll_add_service_principal_to_add (enroll, optarg);
- return;
+ return ADCLI_SUCCESS;
case opt_remove_service_principal:
adcli_enroll_add_service_principal_to_remove (enroll, optarg);
- return;
+ return ADCLI_SUCCESS;
case opt_verbose:
- return;
+ return ADCLI_SUCCESS;
/* Should be handled by caller */
case opt_show_details:
@@ -311,7 +318,8 @@ parse_option (Option opt,
break;
}
- errx (EUSAGE, "failure to parse option '%c'", opt);
+ warnx ("failure to parse option '%c'", opt);
+ return EUSAGE;
}
static void
@@ -407,7 +415,11 @@ adcli_tool_computer_join (adcli_conn *conn,
adcli_enroll_unref (enroll);
return opt == 'h' ? 0 : 2;
default:
- parse_option ((Option)opt, optarg, conn, enroll);
+ res = parse_option ((Option)opt, optarg, conn, enroll);
+ if (res != ADCLI_SUCCESS) {
+ adcli_enroll_unref (enroll);
+ return res;
+ }
break;
}
}
@@ -519,7 +531,11 @@ adcli_tool_computer_update (adcli_conn *conn,
adcli_enroll_unref (enroll);
return opt == 'h' ? 0 : 2;
default:
- parse_option ((Option)opt, optarg, conn, enroll);
+ res = parse_option ((Option)opt, optarg, conn, enroll);
+ if (res != ADCLI_SUCCESS) {
+ adcli_enroll_unref (enroll);
+ return res;
+ }
break;
}
}
@@ -610,7 +626,11 @@ adcli_tool_computer_testjoin (adcli_conn *conn,
adcli_enroll_unref (enroll);
return opt == 'h' ? 0 : 2;
default:
- parse_option ((Option)opt, optarg, conn, enroll);
+ res = parse_option ((Option)opt, optarg, conn, enroll);
+ if (res != ADCLI_SUCCESS) {
+ adcli_enroll_unref (enroll);
+ return res;
+ }
break;
}
}
@@ -707,7 +727,11 @@ adcli_tool_computer_preset (adcli_conn *conn,
adcli_enroll_unref (enroll);
return 2;
default:
- parse_option ((Option)opt, optarg, conn, enroll);
+ res = parse_option ((Option)opt, optarg, conn, enroll);
+ if (res != ADCLI_SUCCESS) {
+ adcli_enroll_unref (enroll);
+ return res;
+ }
break;
}
}
@@ -801,7 +825,11 @@ adcli_tool_computer_reset (adcli_conn *conn,
adcli_enroll_unref (enroll);
return opt == 'h' ? 0 : 2;
default:
- parse_option ((Option)opt, optarg, conn, enroll);
+ res = parse_option ((Option)opt, optarg, conn, enroll);
+ if (res != ADCLI_SUCCESS) {
+ adcli_enroll_unref (enroll);
+ return res;
+ }
break;
}
}
@@ -884,7 +912,11 @@ adcli_tool_computer_delete (adcli_conn *conn,
adcli_enroll_unref (enroll);
return opt == 'h' ? 0 : 2;
default:
- parse_option ((Option)opt, optarg, conn, enroll);
+ res = parse_option ((Option)opt, optarg, conn, enroll);
+ if (res != ADCLI_SUCCESS) {
+ adcli_enroll_unref (enroll);
+ return res;
+ }
break;
}
}
--
2.20.1

View File

@ -1,6 +1,6 @@
Name: adcli
Version: 0.8.2
Release: 2%{?dist}
Release: 3%{?dist}
Summary: Active Directory enrollment
License: LGPLv2+
URL: http://cgit.freedesktop.org/realmd/adcli
@ -36,6 +36,60 @@ Patch26: 0002-_adcli_call_external_program-silence-noisy-debug-mes.patch
Patch27: 0003-Do-not-add-service-principals-twice.patch
Patch28: 0004-Do-not-depend-on-default_realm-in-krb5.conf.patch
# rhbz#1677194 - Realm cannot join domain when hostname is not FQDN
Patch29: 0001-adutil-add-_adcli_strv_add_unique.patch
Patch30: 0002-adenroll-use-_adcli_strv_add_unique-for-service-prin.patch
# Forward port of RHEL-7.7 ticket rhbz#1642546 - adcli exports kerberos ticket
# with old kvno
Patch31: 0001-Increment-kvno-after-password-change-with-user-creds.patch
# Forward port of RHEL-7.7 ticket rhbz#1595911 - [RFE] Have `adcli join` work
# without FQDN in `hostname` output
Patch32: 0001-library-use-getaddrinfo-with-AI_CANONNAME-to-find-a-.patch
# Forward port of RHEL-7.7 ticket rhbz#1644311 - Improve handling of service
# principals
Patch33: 0001-join-always-add-service-principals.patch
Patch34: 0002-library-return-error-if-no-matching-key-was-found.patch
# Forward port of RHEL-7.7 ticket rhbz#1337489 - [RFE] adcli command with
# --unix-* options doesn't update values in UnixAttributes Tab for user
Patch35: 0001-create-user-add-nis-domain-option.patch
Patch36: 0002-create-user-try-to-find-NIS-domain-if-needed.patch
# Forward port of RHEL-7.7 ticket rhbz#1630187 - [RFE] adcli join should
# preserve SPN added by adcli preset-computer
Patch37: 0001-ensure_keytab_principals-do-not-leak-memory-when-cal.patch
Patch38: 0002-library-make-_adcli_strv_has_ex-public.patch
Patch39: 0003-library-_adcli_krb5_build_principal-allow-principals.patch
Patch40: 0004-library-make-sure-server-side-SPNs-are-preserved.patch
# Forward port of RHEL-7.7 ticket rhbz#1622583 - [RFE] Need an option for adcli
# command which will show domain join status.
Patch41: 0001-Implement-adcli-testjoin.patch
# Forward port of RHEL-7.7 ticket rhbz#1630187 - [RFE] adcli join should
# preserve SPN added by adcli preset-computer - additional patch
Patch42: 0001-library-add-missing-strdup.patch
# Forward port of RHEL-7.7 ticket rhbz#1588596 - many adcli-krb5-?????
# directories are created /tmp
Patch43: 0001-tools-remove-errx-from-computer-commands.patch
Patch44: 0002-tools-remove-errx-from-user-and-group-commands.patch
Patch45: 0003-tools-remove-errx-from-info-commands.patch
Patch46: 0004-tools-remove-errx-from-adcli_read_password_func.patch
Patch47: 0005-tools-remove-errx-from-setup_krb5_conf_directory.patch
Patch48: 0006-tools-entry-remove-errx-from-parse_option.patch
Patch49: 0007-tools-computer-remove-errx-from-parse_option.patch
# rhbz#1717355 - `adcli join` fails in FIPS enabled environment
Patch50: 0001-Fix-for-issues-found-by-Coverity.patch
Patch51: 0001-adenroll-make-sure-only-allowed-enctypes-are-used-in.patch
Patch52: 0002-adconn-add-adcli_conn_set_krb5_context.patch
Patch53: 0003-adenroll-add-adcli_enroll_get_permitted_keytab_encty.patch
Patch54: 0004-adenroll-use-only-enctypes-permitted-by-Kerberos-con.patch
BuildRequires: gcc
BuildRequires: intltool pkgconfig
BuildRequires: libtool
@ -58,35 +112,7 @@ standard LDAP and Kerberos calls.
%define _hardened_build 1
%prep
%setup -q
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
%patch28 -p1
%autosetup -p1
%build
autoreconf --force --install --verbose
@ -124,6 +150,13 @@ documentation.
%doc %{_datadir}/doc/adcli/*
%changelog
* Fri Jun 14 2019 Sumit Bose <sbose@redhat.com> - 0.8.2-3
- use autosetup macro to simplify patch handling
- fixed rpmlint warnings in the spec file
- join failed if hostname is not FQDN [#1677194]
- adcli join fails in FIPS enabled environment [#1717355]
- forward port of RHEL-7.7 fixes and enhancements
* Tue Oct 09 2018 Sumit Bose <sbose@redhat.com> - 0.8.2-2
- Do not add service principals twice and related fixes
- Resolves: rhbz#1631734