diff --git a/.gitignore b/.gitignore index 440751f..e6fcc1d 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ /adcli-0.9.0.tar.gz /adcli-0.9.1.tar.gz /adcli-0.9.2.tar.gz +/adcli-0.9.3.1.tar.gz diff --git a/0001-disco-Add-functions-to-extract-domain-GUID-from-LDAP.patch b/0001-disco-Add-functions-to-extract-domain-GUID-from-LDAP.patch deleted file mode 100644 index fab7322..0000000 --- a/0001-disco-Add-functions-to-extract-domain-GUID-from-LDAP.patch +++ /dev/null @@ -1,97 +0,0 @@ -From a4aa0d00f588ba24484db70aeb3bdafdf618c4f6 Mon Sep 17 00:00:00 2001 -From: Samuel Cabrero -Date: Thu, 31 Aug 2023 13:39:12 +0200 -Subject: [PATCH 01/17] disco: Add functions to extract domain GUID from LDAP - ping - -Signed-off-by: Samuel Cabrero ---- - library/addisco.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 72 insertions(+) - -diff --git a/library/addisco.c b/library/addisco.c -index b2c5553..ac073e5 100644 ---- a/library/addisco.c -+++ b/library/addisco.c -@@ -335,6 +335,78 @@ get_32_le (unsigned char **at, - return 1; - } - -+static int -+get_16_le (unsigned char **at, -+ unsigned char *end, -+ uint16_t *val) -+{ -+ unsigned char *p = *at; -+ if (end - p < 2) -+ return 0; -+ *val = p[0] | p[1] << 8; -+ (*at) += 2; -+ return 1; -+} -+ -+struct GUID { -+ uint32_t time_low; -+ uint16_t time_mid; -+ uint16_t time_hi_and_version; -+ uint8_t clock_seq[2]; -+ uint8_t node[6]; -+}; -+ -+/* Format is "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x" */ -+/* 32 chars + 4 ' ' + \0 + 2 for adding {} */ -+struct GUID_txt_buf { -+ char buf[39]; -+}; -+ -+static char *GUID_buf_string(const struct GUID *guid, -+ struct GUID_txt_buf *dst) -+{ -+ if (guid == NULL) { -+ return NULL; -+ } -+ snprintf(dst->buf, sizeof(dst->buf), -+ "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", -+ guid->time_low, guid->time_mid, -+ guid->time_hi_and_version, -+ guid->clock_seq[0], -+ guid->clock_seq[1], -+ guid->node[0], guid->node[1], -+ guid->node[2], guid->node[3], -+ guid->node[4], guid->node[5]); -+ return dst->buf; -+} -+ -+static int -+parse_guid (unsigned char **at, -+ unsigned char *end, -+ char **result) -+{ -+ struct GUID g = { 0 }; -+ struct GUID_txt_buf buf; -+ -+ if (end - (*at) < sizeof(struct GUID)) { -+ return 0; -+ } -+ -+ get_32_le(at, end, &g.time_low); -+ get_16_le(at, end, &g.time_mid); -+ get_16_le(at, end, &g.time_hi_and_version); -+ -+ memcpy(&g.clock_seq, *at, sizeof(g.clock_seq)); -+ (*at) += sizeof(g.clock_seq); -+ -+ memcpy(&g.node, *at, sizeof(g.node)); -+ (*at) += sizeof(g.node); -+ -+ *result = strdup(GUID_buf_string(&g, &buf)); -+ -+ return 1; -+} -+ - static int - skip_n (unsigned char **at, - unsigned char *end, --- -2.47.0 - diff --git a/0002-disco-Extract-domain-GUID-from-LDAP-ping.patch b/0002-disco-Extract-domain-GUID-from-LDAP-ping.patch deleted file mode 100644 index d91ce20..0000000 --- a/0002-disco-Extract-domain-GUID-from-LDAP-ping.patch +++ /dev/null @@ -1,65 +0,0 @@ -From f443691a420b37f84e5af04ffd8fd2e7e1e7be25 Mon Sep 17 00:00:00 2001 -From: Samuel Cabrero -Date: Thu, 31 Aug 2023 13:40:08 +0200 -Subject: [PATCH 02/17] disco: Extract domain GUID from LDAP ping - -Signed-off-by: Samuel Cabrero ---- - library/addisco.c | 14 ++------------ - library/addisco.h | 1 + - 2 files changed, 3 insertions(+), 12 deletions(-) - -diff --git a/library/addisco.c b/library/addisco.c -index ac073e5..7136f0e 100644 ---- a/library/addisco.c -+++ b/library/addisco.c -@@ -407,17 +407,6 @@ parse_guid (unsigned char **at, - return 1; - } - --static int --skip_n (unsigned char **at, -- unsigned char *end, -- int n) --{ -- if (end - (*at) < n) -- return 0; -- (*at) += n; -- return 1; --} -- - static adcli_disco * - parse_disco_data (struct berval *bv) - { -@@ -436,7 +425,7 @@ parse_disco_data (struct berval *bv) - /* domain forest */ - if (!get_32_le (&at, end, &type) || type != 23 || - !get_32_le (&at, end, &disco->flags) || -- !skip_n (&at, end, 16) || /* guid */ -+ !parse_guid (&at, end, &disco->domain_guid) || - !parse_disco_string (beg, end, &at, &disco->forest) || - !parse_disco_string (beg, end, &at, &disco->domain) || - !parse_disco_string (beg, end, &at, &disco->host_name) || -@@ -1077,6 +1066,7 @@ adcli_disco_free (adcli_disco *disco) - free (disco->host_addr); - free (disco->host_name); - free (disco->host_short); -+ free (disco->domain_guid); - free (disco->forest); - free (disco->domain); - free (disco->domain_short); -diff --git a/library/addisco.h b/library/addisco.h -index 718db7d..11a1464 100644 ---- a/library/addisco.h -+++ b/library/addisco.h -@@ -48,6 +48,7 @@ typedef struct _adcli_disco { - char *forest; - char *domain; - char *domain_short; -+ char *domain_guid; - char *host_name; - char *host_addr; - char *host_short; --- -2.47.0 - diff --git a/0003-conn-Copy-domain-GUID-from-disco.patch b/0003-conn-Copy-domain-GUID-from-disco.patch deleted file mode 100644 index 674eff7..0000000 --- a/0003-conn-Copy-domain-GUID-from-disco.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 396ba2b16136611334a87ac7d72ae29e53dc6808 Mon Sep 17 00:00:00 2001 -From: Samuel Cabrero -Date: Thu, 31 Aug 2023 13:43:47 +0200 -Subject: [PATCH 03/17] conn: Copy domain GUID from disco - -Signed-off-by: Samuel Cabrero ---- - library/adconn.c | 14 ++++++++++++++ - library/adconn.h | 2 ++ - 2 files changed, 16 insertions(+) - -diff --git a/library/adconn.c b/library/adconn.c -index 37405cc..f28ccba 100644 ---- a/library/adconn.c -+++ b/library/adconn.c -@@ -74,6 +74,7 @@ struct _adcli_conn_ctx { - char *canonical_host; - char *domain_short; - char *domain_sid; -+ char *domain_guid; - adcli_disco *domain_disco; - enum conn_is_writeable is_writeable; - char *default_naming_context; -@@ -164,6 +165,11 @@ disco_dance_if_necessary (adcli_conn *conn) - conn->domain_short = strdup (conn->domain_disco->domain_short); - return_if_fail (conn->domain_short != NULL); - } -+ -+ if (!conn->domain_guid && conn->domain_disco->domain_guid) { -+ conn->domain_guid = strdup(conn->domain_disco->domain_guid); -+ return_if_fail (conn->domain_guid != NULL); -+ } - } - } - -@@ -1313,6 +1319,7 @@ conn_free (adcli_conn *conn) - free (conn->domain_realm); - free (conn->domain_controller); - free (conn->domain_short); -+ free (conn->domain_guid); - free (conn->default_naming_context); - free (conn->configuration_naming_context); - _adcli_strv_free (conn->supported_capabilities); -@@ -1421,6 +1428,13 @@ adcli_conn_get_domain_name (adcli_conn *conn) - return conn->domain_name; - } - -+const char * -+adcli_conn_get_domain_guid(adcli_conn *conn) -+{ -+ return_val_if_fail (conn != NULL, NULL); -+ return conn->domain_guid; -+} -+ - void - adcli_conn_set_domain_name (adcli_conn *conn, - const char *value) -diff --git a/library/adconn.h b/library/adconn.h -index 3a3c32b..34b4c23 100644 ---- a/library/adconn.h -+++ b/library/adconn.h -@@ -104,6 +104,8 @@ const char * adcli_conn_get_domain_short (adcli_conn *conn); - - const char * adcli_conn_get_domain_sid (adcli_conn *conn); - -+const char * adcli_conn_get_domain_guid (adcli_conn *conn); -+ - LDAP * adcli_conn_get_ldap_connection (adcli_conn *conn); - - krb5_context adcli_conn_get_krb5_context (adcli_conn *conn); --- -2.47.0 - diff --git a/0004-conn-Copy-forest-name-from-disco.patch b/0004-conn-Copy-forest-name-from-disco.patch deleted file mode 100644 index 2611219..0000000 --- a/0004-conn-Copy-forest-name-from-disco.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 8c0d20d2f7d3eefa67f8d1c7d05fdc5680d7919c Mon Sep 17 00:00:00 2001 -From: Samuel Cabrero -Date: Thu, 31 Aug 2023 13:45:06 +0200 -Subject: [PATCH 04/17] conn: Copy forest name from disco - -Signed-off-by: Samuel Cabrero ---- - library/adconn.c | 14 ++++++++++++++ - library/adconn.h | 2 ++ - 2 files changed, 16 insertions(+) - -diff --git a/library/adconn.c b/library/adconn.c -index f28ccba..c714169 100644 ---- a/library/adconn.c -+++ b/library/adconn.c -@@ -75,6 +75,7 @@ struct _adcli_conn_ctx { - char *domain_short; - char *domain_sid; - char *domain_guid; -+ char *forest; - adcli_disco *domain_disco; - enum conn_is_writeable is_writeable; - char *default_naming_context; -@@ -166,6 +167,11 @@ disco_dance_if_necessary (adcli_conn *conn) - return_if_fail (conn->domain_short != NULL); - } - -+ if (!conn->forest && conn->domain_disco->forest) { -+ conn->forest = strdup(conn->domain_disco->forest); -+ return_if_fail (conn->forest != NULL); -+ } -+ - if (!conn->domain_guid && conn->domain_disco->domain_guid) { - conn->domain_guid = strdup(conn->domain_disco->domain_guid); - return_if_fail (conn->domain_guid != NULL); -@@ -1320,6 +1326,7 @@ conn_free (adcli_conn *conn) - free (conn->domain_controller); - free (conn->domain_short); - free (conn->domain_guid); -+ free (conn->forest); - free (conn->default_naming_context); - free (conn->configuration_naming_context); - _adcli_strv_free (conn->supported_capabilities); -@@ -1428,6 +1435,13 @@ adcli_conn_get_domain_name (adcli_conn *conn) - return conn->domain_name; - } - -+const char * -+adcli_conn_get_forest_name (adcli_conn *conn) -+{ -+ return_val_if_fail (conn != NULL, NULL); -+ return conn->forest; -+} -+ - const char * - adcli_conn_get_domain_guid(adcli_conn *conn) - { -diff --git a/library/adconn.h b/library/adconn.h -index 34b4c23..f377ea7 100644 ---- a/library/adconn.h -+++ b/library/adconn.h -@@ -83,6 +83,8 @@ void adcli_conn_set_host_fqdn (adcli_conn *conn, - - const char * adcli_conn_get_domain_name (adcli_conn *conn); - -+const char * adcli_conn_get_forest_name (adcli_conn *conn); -+ - void adcli_conn_set_domain_name (adcli_conn *conn, - const char *value); - --- -2.47.0 - diff --git a/0005-conn-Stop-as-soon-as-we-have-a-valid-LDAP-connection.patch b/0005-conn-Stop-as-soon-as-we-have-a-valid-LDAP-connection.patch deleted file mode 100644 index 1038314..0000000 --- a/0005-conn-Stop-as-soon-as-we-have-a-valid-LDAP-connection.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 04564d8295c42ad012f16570a16770f511b7fd16 Mon Sep 17 00:00:00 2001 -From: Samuel Cabrero -Date: Thu, 31 Aug 2023 17:56:24 +0200 -Subject: [PATCH 05/17] conn: Stop as soon as we have a valid LDAP connection - -No need to test all possible addresses. - -Signed-off-by: Samuel Cabrero ---- - library/adconn.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/library/adconn.c b/library/adconn.c -index c714169..77c09c4 100644 ---- a/library/adconn.c -+++ b/library/adconn.c -@@ -868,6 +868,7 @@ connect_to_address (const char *host, - break; - } - } -+ break; - } - } - --- -2.47.0 - diff --git a/0006-conn-Store-the-address-of-the-connected-server.patch b/0006-conn-Store-the-address-of-the-connected-server.patch deleted file mode 100644 index 1f46153..0000000 --- a/0006-conn-Store-the-address-of-the-connected-server.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 347c843807678135fb4a2c287bc35606d35ff626 Mon Sep 17 00:00:00 2001 -From: Samuel Cabrero -Date: Thu, 31 Aug 2023 14:56:54 +0200 -Subject: [PATCH 06/17] conn: Store the address of the connected server - -Signed-off-by: Samuel Cabrero ---- - library/adconn.c | 19 +++++++++++++++++-- - 1 file changed, 17 insertions(+), 2 deletions(-) - -diff --git a/library/adconn.c b/library/adconn.c -index 77c09c4..34b6fe1 100644 ---- a/library/adconn.c -+++ b/library/adconn.c -@@ -85,6 +85,7 @@ struct _adcli_conn_ctx { - - /* Connect state */ - LDAP *ldap; -+ struct sockaddr *addr; - int ldap_authenticated; - krb5_context k5; - krb5_ccache ccache; -@@ -792,7 +793,8 @@ int ldap_init_fd (ber_socket_t fd, int proto, LDAP_CONST char *url, struct ldap - static LDAP * - connect_to_address (const char *host, - const char *canonical_host, -- bool use_ldaps) -+ bool use_ldaps, -+ struct sockaddr **addr) - { - struct addrinfo *res = NULL; - struct addrinfo *ai; -@@ -875,6 +877,11 @@ connect_to_address (const char *host, - if (!ldap && error) - _adcli_err ("Couldn't connect to host: %s: %s", host, strerror (error)); - -+ *addr = malloc(sizeof(struct sockaddr)); -+ if (*addr != NULL) { -+ memcpy(*addr, ai->ai_addr, sizeof(struct sockaddr)); -+ } -+ - freeaddrinfo (res); - /* coverity[leaked_handle] - the socket is carried inside the ldap struct */ - return ldap; -@@ -888,6 +895,7 @@ connect_and_lookup_naming (adcli_conn *conn, - LDAPMessage *results; - adcli_result res; - LDAP *ldap; -+ struct sockaddr *addr; - int ret; - int ver; - -@@ -900,13 +908,15 @@ connect_and_lookup_naming (adcli_conn *conn, - }; - - assert (conn->ldap == NULL); -+ assert (conn->addr == NULL); - - canonical_host = disco->host_name; - if (!canonical_host) - canonical_host = disco->host_addr; - - ldap = connect_to_address (disco->host_addr, canonical_host, -- adcli_conn_get_use_ldaps (conn)); -+ adcli_conn_get_use_ldaps (conn), -+ &addr); - if (ldap == NULL) - return ADCLI_ERR_DIRECTORY; - -@@ -969,6 +979,7 @@ connect_and_lookup_naming (adcli_conn *conn, - } - - conn->ldap = ldap; -+ conn->addr = addr; - - free (conn->canonical_host); - conn->canonical_host = strdup (canonical_host); -@@ -1228,6 +1239,10 @@ conn_clear_state (adcli_conn *conn) - ldap_unbind_ext_s (conn->ldap, NULL, NULL); - conn->ldap = NULL; - -+ if (conn->addr) -+ free(conn->addr); -+ conn->addr = NULL; -+ - free (conn->canonical_host); - conn->canonical_host = NULL; - --- -2.47.0 - diff --git a/0007-conn-Allow-to-retrieve-the-connected-LDAP-address.patch b/0007-conn-Allow-to-retrieve-the-connected-LDAP-address.patch deleted file mode 100644 index 8c910ad..0000000 --- a/0007-conn-Allow-to-retrieve-the-connected-LDAP-address.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 77794bc757af097682f0aa9cf85c2208c478b6f1 Mon Sep 17 00:00:00 2001 -From: Samuel Cabrero -Date: Thu, 31 Aug 2023 17:11:55 +0200 -Subject: [PATCH 07/17] conn: Allow to retrieve the connected LDAP address - -Signed-off-by: Samuel Cabrero ---- - library/adconn.c | 7 +++++++ - library/adconn.h | 2 ++ - 2 files changed, 9 insertions(+) - -diff --git a/library/adconn.c b/library/adconn.c -index 34b6fe1..087225d 100644 ---- a/library/adconn.c -+++ b/library/adconn.c -@@ -1542,6 +1542,13 @@ adcli_conn_get_ldap_connection (adcli_conn *conn) - return conn->ldap; - } - -+struct sockaddr * -+adcli_conn_get_ldap_address (adcli_conn *conn) -+{ -+ return_val_if_fail (conn != NULL, NULL); -+ return conn->addr; -+} -+ - krb5_context - adcli_conn_get_krb5_context (adcli_conn *conn) - { -diff --git a/library/adconn.h b/library/adconn.h -index f377ea7..7c615df 100644 ---- a/library/adconn.h -+++ b/library/adconn.h -@@ -110,6 +110,8 @@ const char * adcli_conn_get_domain_guid (adcli_conn *conn); - - LDAP * adcli_conn_get_ldap_connection (adcli_conn *conn); - -+struct sockaddr * adcli_conn_get_ldap_address (adcli_conn *conn); -+ - krb5_context adcli_conn_get_krb5_context (adcli_conn *conn); - - void adcli_conn_set_krb5_context (adcli_conn *conn, --- -2.47.0 - diff --git a/0008-util-Allow-to-append-variables-to-external-program-e.patch b/0008-util-Allow-to-append-variables-to-external-program-e.patch deleted file mode 100644 index b623345..0000000 --- a/0008-util-Allow-to-append-variables-to-external-program-e.patch +++ /dev/null @@ -1,186 +0,0 @@ -From f4b3ede69824dd84456f252f0da2fe595874cb88 Mon Sep 17 00:00:00 2001 -From: Samuel Cabrero -Date: Wed, 6 Sep 2023 11:49:19 +0200 -Subject: [PATCH 08/17] util: Allow to append variables to external program - environment - -Signed-off-by: Samuel Cabrero ---- - library/adenroll.c | 4 +-- - library/adprivate.h | 1 + - library/adutil.c | 69 +++++++++++++++++++++++++++++++++++++++------ - 3 files changed, 64 insertions(+), 10 deletions(-) - -diff --git a/library/adenroll.c b/library/adenroll.c -index 5ae1215..72f1b6f 100644 ---- a/library/adenroll.c -+++ b/library/adenroll.c -@@ -2384,14 +2384,14 @@ update_samba_data (adcli_enroll *enroll) - _adcli_info ("Trying to set domain SID %s for Samba.", - argv_sid[2]); - ret = _adcli_call_external_program (argv_sid[0], argv_sid, -- NULL, NULL, NULL); -+ NULL, NULL, NULL, NULL); - if (ret != ADCLI_SUCCESS) { - _adcli_err ("Failed to set Samba domain SID."); - } - } - - _adcli_info ("Trying to set Samba secret."); -- ret = _adcli_call_external_program (argv_pw[0], argv_pw, -+ ret = _adcli_call_external_program (argv_pw[0], argv_pw, NULL, - enroll->computer_password, NULL, NULL); - if (ret != ADCLI_SUCCESS) { - _adcli_err ("Failed to set Samba computer account password."); -diff --git a/library/adprivate.h b/library/adprivate.h -index 822f919..bf0381c 100644 ---- a/library/adprivate.h -+++ b/library/adprivate.h -@@ -318,6 +318,7 @@ bool _adcli_check_nt_time_string_lifetime (const char *nt_time_strin - - adcli_result _adcli_call_external_program (const char *binary, - char * const *argv, -+ char * const *envp, - const char *stdin_data, - uint8_t **stdout_data, - size_t *stdout_data_len); -diff --git a/library/adutil.c b/library/adutil.c -index 4bb06a3..6a8e612 100644 ---- a/library/adutil.c -+++ b/library/adutil.c -@@ -551,7 +551,7 @@ _adcli_check_nt_time_string_lifetime (const char *nt_time_string, - - adcli_result - _adcli_call_external_program (const char *binary, char * const *argv, -- const char *stdin_data, -+ char * const *envp, const char *stdin_data, - uint8_t **stdout_data, size_t *stdout_data_len) - { - int ret; -@@ -565,6 +565,48 @@ _adcli_call_external_program (const char *binary, char * const *argv, - int status; - uint8_t read_buf[4096]; - uint8_t *out; -+ char **child_env = NULL; -+ size_t child_env_size = 0; -+ -+ /* prepare child environment, append envp to environ */ -+ if (envp != NULL) { -+ size_t environ_size = 0; -+ size_t envp_size = 0; -+ int i, j; -+ -+ for (i = 0; environ[i] != NULL; i++) { -+ environ_size++; -+ } -+ -+ for (i = 0; envp[i] != NULL; i++) { -+ envp_size++; -+ } -+ -+ child_env_size = environ_size + envp_size + 1; -+ child_env = calloc(child_env_size, sizeof(char *)); -+ if (child_env == NULL) { -+ _adcli_err("Failed to allocate memory."); -+ return ADCLI_ERR_FAIL; -+ } -+ -+ memset(child_env, 0, child_env_size); -+ -+ for (i = 0, j = 0; environ[i] != NULL; i++, j++) { -+ child_env[j] = strdup(environ[i]); -+ if (child_env[j] == NULL) { -+ _adcli_err("Failed to allocate memory."); -+ return ADCLI_ERR_FAIL; -+ } -+ } -+ -+ for (i = 0; envp[i] != NULL; i++, j++) { -+ child_env[j] = strdup(envp[i]); -+ if (child_env[j] == NULL) { -+ _adcli_err("Failed to allocate memory."); -+ return ADCLI_ERR_FAIL; -+ } -+ } -+ } - - errno = 0; - ret = access (binary, X_OK); -@@ -613,7 +655,11 @@ _adcli_call_external_program (const char *binary, char * const *argv, - exit (EXIT_FAILURE); - } - -- execv (binary, argv); -+ if (child_env != NULL) { -+ execve(binary, argv, child_env); -+ } else { -+ execv(binary, argv); -+ } - _adcli_err ("Failed to run %s.", binary); - ret = ADCLI_ERR_FAIL; - goto done; -@@ -672,6 +718,13 @@ _adcli_call_external_program (const char *binary, char * const *argv, - goto done; - } - -+ if (child_env != NULL) { -+ for (int i = 0; i < child_env_size; i++) { -+ free(child_env[i]); -+ } -+ free(child_env); -+ } -+ - ret = ADCLI_SUCCESS; - - done: -@@ -853,25 +906,25 @@ test_call_external_program (void) - size_t stdout_data_len; - - argv[0] = "/does/not/exists"; -- res = _adcli_call_external_program (argv[0], argv, NULL, NULL, NULL); -+ res = _adcli_call_external_program (argv[0], argv, NULL, NULL, NULL, NULL); - assert (res == ADCLI_ERR_FAIL); - - #ifdef BIN_CAT - argv[0] = BIN_CAT; -- res = _adcli_call_external_program (argv[0], argv, "Hello", -+ res = _adcli_call_external_program (argv[0], argv, NULL, "Hello", - &stdout_data, &stdout_data_len); - assert (res == ADCLI_SUCCESS); - assert (strncmp ("Hello", (char *) stdout_data, stdout_data_len) == 0); - free (stdout_data); - -- res = _adcli_call_external_program (argv[0], argv, "Hello", -+ res = _adcli_call_external_program (argv[0], argv, NULL, "Hello", - NULL, NULL); - assert (res == ADCLI_SUCCESS); - #endif - - #ifdef BIN_REV - argv[0] = BIN_REV; -- res = _adcli_call_external_program (argv[0], argv, "Hello\n", -+ res = _adcli_call_external_program (argv[0], argv, NULL, "Hello\n", - &stdout_data, &stdout_data_len); - assert (res == ADCLI_SUCCESS); - assert (strncmp ("olleH\n", (char *) stdout_data, stdout_data_len) == 0); -@@ -880,7 +933,7 @@ test_call_external_program (void) - - #ifdef BIN_TAC - argv[0] = BIN_TAC; -- res = _adcli_call_external_program (argv[0], argv, "Hello\nWorld\n", -+ res = _adcli_call_external_program (argv[0], argv, NULL, "Hello\nWorld\n", - &stdout_data, &stdout_data_len); - assert (res == ADCLI_SUCCESS); - assert (strncmp ("World\nHello\n", (char *) stdout_data, stdout_data_len) == 0); -@@ -890,7 +943,7 @@ test_call_external_program (void) - #ifdef BIN_ECHO - argv[0] = BIN_ECHO; - argv[1] = "Hello"; -- res = _adcli_call_external_program (argv[0], argv, NULL, -+ res = _adcli_call_external_program (argv[0], argv, NULL, NULL, - &stdout_data, &stdout_data_len); - assert (res == ADCLI_SUCCESS); - assert (strncmp ("Hello\n", (char *) stdout_data, stdout_data_len) == 0); --- -2.47.0 - diff --git a/0009-util-Flag-write-end-of-pipe-as-invalid-after-closing.patch b/0009-util-Flag-write-end-of-pipe-as-invalid-after-closing.patch deleted file mode 100644 index 1eef731..0000000 --- a/0009-util-Flag-write-end-of-pipe-as-invalid-after-closing.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 302d5ff3dd9d7d619da7cbf1a108d2168de1a630 Mon Sep 17 00:00:00 2001 -From: Samuel Cabrero -Date: Wed, 6 Sep 2023 12:05:03 +0200 -Subject: [PATCH 09/17] util: Flag write end of pipe as invalid after closing - it - -Signed-off-by: Samuel Cabrero ---- - library/adutil.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/library/adutil.c b/library/adutil.c -index 6a8e612..2947391 100644 ---- a/library/adutil.c -+++ b/library/adutil.c -@@ -679,7 +679,7 @@ _adcli_call_external_program (const char *binary, char * const *argv, - close (pipefd_to_child[0]); - pipefd_to_child[0] = -1; - close (pipefd_to_child[1]); -- pipefd_to_child[0] = -1; -+ pipefd_to_child[1] = -1; - - if (stdout_data != NULL || stdout_data_len != NULL) { - rlen = read (pipefd_from_child[0], read_buf, sizeof (read_buf)); --- -2.47.0 - diff --git a/0010-util-Return-failure-if-child-exit-status-reports-so.patch b/0010-util-Return-failure-if-child-exit-status-reports-so.patch deleted file mode 100644 index 797f0f9..0000000 --- a/0010-util-Return-failure-if-child-exit-status-reports-so.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 1d98352999e797f8f091064d0d3bd0627bccecb8 Mon Sep 17 00:00:00 2001 -From: Samuel Cabrero -Date: Wed, 6 Sep 2023 16:30:45 +0200 -Subject: [PATCH 10/17] util: Return failure if child exit status reports so - -Otherwise error string from stdout won't be printed. - -Signed-off-by: Samuel Cabrero ---- - library/adutil.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/library/adutil.c b/library/adutil.c -index 2947391..ea49607 100644 ---- a/library/adutil.c -+++ b/library/adutil.c -@@ -749,6 +749,7 @@ done: - if (WIFEXITED (status) && WEXITSTATUS (status) != 0) { - _adcli_err ("net command failed with %d.", - WEXITSTATUS (status)); -+ ret = ADCLI_ERR_FAIL; - } - } - } --- -2.47.0 - diff --git a/0011-enroll-Issue-a-warning-if-Samba-provision-was-reques.patch b/0011-enroll-Issue-a-warning-if-Samba-provision-was-reques.patch deleted file mode 100644 index 4fdc233..0000000 --- a/0011-enroll-Issue-a-warning-if-Samba-provision-was-reques.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 5a8b64a1647808d6649f82b2ea20331fcc7367f9 Mon Sep 17 00:00:00 2001 -From: Samuel Cabrero -Date: Wed, 6 Sep 2023 16:29:32 +0200 -Subject: [PATCH 11/17] enroll: Issue a warning if Samba provision was - requested but failed - -Signed-off-by: Samuel Cabrero ---- - library/adenroll.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/library/adenroll.c b/library/adenroll.c -index 72f1b6f..c5a85a5 100644 ---- a/library/adenroll.c -+++ b/library/adenroll.c -@@ -2618,9 +2618,9 @@ enroll_join_or_update_tasks (adcli_enroll *enroll, - if ( (flags & ADCLI_ENROLL_ADD_SAMBA_DATA) && ! (flags & ADCLI_ENROLL_PASSWORD_VALID)) { - res = update_samba_data (enroll); - if (res != ADCLI_SUCCESS) { -- _adcli_info ("Failed to add Samba specific data, smbd " -+ _adcli_warn ("Failed to add Samba specific data, smbd " - "or winbindd might not work as " -- "expected.\n"); -+ "expected."); - } - } - --- -2.47.0 - diff --git a/0012-enroll-Add-a-function-to-convert-an-IP-address-to-te.patch b/0012-enroll-Add-a-function-to-convert-an-IP-address-to-te.patch deleted file mode 100644 index 5d172ca..0000000 --- a/0012-enroll-Add-a-function-to-convert-an-IP-address-to-te.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 14a55c1f1f0195e9ada03457e252fafda37ba3f9 Mon Sep 17 00:00:00 2001 -From: Samuel Cabrero -Date: Wed, 6 Sep 2023 12:55:50 +0200 -Subject: [PATCH 12/17] enroll: Add a function to convert an IP address to text - -Signed-off-by: Samuel Cabrero ---- - library/adutil.c | 34 ++++++++++++++++++++++++++++++++++ - library/adutil.h | 5 +++++ - 2 files changed, 39 insertions(+) - -diff --git a/library/adutil.c b/library/adutil.c -index ea49607..36822e2 100644 ---- a/library/adutil.c -+++ b/library/adutil.c -@@ -38,6 +38,7 @@ - #include - #include - #include -+#include - - static adcli_message_func message_func = NULL; - static char last_error[2048] = { 0, }; -@@ -757,6 +758,39 @@ done: - return ret; - } - -+adcli_result -+adcli_sockaddr_to_string(struct sockaddr *sa, char *addr, size_t addr_len) -+{ -+ const char *p; -+ -+ if (sa == NULL) { -+ return ADCLI_ERR_FAIL; -+ } -+ -+ errno = 0; -+ switch (sa->sa_family) { -+ case AF_INET: -+ p = inet_ntop(AF_INET, -+ &(((struct sockaddr_in *)sa)->sin_addr), -+ addr, addr_len); -+ break; -+ case AF_INET6: -+ p = inet_ntop(AF_INET6, -+ &(((struct sockaddr_in6 *)sa)->sin6_addr), -+ addr, addr_len); -+ break; -+ default: -+ _adcli_err("Failed to get LDAP server address, unknown socket family"); -+ return ADCLI_ERR_FAIL; -+ } -+ -+ if (p == NULL) { -+ _adcli_err("Failed to convert LDAP server address: %s", strerror(errno)); -+ return ADCLI_ERR_FAIL; -+ } -+ -+ return ADCLI_SUCCESS; -+} - - #ifdef UTIL_TESTS - -diff --git a/library/adutil.h b/library/adutil.h -index a07c5da..27c0587 100644 ---- a/library/adutil.h -+++ b/library/adutil.h -@@ -26,6 +26,7 @@ - - #include - #include -+#include - - typedef enum { - /* Successful completion */ -@@ -91,4 +92,8 @@ void adcli_clear_last_error (void); - - const char * adcli_get_last_error (void); - -+adcli_result adcli_sockaddr_to_string (struct sockaddr *sa, -+ char *addr, -+ size_t addr_len); -+ - #endif /* ADUTIL_H_ */ --- -2.47.0 - diff --git a/0013-build-Check-for-NetComposeOfflineDomainJoin-in-samba.patch b/0013-build-Check-for-NetComposeOfflineDomainJoin-in-samba.patch deleted file mode 100644 index 38f2c7d..0000000 --- a/0013-build-Check-for-NetComposeOfflineDomainJoin-in-samba.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 1231fbdd894570afc0081ca6c36675b6e2581c7f Mon Sep 17 00:00:00 2001 -From: Samuel Cabrero -Date: Thu, 7 Sep 2023 10:13:38 +0200 -Subject: [PATCH 13/17] build: Check for NetComposeOfflineDomainJoin in samba's - netapi library - -Signed-off-by: Samuel Cabrero ---- - configure.ac | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/configure.ac b/configure.ac -index af62507..1912019 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -95,6 +95,12 @@ AC_CHECK_LIB(ldap, ldap_init_fd, [true], [ - AC_SUBST(LDAP_LIBS) - AC_SUBST(LDAP_CFLAGS) - -+# ------------------------------------------------------------------- -+# samba -+ -+AC_CHECK_LIB([netapi], [NetComposeOfflineDomainJoin], -+ [AC_DEFINE(SAMBA_NETAPI_HAS_COMPOSEODJ, 1, [Samba NetApi supports composeodj])]) -+ - # ------------------------------------------------------------------- - # resolv - --- -2.47.0 - diff --git a/0014-enroll-Populate-Samba-s-secrets-database-using-offli.patch b/0014-enroll-Populate-Samba-s-secrets-database-using-offli.patch deleted file mode 100644 index 6a85aaa..0000000 --- a/0014-enroll-Populate-Samba-s-secrets-database-using-offli.patch +++ /dev/null @@ -1,178 +0,0 @@ -From 573216f40efd8aa1bcbaf606cd89d3906e648acb Mon Sep 17 00:00:00 2001 -From: Samuel Cabrero -Date: Thu, 7 Sep 2023 10:19:29 +0200 -Subject: [PATCH 14/17] enroll: Populate Samba's secrets database using offline - domain join - -Signed-off-by: Samuel Cabrero ---- - library/adenroll.c | 146 +++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 146 insertions(+) - -diff --git a/library/adenroll.c b/library/adenroll.c -index c5a85a5..b6558ed 100644 ---- a/library/adenroll.c -+++ b/library/adenroll.c -@@ -2363,6 +2363,150 @@ update_keytab_for_principals (adcli_enroll *enroll, - return ADCLI_SUCCESS; - } - -+#if defined(SAMBA_NETAPI_HAS_COMPOSEODJ) -+ -+#define CHECK_SNPRINTF(x, v) \ -+ do { if ((x) < 0 || (x) >= sizeof((v))) { \ -+ _adcli_err ("%s: Insufficient buffer for %s", __func__, #v); \ -+ return ADCLI_ERR_FAIL; \ -+ } } while (0) -+ -+static adcli_result -+update_samba_data (adcli_enroll *enroll) -+{ -+ int ret; -+ char dns_domain_name[128]; -+ char netbios_domain_name[128]; -+ char domain_sid[128]; -+ char domain_guid[128]; -+ char forest_name[128]; -+ char machine_account_name[128]; -+ char dc_name[128]; -+ char dc_address[128]; -+ char ldap_address[INET6_ADDRSTRLEN]; -+ char *envp_composeodj[] = {"PASSWD_FD=0", NULL}; -+ char *argv_composeodj[] = { -+ NULL, -+ "offlinejoin", -+ "composeodj", -+ dns_domain_name, -+ netbios_domain_name, -+ domain_sid, -+ domain_guid, -+ forest_name, -+ machine_account_name, -+ dc_name, -+ dc_address, -+ "printblob", -+ NULL}; -+ char *argv_requestodj[] = { -+ NULL, -+ "offlinejoin", -+ "requestodj", -+ "-i", -+ NULL}; -+ uint8_t *compose_out_data = NULL; -+ size_t compose_out_data_len = 0; -+ uint8_t *request_out_data = NULL; -+ size_t request_out_data_len = 0; -+ -+ argv_composeodj[0] = (char *)adcli_enroll_get_samba_data_tool(enroll); -+ if (argv_composeodj[0] == NULL) { -+ _adcli_err("Samba data tool not available."); -+ return ADCLI_ERR_FAIL; -+ } -+ argv_requestodj[0] = argv_composeodj[0]; -+ -+ ret = adcli_sockaddr_to_string(adcli_conn_get_ldap_address(enroll->conn), -+ ldap_address, sizeof(ldap_address)); -+ if (ret != ADCLI_SUCCESS) { -+ return ret; -+ } -+ -+ ret = snprintf(dns_domain_name, sizeof(dns_domain_name), "--realm=%s", -+ adcli_conn_get_domain_name(enroll->conn)); -+ CHECK_SNPRINTF(ret, dns_domain_name); -+ -+ ret = snprintf(netbios_domain_name, sizeof(netbios_domain_name), -+ "--workgroup=%s", adcli_conn_get_domain_short(enroll->conn)); -+ CHECK_SNPRINTF(ret, netbios_domain_name); -+ -+ ret = snprintf(domain_sid, sizeof(domain_sid), "domain_sid=%s", -+ adcli_conn_get_domain_sid(enroll->conn)); -+ CHECK_SNPRINTF(ret, domain_sid); -+ -+ ret = snprintf(domain_guid, sizeof(domain_guid), "domain_guid=%s", -+ adcli_conn_get_domain_guid(enroll->conn)); -+ CHECK_SNPRINTF(ret, domain_guid); -+ -+ ret = snprintf(forest_name, sizeof(forest_name), "forest_name=%s", -+ adcli_conn_get_forest_name(enroll->conn)); -+ CHECK_SNPRINTF(ret, forest_name); -+ -+ ret = snprintf(machine_account_name, sizeof(machine_account_name), -+ "--user=%s", enroll->computer_sam); -+ CHECK_SNPRINTF(ret, machine_account_name); -+ -+ ret = snprintf(dc_name, sizeof(dc_name), "--server=%s", -+ adcli_conn_get_domain_controller(enroll->conn)); -+ CHECK_SNPRINTF(ret, dc_name); -+ -+ ret = snprintf(dc_address, sizeof(dc_address), "--ipaddress=%s", -+ ldap_address); -+ CHECK_SNPRINTF(ret, dc_address); -+ -+ _adcli_info("Trying to compose Samba ODJ blob."); -+ ret = _adcli_call_external_program(argv_composeodj[0], -+ argv_composeodj, envp_composeodj, -+ enroll->computer_password, -+ &compose_out_data, &compose_out_data_len); -+ if (ret != ADCLI_SUCCESS) { -+ while (compose_out_data && compose_out_data_len > 0 && -+ compose_out_data[compose_out_data_len - 1] == '\n') { -+ compose_out_data_len--; -+ } -+ _adcli_err("Failed to compose Samba ODJ blob: %.*s", -+ (int)compose_out_data_len, (char *)compose_out_data); -+ goto out; -+ } -+ -+ if (compose_out_data == NULL || compose_out_data_len == 0) { -+ _adcli_err("Failed to compose ODJ blob, no data returned."); -+ ret = ADCLI_ERR_FAIL; -+ goto out; -+ } -+ -+ _adcli_info("Trying to request Samba ODJ."); -+ ret = _adcli_call_external_program(argv_requestodj[0], -+ argv_requestodj, NULL, -+ (const char *)compose_out_data, -+ &request_out_data, &request_out_data_len); -+ if (ret != ADCLI_SUCCESS) { -+ while (request_out_data && request_out_data_len > 0 && -+ request_out_data[request_out_data_len - 1] == '\n') { -+ request_out_data_len--; -+ } -+ _adcli_err("Failed to request Samba ODJ: %.*s", -+ (int)request_out_data_len, request_out_data); -+ goto out; -+ } -+ -+ ret = ADCLI_SUCCESS; -+out: -+ if (compose_out_data != NULL) { -+ /* Burn memory, the blob contains the machine password */ -+ memset(compose_out_data, 0, compose_out_data_len); -+ free(compose_out_data); -+ } -+ if (request_out_data != NULL) { -+ free(request_out_data); -+ } -+ -+ return ret; -+} -+ -+#else /* defined(SAMBA_NETAPI_HAS_COMPOSEODJ) */ -+ - static adcli_result - update_samba_data (adcli_enroll *enroll) - { -@@ -2400,6 +2544,8 @@ update_samba_data (adcli_enroll *enroll) - return ret; - } - -+#endif -+ - static void - enroll_clear_state (adcli_enroll *enroll) - { --- -2.47.0 - diff --git a/0015-doc-improve-some-Samba-related-doc-items.patch b/0015-doc-improve-some-Samba-related-doc-items.patch deleted file mode 100644 index 3bdb610..0000000 --- a/0015-doc-improve-some-Samba-related-doc-items.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 954a0bd085ae9e62fc33405d190484f88cc18a93 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 5 Nov 2024 11:42:20 +0100 -Subject: [PATCH 15/17] doc: improve some Samba related doc items - ---- - doc/adcli-devel.xml | 9 +++++++-- - doc/adcli.xml | 10 ++++++---- - 2 files changed, 13 insertions(+), 6 deletions(-) - -diff --git a/doc/adcli-devel.xml b/doc/adcli-devel.xml -index 0f1f4ad..ef51ba0 100644 ---- a/doc/adcli-devel.xml -+++ b/doc/adcli-devel.xml -@@ -43,12 +43,17 @@ - MIT Kerberos libraries - - -+ If Samba's offline join feature should be used the -+ libnetapi development package should be install as well -+ so that configure can detect if the used Samba version -+ already supports offline joins. -+ - On Debian or Ubuntu you can use the following command to - install the dependencies: - - - $ sudo apt-get install build-essential autoconf automake xmlto xsltproc \ -- libkrb5-dev libldap2-dev libsasl2-dev -+ libkrb5-dev libldap2-dev libsasl2-dev samba-dev - - - On Fedora you can use the following command to install the -@@ -57,7 +62,7 @@ $ sudo apt-get install build-essential autoconf automake xmlto xsltproc \ - - $ sudo yum groupinstall "Development Tools" - $ sudo yum install automake autoconf xmlto xsltproc krb5-devel openldap-devel \ -- cyrus-sasl-devel -+ cyrus-sasl-devel libnetapi-devel - - - -diff --git a/doc/adcli.xml b/doc/adcli.xml -index 93e1520..7f65f06 100644 ---- a/doc/adcli.xml -+++ b/doc/adcli.xml -@@ -413,8 +413,9 @@ Password for Administrator: - Please note that Samba's net - requires some settings in smb.conf - to create the database entries correctly. Most -- important here is currently the -- option, see -+ important here are currently the -+ , and -+ options, see - smb.conf5 - for details. - -@@ -615,8 +616,9 @@ $ adcli update --login-ccache=/tmp/krbcc_123 - Please note that Samba's net - requires some settings in smb.conf - to create the database entries correctly. Most -- important here is currently the -- option, see -+ important here are currently the -+ , and -+ options, see - smb.conf5 - for details. - Note that if the machine account password is not --- -2.47.0 - diff --git a/0016-Various-fixes-for-issues-found-by-static-code-scanne.patch b/0016-Various-fixes-for-issues-found-by-static-code-scanne.patch deleted file mode 100644 index dd60edc..0000000 --- a/0016-Various-fixes-for-issues-found-by-static-code-scanne.patch +++ /dev/null @@ -1,198 +0,0 @@ -From fab13daeaf23cc4a26b10cfe0c3d7ac469a9da76 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 5 Nov 2024 14:22:47 +0100 -Subject: [PATCH 16/17] Various fixes for issues found by static code scanners - ---- - library/adconn.c | 17 ++++++++++++----- - library/adenroll.c | 4 ++-- - library/adutil.c | 2 +- - library/seq.c | 13 +++++++++---- - library/seq.h | 3 ++- - tools/tools.c | 24 +++++++++++++++++------- - 6 files changed, 43 insertions(+), 20 deletions(-) - -diff --git a/library/adconn.c b/library/adconn.c -index 087225d..e668b8d 100644 ---- a/library/adconn.c -+++ b/library/adconn.c -@@ -402,9 +402,9 @@ clear_krb5_conf_snippet (adcli_conn *conn) - static adcli_result - setup_krb5_conf_snippet (adcli_conn *conn) - { -- char *filename; -- char *snippet; -- char *controller; -+ char *filename = NULL; -+ char *snippet = NULL; -+ char *controller = NULL; - int errn; - int ret; - int fd; -@@ -429,7 +429,10 @@ setup_krb5_conf_snippet (adcli_conn *conn) - controller = strdup (conn->domain_controller); - } - -- return_unexpected_if_fail (controller != NULL); -+ if (controller == NULL) { -+ free (filename); -+ return_unexpected_if_reached (); -+ } - - if (asprintf (&snippet, "[realms]\n" - " %s = {\n" -@@ -442,8 +445,11 @@ setup_krb5_conf_snippet (adcli_conn *conn) - " %s = %s\n", - conn->domain_realm, controller, controller, controller, - conn->canonical_host, conn->domain_realm, -- conn->domain_controller, conn->domain_realm) < 0) -+ conn->domain_controller, conn->domain_realm) < 0) { -+ free (controller); -+ free (filename); - return_unexpected_if_reached (); -+ } - - old_mask = umask (0177); - fd = mkstemp (filename); -@@ -451,6 +457,7 @@ setup_krb5_conf_snippet (adcli_conn *conn) - if (fd < 0) { - _adcli_warn ("Couldn't create krb5.conf snippet file in: %s: %s", - conn->krb5_conf_dir, strerror (errno)); -+ free (filename); - - } else { - conn->krb5_conf_snippet = filename; -diff --git a/library/adenroll.c b/library/adenroll.c -index b6558ed..e978f46 100644 ---- a/library/adenroll.c -+++ b/library/adenroll.c -@@ -2340,9 +2340,9 @@ update_keytab_for_principals (adcli_enroll *enroll, - - for (i = 0; enroll->keytab_principals[i] != 0; i++) { - if (krb5_unparse_name (k5, enroll->keytab_principals[i], &name) != 0) -- name = ""; -+ name = NULL; - res = add_principal_to_keytab (enroll, k5, enroll->keytab_principals[i], -- name, &which_salt, flags); -+ name != NULL ? name : "", &which_salt, flags); - krb5_free_unparsed_name (k5, name); - - if (res != ADCLI_SUCCESS) -diff --git a/library/adutil.c b/library/adutil.c -index 36822e2..a112ad8 100644 ---- a/library/adutil.c -+++ b/library/adutil.c -@@ -169,7 +169,7 @@ _adcli_strv_dup (char **strv) - return NULL; - - count = seq_count (strv); -- return seq_dup (strv, &count, (seq_copy)strdup); -+ return seq_dup (strv, &count, (seq_copy)strdup, (seq_destroy)free); - } - - char * -diff --git a/library/seq.c b/library/seq.c -index 8e7475d..5410918 100644 ---- a/library/seq.c -+++ b/library/seq.c -@@ -299,7 +299,8 @@ seq_lookup (seq_voidp sequence, - void * - seq_dup (seq_voidp sequence, - int *length, -- seq_copy copy) -+ seq_copy copy, -+ seq_destroy destroy) - { - void **seq = sequence; - void **copied; -@@ -308,6 +309,7 @@ seq_dup (seq_voidp sequence, - int at; - - assert (length != NULL); -+ assert ( (copy != NULL && destroy != NULL) || (copy == NULL && destroy == NULL) ); - - len = *length; - alloc = alloc_size (len + 1); -@@ -321,7 +323,10 @@ seq_dup (seq_voidp sequence, - copied[at] = seq[at]; - } else { - copied[at] = copy (seq[at]); -- bail_on_null (copied[at]); -+ if (copied[at] == NULL) { -+ destroy (copied); -+ return NULL; -+ } - } - } - -@@ -707,7 +712,7 @@ test_dup (void) - seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, NULL); - seq = seq_insert (seq, &len, "1", (seq_compar)strcmp, NULL); - -- dup = seq_dup (seq, &len, NULL); -+ dup = seq_dup (seq, &len, NULL, NULL); - assert (dup != NULL); - - assert_str_eq (dup[0], "1"); -@@ -734,7 +739,7 @@ test_dup_deep (void) - seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, NULL); - seq = seq_insert (seq, &len, "1", (seq_compar)strcmp, NULL); - -- dup = seq_dup (seq, &len, (seq_copy)strdup); -+ dup = seq_dup (seq, &len, (seq_copy)strdup, (seq_destroy)free); - assert (dup != NULL); - - assert_str_eq (dup[0], "1"); -diff --git a/library/seq.h b/library/seq.h -index 5d48848..3fec747 100644 ---- a/library/seq.h -+++ b/library/seq.h -@@ -89,7 +89,8 @@ int seq_count (seq_voidp seq); - - seq_voidp seq_dup (seq_voidp seq, - int *length, -- seq_copy copy); -+ seq_copy copy, -+ seq_destroy destroy); - - void seq_free (seq_voidp seq, - seq_destroy destroy); -diff --git a/tools/tools.c b/tools/tools.c -index 7e382ae..444485c 100644 ---- a/tools/tools.c -+++ b/tools/tools.c -@@ -399,14 +399,24 @@ setup_krb5_conf_directory (adcli_conn *conn) - 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) { -+ if (asprintf (&filename, "%s/krb5.conf", directory) < 0) { -+ warnx ("unexpected: out of memory"); -+ failed = 1; -+ } -+ if (!failed && asprintf (&snippets, "%s/krb5.d", directory) < 0) { -+ free (filename); -+ filename = NULL; -+ warnx ("unexpected: out of memory"); -+ failed = 1; -+ } -+ if (!failed && asprintf (&contents, "includedir %s\n%s%s\n", snippets, -+ krb5_conf ? "include " : "", -+ krb5_conf ? krb5_conf : "") < 0) { -+ free (snippets); -+ snippets = NULL; -+ free (filename); -+ filename = NULL; - warnx ("unexpected: out of memory"); -- filename = NULL; /* content is undefined */ -- snippets = NULL; /* content is undefined */ - contents = NULL; /* content is undefined */ - failed = 1; - } --- -2.47.0 - diff --git a/0017-krb5-add-adcli_krb5_get_error_message.patch b/0017-krb5-add-adcli_krb5_get_error_message.patch deleted file mode 100644 index 0c5ba40..0000000 --- a/0017-krb5-add-adcli_krb5_get_error_message.patch +++ /dev/null @@ -1,226 +0,0 @@ -From d3db46e8b03f0f2db0df01466b597fde588a06bf Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 5 Nov 2024 19:00:54 +0100 -Subject: [PATCH 17/17] krb5: add adcli_krb5_get_error_message() - -The krb5_get_error_message() call returns an error message in an -allocated string which must be freed. This makes it hard to simply use -krb5_get_error_message() in a printf() argument list. -adcli_krb5_get_error_message() used a static memory area to make the -usage more easy. ---- - library/adconn.c | 10 +++++----- - library/adenroll.c | 18 +++++++++--------- - library/adentry.c | 2 +- - library/adkrb5.c | 22 +++++++++++++++++++--- - library/adprivate.h | 2 ++ - 5 files changed, 36 insertions(+), 18 deletions(-) - -diff --git a/library/adconn.c b/library/adconn.c -index e668b8d..2c94af9 100644 ---- a/library/adconn.c -+++ b/library/adconn.c -@@ -367,20 +367,20 @@ handle_kinit_krb5_code (adcli_conn *conn, - code == KRB5_PREAUTH_FAILED) { - if (type == ADCLI_LOGIN_COMPUTER_ACCOUNT) { - _adcli_err ("Couldn't authenticate as machine account: %s: %s", -- name, krb5_get_error_message (conn->k5, code)); -+ name, adcli_krb5_get_error_message (conn->k5, code)); - } else { - _adcli_err ("Couldn't authenticate as: %s: %s", -- name, krb5_get_error_message (conn->k5, code)); -+ name, adcli_krb5_get_error_message (conn->k5, code)); - } - return ADCLI_ERR_CREDENTIALS; - - } else { - if (type == ADCLI_LOGIN_COMPUTER_ACCOUNT) { - _adcli_err ("Couldn't get kerberos ticket for machine account: %s: %s", -- name, krb5_get_error_message (conn->k5, code)); -+ name, adcli_krb5_get_error_message (conn->k5, code)); - } else { - _adcli_err ("Couldn't get kerberos ticket for: %s: %s", -- name, krb5_get_error_message (conn->k5, code)); -+ name, adcli_krb5_get_error_message (conn->k5, code)); - } - return ADCLI_ERR_DIRECTORY; - } -@@ -726,7 +726,7 @@ prep_kerberos_and_kinit (adcli_conn *conn) - - if (code != 0) { - _adcli_err ("Couldn't open kerberos credential cache: %s: %s", -- conn->login_ccache_name, krb5_get_error_message (NULL, code)); -+ conn->login_ccache_name, adcli_krb5_get_error_message (NULL, code)); - return ADCLI_ERR_CONFIG; - } - } -diff --git a/library/adenroll.c b/library/adenroll.c -index e978f46..c854c9e 100644 ---- a/library/adenroll.c -+++ b/library/adenroll.c -@@ -549,7 +549,7 @@ ensure_keytab_principals (adcli_result res, - if (code != 0) { - _adcli_err ("Couldn't parse kerberos user principal: %s: %s", - enroll->user_principal, -- krb5_get_error_message (k5, code)); -+ adcli_krb5_get_error_message (k5, code)); - return ADCLI_ERR_CONFIG; - } - } -@@ -1523,7 +1523,7 @@ set_password_with_user_creds (adcli_enroll *enroll) - if (code != 0) { - _adcli_err ("Couldn't set password for %s account: %s: %s", - s_or_c (enroll), -- enroll->computer_sam, krb5_get_error_message (k5, code)); -+ enroll->computer_sam, adcli_krb5_get_error_message (k5, code)); - /* TODO: Parse out these values */ - res = ADCLI_ERR_DIRECTORY; - -@@ -1584,7 +1584,7 @@ set_password_with_computer_creds (adcli_enroll *enroll) - if (code != 0) { - _adcli_err ("Couldn't get change password ticket for %s account: %s: %s", - s_or_c (enroll), -- enroll->computer_sam, krb5_get_error_message (k5, code)); -+ enroll->computer_sam, adcli_krb5_get_error_message (k5, code)); - return ADCLI_ERR_DIRECTORY; - } - -@@ -1596,7 +1596,7 @@ set_password_with_computer_creds (adcli_enroll *enroll) - if (code != 0) { - _adcli_err ("Couldn't change password for %s account: %s: %s", - s_or_c (enroll), -- enroll->computer_sam, krb5_get_error_message (k5, code)); -+ enroll->computer_sam, adcli_krb5_get_error_message (k5, code)); - /* TODO: Parse out these values */ - res = ADCLI_ERR_DIRECTORY; - -@@ -2113,7 +2113,7 @@ load_host_keytab (adcli_enroll *enroll) - code = _adcli_krb5_keytab_enumerate (k5, keytab, load_keytab_entry, enroll); - if (code != 0) { - _adcli_err ("Couldn't enumerate keytab: %s: %s", -- enroll->keytab_name, krb5_get_error_message (k5, code)); -+ enroll->keytab_name, adcli_krb5_get_error_message (k5, code)); - res = ADCLI_ERR_FAIL; - } - krb5_kt_close (k5, keytab); -@@ -2225,7 +2225,7 @@ remove_principal_from_keytab (adcli_enroll *enroll, - - if (code != 0) { - _adcli_err ("Couldn't update keytab: %s: %s", -- enroll->keytab_name, krb5_get_error_message (k5, code)); -+ enroll->keytab_name, adcli_krb5_get_error_message (k5, code)); - return ADCLI_ERR_FAIL; - } - -@@ -2257,7 +2257,7 @@ add_principal_to_keytab (adcli_enroll *enroll, - - if (code != 0) { - _adcli_err ("Couldn't update keytab: %s: %s", -- enroll->keytab_name, krb5_get_error_message (k5, code)); -+ enroll->keytab_name, adcli_krb5_get_error_message (k5, code)); - return ADCLI_ERR_FAIL; - } - -@@ -2296,7 +2296,7 @@ add_principal_to_keytab (adcli_enroll *enroll, - enctypes, salts, which_salt); - if (code != 0) { - _adcli_warn ("Couldn't authenticate with keytab while discovering which salt to use: %s: %s", -- principal_name, krb5_get_error_message (k5, code)); -+ principal_name, adcli_krb5_get_error_message (k5, code)); - *which_salt = DEFAULT_SALT; - } else { - assert (*which_salt >= 0); -@@ -2313,7 +2313,7 @@ add_principal_to_keytab (adcli_enroll *enroll, - - if (code != 0) { - _adcli_err ("Couldn't add keytab entries: %s: %s", -- enroll->keytab_name, krb5_get_error_message (k5, code)); -+ enroll->keytab_name, adcli_krb5_get_error_message (k5, code)); - return ADCLI_ERR_FAIL; - } - -diff --git a/library/adentry.c b/library/adentry.c -index 0d9b9af..38ec7ca 100644 ---- a/library/adentry.c -+++ b/library/adentry.c -@@ -515,7 +515,7 @@ adcli_entry_set_passwd (adcli_entry *entry, const char *user_pwd) - if (code != 0) { - _adcli_err ("Couldn't set password for %s account: %s: %s", - entry->object_class, -- entry->sam_name, krb5_get_error_message (k5, code)); -+ entry->sam_name, adcli_krb5_get_error_message (k5, code)); - /* TODO: Parse out these values */ - res = ADCLI_ERR_DIRECTORY; - -diff --git a/library/adkrb5.c b/library/adkrb5.c -index be3ede5..7a9ee8f 100644 ---- a/library/adkrb5.c -+++ b/library/adkrb5.c -@@ -33,6 +33,7 @@ - #include - #include - #include -+#include - - krb5_error_code - _adcli_krb5_build_principal (krb5_context k5, -@@ -174,7 +175,7 @@ _adcli_krb5_init_context (krb5_context *k5) - - } else if (code != 0) { - _adcli_err ("Failed to create kerberos context: %s", -- krb5_get_error_message (NULL, code)); -+ adcli_krb5_get_error_message (NULL, code)); - return ADCLI_ERR_UNEXPECTED; - } - -@@ -192,7 +193,7 @@ _adcli_krb5_open_keytab (krb5_context k5, - code = krb5_kt_resolve (k5, keytab_name, keytab); - if (code != 0) { - _adcli_err ("Failed to open keytab: %s: %s", -- keytab_name, krb5_get_error_message (k5, code)); -+ keytab_name, adcli_krb5_get_error_message (k5, code)); - return ADCLI_ERR_FAIL; - } - -@@ -200,7 +201,7 @@ _adcli_krb5_open_keytab (krb5_context k5, - code = krb5_kt_default (k5, keytab); - if (code != 0) { - _adcli_err ("Failed to open default keytab: %s", -- krb5_get_error_message (k5, code)); -+ adcli_krb5_get_error_message (k5, code)); - return ADCLI_ERR_FAIL; - } - } -@@ -570,3 +571,18 @@ _adcli_krb5_format_enctypes (krb5_enctype *enctypes) - - return value; - } -+ -+const char *adcli_krb5_get_error_message (krb5_context ctx, krb5_error_code code) -+{ -+ static char out[4096]; -+ const char *tmp; -+ size_t len; -+ -+ tmp = krb5_get_error_message (ctx, code); -+ len = strlen (tmp); -+ memcpy (out, tmp, MIN (sizeof (out), len)); -+ out[sizeof(out) - 1] = '\0'; -+ krb5_free_error_message (ctx, tmp); -+ -+ return out; -+} -diff --git a/library/adprivate.h b/library/adprivate.h -index bf0381c..cca58f9 100644 ---- a/library/adprivate.h -+++ b/library/adprivate.h -@@ -323,4 +323,6 @@ adcli_result _adcli_call_external_program (const char *binary, - uint8_t **stdout_data, - size_t *stdout_data_len); - -+const char *adcli_krb5_get_error_message (krb5_context ctx, -+ krb5_error_code code); - #endif /* ADPRIVATE_H_ */ --- -2.47.0 - diff --git a/adcli.spec b/adcli.spec index 1ce90e3..475a660 100644 --- a/adcli.spec +++ b/adcli.spec @@ -1,31 +1,14 @@ +%global with_selinux 1 +%global selinuxtype targeted +%global modulename adcli + Name: adcli -Version: 0.9.2 -Release: 10%{?dist} +Version: 0.9.3.1 +Release: 1%{?dist} Summary: Active Directory enrollment License: LGPL-2.1-or-later URL: https://gitlab.freedesktop.org/realmd/adcli -Source0: https://gitlab.freedesktop.org/realmd/adcli/uploads/ea560656ac921b3fe0d455976aaae9be/adcli-%{version}.tar.gz - -# Add support for Samba's offline join feature -Patch1: 0001-disco-Add-functions-to-extract-domain-GUID-from-LDAP.patch -Patch2: 0002-disco-Extract-domain-GUID-from-LDAP-ping.patch -Patch3: 0003-conn-Copy-domain-GUID-from-disco.patch -Patch4: 0004-conn-Copy-forest-name-from-disco.patch -Patch5: 0005-conn-Stop-as-soon-as-we-have-a-valid-LDAP-connection.patch -Patch6: 0006-conn-Store-the-address-of-the-connected-server.patch -Patch7: 0007-conn-Allow-to-retrieve-the-connected-LDAP-address.patch -Patch8: 0008-util-Allow-to-append-variables-to-external-program-e.patch -Patch9: 0009-util-Flag-write-end-of-pipe-as-invalid-after-closing.patch -Patch10: 0010-util-Return-failure-if-child-exit-status-reports-so.patch -Patch11: 0011-enroll-Issue-a-warning-if-Samba-provision-was-reques.patch -Patch12: 0012-enroll-Add-a-function-to-convert-an-IP-address-to-te.patch -Patch13: 0013-build-Check-for-NetComposeOfflineDomainJoin-in-samba.patch -Patch14: 0014-enroll-Populate-Samba-s-secrets-database-using-offli.patch -Patch15: 0015-doc-improve-some-Samba-related-doc-items.patch - -# fixes for issues found by static analyser -Patch16: 0016-Various-fixes-for-issues-found-by-static-code-scanne.patch -Patch17: 0017-krb5-add-adcli_krb5_get_error_message.patch +Source0: https://gitlab.freedesktop.org/-/project/1196/uploads/5a1c55410c0965835b81fbd28d820d46/adcli-%{version}.tar.gz BuildRequires: gcc BuildRequires: intltool pkgconfig @@ -38,6 +21,12 @@ BuildRequires: xmlto BuildRequires: make BuildRequires: libnetapi-devel +# Build dependencies for SELinux policy +%if %{with selinux} +BuildRequires: libselinux-devel +BuildRequires: selinux-policy-devel +%endif + Requires: cyrus-sasl-gssapi Conflicts: adcli-doc < %{version}-%{release} @@ -45,10 +34,31 @@ Conflicts: adcli-doc < %{version}-%{release} # the adcli tool itself is to be used by callers Obsoletes: adcli-devel < 0.5 +%if %{with selinux} +# This ensures that the *-selinux package and all it’s dependencies are not +# pulled into containers and other systems that do not use SELinux. The +# policy defines types and file contexts for client and server. +Requires: (%{name}-selinux if selinux-policy-%{selinuxtype}) +%endif + %description adcli is a tool for joining an Active Directory domain using standard LDAP and Kerberos calls. +%if %{with selinux} +# SELinux subpackage +%package selinux +Summary: The adcli SELinux policy +BuildArch: noarch +Requires: selinux-policy-%{selinuxtype} +Requires(post): selinux-policy-%{selinuxtype} +%{?selinux_requires} + +%description selinux +Custom SELinux policy module for adcli to make sure generated Kerberos keytab +files have the right SELinux context. +%endif + %define _hardened_build 1 %prep @@ -72,13 +82,32 @@ find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' %ldconfig_scriptlets +%if %{with selinux} +# SELinux contexts are saved so that only affected files can be +# relabeled after the policy module installation +%pre selinux +%selinux_relabel_pre -s %{selinuxtype} + +%post selinux +%selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp + +%postun selinux +if [ $1 -eq 0 ]; then + %selinux_modules_uninstall -s %{selinuxtype} %{modulename} +fi + +%posttrans selinux +%selinux_relabel_post -s %{selinuxtype} + +%endif + %files %{_sbindir}/adcli %doc AUTHORS COPYING ChangeLog NEWS README %doc %{_mandir}/*/* %package doc -Summary: adcli documentation +Summary: The adcli documentation package BuildArch: noarch Conflicts: adcli < %{version}-%{release} @@ -90,7 +119,16 @@ documentation. %files doc %doc %{_datadir}/doc/adcli/* +%if %{with selinux} +%files selinux +%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp +%ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename} +%endif + %changelog +* Tue Dec 09 2025 Sumit Bose - 0.9.3.1-1 +- Rebase to latest upstream version + * Wed Jul 23 2025 Fedora Release Engineering - 0.9.2-10 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild diff --git a/sources b/sources index 1dd0180..aa241fa 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (adcli-0.9.2.tar.gz) = 0953ffb940b9abdf6277731b3fa14656b9af5686902f1b8c44389c2537e6c33db5b5272061964cf60fd6a7831e581c5362bff89d0adddc9b17059ed3a30e3971 +SHA512 (adcli-0.9.3.1.tar.gz) = 3f501173b5344b38f33a3f65faec9e894da81b44b37bb161da103d8a29459d8807dfe566a5dd0a8c7eec466567b6cca4331c81dd70158b5478a61b03be37355d