import adcli-0.8.2-6.el8

This commit is contained in:
CentOS Sources 2020-07-28 02:11:38 -04:00 committed by Stepan Oksanichenko
parent c145c6138e
commit 8d46620b37
9 changed files with 921 additions and 1 deletions

View File

@ -0,0 +1,216 @@
From 0a0d0f66409eb83e06b7dc50543c2f6c15a36bc4 Mon Sep 17 00:00:00 2001
From: Alexey A Nikitin <nikitin@amazon.com>
Date: Mon, 29 Oct 2018 20:40:36 -0700
Subject: [PATCH] Make 'adcli info' DC location mechanism more compliant with
[MS-ADTS] and [MS-NRPC]
AD specifications say that DC locator must attempt to find a suitable DC for the client. That means going through all of the DCs in SRV RRs one by one until one of them answers.
The problem with adcli's original behavior is that it queries only five DCs from SRV, ever. This becomes a problem if for any reason there is a large number of DCs in the domain from which the client cannot get a CLDAP response.
---
library/addisco.c | 146 +++++++++++++++++++++++++++++-----------------
1 file changed, 94 insertions(+), 52 deletions(-)
diff --git a/library/addisco.c b/library/addisco.c
index 8cc5bf0..6e73ead 100644
--- a/library/addisco.c
+++ b/library/addisco.c
@@ -41,8 +41,10 @@
#include <string.h>
#include <time.h>
-/* Number of servers to do discovery against */
-#define DISCO_COUNT 5
+/* Number of servers to do discovery against.
+ * For AD DS maximum number of DCs is 1200.
+ */
+#define DISCO_COUNT 1200
/* The time period in which to do rapid requests */
#define DISCO_FEVER 1
@@ -453,6 +455,51 @@ parse_disco (LDAP *ldap,
return usability;
}
+static int
+ldap_disco_poller (LDAP **ldap,
+ LDAPMessage **message,
+ adcli_disco **results,
+ const char **addrs)
+{
+ int found = ADCLI_DISCO_UNUSABLE;
+ int close_ldap;
+ int parsed;
+ int ret = 0;
+ struct timeval tvpoll = { 0, 0 };
+
+ switch (ldap_result (*ldap, LDAP_RES_ANY, 1, &tvpoll, message)) {
+ case LDAP_RES_SEARCH_ENTRY:
+ case LDAP_RES_SEARCH_RESULT:
+ parsed = parse_disco (*ldap, *addrs, *message, results);
+ if (parsed > found)
+ found = parsed;
+ ldap_msgfree (*message);
+ close_ldap = 1;
+ break;
+ case -1:
+ ldap_get_option (*ldap, LDAP_OPT_RESULT_CODE, &ret);
+ close_ldap = 1;
+ break;
+ default:
+ ldap_msgfree (*message);
+ close_ldap = 0;
+ break;
+ }
+
+ if (ret != LDAP_SUCCESS) {
+ _adcli_ldap_handle_failure (*ldap, ADCLI_ERR_CONFIG,
+ "Couldn't perform discovery search");
+ }
+
+ /* Done with this connection */
+ if (close_ldap) {
+ ldap_unbind_ext_s (*ldap, NULL, NULL);
+ *ldap = NULL;
+ }
+
+ return found;
+}
+
static int
ldap_disco (const char *domain,
srvinfo *srv,
@@ -477,6 +524,7 @@ ldap_disco (const char *domain,
int num, i;
int ret;
int have_any = 0;
+ struct timeval interval;
if (domain) {
value = _adcli_ldap_escape_filter (domain);
@@ -540,7 +588,6 @@ ldap_disco (const char *domain,
version = LDAP_VERSION3;
ldap_set_option (ldap[num], LDAP_OPT_PROTOCOL_VERSION, &version);
ldap_set_option (ldap[num], LDAP_OPT_REFERRALS , 0);
- _adcli_info ("Sending netlogon pings to domain controller: %s", url);
addrs[num] = srv->hostname;
have_any = 1;
num++;
@@ -555,70 +602,65 @@ ldap_disco (const char *domain,
freeaddrinfo (res);
}
- /* Wait for the first response. Poor mans fd watch */
- for (started = now = time (NULL);
- have_any && found != ADCLI_DISCO_USABLE && now < started + DISCO_TIME;
- now = time (NULL)) {
+ /* Initial send and short time wait */
+ interval.tv_sec = 0;
+ for (i = 0; ADCLI_DISCO_UNUSABLE == found && i < num; ++i) {
+ int parsed;
+
+ if (NULL == ldap[i])
+ continue;
- struct timeval tvpoll = { 0, 0 };
- struct timeval interval;
+ have_any = 1;
+ _adcli_info ("Sending NetLogon ping to domain controller: %s", addrs[i]);
- /* If in the initial period, send feverishly */
- if (now < started + DISCO_FEVER) {
- interval.tv_sec = 0;
- interval.tv_usec = 100 * 1000;
+ ret = ldap_search_ext (ldap[i], "", LDAP_SCOPE_BASE,
+ filter, attrs, 0, NULL, NULL, NULL,
+ -1, &msgidp);
+
+ if (ret != LDAP_SUCCESS) {
+ _adcli_ldap_handle_failure (ldap[i], ADCLI_ERR_CONFIG,
+ "Couldn't perform discovery search");
+ ldap_unbind_ext_s (ldap[i], NULL, NULL);
+ ldap[i] = NULL;
+ }
+
+ /* From https://msdn.microsoft.com/en-us/library/ff718294.aspx first
+ * five DCs are given 0.4 seconds timeout, next five are given 0.2
+ * seconds, and the rest are given 0.1 seconds
+ */
+ if (i < 5) {
+ interval.tv_usec = 400000;
+ } else if (i < 10) {
+ interval.tv_usec = 200000;
} else {
- interval.tv_sec = 1;
- interval.tv_usec = 0;
+ interval.tv_usec = 100000;
}
+ select (0, NULL, NULL, NULL, &interval);
+
+ parsed = ldap_disco_poller (&(ldap[i]), &message, results, &(addrs[i]));
+ if (parsed > found)
+ found = parsed;
+ }
+
+ /* Wait some more until LDAP timeout (DISCO_TIME) */
+ for (started = now = time (NULL);
+ have_any && ADCLI_DISCO_UNUSABLE == found && now < started + DISCO_TIME;
+ now = time (NULL)) {
select (0, NULL, NULL, NULL, &interval);
have_any = 0;
- for (i = 0; found != ADCLI_DISCO_USABLE && i < num; i++) {
- int close_ldap;
+ for (i = 0; ADCLI_DISCO_UNUSABLE == found && i < num; ++i) {
int parsed;
if (ldap[i] == NULL)
continue;
- ret = 0;
have_any = 1;
- switch (ldap_result (ldap[i], LDAP_RES_ANY, 1, &tvpoll, &message)) {
- case LDAP_RES_SEARCH_ENTRY:
- case LDAP_RES_SEARCH_RESULT:
- parsed = parse_disco (ldap[i], addrs[i], message, results);
- if (parsed > found)
- found = parsed;
- ldap_msgfree (message);
- close_ldap = 1;
- break;
- case 0:
- ret = ldap_search_ext (ldap[i], "", LDAP_SCOPE_BASE,
- filter, attrs, 0, NULL, NULL, NULL,
- -1, &msgidp);
- close_ldap = (ret != 0);
- break;
- case -1:
- ldap_get_option (ldap[i], LDAP_OPT_RESULT_CODE, &ret);
- close_ldap = 1;
- break;
- default:
- ldap_msgfree (message);
- close_ldap = 0;
- break;
- }
-
- if (ret != LDAP_SUCCESS) {
- _adcli_ldap_handle_failure (ldap[i], ADCLI_ERR_CONFIG,
- "Couldn't perform discovery search");
- }
- /* Done with this connection */
- if (close_ldap) {
- ldap_unbind_ext_s (ldap[i], NULL, NULL);
- ldap[i] = NULL;
- }
+ parsed = ldap_disco_poller (&(ldap[i]), &message, results, &(addrs[i]));
+ if (parsed > found)
+ found = parsed;
}
}
--
2.26.2

View File

@ -0,0 +1,124 @@
From a6f795ba3d6048b32d7863468688bf7f42b2cafd Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
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
---
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 bcaced8..ffb54f9 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);
@@ -1606,6 +1619,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 1ad5715..37ebdd9 100644
--- a/library/adconn.h
+++ b/library/adconn.h
@@ -149,6 +149,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.21.0

View File

@ -0,0 +1,32 @@
From 40d3be22f6e518e4354aa7c3d0278291fcbed32f Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 5 Jun 2020 17:06:58 +0200
Subject: [PATCH] delete: do not exit if keytab cannot be read
Reading the keytab is not required when deleting a host object in AD. It
is only needed in the case where the host was added with a manual set
NetBIOS name (--computer-name option) which does not match the short
hostname and no computer name was given at the delete-computer command
line.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1840752
---
tools/computer.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/tools/computer.c b/tools/computer.c
index 292c4d8..a90c4b2 100644
--- a/tools/computer.c
+++ b/tools/computer.c
@@ -952,8 +952,6 @@ adcli_tool_computer_delete (adcli_conn *conn,
if (res != ADCLI_SUCCESS) {
warnx ("couldn't lookup domain info from keytab: %s",
adcli_get_last_error ());
- adcli_enroll_unref (enroll);
- return -res;
}
res = adcli_conn_connect (conn);
--
2.26.2

View File

@ -0,0 +1,27 @@
From 08bac0946de29f3e5de90743ce6dfc7118d4ad20 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 11 Feb 2020 17:42:03 +0100
Subject: [PATCH] discovery fix
Do not continue processing on closed connection.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1802258
---
library/addisco.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/library/addisco.c b/library/addisco.c
index 6e73ead..f3b3546 100644
--- a/library/addisco.c
+++ b/library/addisco.c
@@ -622,6 +622,7 @@ ldap_disco (const char *domain,
"Couldn't perform discovery search");
ldap_unbind_ext_s (ldap[i], NULL, NULL);
ldap[i] = NULL;
+ continue;
}
/* From https://msdn.microsoft.com/en-us/library/ff718294.aspx first
--
2.26.2

View File

@ -0,0 +1,44 @@
From 93a39bd12db11dd407676f428cfbc30406a88c36 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 15 Jun 2020 15:57:47 +0200
Subject: [PATCH] man: explain optional parameter of login-ccache better
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1791545
---
doc/adcli.xml | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/doc/adcli.xml b/doc/adcli.xml
index acced25..ecf8726 100644
--- a/doc/adcli.xml
+++ b/doc/adcli.xml
@@ -155,13 +155,19 @@ $ LDAPTLS_CACERT=/path/to/ad_dc_ca_cert.pem adcli join --use-ldaps -D domain.exa
<varlistentry>
<term><option>-C, --login-ccache=<parameter>ccache_name</parameter></option></term>
<listitem><para>Use the specified kerberos credential
- cache to authenticate with the domain. If no credential
- cache is specified, the default kerberos credential
- cache will be used. Credential caches of type FILE can
- be given with the path to the file. For other
- credential cache types, e.g. DIR, KEYRING or KCM, the
- type must be specified explicitly together with a
- suitable identifier.</para></listitem>
+ cache to authenticate with the domain. If no credential
+ cache is specified, the default kerberos credential
+ cache will be used. Credential caches of type FILE can
+ be given with the path to the file. For other
+ credential cache types, e.g. DIR, KEYRING or KCM, the
+ type must be specified explicitly together with a
+ suitable identifier.</para>
+ <para>Please note that since the
+ <parameter>ccache_name</parameter> is optional the
+ =(equal) sign is mandatory. If = is missing the
+ parameter is treated as optionless extra argument. How
+ this is handled depends on the specific sub-command.
+ </para></listitem>
</varlistentry>
<varlistentry>
<term><option>-U, --login-user=<parameter>User</parameter></option></term>
--
2.26.2

View File

@ -0,0 +1,41 @@
From 50d580c58dab5928cadfc6ca82aedccee58eaced Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 5 Jun 2020 17:28:28 +0200
Subject: [PATCH] tools: disable SSSD's locator plugin
MIT's libkrb5 checks available locator plugins first before checking the
config file. This might cause issues when the locator plugin returns a
different DC than the one used for the LDAP connection if some data must
be replicated.
This patch sets the SSSD_KRB5_LOCATOR_DISABLE environment variable to
'true' to disable SSSD's locator plugin for adcli.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1762633
---
tools/tools.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tools/tools.c b/tools/tools.c
index 9d422f2..1b6d879 100644
--- a/tools/tools.c
+++ b/tools/tools.c
@@ -296,6 +296,7 @@ cleanup_krb5_conf_directory (void)
}
unsetenv ("KRB5_CONFIG");
+ unsetenv ("SSSD_KRB5_LOCATOR_DISABLE");
}
static void
@@ -394,6 +395,7 @@ setup_krb5_conf_directory (adcli_conn *conn)
adcli_krb5_conf_filename = filename;
adcli_krb5_d_directory = snippets;
setenv ("KRB5_CONFIG", adcli_krb5_conf_filename, 1);
+ setenv ("SSSD_KRB5_LOCATOR_DISABLE", "true", 1);
} else {
free (filename);
--
2.26.2

View File

@ -0,0 +1,26 @@
From d70075c597e7ebc1683d407409c45b04110676a0 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 15 Jun 2020 15:41:53 +0200
Subject: [PATCH] tools: fix typo in show-password help output
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1791611
---
tools/computer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/computer.c b/tools/computer.c
index a90c4b2..24ea258 100644
--- a/tools/computer.c
+++ b/tools/computer.c
@@ -154,7 +154,7 @@ static adcli_tool_desc common_usages[] = {
"accounts" },
{ opt_show_details, "show information about joining the domain after\n"
"a successful join" },
- { opt_show_password, "show computer account password after after a\n"
+ { opt_show_password, "show computer account password after a\n"
"successful join" },
{ opt_add_samba_data, "add domain SID and computer account password\n"
"to the Samba specific configuration database" },
--
2.26.2

View File

@ -0,0 +1,378 @@
From 85097245b57f190337225dbdbf6e33b58616c092 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
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
---
doc/adcli.xml | 24 +++++++++++++++
library/adconn.c | 79 ++++++++++++++++++++++++++++++++++++++++++------
library/adconn.h | 4 +++
tools/computer.c | 10 ++++++
tools/entry.c | 11 +++++++
5 files changed, 119 insertions(+), 9 deletions(-)
diff --git a/doc/adcli.xml b/doc/adcli.xml
index dd30435..acced25 100644
--- a/doc/adcli.xml
+++ b/doc/adcli.xml
@@ -128,6 +128,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 ffb54f9..7bab852 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 37ebdd9..1d5faa8 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 840e334..292c4d8 100644
--- a/tools/computer.c
+++ b/tools/computer.c
@@ -113,12 +113,14 @@ typedef enum {
opt_add_service_principal,
opt_remove_service_principal,
opt_description,
+ 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" },
@@ -311,6 +313,9 @@ parse_option (Option opt,
case opt_description:
adcli_enroll_set_description (enroll, optarg);
return ADCLI_SUCCESS;
+ case opt_use_ldaps:
+ adcli_conn_set_use_ldaps (conn, true);
+ return ADCLI_SUCCESS;
case opt_verbose:
return ADCLI_SUCCESS;
@@ -357,6 +362,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 },
@@ -688,6 +694,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 },
@@ -800,6 +807,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 },
@@ -888,6 +896,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 },
@@ -985,6 +994,7 @@ adcli_tool_computer_show (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 },
diff --git a/tools/entry.c b/tools/entry.c
index f361845..05e4313 100644
--- a/tools/entry.c
+++ b/tools/entry.c
@@ -53,6 +53,7 @@ typedef enum {
opt_unix_gid,
opt_unix_shell,
opt_nis_domain,
+ opt_use_ldaps,
} Option;
static adcli_tool_desc common_usages[] = {
@@ -67,6 +68,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"
@@ -136,6 +138,9 @@ parse_option (Option opt,
stdin_password = 1;
}
return ADCLI_SUCCESS;
+ case opt_use_ldaps:
+ adcli_conn_set_use_ldaps (conn, true);
+ return ADCLI_SUCCESS;
case opt_verbose:
return ADCLI_SUCCESS;
default:
@@ -172,6 +177,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 },
@@ -306,6 +312,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 },
@@ -394,6 +401,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 },
@@ -496,6 +504,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 },
@@ -622,6 +631,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 },
@@ -722,6 +732,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.21.0

View File

@ -1,6 +1,6 @@
Name: adcli
Version: 0.8.2
Release: 4%{?dist}
Release: 6%{?dist}
Summary: Active Directory enrollment
License: LGPLv2+
URL: http://cgit.freedesktop.org/realmd/adcli
@ -104,6 +104,26 @@ Patch58: 0001-Fix-for-issue-found-by-Coverity.patch
Patch59: 0001-tools-add-show-computer-command.patch
Patch60: 0002-add-description-option-to-join-and-update.patch
Patch61: 0001-Use-GSS-SPNEGO-if-available.patch
Patch62: 0002-add-option-use-ldaps.patch
# rhbz#1806260 - [abrt] [faf] adcli: raise(): /usr/sbin/adcli killed by 6
Patch63: 0001-Make-adcli-info-DC-location-mechanism-more-compliant.patch
Patch64: 0001-discovery-fix.patch
# rhbz#1846882 - No longer able to delete computer from AD using adcli
Patch65: 0001-delete-do-not-exit-if-keytab-cannot-be-read.patch
# rhbz#1846878 - adcli: presetting $computer in $domain domain failed: Cannot
# set computer password: Authentication error
Patch66: 0001-tools-disable-SSSD-s-locator-plugin.patch
# rhbz#1791611 - Typo in adcli update --help option
Patch67: 0001-tools-fix-typo-in-show-password-help-output.patch
# rhbz#1791545 - Manpage and help does not explain the use of "-C" option
Patch68: 0001-man-explain-optional-parameter-of-login-ccache-bette.patch
BuildRequires: gcc
BuildRequires: intltool pkgconfig
BuildRequires: libtool
@ -164,6 +184,18 @@ documentation.
%doc %{_datadir}/doc/adcli/*
%changelog
* Mon Jun 15 2020 Sumit Bose <sbose@redhat.com> - 0.8.2-6
- [abrt] [faf] adcli: raise(): /usr/sbin/adcli killed by 6 [#1806260]
- No longer able to delete computer from AD using adcli [#1846882]
- adcli: presetting $computer in $domain domain failed: Cannot set computer
password: Authentication error [#1846878]
- Typo in adcli update --help option [#1791611]
- Manpage and help does not explain the use of "-C" option [#1791545]
* Wed Jan 29 2020 Sumit Bose <sbose@redhat.com> - 0.8.2-5
- adcli should be able to Force LDAPS over 636 with AD Access Provider w.r.t
sssd [#1762420]
* Thu Nov 28 2019 Sumit Bose <sbose@redhat.com> - 0.8.2-4
- adcli update --add-samba-data does not work as expected [#1745931]
- Issue is that with arcfour-hmac as first encryption type [#1745932]