sssd/0013-ad-add-ad_use_ldaps.patch

439 lines
19 KiB
Diff

From da0be382d95f0bdbc6ad5ccb68503456c2ee858b Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 26 Sep 2019 20:27:09 +0200
Subject: [PATCH 11/13] ad: add ad_use_ldaps
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
With this new boolean option the AD provider should only use the LDAPS
port 636 and the Global Catalog port 3629 which is TLS protected as
well.
Related to https://pagure.io/SSSD/sssd/issue/4131
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/config/SSSDConfig/__init__.py.in | 1 +
src/config/cfg_rules.ini | 1 +
src/config/etc/sssd.api.d/sssd-ad.conf | 1 +
src/man/sssd-ad.5.xml | 20 +++++++++++++++++++
src/providers/ad/ad_common.c | 24 +++++++++++++++++++----
src/providers/ad/ad_common.h | 8 +++++++-
src/providers/ad/ad_init.c | 8 +++++++-
src/providers/ad/ad_opts.c | 1 +
src/providers/ad/ad_srv.c | 16 ++++++++++++---
src/providers/ad/ad_srv.h | 3 ++-
src/providers/ad/ad_subdomains.c | 21 ++++++++++++++++++--
src/providers/ipa/ipa_subdomains_server.c | 4 ++--
12 files changed, 94 insertions(+), 14 deletions(-)
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index eba89b461..84631862a 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -252,6 +252,7 @@ option_strings = {
'ad_site' : _('a particular site to be used by the client'),
'ad_maximum_machine_account_password_age' : _('Maximum age in days before the machine account password should be renewed'),
'ad_machine_account_password_renewal_opts' : _('Option for tuning the machine account renewal task'),
+ 'ad_use_ldaps' : _('Use LDAPS port for LDAP and Global Catalog requests'),
# [provider/krb5]
'krb5_kdcip' : _('Kerberos server address'),
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
index c56d5a668..1034a1fd6 100644
--- a/src/config/cfg_rules.ini
+++ b/src/config/cfg_rules.ini
@@ -464,6 +464,7 @@ option = ad_machine_account_password_renewal_opts
option = ad_maximum_machine_account_password_age
option = ad_server
option = ad_site
+option = ad_use_ldaps
# IPA provider specific options
option = ipa_anchor_uuid
diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf
index aaa0b2345..a2af72603 100644
--- a/src/config/etc/sssd.api.d/sssd-ad.conf
+++ b/src/config/etc/sssd.api.d/sssd-ad.conf
@@ -20,6 +20,7 @@ ad_gpo_default_right = str, None, false
ad_site = str, None, false
ad_maximum_machine_account_password_age = int, None, false
ad_machine_account_password_renewal_opts = str, None, false
+ad_use_ldaps = bool, None, false
ldap_uri = str, None, false
ldap_backup_uri = str, None, false
ldap_search_base = str, None, false
diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml
index fdcb4e4b9..ade56cd6d 100644
--- a/src/man/sssd-ad.5.xml
+++ b/src/man/sssd-ad.5.xml
@@ -1015,6 +1015,26 @@ ad_gpo_map_deny = +my_pam_service
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>ad_use_ldaps (bool)</term>
+ <listitem>
+ <para>
+ By default SSSD uses the plain LDAP port 389 and the
+ Global Catalog port 3628. If this option is set to
+ True SSSD will use the LDAPS port 636 and Global
+ Catalog port 3629 with LDAPS protection. Since AD
+ does not allow to have multiple encryption layers on
+ a single connection and we still want to use
+ SASL/GSSAPI or SASL/GSS-SPNEGO for authentication
+ the SASL security property maxssf is set to 0 (zero)
+ for those connections.
+ </para>
+ <para>
+ Default: False
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term>dyndns_update (boolean)</term>
<listitem>
diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c
index 600e3ceb2..a2369166a 100644
--- a/src/providers/ad/ad_common.c
+++ b/src/providers/ad/ad_common.c
@@ -729,6 +729,7 @@ ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *bectx,
const char *ad_gc_service,
const char *ad_domain,
bool use_kdcinfo,
+ bool ad_use_ldaps,
size_t n_lookahead_primary,
size_t n_lookahead_backup,
struct ad_service **_service)
@@ -746,6 +747,16 @@ ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *bectx,
goto done;
}
+ if (ad_use_ldaps) {
+ service->ldap_scheme = "ldaps";
+ service->port = LDAPS_PORT;
+ service->gc_port = AD_GC_LDAPS_PORT;
+ } else {
+ service->ldap_scheme = "ldap";
+ service->port = LDAP_PORT;
+ service->gc_port = AD_GC_PORT;
+ }
+
service->sdap = talloc_zero(service, struct sdap_service);
service->gc = talloc_zero(service, struct sdap_service);
if (!service->sdap || !service->gc) {
@@ -927,7 +938,8 @@ ad_resolve_callback(void *private_data, struct fo_server *server)
goto done;
}
- new_uri = talloc_asprintf(service->sdap, "ldap://%s", srv_name);
+ new_uri = talloc_asprintf(service->sdap, "%s://%s", service->ldap_scheme,
+ srv_name);
if (!new_uri) {
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy URI\n");
ret = ENOMEM;
@@ -935,7 +947,7 @@ ad_resolve_callback(void *private_data, struct fo_server *server)
}
DEBUG(SSSDBG_CONF_SETTINGS, "Constructed uri '%s'\n", new_uri);
- sockaddr = resolv_get_sockaddr_address(tmp_ctx, srvaddr, LDAP_PORT);
+ sockaddr = resolv_get_sockaddr_address(tmp_ctx, srvaddr, service->port);
if (sockaddr == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "resolv_get_sockaddr_address failed.\n");
ret = EIO;
@@ -951,8 +963,12 @@ ad_resolve_callback(void *private_data, struct fo_server *server)
talloc_zfree(service->gc->uri);
talloc_zfree(service->gc->sockaddr);
if (sdata && sdata->gc) {
- new_port = fo_get_server_port(server);
- new_port = (new_port == 0) ? AD_GC_PORT : new_port;
+ if (service->gc_port == AD_GC_LDAPS_PORT) {
+ new_port = service->gc_port;
+ } else {
+ new_port = fo_get_server_port(server);
+ new_port = (new_port == 0) ? service->gc_port : new_port;
+ }
service->gc->uri = talloc_asprintf(service->gc, "%s:%d",
new_uri, new_port);
diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h
index 75f11de2e..820e06124 100644
--- a/src/providers/ad/ad_common.h
+++ b/src/providers/ad/ad_common.h
@@ -29,7 +29,8 @@
#define AD_SERVICE_NAME "AD"
#define AD_GC_SERVICE_NAME "AD_GC"
/* The port the Global Catalog runs on */
-#define AD_GC_PORT 3268
+#define AD_GC_PORT 3268
+#define AD_GC_LDAPS_PORT 3269
#define AD_AT_OBJECT_SID "objectSID"
#define AD_AT_DNS_DOMAIN "DnsDomain"
@@ -67,6 +68,7 @@ enum ad_basic_opt {
AD_KRB5_CONFD_PATH,
AD_MAXIMUM_MACHINE_ACCOUNT_PASSWORD_AGE,
AD_MACHINE_ACCOUNT_PASSWORD_RENEWAL_OPTS,
+ AD_USE_LDAPS,
AD_OPTS_BASIC /* opts counter */
};
@@ -82,6 +84,9 @@ struct ad_service {
struct sdap_service *sdap;
struct sdap_service *gc;
struct krb5_service *krb5_service;
+ const char *ldap_scheme;
+ int port;
+ int gc_port;
};
struct ad_options {
@@ -147,6 +152,7 @@ ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *ctx,
const char *ad_gc_service,
const char *ad_domain,
bool use_kdcinfo,
+ bool ad_use_ldaps,
size_t n_lookahead_primary,
size_t n_lookahead_backup,
struct ad_service **_service);
diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c
index 290d5b5c1..2b4b9e2e7 100644
--- a/src/providers/ad/ad_init.c
+++ b/src/providers/ad/ad_init.c
@@ -138,6 +138,7 @@ static errno_t ad_init_options(TALLOC_CTX *mem_ctx,
char *ad_servers = NULL;
char *ad_backup_servers = NULL;
char *ad_realm;
+ bool ad_use_ldaps = false;
errno_t ret;
ad_sasl_initialize();
@@ -154,12 +155,14 @@ static errno_t ad_init_options(TALLOC_CTX *mem_ctx,
ad_servers = dp_opt_get_string(ad_options->basic, AD_SERVER);
ad_backup_servers = dp_opt_get_string(ad_options->basic, AD_BACKUP_SERVER);
ad_realm = dp_opt_get_string(ad_options->basic, AD_KRB5_REALM);
+ ad_use_ldaps = dp_opt_get_bool(ad_options->basic, AD_USE_LDAPS);
/* Set up the failover service */
ret = ad_failover_init(ad_options, be_ctx, ad_servers, ad_backup_servers,
ad_realm, AD_SERVICE_NAME, AD_GC_SERVICE_NAME,
dp_opt_get_string(ad_options->basic, AD_DOMAIN),
false, /* will be set in ad_get_auth_options() */
+ ad_use_ldaps,
(size_t) -1,
(size_t) -1,
&ad_options->service);
@@ -184,11 +187,13 @@ static errno_t ad_init_srv_plugin(struct be_ctx *be_ctx,
const char *ad_site_override;
bool sites_enabled;
errno_t ret;
+ bool ad_use_ldaps;
hostname = dp_opt_get_string(ad_options->basic, AD_HOSTNAME);
ad_domain = dp_opt_get_string(ad_options->basic, AD_DOMAIN);
ad_site_override = dp_opt_get_string(ad_options->basic, AD_SITE);
sites_enabled = dp_opt_get_bool(ad_options->basic, AD_ENABLE_DNS_SITES);
+ ad_use_ldaps = dp_opt_get_bool(ad_options->basic, AD_USE_LDAPS);
if (!sites_enabled) {
@@ -205,7 +210,8 @@ static errno_t ad_init_srv_plugin(struct be_ctx *be_ctx,
srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx, be_ctx->be_res,
default_host_dbs, ad_options->id,
hostname, ad_domain,
- ad_site_override);
+ ad_site_override,
+ ad_use_ldaps);
if (srv_ctx == NULL) {
DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n");
return ENOMEM;
diff --git a/src/providers/ad/ad_opts.c b/src/providers/ad/ad_opts.c
index 1293219ee..30f9b62fd 100644
--- a/src/providers/ad/ad_opts.c
+++ b/src/providers/ad/ad_opts.c
@@ -54,6 +54,7 @@ struct dp_option ad_basic_opts[] = {
{ "krb5_confd_path", DP_OPT_STRING, { KRB5_MAPPING_DIR }, NULL_STRING },
{ "ad_maximum_machine_account_password_age", DP_OPT_NUMBER, { .number = 30 }, NULL_NUMBER },
{ "ad_machine_account_password_renewal_opts", DP_OPT_STRING, { "86400:750" }, NULL_STRING },
+ { "ad_use_ldaps", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
DP_OPTION_TERMINATOR
};
diff --git a/src/providers/ad/ad_srv.c b/src/providers/ad/ad_srv.c
index 5fd25f60e..ca15d3715 100644
--- a/src/providers/ad/ad_srv.c
+++ b/src/providers/ad/ad_srv.c
@@ -244,6 +244,7 @@ struct ad_get_client_site_state {
enum host_database *host_db;
struct sdap_options *opts;
const char *ad_domain;
+ bool ad_use_ldaps;
struct fo_server_info *dcs;
size_t num_dcs;
size_t dc_index;
@@ -264,6 +265,7 @@ struct tevent_req *ad_get_client_site_send(TALLOC_CTX *mem_ctx,
enum host_database *host_db,
struct sdap_options *opts,
const char *ad_domain,
+ bool ad_use_ldaps,
struct fo_server_info *dcs,
size_t num_dcs)
{
@@ -288,6 +290,7 @@ struct tevent_req *ad_get_client_site_send(TALLOC_CTX *mem_ctx,
state->host_db = host_db;
state->opts = opts;
state->ad_domain = ad_domain;
+ state->ad_use_ldaps = ad_use_ldaps;
state->dcs = dcs;
state->num_dcs = num_dcs;
@@ -331,8 +334,11 @@ static errno_t ad_get_client_site_next_dc(struct tevent_req *req)
subreq = sdap_connect_host_send(state, state->ev, state->opts,
state->be_res->resolv,
state->be_res->family_order,
- state->host_db, "ldap", state->dc.host,
- state->dc.port, false);
+ state->host_db,
+ state->ad_use_ldaps ? "ldaps" : "ldap",
+ state->dc.host,
+ state->ad_use_ldaps ? 636 : state->dc.port,
+ false);
if (subreq == NULL) {
ret = ENOMEM;
goto done;
@@ -491,6 +497,7 @@ struct ad_srv_plugin_ctx {
const char *ad_domain;
const char *ad_site_override;
const char *current_site;
+ bool ad_use_ldaps;
};
struct ad_srv_plugin_ctx *
@@ -501,7 +508,8 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
struct sdap_options *opts,
const char *hostname,
const char *ad_domain,
- const char *ad_site_override)
+ const char *ad_site_override,
+ bool ad_use_ldaps)
{
struct ad_srv_plugin_ctx *ctx = NULL;
errno_t ret;
@@ -515,6 +523,7 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
ctx->be_res = be_res;
ctx->host_dbs = host_dbs;
ctx->opts = opts;
+ ctx->ad_use_ldaps = ad_use_ldaps;
ctx->hostname = talloc_strdup(ctx, hostname);
if (ctx->hostname == NULL) {
@@ -714,6 +723,7 @@ static void ad_srv_plugin_dcs_done(struct tevent_req *subreq)
state->ctx->host_dbs,
state->ctx->opts,
state->discovery_domain,
+ state->ctx->ad_use_ldaps,
dcs, num_dcs);
if (subreq == NULL) {
ret = ENOMEM;
diff --git a/src/providers/ad/ad_srv.h b/src/providers/ad/ad_srv.h
index e553d594d..8e410ec26 100644
--- a/src/providers/ad/ad_srv.h
+++ b/src/providers/ad/ad_srv.h
@@ -31,7 +31,8 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
struct sdap_options *opts,
const char *hostname,
const char *ad_domain,
- const char *ad_site_override);
+ const char *ad_site_override,
+ bool ad_use_ldaps);
struct tevent_req *ad_srv_plugin_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index 2ce34489f..d8c201437 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -282,6 +282,7 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
bool use_kdcinfo = false;
size_t n_lookahead_primary = SSS_KRB5_LOOKAHEAD_PRIMARY_DEFAULT;
size_t n_lookahead_backup = SSS_KRB5_LOOKAHEAD_BACKUP_DEFAULT;
+ bool ad_use_ldaps = false;
realm = dp_opt_get_cstring(id_ctx->ad_options->basic, AD_KRB5_REALM);
hostname = dp_opt_get_cstring(id_ctx->ad_options->basic, AD_HOSTNAME);
@@ -312,6 +313,21 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
return ENOMEM;
}
+ ret = ad_inherit_opts_if_needed(id_ctx->ad_options->basic,
+ ad_options->basic,
+ be_ctx->cdb, subdom_conf_path,
+ AD_USE_LDAPS);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Failed to inherit option [%s] to sub-domain [%s]. "
+ "This error is ignored but might cause issues or unexpected "
+ "behavior later on.\n",
+ id_ctx->ad_options->basic[AD_USE_LDAPS].opt_name,
+ subdom->name);
+
+ return ret;
+ }
+
ret = ad_inherit_opts_if_needed(id_ctx->sdap_id_ctx->opts->basic,
ad_options->id->basic,
be_ctx->cdb, subdom_conf_path,
@@ -344,6 +360,7 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
servers = dp_opt_get_string(ad_options->basic, AD_SERVER);
backup_servers = dp_opt_get_string(ad_options->basic, AD_BACKUP_SERVER);
+ ad_use_ldaps = dp_opt_get_bool(ad_options->basic, AD_USE_LDAPS);
if (id_ctx->ad_options->auth_ctx != NULL
&& id_ctx->ad_options->auth_ctx->opts != NULL) {
@@ -362,7 +379,7 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
ret = ad_failover_init(ad_options, be_ctx, servers, backup_servers,
subdom->realm, service_name, gc_service_name,
- subdom->name, use_kdcinfo,
+ subdom->name, use_kdcinfo, ad_use_ldaps,
n_lookahead_primary,
n_lookahead_backup,
&ad_options->service);
@@ -386,7 +403,7 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
ad_id_ctx->ad_options->id,
hostname,
ad_domain,
- ad_site_override);
+ ad_site_override, ad_use_ldaps);
if (srv_ctx == NULL) {
DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n");
return ENOMEM;
diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c
index fd998877b..9aebf72a5 100644
--- a/src/providers/ipa/ipa_subdomains_server.c
+++ b/src/providers/ipa/ipa_subdomains_server.c
@@ -319,7 +319,7 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx,
ret = ad_failover_init(ad_options, be_ctx, ad_servers, ad_backup_servers,
subdom->realm,
service_name, gc_service_name,
- subdom->name, use_kdcinfo,
+ subdom->name, use_kdcinfo, false,
n_lookahead_primary, n_lookahead_backup,
&ad_options->service);
if (ret != EOK) {
@@ -344,7 +344,7 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx,
ad_id_ctx->ad_options->id,
id_ctx->server_mode->hostname,
ad_domain,
- ad_site_override);
+ ad_site_override, false);
if (srv_ctx == NULL) {
DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n");
return ENOMEM;
--
2.20.1