Hello community, here is the log from the commit of package adcli for openSUSE:Leap:15.2 checked in at 2020-03-13 10:55:46 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Leap:15.2/adcli (Old) and /work/SRC/openSUSE:Leap:15.2/.adcli.new.3160 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "adcli" Fri Mar 13 10:55:46 2020 rev:4 rq:783336 version:0.8.2 Changes: -------- --- /work/SRC/openSUSE:Leap:15.2/adcli/adcli.changes 2020-01-19 15:46:59.825685221 +0100 +++ /work/SRC/openSUSE:Leap:15.2/.adcli.new.3160/adcli.changes 2020-03-13 10:55:48.832367887 +0100 @@ -1,0 +2,22 @@ +Mon Mar 9 13:55:37 UTC 2020 - Samuel Cabrero <[email protected]> + +- Update samba secrets database after changing the machine password + (jsc#sle-11503) + * 0028-tools-add-option-add-samba-data.patch + * 0029-tools-store-Samba-data-if-requested.patch + * 0030-make-Samba-data-tool-configurable.patch + * 0031-fix-typo-in-flag-value.patch + * 0032-samba-data-tool-needs-to-take-an-argument.patch + * 0033-doc-add-missing-samba_data_tool_path.xml-.in-to-EXTR.patch +- Support testjoin command (jsc#sle-11503) + * 0034-Implement-adcli-testjoin.patch + +------------------------------------------------------------------- +Thu Feb 20 10:37:11 UTC 2020 - Samuel Cabrero <[email protected]> + +- Use GSS-SPNEGO if available (bsc#1162518) + * 0026-Use-GSS-SPNEGO-if-available.patch +- Add option to use ldaps (bsc#1162518) + * 0027-add-option-use-ldaps.patch + +------------------------------------------------------------------- New: ---- 0026-Use-GSS-SPNEGO-if-available.patch 0027-add-option-use-ldaps.patch 0028-tools-add-option-add-samba-data.patch 0029-tools-store-Samba-data-if-requested.patch 0030-make-Samba-data-tool-configurable.patch 0031-fix-typo-in-flag-value.patch 0032-samba-data-tool-needs-to-take-an-argument.patch 0033-doc-add-missing-samba_data_tool_path.xml-.in-to-EXTR.patch 0034-Implement-adcli-testjoin.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ adcli.spec ++++++ --- /var/tmp/diff_new_pack.ZZBuRl/_old 2020-03-13 10:55:49.580368420 +0100 +++ /var/tmp/diff_new_pack.ZZBuRl/_new 2020-03-13 10:55:49.592368429 +0100 @@ -58,6 +58,15 @@ Patch23: 0023-adenroll-use-_adcli_strv_add_unique-for-service-prin.patch Patch24: 0024-Increment-kvno-after-password-change-with-user-creds.patch Patch25: 0025-library-use-getaddrinfo-with-AI_CANONNAME-to-find-a-.patch +Patch26: 0026-Use-GSS-SPNEGO-if-available.patch +Patch27: 0027-add-option-use-ldaps.patch +Patch28: 0028-tools-add-option-add-samba-data.patch +Patch29: 0029-tools-store-Samba-data-if-requested.patch +Patch30: 0030-make-Samba-data-tool-configurable.patch +Patch31: 0031-fix-typo-in-flag-value.patch +Patch32: 0032-samba-data-tool-needs-to-take-an-argument.patch +Patch33: 0033-doc-add-missing-samba_data_tool_path.xml-.in-to-EXTR.patch +Patch34: 0034-Implement-adcli-testjoin.patch %description Library of routines for joining a machine to Active Directory (without samba) ++++++ 0026-Use-GSS-SPNEGO-if-available.patch ++++++ >From 89fde01eaffd84630d0088d49b18b084aa807b65 Mon Sep 17 00:00:00 2001 From: Sumit Bose <[email protected]> Date: Fri, 11 Oct 2019 16:39:25 +0200 Subject: [PATCH 1/2] Use GSS-SPNEGO if available Currently adcli uses the GSSAPI SASL mechanism for LDAP authentication and to establish encryption. While this works in general it does not handle some of the more advanced features which can be required by AD DCs. The GSS-SPNEGO mechanism can handle them and is used with this patch by adcli if the AD DC indicates that it supports it. Related to https://bugzilla.redhat.com/show_bug.cgi?id=1762420 (cherry picked from commit a6f795ba3d6048b32d7863468688bf7f42b2cafd) --- library/adconn.c | 35 ++++++++++++++++++++++++++++++++++- library/adconn.h | 3 +++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/library/adconn.c b/library/adconn.c index f6c23d3..a3f4548 100644 --- a/library/adconn.c +++ b/library/adconn.c @@ -77,6 +77,7 @@ struct _adcli_conn_ctx { char *default_naming_context; char *configuration_naming_context; char **supported_capabilities; + char **supported_sasl_mechs; /* Connect state */ LDAP *ldap; @@ -845,6 +846,7 @@ connect_and_lookup_naming (adcli_conn *conn, "defaultNamingContext", "configurationNamingContext", "supportedCapabilities", + "supportedSASLMechanisms", NULL }; @@ -897,6 +899,11 @@ connect_and_lookup_naming (adcli_conn *conn, "supportedCapabilities"); } + if (conn->supported_sasl_mechs == NULL) { + conn->supported_sasl_mechs = _adcli_ldap_parse_values (ldap, results, + "supportedSASLMechanisms"); + } + ldap_msgfree (results); if (conn->default_naming_context == NULL) { @@ -1022,6 +1029,7 @@ authenticate_to_directory (adcli_conn *conn) OM_uint32 minor; ber_len_t ssf; int ret; + const char *mech = "GSSAPI"; if (conn->ldap_authenticated) return ADCLI_SUCCESS; @@ -1038,7 +1046,11 @@ authenticate_to_directory (adcli_conn *conn) ret = ldap_set_option (conn->ldap, LDAP_OPT_X_SASL_SSF_MIN, &ssf); return_unexpected_if_fail (ret == 0); - ret = ldap_sasl_interactive_bind_s (conn->ldap, NULL, "GSSAPI", NULL, NULL, + if (adcli_conn_server_has_sasl_mech (conn, "GSS-SPNEGO")) { + mech = "GSS-SPNEGO"; + } + + ret = ldap_sasl_interactive_bind_s (conn->ldap, NULL, mech, NULL, NULL, LDAP_SASL_QUIET, sasl_interact, NULL); /* Clear the credential cache GSSAPI to use (for this thread) */ @@ -1231,6 +1243,7 @@ conn_free (adcli_conn *conn) free (conn->default_naming_context); free (conn->configuration_naming_context); _adcli_strv_free (conn->supported_capabilities); + _adcli_strv_free (conn->supported_sasl_mechs); free (conn->computer_name); free (conn->host_fqdn); @@ -1593,6 +1606,26 @@ adcli_conn_server_has_capability (adcli_conn *conn, return 0; } +bool +adcli_conn_server_has_sasl_mech (adcli_conn *conn, + const char *mech) +{ + int i; + + return_val_if_fail (conn != NULL, false); + return_val_if_fail (mech != NULL, false); + + if (!conn->supported_sasl_mechs) + return false; + + for (i = 0; conn->supported_sasl_mechs[i] != NULL; i++) { + if (strcasecmp (mech, conn->supported_sasl_mechs[i]) == 0) + return true; + } + + return false; +} + bool adcli_conn_is_writeable (adcli_conn *conn) { disco_dance_if_necessary (conn); diff --git a/library/adconn.h b/library/adconn.h index 13cfd32..8e88045 100644 --- a/library/adconn.h +++ b/library/adconn.h @@ -146,6 +146,9 @@ void adcli_conn_set_krb5_conf_dir (adcli_conn *conn, int adcli_conn_server_has_capability (adcli_conn *conn, const char *capability); +bool adcli_conn_server_has_sasl_mech (adcli_conn *conn, + const char *mech); + bool adcli_conn_is_writeable (adcli_conn *conn); #endif /* ADCONN_H_ */ -- 2.25.0 ++++++ 0027-add-option-use-ldaps.patch ++++++ >From 41db84aac101a54c4b0ef78119ccf9905f0691fe Mon Sep 17 00:00:00 2001 From: Sumit Bose <[email protected]> Date: Thu, 19 Dec 2019 07:22:33 +0100 Subject: [PATCH 2/2] add option use-ldaps In general using the LDAP port with GSS-SPNEGO should satifiy all requirements an AD DC should have for authentication on an encrypted LDAP connection. But if e.g. the LDAP port is blocked by a firewall using the LDAPS port with TLS encryption might be an alternative. For this use case the --use-ldaps option is added. Related to https://bugzilla.redhat.com/show_bug.cgi?id=1762420 (cherry picked from commit 85097245b57f190337225dbdbf6e33b58616c092) --- doc/adcli.xml | 24 +++++++++++++++ library/adconn.c | 79 ++++++++++++++++++++++++++++++++++++++++++------ library/adconn.h | 4 +++ tools/computer.c | 9 ++++++ tools/entry.c | 11 +++++++ 5 files changed, 118 insertions(+), 9 deletions(-) diff --git a/doc/adcli.xml b/doc/adcli.xml index 2fe9309..f257c88 100644 --- a/doc/adcli.xml +++ b/doc/adcli.xml @@ -117,6 +117,30 @@ If not specified then an appropriate domain controller is automatically discovered.</para></listitem> </varlistentry> + <varlistentry> + <term><option>--use-ldaps</option></term> + <listitem><para>Connect to the domain controller + with LDAPS. By default the LDAP port is used and SASL + GSS-SPNEGO or GSSAPI is used for authentication and to + establish encryption. This should satisfy all + requirements set on the server side and LDAPS should + only be used if the LDAP port is not accessible due to + firewalls or other reasons.</para> + <para> Please note that the place where CA certificates + can be found to validate the AD DC certificates + must be configured in the OpenLDAP configuration + file, e.g. <filename>/etc/openldap/ldap.conf</filename>. + As an alternative it can be specified with the help of + an environment variable, e.g. +<programlisting> +$ LDAPTLS_CACERT=/path/to/ad_dc_ca_cert.pem adcli join --use-ldaps -D domain.example.com +... +</programlisting> + Please see + <citerefentry><refentrytitle>ldap.conf</refentrytitle> + <manvolnum>5</manvolnum></citerefentry> for details. + </para></listitem> + </varlistentry> <varlistentry> <term><option>-C, --login-ccache=<parameter>ccache_name</parameter></option></term> <listitem><para>Use the specified kerberos credential diff --git a/library/adconn.c b/library/adconn.c index a3f4548..8a55776 100644 --- a/library/adconn.c +++ b/library/adconn.c @@ -70,6 +70,7 @@ struct _adcli_conn_ctx { char *domain_name; char *domain_realm; char *domain_controller; + bool use_ldaps; char *canonical_host; char *domain_short; char *domain_sid; @@ -773,7 +774,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) + const char *canonical_host, + bool use_ldaps) { struct addrinfo *res = NULL; struct addrinfo *ai; @@ -783,6 +785,16 @@ connect_to_address (const char *host, char *url; int sock; int rc; + int opt_rc; + const char *port = "389"; + const char *proto = "ldap"; + const char *errmsg = NULL; + + if (use_ldaps) { + port = "636"; + proto = "ldaps"; + _adcli_info ("Using LDAPS to connect to %s", host); + } memset (&hints, '\0', sizeof(hints)); #ifdef AI_ADDRCONFIG @@ -794,7 +806,7 @@ connect_to_address (const char *host, if (!canonical_host) canonical_host = host; - rc = getaddrinfo (host, "389", &hints, &res); + rc = getaddrinfo (host, port, &hints, &res); if (rc != 0) { _adcli_err ("Couldn't resolve host name: %s: %s", host, gai_strerror (rc)); return NULL; @@ -810,7 +822,7 @@ connect_to_address (const char *host, close (sock); } else { error = 0; - if (asprintf (&url, "ldap://%s", canonical_host) < 0) + if (asprintf (&url, "%s://%s", proto, canonical_host) < 0) return_val_if_reached (NULL); rc = ldap_init_fd (sock, 1, url, &ldap); free (url); @@ -820,6 +832,25 @@ connect_to_address (const char *host, ldap_err2string (rc)); break; } + + if (use_ldaps) { + rc = ldap_install_tls (ldap); + if (rc != LDAP_SUCCESS) { + opt_rc = ldap_get_option (ldap, + LDAP_OPT_DIAGNOSTIC_MESSAGE, + (void *) &errmsg); + if (opt_rc != LDAP_SUCCESS) { + errmsg = NULL; + } + _adcli_err ("Couldn't initialize TLS [%s]: %s", + ldap_err2string (rc), + errmsg == NULL ? "- no details -" + : errmsg); + ldap_unbind_ext_s (ldap, NULL, NULL); + ldap = NULL; + break; + } + } } } @@ -856,7 +887,8 @@ connect_and_lookup_naming (adcli_conn *conn, if (!canonical_host) canonical_host = disco->host_addr; - ldap = connect_to_address (disco->host_addr, canonical_host); + ldap = connect_to_address (disco->host_addr, canonical_host, + adcli_conn_get_use_ldaps (conn)); if (ldap == NULL) return ADCLI_ERR_DIRECTORY; @@ -1041,14 +1073,28 @@ authenticate_to_directory (adcli_conn *conn) status = gss_krb5_ccache_name (&minor, conn->login_ccache_name, NULL); return_unexpected_if_fail (status == 0); - /* Clumsily tell ldap + cyrus-sasl that we want encryption */ - ssf = 1; - ret = ldap_set_option (conn->ldap, LDAP_OPT_X_SASL_SSF_MIN, &ssf); - return_unexpected_if_fail (ret == 0); + if (adcli_conn_get_use_ldaps (conn)) { + /* do not use SASL encryption on LDAPS connection */ + ssf = 0; + ret = ldap_set_option (conn->ldap, LDAP_OPT_X_SASL_SSF_MIN, &ssf); + return_unexpected_if_fail (ret == 0); + ret = ldap_set_option (conn->ldap, LDAP_OPT_X_SASL_SSF_MAX, &ssf); + return_unexpected_if_fail (ret == 0); + } else { + /* Clumsily tell ldap + cyrus-sasl that we want encryption */ + ssf = 1; + ret = ldap_set_option (conn->ldap, LDAP_OPT_X_SASL_SSF_MIN, &ssf); + return_unexpected_if_fail (ret == 0); + } - if (adcli_conn_server_has_sasl_mech (conn, "GSS-SPNEGO")) { + /* There are issues with cryrus-sasl and GSS-SPNEGO with TLS even if + * ssf_max is set to 0. To be on the safe side GSS-SPNEGO is only used + * without LDAPS. */ + if (adcli_conn_server_has_sasl_mech (conn, "GSS-SPNEGO") + && !adcli_conn_get_use_ldaps (conn)) { mech = "GSS-SPNEGO"; } + _adcli_info ("Using %s for SASL bind", mech); ret = ldap_sasl_interactive_bind_s (conn->ldap, NULL, mech, NULL, NULL, LDAP_SASL_QUIET, sasl_interact, NULL); @@ -1230,6 +1276,7 @@ adcli_conn_new (const char *domain_name) conn->refs = 1; conn->logins_allowed = ADCLI_LOGIN_COMPUTER_ACCOUNT | ADCLI_LOGIN_USER_ACCOUNT; adcli_conn_set_domain_name (conn, domain_name); + adcli_conn_set_use_ldaps (conn, false); return conn; } @@ -1389,6 +1436,20 @@ adcli_conn_set_domain_controller (adcli_conn *conn, no_more_disco (conn); } +bool +adcli_conn_get_use_ldaps (adcli_conn *conn) +{ + return_val_if_fail (conn != NULL, NULL); + return conn->use_ldaps; +} + +void +adcli_conn_set_use_ldaps (adcli_conn *conn, bool value) +{ + return_if_fail (conn != NULL); + conn->use_ldaps = value; +} + const char * adcli_conn_get_domain_short (adcli_conn *conn) { diff --git a/library/adconn.h b/library/adconn.h index 8e88045..3e287b1 100644 --- a/library/adconn.h +++ b/library/adconn.h @@ -89,6 +89,10 @@ const char * adcli_conn_get_domain_controller (adcli_conn *conn); void adcli_conn_set_domain_controller (adcli_conn *conn, const char *value); +bool adcli_conn_get_use_ldaps (adcli_conn *conn); +void adcli_conn_set_use_ldaps (adcli_conn *conn, + bool value); + const char * adcli_conn_get_domain_short (adcli_conn *conn); const char * adcli_conn_get_domain_sid (adcli_conn *conn); diff --git a/tools/computer.c b/tools/computer.c index 7a0c6f5..bb77963 100644 --- a/tools/computer.c +++ b/tools/computer.c @@ -109,12 +109,14 @@ typedef enum { opt_trusted_for_delegation, opt_add_service_principal, opt_remove_service_principal, + opt_use_ldaps, } Option; static adcli_tool_desc common_usages[] = { { opt_domain, "active directory domain name" }, { opt_domain_realm, "kerberos realm for the domain" }, { opt_domain_controller, "domain controller to connect to" }, + { opt_use_ldaps, "use LDAPS port for communication" }, { opt_host_fqdn, "override the fully qualified domain name of the\n" "local machine" }, { opt_host_keytab, "filename for the host kerberos keytab" }, @@ -282,6 +284,9 @@ parse_option (Option opt, case opt_remove_service_principal: adcli_enroll_add_service_principal_to_remove (enroll, optarg); return; + case opt_use_ldaps: + adcli_conn_set_use_ldaps (conn, true); + return; case opt_verbose: return; @@ -326,6 +331,7 @@ adcli_tool_computer_join (adcli_conn *conn, { "domain-realm", required_argument, NULL, opt_domain_realm }, { "domain-controller", required_argument, NULL, opt_domain_controller }, { "domain-server", required_argument, NULL, opt_domain_controller }, /* compat */ + { "use-ldaps", no_argument, 0, opt_use_ldaps }, { "login-user", required_argument, NULL, opt_login_user }, { "user", required_argument, NULL, opt_login_user }, /* compat */ { "login-ccache", optional_argument, NULL, opt_login_ccache }, @@ -542,6 +548,7 @@ adcli_tool_computer_preset (adcli_conn *conn, { "domain", required_argument, NULL, opt_domain }, { "domain-realm", required_argument, NULL, opt_domain_realm }, { "domain-controller", required_argument, NULL, opt_domain_controller }, + { "use-ldaps", no_argument, 0, opt_use_ldaps }, { "domain-ou", required_argument, NULL, opt_domain_ou }, { "login-user", required_argument, NULL, opt_login_user }, { "login-ccache", optional_argument, NULL, opt_login_ccache }, @@ -641,6 +648,7 @@ adcli_tool_computer_reset (adcli_conn *conn, { "domain", required_argument, NULL, opt_domain }, { "domain-realm", required_argument, NULL, opt_domain_realm }, { "domain-controller", required_argument, NULL, opt_domain_controller }, + { "use-ldaps", no_argument, 0, opt_use_ldaps }, { "login-user", required_argument, NULL, opt_login_user }, { "login-ccache", optional_argument, NULL, opt_login_ccache }, { "login-type", required_argument, NULL, opt_login_type }, @@ -716,6 +724,7 @@ adcli_tool_computer_delete (adcli_conn *conn, { "domain", required_argument, NULL, opt_domain }, { "domain-realm", required_argument, NULL, opt_domain_realm }, { "domain-controller", required_argument, NULL, opt_domain_controller }, + { "use-ldaps", no_argument, 0, opt_use_ldaps }, { "login-user", required_argument, NULL, opt_login_user }, { "login-ccache", optional_argument, NULL, opt_login_ccache }, { "no-password", no_argument, 0, opt_no_password }, diff --git a/tools/entry.c b/tools/entry.c index 7b6a200..737fefe 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_use_ldaps, } Option; static adcli_tool_desc common_usages[] = { @@ -65,6 +66,7 @@ static adcli_tool_desc common_usages[] = { { opt_domain, "active directory domain name" }, { opt_domain_realm, "kerberos realm for the domain" }, { opt_domain_controller, "domain directory server to connect to" }, + { opt_use_ldaps, "use LDAPS port for communication" }, { opt_login_ccache, "kerberos credential cache file which contains\n" "ticket to used to connect to the domain" }, { opt_login_user, "user (usually administrative) login name of\n" @@ -131,6 +133,9 @@ parse_option (Option opt, stdin_password = 1; } return; + case opt_use_ldaps: + adcli_conn_set_use_ldaps (conn, true); + return; case opt_verbose: return; default: @@ -163,6 +168,7 @@ adcli_tool_user_create (adcli_conn *conn, { "domain", required_argument, NULL, opt_domain }, { "domain-realm", required_argument, NULL, opt_domain_realm }, { "domain-controller", required_argument, NULL, opt_domain_controller }, + { "use-ldaps", no_argument, 0, opt_use_ldaps }, { "login-user", required_argument, NULL, opt_login_user }, { "login-ccache", optional_argument, NULL, opt_login_ccache }, { "no-password", no_argument, 0, opt_no_password }, @@ -263,6 +269,7 @@ adcli_tool_user_delete (adcli_conn *conn, { "domain", required_argument, NULL, opt_domain }, { "domain-realm", required_argument, NULL, opt_domain_realm }, { "domain-controller", required_argument, NULL, opt_domain_controller }, + { "use-ldaps", no_argument, 0, opt_use_ldaps }, { "login-user", required_argument, NULL, opt_login_user }, { "login-ccache", optional_argument, NULL, opt_login_ccache }, { "no-password", no_argument, 0, opt_no_password }, @@ -340,6 +347,7 @@ adcli_tool_group_create (adcli_conn *conn, { "domain", required_argument, NULL, opt_domain }, { "domain-realm", required_argument, NULL, opt_domain_realm }, { "domain-controller", required_argument, NULL, opt_domain_controller }, + { "use-ldaps", no_argument, 0, opt_use_ldaps }, { "domain-ou", required_argument, NULL, opt_domain_ou }, { "login-user", required_argument, NULL, opt_login_user }, { "login-ccache", optional_argument, NULL, opt_login_ccache }, @@ -426,6 +434,7 @@ adcli_tool_group_delete (adcli_conn *conn, { "domain", required_argument, NULL, opt_domain }, { "domain-realm", required_argument, NULL, opt_domain_realm }, { "domain-controller", required_argument, NULL, opt_domain_controller }, + { "use-ldaps", no_argument, 0, opt_use_ldaps }, { "login-user", required_argument, NULL, opt_login_user }, { "login-ccache", optional_argument, NULL, opt_login_ccache }, { "no-password", no_argument, 0, opt_no_password }, @@ -536,6 +545,7 @@ adcli_tool_member_add (adcli_conn *conn, { "domain", required_argument, NULL, opt_domain }, { "domain-realm", required_argument, NULL, opt_domain_realm }, { "domain-controller", required_argument, NULL, opt_domain_controller }, + { "use-ldaps", no_argument, 0, opt_use_ldaps }, { "login-user", required_argument, NULL, opt_login_user }, { "login-ccache", optional_argument, NULL, opt_login_ccache }, { "no-password", no_argument, 0, opt_no_password }, @@ -618,6 +628,7 @@ adcli_tool_member_remove (adcli_conn *conn, { "domain", required_argument, NULL, opt_domain }, { "domain-realm", required_argument, NULL, opt_domain_realm }, { "domain-controller", required_argument, NULL, opt_domain_controller }, + { "use-ldaps", no_argument, 0, opt_use_ldaps }, { "login-user", required_argument, NULL, opt_login_user }, { "login-ccache", optional_argument, NULL, opt_login_ccache }, { "no-password", no_argument, 0, opt_no_password }, -- 2.25.0 ++++++ 0028-tools-add-option-add-samba-data.patch ++++++ >From 935eba15826568dcabbff69a6a3722365fec7952 Mon Sep 17 00:00:00 2001 From: Sumit Bose <[email protected]> Date: Tue, 30 Jan 2018 14:46:00 +0100 Subject: [PATCH 28/34] tools: add option --add-samba-data https://bugs.freedesktop.org/show_bug.cgi?id=100118 https://gitlab.freedesktop.org/realmd/adcli/issues/6 Reviewed-by: Jakub Hrozek <[email protected]> (cherry picked from commit 9e2be6f374d6d9107a34acfcd6fa551190d756d5) --- doc/adcli.xml | 30 ++++++++++++++++++++++++++++++ library/adenroll.h | 1 + tools/computer.c | 12 ++++++++++++ 3 files changed, 43 insertions(+) diff --git a/doc/adcli.xml b/doc/adcli.xml index f257c88..fbbe639 100644 --- a/doc/adcli.xml +++ b/doc/adcli.xml @@ -335,6 +335,21 @@ Password for Administrator: machine account password. This is output in a format that should be both human and machine readable.</para></listitem> </varlistentry> + <varlistentry> + <term><option>--add-samba-data</option></term> + <listitem><para>After a successful join add the domain + SID and the machine account password to the Samba + specific databases by calling Samba's + <command>net</command> utility.</para> + + <para>Please note that Samba's <command>net</command> + requires some settings in <filename>smb.conf</filename> + to create the database entries correctly. Most + important here is currently the + <option>workgroup</option> option, see + <citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> + for details.</para></listitem> + </varlistentry> </variablelist> </refsect1> @@ -445,6 +460,21 @@ $ adcli update --login-ccache=/tmp/krbcc_123 about join operation. This is output in a format that should be both human and machine readable.</para></listitem> </varlistentry> + <varlistentry> + <term><option>--add-samba-data</option></term> + <listitem><para>After a successful join add the domain + SID and the machine account password to the Samba + specific databases by calling Samba's + <command>net</command> utility.</para> + + <para>Please note that Samba's <command>net</command> + requires some settings in <filename>smb.conf</filename> + to create the database entries correctly. Most + important here is currently the + <option>workgroup</option> option, see + <citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> + for details.</para></listitem> + </varlistentry> </variablelist> </refsect1> diff --git a/library/adenroll.h b/library/adenroll.h index 5a24c42..438216e 100644 --- a/library/adenroll.h +++ b/library/adenroll.h @@ -30,6 +30,7 @@ typedef enum { ADCLI_ENROLL_NO_KEYTAB = 1 << 1, ADCLI_ENROLL_ALLOW_OVERWRITE = 1 << 2, ADCLI_ENROLL_PASSWORD_VALID = 1 << 3, + ADCLI_ENROLL_ADD_SAMBA_DATA = 1 << 3, } adcli_enroll_flags; typedef struct _adcli_enroll adcli_enroll; diff --git a/tools/computer.c b/tools/computer.c index bb77963..868bb60 100644 --- a/tools/computer.c +++ b/tools/computer.c @@ -106,6 +106,7 @@ typedef enum { opt_os_service_pack, opt_user_principal, opt_computer_password_lifetime, + opt_add_samba_data, opt_trusted_for_delegation, opt_add_service_principal, opt_remove_service_principal, @@ -151,6 +152,8 @@ static adcli_tool_desc common_usages[] = { "a successful join" }, { opt_show_password, "show computer account password after after a\n" "successful join" }, + { opt_add_samba_data, "add domain SID and computer account password\n" + "to the Samba specific configuration database" }, { opt_verbose, "show verbose progress and failure messages", }, { 0 }, }; @@ -294,6 +297,7 @@ parse_option (Option opt, case opt_show_details: case opt_show_password: case opt_one_time_password: + case opt_add_samba_data: assert (0 && "not reached"); break; } @@ -354,6 +358,7 @@ adcli_tool_computer_join (adcli_conn *conn, { "add-service-principal", required_argument, NULL, opt_add_service_principal }, { "show-details", no_argument, NULL, opt_show_details }, { "show-password", no_argument, NULL, opt_show_password }, + { "add-samba-data", no_argument, NULL, opt_add_samba_data }, { "verbose", no_argument, NULL, opt_verbose }, { "help", no_argument, NULL, 'h' }, { 0 }, @@ -380,6 +385,9 @@ adcli_tool_computer_join (adcli_conn *conn, case opt_show_password: show_password = 1; break; + case opt_add_samba_data: + flags |= ADCLI_ENROLL_ADD_SAMBA_DATA; + break; case 'h': case '?': case ':': @@ -456,6 +464,7 @@ adcli_tool_computer_update (adcli_conn *conn, { "remove-service-principal", required_argument, NULL, opt_remove_service_principal }, { "show-details", no_argument, NULL, opt_show_details }, { "show-password", no_argument, NULL, opt_show_password }, + { "add-samba-data", no_argument, NULL, opt_add_samba_data }, { "verbose", no_argument, NULL, opt_verbose }, { "help", no_argument, NULL, 'h' }, { 0 }, @@ -478,6 +487,9 @@ adcli_tool_computer_update (adcli_conn *conn, case opt_show_password: show_password = 1; break; + case opt_add_samba_data: + flags |= ADCLI_ENROLL_ADD_SAMBA_DATA; + break; case 'h': case '?': case ':': -- 2.25.1 ++++++ 0029-tools-store-Samba-data-if-requested.patch ++++++ >From 87f60b57a9593ae7947a579711e4039fa22d1ba4 Mon Sep 17 00:00:00 2001 From: Sumit Bose <[email protected]> Date: Tue, 30 Jan 2018 18:24:15 +0100 Subject: [PATCH 29/34] tools: store Samba data if requested Use Samba's net utility to add the machine account password and the domain SID to the Samba configuration. https://bugs.freedesktop.org/show_bug.cgi?id=100118 https://gitlab.freedesktop.org/realmd/adcli/issues/6 Reviewed-by: Jakub Hrozek <[email protected]> (cherry picked from commit a79e03c5a559389c5c9c0e9d72831e5fe5c62f54) --- library/adenroll.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/library/adenroll.c b/library/adenroll.c index 6a17d92..3f11e63 100644 --- a/library/adenroll.c +++ b/library/adenroll.c @@ -1794,6 +1794,36 @@ update_keytab_for_principals (adcli_enroll *enroll, return ADCLI_SUCCESS; } +static adcli_result +update_samba_data (adcli_enroll *enroll) +{ + int ret; + char *argv_pw[] = { "/usr/bin/net", "changesecretpw", "-i", "-f", NULL }; + char *argv_sid[] = { "/usr/bin/net", "setdomainsid", NULL, NULL }; + + _adcli_info ("Trying to set Samba secret.\n"); + ret = _adcli_call_external_program (argv_pw[0], argv_pw, + enroll->computer_password, NULL, NULL); + if (ret != ADCLI_SUCCESS) { + _adcli_err ("Failed to set Samba computer account password.\n"); + } + + argv_sid[2] = (char *) adcli_conn_get_domain_sid (enroll->conn); + if (argv_sid[2] == NULL) { + _adcli_err ("Domain SID not available.\n"); + } else { + _adcli_info ("Trying to set domain SID %s for Samba.\n", + argv_sid[2]); + ret = _adcli_call_external_program (argv_sid[0], argv_sid, + NULL, NULL, NULL); + if (ret != ADCLI_SUCCESS) { + _adcli_err ("Failed to set Samba domain SID.\n"); + } + } + + return ret; +} + static void enroll_clear_state (adcli_enroll *enroll) { @@ -1962,6 +1992,15 @@ enroll_join_or_update_tasks (adcli_enroll *enroll, update_service_principals (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 " + "or winbindd might not work as " + "expected.\n"); + } + } + if (flags & ADCLI_ENROLL_NO_KEYTAB) return ADCLI_SUCCESS; -- 2.25.1 ++++++ 0030-make-Samba-data-tool-configurable.patch ++++++ >From 211318e8d96ce6133498044345b4818ce48f8820 Mon Sep 17 00:00:00 2001 From: Sumit Bose <[email protected]> Date: Thu, 1 Feb 2018 14:26:22 +0100 Subject: [PATCH 30/34] make Samba data tool configurable Allow to specify an alternative path to Samba's net utility at configure time and at run time. https://bugs.freedesktop.org/show_bug.cgi?id=100118 https://gitlab.freedesktop.org/realmd/adcli/issues/6 Reviewed-by: Jakub Hrozek <[email protected]> (cherry picked from commit 9fa4b8d2bd98525212a019bfa62c2f132614faba) --- configure.ac | 13 ++++++++++ doc/adcli.xml | 21 ++++++++++++++- doc/samba_data_tool_path.xml.in | 1 + library/adenroll.c | 46 ++++++++++++++++++++++++++++----- library/adenroll.h | 5 ++++ tools/computer.c | 16 ++++++++++++ 7 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 doc/samba_data_tool_path.xml.in diff --git a/configure.ac b/configure.ac index fe86638..68877c7 100644 --- a/configure.ac +++ b/configure.ac @@ -291,6 +291,18 @@ else AC_DEFINE_UNQUOTED(BIN_ECHO, "$BIN_ECHO", [path to echo, used in unit test]) fi +AC_MSG_CHECKING([where is Samba's net utility]) +AC_ARG_WITH([samba_data_tool], + AC_HELP_STRING([--with-samba-data-tool=/path], + [Path to Samba's net utility]), + [], + [with_samba_data_tool=/usr/bin/net]) +AC_MSG_RESULT([$with_samba_data_tool]) + +AC_DEFINE_UNQUOTED(SAMBA_DATA_TOOL, "$with_samba_data_tool", + [Path to Samba's net utility]) + +AC_SUBST(SAMBA_DATA_TOOL, [$with_samba_data_tool]) # --------------------------------------------------------------------- ADCLI_LT_RELEASE=$ADCLI_CURRENT:$ADCLI_REVISION:$ADCLI_AGE @@ -300,6 +312,7 @@ AC_CONFIG_FILES([Makefile build/Makefile doc/Makefile doc/version.xml + doc/samba_data_tool_path.xml library/Makefile tools/Makefile ]) diff --git a/doc/adcli.xml b/doc/adcli.xml index fbbe639..b3ea801 100644 --- a/doc/adcli.xml +++ b/doc/adcli.xml @@ -1,6 +1,9 @@ <?xml version='1.0'?> <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> + "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" +[ + <!ENTITY samba_data_tool SYSTEM "samba_data_tool_path.xml"> +]> <refentry id="adcli"> @@ -350,6 +353,14 @@ Password for Administrator: <citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details.</para></listitem> </varlistentry> + <varlistentry> + <term><option>--samba-data-tool=<parameter>/path/to/net</parameter></option></term> + <listitem><para>If Samba's <command>net</command> + cannot be found at + <filename>&samba_data_tool;</filename> this option can + be used to specific an alternative location with the + help of an absolute path.</para></listitem> + </varlistentry> </variablelist> </refsect1> @@ -475,6 +486,14 @@ $ adcli update --login-ccache=/tmp/krbcc_123 <citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details.</para></listitem> </varlistentry> + <varlistentry> + <term><option>--samba-data-tool=<parameter>/path/to/net</parameter></option></term> + <listitem><para>If Samba's <command>net</command> + cannot be found at + <filename>&samba_data_tool;</filename> this option can + be used to specific an alternative location with the + help of an absolute path.</para></listitem> + </varlistentry> </variablelist> </refsect1> diff --git a/doc/samba_data_tool_path.xml.in b/doc/samba_data_tool_path.xml.in new file mode 100644 index 0000000..a667c57 --- /dev/null +++ b/doc/samba_data_tool_path.xml.in @@ -0,0 +1 @@ +@SAMBA_DATA_TOOL@ diff --git a/library/adenroll.c b/library/adenroll.c index 3f11e63..5b35c9a 100644 --- a/library/adenroll.c +++ b/library/adenroll.c @@ -42,6 +42,10 @@ #include <stdio.h> #include <unistd.h> +#ifndef SAMBA_DATA_TOOL +#define SAMBA_DATA_TOOL "/usr/bin/net" +#endif + static krb5_enctype v60_later_enctypes[] = { ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_AES128_CTS_HMAC_SHA1_96, @@ -113,6 +117,7 @@ struct _adcli_enroll { int keytab_enctypes_explicit; unsigned int computer_password_lifetime; int computer_password_lifetime_explicit; + char *samba_data_tool; bool trusted_for_delegation; int trusted_for_delegation_explicit; }; @@ -1798,26 +1803,33 @@ static adcli_result update_samba_data (adcli_enroll *enroll) { int ret; - char *argv_pw[] = { "/usr/bin/net", "changesecretpw", "-i", "-f", NULL }; - char *argv_sid[] = { "/usr/bin/net", "setdomainsid", NULL, NULL }; + char *argv_pw[] = { NULL, "changesecretpw", "-i", "-f", NULL }; + char *argv_sid[] = { NULL, "setdomainsid", NULL, NULL }; + + argv_pw[0] = (char *) adcli_enroll_get_samba_data_tool (enroll); + if (argv_pw[0] ==NULL) { + _adcli_err ("Samba data tool not available."); + return ADCLI_ERR_FAIL; + } + argv_sid[0] = argv_pw[0]; - _adcli_info ("Trying to set Samba secret.\n"); + _adcli_info ("Trying to set Samba secret."); ret = _adcli_call_external_program (argv_pw[0], argv_pw, enroll->computer_password, NULL, NULL); if (ret != ADCLI_SUCCESS) { - _adcli_err ("Failed to set Samba computer account password.\n"); + _adcli_err ("Failed to set Samba computer account password."); } argv_sid[2] = (char *) adcli_conn_get_domain_sid (enroll->conn); if (argv_sid[2] == NULL) { - _adcli_err ("Domain SID not available.\n"); + _adcli_err ("Domain SID not available."); } else { - _adcli_info ("Trying to set domain SID %s for Samba.\n", + _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); if (ret != ADCLI_SUCCESS) { - _adcli_err ("Failed to set Samba domain SID.\n"); + _adcli_err ("Failed to set Samba domain SID."); } } @@ -2233,6 +2245,9 @@ adcli_enroll_new (adcli_conn *conn) enroll->os_name = strdup (value); return_val_if_fail (enroll->os_name != NULL, NULL); + enroll->samba_data_tool = strdup (SAMBA_DATA_TOOL); + return_val_if_fail (enroll->samba_data_tool != NULL, NULL); + return enroll; } @@ -2260,6 +2275,7 @@ enroll_free (adcli_enroll *enroll) free (enroll->os_name); free (enroll->os_version); free (enroll->os_service_pack); + free (enroll->samba_data_tool); free (enroll->user_principal); _adcli_strv_free (enroll->service_names); @@ -2629,6 +2645,22 @@ adcli_enroll_set_computer_password_lifetime (adcli_enroll *enroll, enroll->computer_password_lifetime_explicit = 1; } +void +adcli_enroll_set_samba_data_tool (adcli_enroll *enroll, const char *value) +{ + return_if_fail (enroll != NULL); + if (value != NULL && value[0] != '\0') { + _adcli_str_set (&enroll->samba_data_tool, value); + } +} + +const char * +adcli_enroll_get_samba_data_tool (adcli_enroll *enroll) +{ + return_val_if_fail (enroll != NULL, NULL); + return enroll->samba_data_tool; +} + bool adcli_enroll_get_trusted_for_delegation (adcli_enroll *enroll) { diff --git a/library/adenroll.h b/library/adenroll.h index 438216e..f87dffa 100644 --- a/library/adenroll.h +++ b/library/adenroll.h @@ -153,4 +153,9 @@ const char * adcli_enroll_get_os_service_pack (adcli_enroll *enroll); void adcli_enroll_set_os_service_pack (adcli_enroll *enroll, const char *value); +void adcli_enroll_set_samba_data_tool (adcli_enroll *enroll, + const char *value); + +const char * adcli_enroll_get_samba_data_tool (adcli_enroll *enroll); + #endif /* ADENROLL_H_ */ diff --git a/tools/computer.c b/tools/computer.c index 868bb60..07503a9 100644 --- a/tools/computer.c +++ b/tools/computer.c @@ -30,6 +30,7 @@ #include <err.h> #include <stdio.h> #include <errno.h> +#include <unistd.h> static void dump_details (adcli_conn *conn, @@ -107,6 +108,7 @@ typedef enum { opt_user_principal, opt_computer_password_lifetime, opt_add_samba_data, + opt_samba_data_tool, opt_trusted_for_delegation, opt_add_service_principal, opt_remove_service_principal, @@ -154,6 +156,7 @@ static adcli_tool_desc common_usages[] = { "successful join" }, { opt_add_samba_data, "add domain SID and computer account password\n" "to the Samba specific configuration database" }, + { opt_samba_data_tool, "Absolute path to the tool used for add-samba-data" }, { opt_verbose, "show verbose progress and failure messages", }, { 0 }, }; @@ -169,6 +172,7 @@ parse_option (Option opt, static int stdin_password = 0; char *endptr; unsigned int lifetime; + int ret; switch (opt) { case opt_login_ccache: @@ -274,6 +278,16 @@ parse_option (Option opt, adcli_enroll_set_computer_password_lifetime (enroll, lifetime); return; + 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)); + } else { + adcli_enroll_set_samba_data_tool (enroll, optarg); + } + return; case opt_trusted_for_delegation: if (strcasecmp (optarg, "true") == 0 || strcasecmp (optarg, "yes") == 0) { adcli_enroll_set_trusted_for_delegation (enroll, true); @@ -359,6 +373,7 @@ adcli_tool_computer_join (adcli_conn *conn, { "show-details", no_argument, NULL, opt_show_details }, { "show-password", no_argument, NULL, opt_show_password }, { "add-samba-data", no_argument, NULL, opt_add_samba_data }, + { "samba-data-tool", no_argument, NULL, opt_samba_data_tool }, { "verbose", no_argument, NULL, opt_verbose }, { "help", no_argument, NULL, 'h' }, { 0 }, @@ -465,6 +480,7 @@ adcli_tool_computer_update (adcli_conn *conn, { "show-details", no_argument, NULL, opt_show_details }, { "show-password", no_argument, NULL, opt_show_password }, { "add-samba-data", no_argument, NULL, opt_add_samba_data }, + { "samba-data-tool", no_argument, NULL, opt_samba_data_tool }, { "verbose", no_argument, NULL, opt_verbose }, { "help", no_argument, NULL, 'h' }, { 0 }, -- 2.25.1 ++++++ 0031-fix-typo-in-flag-value.patch ++++++ >From c075e8ab860a52286ce1d7f3a66e9e034a7465fa Mon Sep 17 00:00:00 2001 From: Sumit Bose <[email protected]> Date: Wed, 8 Aug 2018 12:03:01 +0200 Subject: [PATCH 31/34] fix typo in flag value (cherry picked from commit 12e13aaea8ab999540ad62e91829fc3d1815fac1) --- library/adenroll.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/adenroll.h b/library/adenroll.h index f87dffa..abbbfd4 100644 --- a/library/adenroll.h +++ b/library/adenroll.h @@ -30,7 +30,7 @@ typedef enum { ADCLI_ENROLL_NO_KEYTAB = 1 << 1, ADCLI_ENROLL_ALLOW_OVERWRITE = 1 << 2, ADCLI_ENROLL_PASSWORD_VALID = 1 << 3, - ADCLI_ENROLL_ADD_SAMBA_DATA = 1 << 3, + ADCLI_ENROLL_ADD_SAMBA_DATA = 1 << 4, } adcli_enroll_flags; typedef struct _adcli_enroll adcli_enroll; -- 2.25.1 ++++++ 0032-samba-data-tool-needs-to-take-an-argument.patch ++++++ >From d65c1cb7859d121b8773769e878f574469313287 Mon Sep 17 00:00:00 2001 From: George Hartzell <[email protected]> Date: Mon, 14 Jan 2019 17:40:42 -0800 Subject: [PATCH 32/34] samba-data-tool needs to take an argument See https://gitlab.freedesktop.org/realmd/adcli/issues/15 (cherry picked from commit 4bc96c69fbb93eb1fe9fcef6c6d942c296852e03) --- tools/computer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/computer.c b/tools/computer.c index 07503a9..929f18c 100644 --- a/tools/computer.c +++ b/tools/computer.c @@ -373,7 +373,7 @@ adcli_tool_computer_join (adcli_conn *conn, { "show-details", no_argument, NULL, opt_show_details }, { "show-password", no_argument, NULL, opt_show_password }, { "add-samba-data", no_argument, NULL, opt_add_samba_data }, - { "samba-data-tool", no_argument, NULL, opt_samba_data_tool }, + { "samba-data-tool", required_argument, 0, opt_samba_data_tool }, { "verbose", no_argument, NULL, opt_verbose }, { "help", no_argument, NULL, 'h' }, { 0 }, @@ -480,7 +480,7 @@ adcli_tool_computer_update (adcli_conn *conn, { "show-details", no_argument, NULL, opt_show_details }, { "show-password", no_argument, NULL, opt_show_password }, { "add-samba-data", no_argument, NULL, opt_add_samba_data }, - { "samba-data-tool", no_argument, NULL, opt_samba_data_tool }, + { "samba-data-tool", required_argument, 0, opt_samba_data_tool }, { "verbose", no_argument, NULL, opt_verbose }, { "help", no_argument, NULL, 'h' }, { 0 }, -- 2.25.1 ++++++ 0033-doc-add-missing-samba_data_tool_path.xml-.in-to-EXTR.patch ++++++ >From d32a4d6794674ea734fdc9e3179168a6e7c991e5 Mon Sep 17 00:00:00 2001 From: Sumit Bose <[email protected]> Date: Tue, 3 Sep 2019 14:39:37 +0200 Subject: [PATCH 33/34] doc: add missing samba_data_tool_path.xml(.in) to EXTRA_DIST (cherry picked from commit 2edc26afda17db1a92703deb16658e9de9f79e14) --- doc/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/Makefile.am b/doc/Makefile.am index 3a53843..4490688 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -31,6 +31,8 @@ EXTRA_DIST = \ static \ version.xml.in \ version.xml \ + samba_data_tool_path.xml.in \ + samba_data_tool_path.xml \ $(NULL) CLEANFILES = \ -- 2.25.1 ++++++ 0034-Implement-adcli-testjoin.patch ++++++ >From c9c9e7a59c2a38baf7ab3f4eff56fcd6c6a19254 Mon Sep 17 00:00:00 2001 From: Sumit Bose <[email protected]> Date: Fri, 22 Mar 2019 12:37:39 +0100 Subject: [PATCH 34/34] 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 (cherry picked from commit 6fd99ff6c5dd6ef0be8d942989b1c6dcee3102d9) --- 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 b3ea801..154df07 100644 --- a/doc/adcli.xml +++ b/doc/adcli.xml @@ -43,6 +43,9 @@ <cmdsynopsis> <command>adcli update</command> </cmdsynopsis> + <cmdsynopsis> + <command>adcli testjoin</command> + </cmdsynopsis> <cmdsynopsis> <command>adcli create-user</command> <arg choice="opt">--domain=domain.example.com</arg> @@ -498,6 +501,37 @@ $ adcli update --login-ccache=/tmp/krbcc_123 </refsect1> +<refsect1 id='testjoin'> + <title>Testing if the machine account password is valid</title> + + <para><command>adcli testjoin</command> uses the current credentials in + the keytab and tries to authenticate with the machine account to the AD + domain. If this works the machine account password and the join are + still valid. If it fails the machine account password or the whole + machine account have to be refreshed with + <command>adcli join</command> or <command>adcli update</command>. + </para> + +<programlisting> +$ adcli testjoin +</programlisting> + + <para>Only the global options not related to authentication are + available, additionally you can specify the following options to + control how this operation is done.</para> + + <variablelist> + <varlistentry> + <term><option>-K, --host-keytab=<parameter>/path/to/keytab</parameter></option></term> + <listitem><para>Specify the path to the host keytab where + current host credentials are stored and the new ones + will be written to. If not specified, the default + location will be used, usually + <filename>/etc/krb5.keytab</filename>.</para></listitem> + </varlistentry> + </variablelist> +</refsect1> + <refsect1 id='create_user'> <title>Creating a User</title> diff --git a/tools/computer.c b/tools/computer.c index 929f18c..6a9b3bc 100644 --- a/tools/computer.c +++ b/tools/computer.c @@ -559,6 +559,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.25.1
