From 341f9a43b3b758dfea284e8d43ad634f8d34dc42 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Aug 06 2019 11:01:47 +0000 Subject: import adcli-0.8.1-9.el7 --- diff --git a/SOURCES/0001-Implement-adcli-testjoin.patch b/SOURCES/0001-Implement-adcli-testjoin.patch new file mode 100644 index 0000000..d75cbf2 --- /dev/null +++ b/SOURCES/0001-Implement-adcli-testjoin.patch @@ -0,0 +1,181 @@ +From 6fd99ff6c5dd6ef0be8d942989b1c6dcee3102d9 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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 @@ + + adcli update + ++ ++ adcli testjoin ++ + + adcli create-user + --domain=domain.example.com +@@ -474,6 +477,37 @@ $ adcli update --login-ccache=/tmp/krbcc_123 + + + ++ ++ Testing if the machine account password is valid ++ ++ adcli testjoin 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 ++ adcli join or adcli update. ++ ++ ++ ++$ adcli testjoin ++ ++ ++ Only the global options not related to authentication are ++ available, additionally you can specify the following options to ++ control how this operation is done. ++ ++ ++ ++ ++ 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 ++ /etc/krb5.keytab. ++ ++ ++ ++ + + Creating a User + +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 + diff --git a/SOURCES/0001-Increment-kvno-after-password-change-with-user-creds.patch b/SOURCES/0001-Increment-kvno-after-password-change-with-user-creds.patch new file mode 100644 index 0000000..aeef509 --- /dev/null +++ b/SOURCES/0001-Increment-kvno-after-password-change-with-user-creds.patch @@ -0,0 +1,32 @@ +From 5cf1723c308e21cdbe9b98ed2aaa42cb997456fb Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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 + diff --git a/SOURCES/0001-create-user-add-nis-domain-option.patch b/SOURCES/0001-create-user-add-nis-domain-option.patch new file mode 100644 index 0000000..32b0ca9 --- /dev/null +++ b/SOURCES/0001-create-user-add-nis-domain-option.patch @@ -0,0 +1,71 @@ +From 1457b4a7623a8ae58fb8d6a652d1cc44904b8863 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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. + ++ ++ ++ Set the msSFU30NisDomain 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. ++ + + + +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 + diff --git a/SOURCES/0001-doc-fix-typos-in-the-adcli-man-page.patch b/SOURCES/0001-doc-fix-typos-in-the-adcli-man-page.patch new file mode 100644 index 0000000..41bd97a --- /dev/null +++ b/SOURCES/0001-doc-fix-typos-in-the-adcli-man-page.patch @@ -0,0 +1,203 @@ +From 1143163c367b8473dc3d0ea696eed3c30ccd634b Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Thu, 5 Jul 2018 13:06:26 +0200 +Subject: [PATCH] doc: fix typos in the adcli man page + +Resolves https://bugzilla.redhat.com/show_bug.cgi?id=1440533 +--- + doc/adcli.xml | 44 ++++++++++++++++++++++---------------------- + 1 file changed, 22 insertions(+), 22 deletions(-) + +diff --git a/doc/adcli.xml b/doc/adcli.xml +index 83b6981..97dec08 100644 +--- a/doc/adcli.xml ++++ b/doc/adcli.xml +@@ -105,19 +105,19 @@ + + + The domain to connect to. If a domain is +- not specified then the domain part of the local computer's ++ not specified, then the domain part of the local computer's + host name is used. + + + + Kerberos realm for the domain. If not +- specified then the upper cased domain name is ++ specified, then the upper cased domain name is + used. + + + + Connect to a specific domain controller. +- If not specified then an appropriate domain controller ++ If not specified, then an appropriate domain controller + is automatically discovered. + + +@@ -134,7 +134,7 @@ + + + Use the specified user account to +- authenticate with the domain. If not specified then ++ authenticate with the domain. If not specified, then + the name 'Administrator' will be used. + + +@@ -181,7 +181,7 @@ $ adcli info --domain-controller=dc.domain.example.com + adcli info will output as much information as + it can about the domain. The information is designed to be both machine + and human readable. The command will exit with a non-zero exit code +- if the domain does note exist or cannot be reached. ++ if the domain does not exist or cannot be reached. + + To show domain info for a specific domain controller use the + option to specify which domain +@@ -213,35 +213,35 @@ Password for Administrator: + + + The short non-dotted name of the computer +- account that will be created in the domain. If not specified ++ account that will be created in the domain. If not specified, + then the first portion of the + is used. + + + + The full distinguished name of the OU in +- which to create the computer account. If not specified ++ which to create the computer account. If not specified, + then the computer account will be created in a default + location. + + + + Override the local machine's fully qualified +- domain name. If not specified the local machine's hostname ++ domain name. If not specified, the local machine's hostname + will be retrieved via gethostname(). + + + + Specify the path to the host keytab where + host credentials will be written after a successful join +- operation. If not specified the default location will be ++ operation. If not specified, the default location will be + used, usually /etc/krb5.keytab. + + + + Specify the type of authentication that + will be performed before creating the machine account in +- the domain. If set to 'computer' then the computer must ++ the domain. If set to 'computer', then the computer must + already have a preset account in the domain. If not + specified and none of the other + arguments have been specified, then will try both +@@ -329,7 +329,7 @@ Password for Administrator: + + If Samba's net + cannot be found at +- &samba_data_tool; this option can ++ &samba_data_tool;, this option can + be used to specific an alternative location with the + help of an absolute path. + +@@ -351,7 +351,7 @@ Password for Administrator: + $ adcli update + + +- If used with a credential cache other attributes of the computer ++ If used with a credential cache, other attributes of the computer + account can be changed as well if the principal has sufficient + privileges. + +@@ -367,20 +367,20 @@ $ adcli update --login-ccache=/tmp/krbcc_123 + + + The short non-dotted name of the computer +- account that will be created in the domain. If not specified ++ account that will be created in the domain. If not specified, + it will be retrieved from the keytab entries. + + + + The local machine's fully qualified +- domain name. If not specified the local machine's hostname ++ domain name. If not specified, the local machine's hostname + will be retrieved from the keytab entries. + + + + 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 ++ will be written to. If not specified, the default + location will be used, usually + /etc/krb5.keytab. + +@@ -462,7 +462,7 @@ $ adcli update --login-ccache=/tmp/krbcc_123 + + If Samba's net + cannot be found at +- &samba_data_tool; this option can ++ &samba_data_tool;, this option can + be used to specific an alternative location with the + help of an absolute path. + +@@ -493,7 +493,7 @@ $ adcli create-user Fry --domain=domain.example.com \ + + + The full distinguished name of the OU in +- which to create the user account. If not specified ++ which to create the user account. If not specified, + then the computer account will be created in a default + location. + +@@ -569,7 +569,7 @@ $ adcli create-group Pilots --domain=domain.example.com \ + + + The full distinguished name of the OU in +- which to create the group. If not specified ++ which to create the group. If not specified, + then the group will be created in a default + location. + +@@ -649,14 +649,14 @@ Password for Administrator: + + + The full distinguished name of the OU in +- which to create the computer accounts. If not specified ++ which to create the computer accounts. If not specified, + then the computer account will be created in a default + location. + + + + Specify a one time password to use when +- presetting the computer accounts. If not specified then ++ presetting the computer accounts. If not specified, then + a default password will be used, which allows for later + automatic joins. + +@@ -696,7 +696,7 @@ Password for Administrator: + Reset Computer Account + + adcli reset-computer resets a computer account +- in the domain. If a the appropriate machine is currently joined to the ++ in the domain. If the appropriate machine is currently joined to the + domain, then its membership will be broken. The account must already + exist. + +@@ -716,7 +716,7 @@ $ adcli reset-computer --domain=domain.example.com host2 + + Specify the type of authentication that + will be performed before creating the machine account in +- the domain. If set to 'computer' then the computer must ++ the domain. If set to 'computer', then the computer must + already have a preset account in the domain. If not + specified and none of the other + arguments have been specified, then will try both +-- +2.20.1 + diff --git a/SOURCES/0001-ensure_keytab_principals-do-not-leak-memory-when-cal.patch b/SOURCES/0001-ensure_keytab_principals-do-not-leak-memory-when-cal.patch new file mode 100644 index 0000000..dfdf745 --- /dev/null +++ b/SOURCES/0001-ensure_keytab_principals-do-not-leak-memory-when-cal.patch @@ -0,0 +1,72 @@ +From 3a84c2469c31967bc22c0490456f07723ef5fc86 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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 + diff --git a/SOURCES/0001-join-always-add-service-principals.patch b/SOURCES/0001-join-always-add-service-principals.patch new file mode 100644 index 0000000..0281dc6 --- /dev/null +++ b/SOURCES/0001-join-always-add-service-principals.patch @@ -0,0 +1,86 @@ +From cd296bf24e7cc56fb8d00bad7e9a56c539894309 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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 + diff --git a/SOURCES/0001-library-add-missing-strdup.patch b/SOURCES/0001-library-add-missing-strdup.patch new file mode 100644 index 0000000..378bb3c --- /dev/null +++ b/SOURCES/0001-library-add-missing-strdup.patch @@ -0,0 +1,34 @@ +From a64cce9830c2e9c26e120f671b247ee71b45c888 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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 + diff --git a/SOURCES/0001-library-use-getaddrinfo-with-AI_CANONNAME-to-find-a-.patch b/SOURCES/0001-library-use-getaddrinfo-with-AI_CANONNAME-to-find-a-.patch new file mode 100644 index 0000000..c682c5a --- /dev/null +++ b/SOURCES/0001-library-use-getaddrinfo-with-AI_CANONNAME-to-find-a-.patch @@ -0,0 +1,92 @@ +From 85b835f8258a57e3b23de47a255dddd822d5bfb3 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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: + + Override the local machine's fully qualified + domain name. If not specified, the local machine's hostname +- will be retrieved via gethostname(). ++ will be retrieved via gethostname(). ++ If gethostname() only returns a short name ++ getaddrinfo() with the AI_CANONNAME hint ++ is called to expand the name to a fully qualified domain ++ name. + + + +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 + diff --git a/SOURCES/0001-tools-remove-errx-from-computer-commands.patch b/SOURCES/0001-tools-remove-errx-from-computer-commands.patch new file mode 100644 index 0000000..71db611 --- /dev/null +++ b/SOURCES/0001-tools-remove-errx-from-computer-commands.patch @@ -0,0 +1,328 @@ +From fa7926c7a9d92bc7c42c610ba6f1706c635aa901 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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 + diff --git a/SOURCES/0002-create-user-try-to-find-NIS-domain-if-needed.patch b/SOURCES/0002-create-user-try-to-find-NIS-domain-if-needed.patch new file mode 100644 index 0000000..0ecdc90 --- /dev/null +++ b/SOURCES/0002-create-user-try-to-find-NIS-domain-if-needed.patch @@ -0,0 +1,147 @@ +From 408880a11879b1a57a450e25c77ef2e310bdffd5 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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. ++ Directoy versions show the set UNIX specific attributes. If not specified ++ adcli will try to determine the NIS domain automatically if needed. ++ + + + +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 + diff --git a/SOURCES/0002-library-make-_adcli_strv_has_ex-public.patch b/SOURCES/0002-library-make-_adcli_strv_has_ex-public.patch new file mode 100644 index 0000000..db18951 --- /dev/null +++ b/SOURCES/0002-library-make-_adcli_strv_has_ex-public.patch @@ -0,0 +1,42 @@ +From e1b45e66bc185f5db4c252e1f3fb1b4400b4538e Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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 + diff --git a/SOURCES/0002-library-return-error-if-no-matching-key-was-found.patch b/SOURCES/0002-library-return-error-if-no-matching-key-was-found.patch new file mode 100644 index 0000000..f9c68d6 --- /dev/null +++ b/SOURCES/0002-library-return-error-if-no-matching-key-was-found.patch @@ -0,0 +1,35 @@ +From 4987a21f4839ab7ea50e932c72df05075efb89b3 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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 + diff --git a/SOURCES/0002-tools-remove-errx-from-user-and-group-commands.patch b/SOURCES/0002-tools-remove-errx-from-user-and-group-commands.patch new file mode 100644 index 0000000..36e5567 --- /dev/null +++ b/SOURCES/0002-tools-remove-errx-from-user-and-group-commands.patch @@ -0,0 +1,398 @@ +From cac0fa9df8888245399f2db187e05e31f93d1471 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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 + diff --git a/SOURCES/0003-library-_adcli_krb5_build_principal-allow-principals.patch b/SOURCES/0003-library-_adcli_krb5_build_principal-allow-principals.patch new file mode 100644 index 0000000..217636c --- /dev/null +++ b/SOURCES/0003-library-_adcli_krb5_build_principal-allow-principals.patch @@ -0,0 +1,42 @@ +From 10a4dbb5978b6f05cf75f820d97da908e735ace8 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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 + diff --git a/SOURCES/0003-tools-remove-errx-from-info-commands.patch b/SOURCES/0003-tools-remove-errx-from-info-commands.patch new file mode 100644 index 0000000..c53cf50 --- /dev/null +++ b/SOURCES/0003-tools-remove-errx-from-info-commands.patch @@ -0,0 +1,53 @@ +From 4794812cc98c8783921f534d20dae8b44f3826d2 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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 + diff --git a/SOURCES/0004-library-make-sure-server-side-SPNs-are-preserved.patch b/SOURCES/0004-library-make-sure-server-side-SPNs-are-preserved.patch new file mode 100644 index 0000000..07cc8fb --- /dev/null +++ b/SOURCES/0004-library-make-sure-server-side-SPNs-are-preserved.patch @@ -0,0 +1,82 @@ +From 972f1a2f35829ed89f5353bd204683aa9ad6a2d2 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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 + diff --git a/SOURCES/0004-tools-remove-errx-from-adcli_read_password_func.patch b/SOURCES/0004-tools-remove-errx-from-adcli_read_password_func.patch new file mode 100644 index 0000000..1b53d7d --- /dev/null +++ b/SOURCES/0004-tools-remove-errx-from-adcli_read_password_func.patch @@ -0,0 +1,42 @@ +From 251d7d0c71226afb8e51f7bc5794a7a3164f5a20 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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 + diff --git a/SOURCES/0005-tools-remove-errx-from-setup_krb5_conf_directory.patch b/SOURCES/0005-tools-remove-errx-from-setup_krb5_conf_directory.patch new file mode 100644 index 0000000..8fd9197 --- /dev/null +++ b/SOURCES/0005-tools-remove-errx-from-setup_krb5_conf_directory.patch @@ -0,0 +1,63 @@ +From b8f5d995d30c17eb8bec3ac5e0777ea94f5b76c3 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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 + diff --git a/SOURCES/0006-tools-entry-remove-errx-from-parse_option.patch b/SOURCES/0006-tools-entry-remove-errx-from-parse_option.patch new file mode 100644 index 0000000..17bb9c4 --- /dev/null +++ b/SOURCES/0006-tools-entry-remove-errx-from-parse_option.patch @@ -0,0 +1,175 @@ +From d9912e19e48ec482351b9c384140ad71922ec5c0 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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 + diff --git a/SOURCES/0007-tools-computer-remove-errx-from-parse_option.patch b/SOURCES/0007-tools-computer-remove-errx-from-parse_option.patch new file mode 100644 index 0000000..065fc9f --- /dev/null +++ b/SOURCES/0007-tools-computer-remove-errx-from-parse_option.patch @@ -0,0 +1,294 @@ +From f127ddef23a532cd9763190527bf79b4e47fa2ab Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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 + diff --git a/SPECS/adcli.spec b/SPECS/adcli.spec index 7d864df..4fc9299 100644 --- a/SPECS/adcli.spec +++ b/SPECS/adcli.spec @@ -1,14 +1,14 @@ -Name: adcli -Version: 0.8.1 -Release: 6%{?dist}.1 -Summary: Active Directory enrollment -License: LGPLv2+ -URL: http://cgit.freedesktop.org/realmd/adcli -Source0: http://www.freedesktop.org/software/realmd/releases/adcli-%{version}.tar.gz -Patch1: 0001-library-Fix-check-for-EAGAIN-or-EINTR.patch -Patch2: 0002-Patch-to-adcli.xml-to-fix-documentation-error.patch -Patch3: 0003-Remove-n-or-r-n-from-stdin-password.patch -Patch4: 0001-delete-use-keytab-data-to-determine-realm-and-NetBIO.patch +Name: adcli +Version: 0.8.1 +Release: 9%{?dist} +Summary: Active Directory enrollment +License: LGPLv2+ +URL: http://cgit.freedesktop.org/realmd/adcli +Source0: http://www.freedesktop.org/software/realmd/releases/adcli-%{version}.tar.gz +Patch1: 0001-library-Fix-check-for-EAGAIN-or-EINTR.patch +Patch2: 0002-Patch-to-adcli.xml-to-fix-documentation-error.patch +Patch3: 0003-Remove-n-or-r-n-from-stdin-password.patch +Patch4: 0001-delete-use-keytab-data-to-determine-realm-and-NetBIO.patch Patch5: 0001-Remove-upper-case-only-check-when-looking-for-the-Ne.patch Patch6: 0002-Use-strdup-if-offset-are-used.patch Patch7: 0001-correct-spelling-of-adcli_tool_computer_delete-descr.patch @@ -46,23 +46,63 @@ Patch31: 0003-Do-not-add-service-principals-twice.patch # Additional fixed for rhbz#1547014 Patch32: 0004-Do-not-depend-on-default_realm-in-krb5.conf.patch -# rhbz#1666775 +# rhbz#1649868 Patch33: 0001-adutil-add-_adcli_strv_add_unique.patch Patch34: 0002-adenroll-use-_adcli_strv_add_unique-for-service-prin.patch -BuildRequires: intltool pkgconfig -BuildRequires: libtool -BuildRequires: gettext-devel -BuildRequires: krb5-devel -BuildRequires: openldap-devel -BuildRequires: libxslt -BuildRequires: xmlto +# Patch35 is replaced by Patch49 - Patch55 -Requires: cyrus-sasl-gssapi +# rhbz#1642546 - adcli exports kerberos ticket with old kvno +Patch36: 0001-Increment-kvno-after-password-change-with-user-creds.patch + +# rhbz#1595911 - [RFE] Have `adcli join` work without FQDN in `hostname` output +# with some additional man page fixes from rhbz#1440533 +Patch37: 0001-doc-fix-typos-in-the-adcli-man-page.patch +Patch38: 0001-library-use-getaddrinfo-with-AI_CANONNAME-to-find-a-.patch + +# rhbz#1644311 - Improve handling of service principals +Patch39: 0001-join-always-add-service-principals.patch +Patch40: 0002-library-return-error-if-no-matching-key-was-found.patch + +# rhbz#1337489 - [RFE] adcli command with --unix-* options doesn't update +# values in UnixAttributes Tab for user +Patch41: 0001-create-user-add-nis-domain-option.patch +Patch42: 0002-create-user-try-to-find-NIS-domain-if-needed.patch + +# rhbz#1630187 - [RFE] adcli join should preserve SPN added by adcli preset-computer +Patch43: 0001-ensure_keytab_principals-do-not-leak-memory-when-cal.patch +Patch44: 0002-library-make-_adcli_strv_has_ex-public.patch +Patch45: 0003-library-_adcli_krb5_build_principal-allow-principals.patch +Patch46: 0004-library-make-sure-server-side-SPNs-are-preserved.patch + +# rhbz#1622583 - [RFE] Need an option for adcli command which will show domain join status. +Patch47: 0001-Implement-adcli-testjoin.patch + +# rhbz#1630187 - [RFE] adcli join should preserve SPN added by adcli preset-computer - additional patch +Patch48: 0001-library-add-missing-strdup.patch + +# rhbz#1588596 - many adcli-krb5-????? directories are created /tmp +Patch49: 0001-tools-remove-errx-from-computer-commands.patch +Patch50: 0002-tools-remove-errx-from-user-and-group-commands.patch +Patch51: 0003-tools-remove-errx-from-info-commands.patch +Patch52: 0004-tools-remove-errx-from-adcli_read_password_func.patch +Patch53: 0005-tools-remove-errx-from-setup_krb5_conf_directory.patch +Patch54: 0006-tools-entry-remove-errx-from-parse_option.patch +Patch55: 0007-tools-computer-remove-errx-from-parse_option.patch + +BuildRequires: intltool pkgconfig +BuildRequires: libtool +BuildRequires: gettext-devel +BuildRequires: krb5-devel +BuildRequires: openldap-devel +BuildRequires: libxslt +BuildRequires: xmlto + +Requires: cyrus-sasl-gssapi # adcli no longer has a library of development files # the adcli tool itself is to be used by callers -Obsoletes: adcli-devel < 0.5 +Obsoletes: adcli-devel < 0.5 %description adcli is a library and tool for joining an Active Directory domain using @@ -71,41 +111,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 -%patch29 -p1 -%patch30 -p1 -%patch31 -p1 -%patch32 -p1 -%patch33 -p1 -%patch34 -p1 +%autosetup -p1 %build autoreconf --force --install --verbose @@ -132,8 +138,27 @@ find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' %doc %{_mandir}/*/* %changelog -* Wed Jan 16 2019 Sumit Bose - 0.8.1-6.1 -- join failed if hostname is not FQDN [#1666775] +* Thu May 02 2019 Sumit Bose - 0.8.1-9 +- Fixes for RHEL-7.7 updates +- additional patch for [RFE] adcli join should preserve SPN added by adcli + preset-computer [#1630187] +- new patches for many adcli-krb5-????? directories are created /tmp [#1588596] + +* Fri Mar 22 2019 Sumit Bose - 0.8.1-8 +- Various updates for RHEL-7.7 +- many adcli-krb5-????? directories are created /tmp [#1588596] +- adcli exports kerberos ticket with old kvno [#1642546] +- [RFE] Have `adcli join` work without FQDN in `hostname` output [#1595911] +- Improve handling of service principals [#1644311] +- [RFE] adcli command with --unix-* options doesn't update + values in UnixAttributes Tab for user [#1337489] +- [RFE] adcli join should preserve SPN added by adcli preset-computer [#1630187] +- [RFE] Need an option for adcli command which will show domain join status. [#1622583] + +* Wed Jan 16 2019 Sumit Bose - 0.8.1-7 +- use autosetup macro to simplify patch handling +- fixed rpmlint warnings in the spec file +- join failed if hostname is not FQDN [#1649868] * Tue Aug 14 2018 Sumit Bose - 0.8.1-6 - Couldn't set service principals on computer account [#1608212]