diff -Nru adcli-0.8.2/debian/changelog adcli-0.8.2/debian/changelog --- adcli-0.8.2/debian/changelog 2020-12-05 12:09:01.000000000 +1300 +++ adcli-0.8.2/debian/changelog 2020-12-08 12:52:32.000000000 +1300 @@ -1,3 +1,16 @@ +adcli (0.8.2-1ubuntu3) bionic; urgency=medium + + * Re-introduce support for "use-ldaps" for new Active Directory + requirement ADV190023 (LP: #1868703): + - d/p/lp-1868703-01-Use-GSS-SPNEGO-if-available.patch + - d/p/lp-1868703-02-add-option-use-ldaps.patch + - d/p/lp-1868703-03-tools-add-missing-use-ldaps-option-to-update-and-testjoin.patch + * debian/control: Adding specific dependency of libsasl2-modules-gssapi-mit + 2.1.27~101-g0780600+dfsg-3ubuntu2.2 to ensure adcli uses fixed + GSS-SPNEGO implementation to resolve regression. (LP: #1906627) + + -- Matthew Ruffell Tue, 08 Dec 2020 12:52:32 +1300 + adcli (0.8.2-1ubuntu2) bionic; urgency=medium * Revert all three patches from 0.8.2-1ubuntu1 due to a diff -Nru adcli-0.8.2/debian/control adcli-0.8.2/debian/control --- adcli-0.8.2/debian/control 2016-08-15 22:54:23.000000000 +1200 +++ adcli-0.8.2/debian/control 2020-12-08 12:52:24.000000000 +1300 @@ -16,7 +16,8 @@ Package: adcli Architecture: any -Depends: libsasl2-modules-gssapi-mit, ${misc:Depends}, ${shlibs:Depends} +Depends: libsasl2-modules-gssapi-mit (>= 2.1.27~101-g0780600+dfsg-3ubuntu2.2), + ${misc:Depends}, ${shlibs:Depends} Description: Tool for performing actions on an Active Directory domain This tool allows the administrator to join the local machine to an Active Directory (AD) domain. It's taking care of creating the computer account on the diff -Nru adcli-0.8.2/debian/patches/lp-1868703-01-Use-GSS-SPNEGO-if-available.patch adcli-0.8.2/debian/patches/lp-1868703-01-Use-GSS-SPNEGO-if-available.patch --- adcli-0.8.2/debian/patches/lp-1868703-01-Use-GSS-SPNEGO-if-available.patch 1970-01-01 12:00:00.000000000 +1200 +++ adcli-0.8.2/debian/patches/lp-1868703-01-Use-GSS-SPNEGO-if-available.patch 2020-12-08 12:50:45.000000000 +1300 @@ -0,0 +1,104 @@ +Description: Use GSS-SPNEGO if available +Author: Sumit Bose +From: Matthew Ruffell +Origin: https://gitlab.freedesktop.org/realmd/adcli/-/commit/a6f795ba3d6048b32d7863468688bf7f42b2cafd +Bug: https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/ADV190023 +Bug-Ubuntu: https://launchpad.net/bugs/1868703 + +Index: adcli-0.8.2/library/adconn.c +=================================================================== +--- adcli-0.8.2.orig/library/adconn.c 2020-12-08 12:50:42.688404357 +1300 ++++ adcli-0.8.2/library/adconn.c 2020-12-08 12:50:42.676404137 +1300 +@@ -76,6 +76,7 @@ + char *default_naming_context; + char *configuration_naming_context; + char **supported_capabilities; ++ char **supported_sasl_mechs; + + /* Connect state */ + LDAP *ldap; +@@ -816,6 +817,7 @@ + "defaultNamingContext", + "configurationNamingContext", + "supportedCapabilities", ++ "supportedSASLMechanisms", + NULL + }; + +@@ -868,6 +870,11 @@ + "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) { +@@ -993,6 +1000,7 @@ + OM_uint32 minor; + ber_len_t ssf; + int ret; ++ const char *mech = "GSSAPI"; + + if (conn->ldap_authenticated) + return ADCLI_SUCCESS; +@@ -1009,7 +1017,11 @@ + 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) */ +@@ -1175,6 +1187,7 @@ + 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); +@@ -1528,3 +1541,23 @@ + + 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; ++} +Index: adcli-0.8.2/library/adconn.h +=================================================================== +--- adcli-0.8.2.orig/library/adconn.h 2020-12-08 12:50:42.688404357 +1300 ++++ adcli-0.8.2/library/adconn.h 2020-12-08 12:50:42.684404284 +1300 +@@ -144,4 +144,7 @@ + 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); ++ + #endif /* ADCONN_H_ */ diff -Nru adcli-0.8.2/debian/patches/lp-1868703-02-add-option-use-ldaps.patch adcli-0.8.2/debian/patches/lp-1868703-02-add-option-use-ldaps.patch --- adcli-0.8.2/debian/patches/lp-1868703-02-add-option-use-ldaps.patch 1970-01-01 12:00:00.000000000 +1200 +++ adcli-0.8.2/debian/patches/lp-1868703-02-add-option-use-ldaps.patch 2020-12-08 12:50:58.000000000 +1300 @@ -0,0 +1,352 @@ +Description: add option use-ldaps +Author: Sumit Bose +From: Matthew Ruffell +Origin: https://gitlab.freedesktop.org/realmd/adcli/-/commit/85097245b57f190337225dbdbf6e33b58616c092 +Bug: https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/ADV190023 +Bug-Ubuntu: https://launchpad.net/bugs/1868703 + +Index: adcli-0.8.2/doc/adcli.xml +=================================================================== +--- adcli-0.8.2.orig/doc/adcli.xml 2020-12-08 12:50:55.768643491 +1300 ++++ adcli-0.8.2/doc/adcli.xml 2020-12-08 12:50:55.492638450 +1300 +@@ -131,6 +131,30 @@ + the name 'Administrator' will be used. + + ++ ++ 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. ++ 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. /etc/openldap/ldap.conf. ++ As an alternative it can be specified with the help of ++ an environment variable, e.g. ++ ++$ LDAPTLS_CACERT=/path/to/ad_dc_ca_cert.pem adcli join --use-ldaps -D domain.example.com ++... ++ ++ Please see ++ ldap.conf ++ 5 for details. ++ ++ ++ + + Don't show prompts for or read a + password from input. +Index: adcli-0.8.2/library/adconn.c +=================================================================== +--- adcli-0.8.2.orig/library/adconn.c 2020-12-08 12:50:55.768643491 +1300 ++++ adcli-0.8.2/library/adconn.c 2020-12-08 12:50:55.492638450 +1300 +@@ -70,6 +70,7 @@ + char *domain_name; + char *domain_realm; + char *domain_controller; ++ bool use_ldaps; + char *canonical_host; + char *domain_short; + adcli_disco *domain_disco; +@@ -744,7 +745,8 @@ + + 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; +@@ -754,6 +756,16 @@ + 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 +@@ -765,7 +777,7 @@ + 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; +@@ -781,7 +793,7 @@ + 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); +@@ -791,6 +803,25 @@ + 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; ++ } ++ } + } + } + +@@ -827,7 +858,8 @@ + 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; + +@@ -1012,14 +1044,28 @@ + 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); +@@ -1174,6 +1220,7 @@ + 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; + } + +@@ -1333,6 +1380,20 @@ + 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) + { +Index: adcli-0.8.2/library/adconn.h +=================================================================== +--- adcli-0.8.2.orig/library/adconn.h 2020-12-08 12:50:55.768643491 +1300 ++++ adcli-0.8.2/library/adconn.h 2020-12-08 12:50:55.492638450 +1300 +@@ -89,6 +89,10 @@ + 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); + + LDAP * adcli_conn_get_ldap_connection (adcli_conn *conn); +Index: adcli-0.8.2/tools/computer.c +=================================================================== +--- adcli-0.8.2.orig/tools/computer.c 2020-12-08 12:50:55.768643491 +1300 ++++ adcli-0.8.2/tools/computer.c 2020-12-08 12:50:55.676641810 +1300 +@@ -105,12 +105,14 @@ + opt_os_service_pack, + opt_user_principal, + opt_computer_password_lifetime, ++ 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" }, +@@ -261,6 +263,9 @@ + + adcli_enroll_set_computer_password_lifetime (enroll, lifetime); + return; ++ case opt_use_ldaps: ++ adcli_conn_set_use_ldaps (conn, true); ++ return; + case opt_verbose: + return; + +@@ -305,6 +310,7 @@ + { "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 }, +@@ -516,6 +522,7 @@ + { "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 }, +@@ -615,6 +622,7 @@ + { "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 }, +@@ -690,6 +698,7 @@ + { "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 }, +Index: adcli-0.8.2/tools/entry.c +=================================================================== +--- adcli-0.8.2.orig/tools/entry.c 2020-12-08 12:50:55.768643491 +1300 ++++ adcli-0.8.2/tools/entry.c 2020-12-08 12:50:55.768643491 +1300 +@@ -52,6 +52,7 @@ + opt_unix_uid, + opt_unix_gid, + opt_unix_shell, ++ opt_use_ldaps, + } Option; + + static adcli_tool_desc common_usages[] = { +@@ -65,6 +66,7 @@ + { 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 @@ + 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 @@ + { "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 @@ + { "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 @@ + { "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 @@ + { "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 @@ + { "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 @@ + { "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 -Nru adcli-0.8.2/debian/patches/lp-1868703-03-tools-add-missing-use-ldaps-option-to-update-and-testjoin.patch adcli-0.8.2/debian/patches/lp-1868703-03-tools-add-missing-use-ldaps-option-to-update-and-testjoin.patch --- adcli-0.8.2/debian/patches/lp-1868703-03-tools-add-missing-use-ldaps-option-to-update-and-testjoin.patch 1970-01-01 12:00:00.000000000 +1200 +++ adcli-0.8.2/debian/patches/lp-1868703-03-tools-add-missing-use-ldaps-option-to-update-and-testjoin.patch 2020-12-08 12:51:12.000000000 +1300 @@ -0,0 +1,19 @@ +Description: tools: add missing use-ldaps option to update and testjoin +Author: Sumit Bose +From: Matthew Ruffell +Origin: https://gitlab.freedesktop.org/realmd/adcli/-/commit/76ca1e6737742208d83e016d43a3379e378f8d90 +Bug: https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/ADV190023 +Bug-Ubuntu: https://launchpad.net/bugs/1868703 + +Index: adcli-0.8.2/tools/computer.c +=================================================================== +--- adcli-0.8.2.orig/tools/computer.c 2020-12-08 12:51:08.840882027 +1300 ++++ adcli-0.8.2/tools/computer.c 2020-12-08 12:51:08.840882027 +1300 +@@ -418,6 +418,7 @@ + struct option options[] = { + { "domain", required_argument, NULL, opt_domain }, + { "domain-controller", required_argument, NULL, opt_domain_controller }, ++ { "use-ldaps", no_argument, 0, opt_use_ldaps }, + { "host-fqdn", required_argument, 0, opt_host_fqdn }, + { "computer-name", required_argument, 0, opt_computer_name }, + { "host-keytab", required_argument, 0, opt_host_keytab }, diff -Nru adcli-0.8.2/debian/patches/series adcli-0.8.2/debian/patches/series --- adcli-0.8.2/debian/patches/series 2020-12-05 12:08:58.000000000 +1300 +++ adcli-0.8.2/debian/patches/series 2020-12-08 12:51:06.000000000 +1300 @@ -0,0 +1,3 @@ +lp-1868703-01-Use-GSS-SPNEGO-if-available.patch +lp-1868703-02-add-option-use-ldaps.patch +lp-1868703-03-tools-add-missing-use-ldaps-option-to-update-and-testjoin.patch