From 72b64ad80de46fcab3aa3a7238a20414514bc4af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C5=BDidek?= Date: Thu, 27 Feb 2020 03:40:28 +0100 Subject: [PATCH] Resolves: upstream#4131 Force LDAPS over 636 with AD Provider --- ...oleans-for-ad_inherit_opts_if_needed.patch | 55 +++ 0013-ad-add-ad_use_ldaps.patch | 438 ++++++++++++++++++ ...ldap-add-new-option-ldap_sasl_maxssf.patch | 199 ++++++++ 0015-ad-set-min-and-max-ssf-for-ldaps.patch | 91 ++++ sssd.spec | 9 +- 5 files changed, 791 insertions(+), 1 deletion(-) create mode 100644 0012-ad-allow-booleans-for-ad_inherit_opts_if_needed.patch create mode 100644 0013-ad-add-ad_use_ldaps.patch create mode 100644 0014-ldap-add-new-option-ldap_sasl_maxssf.patch create mode 100644 0015-ad-set-min-and-max-ssf-for-ldaps.patch diff --git a/0012-ad-allow-booleans-for-ad_inherit_opts_if_needed.patch b/0012-ad-allow-booleans-for-ad_inherit_opts_if_needed.patch new file mode 100644 index 0000000..ebe3fd5 --- /dev/null +++ b/0012-ad-allow-booleans-for-ad_inherit_opts_if_needed.patch @@ -0,0 +1,55 @@ +From 090cf77a0fd5f300a753667658af3ed763a88e83 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Thu, 26 Sep 2019 20:24:34 +0200 +Subject: [PATCH 12/15] ad: allow booleans for ad_inherit_opts_if_needed() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Currently ad_inherit_opts_if_needed() can only handle strings. With this +patch it can handle boolean options as well. + +Related to https://pagure.io/SSSD/sssd/issue/4131 + +Reviewed-by: Pavel Březina +--- + src/providers/ad/ad_common.c | 23 ++++++++++++++++++++--- + 1 file changed, 20 insertions(+), 3 deletions(-) + +diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c +index 5540066d4..600e3ceb2 100644 +--- a/src/providers/ad/ad_common.c ++++ b/src/providers/ad/ad_common.c +@@ -1479,9 +1479,26 @@ errno_t ad_inherit_opts_if_needed(struct dp_option *parent_opts, + const char *parent_val = NULL; + char *dummy = NULL; + char *option_list[2] = { NULL, NULL }; +- +- parent_val = dp_opt_get_cstring(parent_opts, opt_id); +- if (parent_val != NULL) { ++ bool is_default = true; ++ ++ switch (parent_opts[opt_id].type) { ++ case DP_OPT_STRING: ++ parent_val = dp_opt_get_cstring(parent_opts, opt_id); ++ break; ++ case DP_OPT_BOOL: ++ /* For booleans it is hard to say if the option is set or not since ++ * both possible values are valid ones. So we check if the value is ++ * different from the default and skip if it is the default. In this ++ * case the sub-domain option would either be the default as well or ++ * manully set and in both cases we do not have to change it. */ ++ is_default = (parent_opts[opt_id].val.boolean ++ == parent_opts[opt_id].def_val.boolean); ++ break; ++ default: ++ DEBUG(SSSDBG_TRACE_FUNC, "Unsupported type, skipping.\n"); ++ } ++ ++ if (parent_val != NULL || !is_default) { + ret = confdb_get_string(cdb, NULL, subdom_conf_path, + parent_opts[opt_id].opt_name, NULL, &dummy); + if (ret != EOK) { +-- +2.20.1 + diff --git a/0013-ad-add-ad_use_ldaps.patch b/0013-ad-add-ad_use_ldaps.patch new file mode 100644 index 0000000..4b23943 --- /dev/null +++ b/0013-ad-add-ad_use_ldaps.patch @@ -0,0 +1,438 @@ +From da0be382d95f0bdbc6ad5ccb68503456c2ee858b Mon Sep 17 00:00:00 2001 +From: Sumit Bose +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 +--- + 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 + + + ++ ++ ad_use_ldaps (bool) ++ ++ ++ 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. ++ ++ ++ Default: False ++ ++ ++ ++ + + dyndns_update (boolean) + +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 + diff --git a/0014-ldap-add-new-option-ldap_sasl_maxssf.patch b/0014-ldap-add-new-option-ldap_sasl_maxssf.patch new file mode 100644 index 0000000..3659564 --- /dev/null +++ b/0014-ldap-add-new-option-ldap_sasl_maxssf.patch @@ -0,0 +1,199 @@ +From 78649907b81b4bdaf8fc6a6e6ae55ed3cd5419f5 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 27 Sep 2019 11:49:59 +0200 +Subject: [PATCH 14/15] ldap: add new option ldap_sasl_maxssf +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There is already the ldap_sasl_minssf option. To be able to control the +maximal security strength factor (ssf) e.g. when using SASL together +with TLS the option ldap_sasl_maxssf is added as well. + +Related to https://pagure.io/SSSD/sssd/issue/4131 + +Reviewed-by: Pavel Březina +--- + src/config/SSSDConfig/__init__.py.in | 1 + + src/config/cfg_rules.ini | 1 + + src/config/etc/sssd.api.d/sssd-ad.conf | 1 + + src/config/etc/sssd.api.d/sssd-ipa.conf | 1 + + src/config/etc/sssd.api.d/sssd-ldap.conf | 1 + + src/man/sssd-ldap.5.xml | 16 ++++++++++++++++ + src/providers/ad/ad_opts.c | 1 + + src/providers/ipa/ipa_opts.c | 1 + + src/providers/ldap/ldap_opts.c | 1 + + src/providers/ldap/sdap.h | 1 + + src/providers/ldap/sdap_async_connection.c | 14 ++++++++++++++ + 11 files changed, 39 insertions(+) + +diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in +index 6c2a1ce44..b3035fcff 100644 +--- a/src/config/SSSDConfig/__init__.py.in ++++ b/src/config/SSSDConfig/__init__.py.in +@@ -306,6 +306,7 @@ option_strings = { + 'ldap_sasl_authid' : _('Specify the sasl authorization id to use'), + 'ldap_sasl_realm' : _('Specify the sasl authorization realm to use'), + 'ldap_sasl_minssf' : _('Specify the minimal SSF for LDAP sasl authorization'), ++ 'ldap_sasl_maxssf' : _('Specify the maximal SSF for LDAP sasl authorization'), + 'ldap_krb5_keytab' : _('Kerberos service keytab'), + 'ldap_krb5_init_creds' : _('Use Kerberos auth for LDAP connection'), + 'ldap_referrals' : _('Follow LDAP referrals'), +diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini +index 478ca9eb4..286443be4 100644 +--- a/src/config/cfg_rules.ini ++++ b/src/config/cfg_rules.ini +@@ -665,6 +665,7 @@ option = ldap_sasl_authid + option = ldap_sasl_canonicalize + option = ldap_sasl_mech + option = ldap_sasl_minssf ++option = ldap_sasl_maxssf + option = ldap_schema + option = ldap_pwmodify_mode + option = ldap_search_base +diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf +index 51cdad536..4d10e69d7 100644 +--- a/src/config/etc/sssd.api.d/sssd-ad.conf ++++ b/src/config/etc/sssd.api.d/sssd-ad.conf +@@ -42,6 +42,7 @@ ldap_tls_reqcert = str, None, false + ldap_sasl_mech = str, None, false + ldap_sasl_authid = str, None, false + ldap_sasl_minssf = int, None, false ++ldap_sasl_maxssf = int, None, false + krb5_kdcip = str, None, false + krb5_server = str, None, false + krb5_backup_server = str, None, false +diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf +index 7ed153d36..839f9f471 100644 +--- a/src/config/etc/sssd.api.d/sssd-ipa.conf ++++ b/src/config/etc/sssd.api.d/sssd-ipa.conf +@@ -32,6 +32,7 @@ ldap_tls_reqcert = str, None, false + ldap_sasl_mech = str, None, false + ldap_sasl_authid = str, None, false + ldap_sasl_minssf = int, None, false ++ldap_sasl_maxssf = int, None, false + krb5_kdcip = str, None, false + krb5_server = str, None, false + krb5_backup_server = str, None, false +diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf +index 4f73e901e..6db9828b9 100644 +--- a/src/config/etc/sssd.api.d/sssd-ldap.conf ++++ b/src/config/etc/sssd.api.d/sssd-ldap.conf +@@ -35,6 +35,7 @@ ldap_page_size = int, None, false + ldap_deref_threshold = int, None, false + ldap_sasl_canonicalize = bool, None, false + ldap_sasl_minssf = int, None, false ++ldap_sasl_maxssf = int, None, false + ldap_connection_expire_timeout = int, None, false + ldap_connection_expire_offset = int, None, false + ldap_disable_paging = bool, None, false +diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml +index f8bb973c7..0dc675410 100644 +--- a/src/man/sssd-ldap.5.xml ++++ b/src/man/sssd-ldap.5.xml +@@ -612,6 +612,22 @@ + + + ++ ++ ldap_sasl_maxssf (integer) ++ ++ ++ When communicating with an LDAP server using SASL, ++ specify the maximal security level necessary to ++ establish the connection. The values of this ++ option are defined by OpenLDAP. ++ ++ ++ Default: Use the system default (usually specified ++ by ldap.conf) ++ ++ ++ ++ + + ldap_deref_threshold (integer) + +diff --git a/src/providers/ad/ad_opts.c b/src/providers/ad/ad_opts.c +index 26420d655..e9a3dd6ef 100644 +--- a/src/providers/ad/ad_opts.c ++++ b/src/providers/ad/ad_opts.c +@@ -106,6 +106,7 @@ struct dp_option ad_def_ldap_opts[] = { + { "ldap_sasl_authid", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_sasl_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_sasl_minssf", DP_OPT_NUMBER, { .number = -1 }, NULL_NUMBER }, ++ { "ldap_sasl_maxssf", DP_OPT_NUMBER, { .number = -1 }, NULL_NUMBER }, + { "ldap_krb5_keytab", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_krb5_init_creds", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, + /* use the same parm name as the krb5 module so we set it only once */ +diff --git a/src/providers/ipa/ipa_opts.c b/src/providers/ipa/ipa_opts.c +index 4fafa073d..55de6e600 100644 +--- a/src/providers/ipa/ipa_opts.c ++++ b/src/providers/ipa/ipa_opts.c +@@ -114,6 +114,7 @@ struct dp_option ipa_def_ldap_opts[] = { + { "ldap_sasl_authid", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_sasl_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_sasl_minssf", DP_OPT_NUMBER, { .number = 56 }, NULL_NUMBER }, ++ { "ldap_sasl_maxssf", DP_OPT_NUMBER, { .number = -1 }, NULL_NUMBER }, + { "ldap_krb5_keytab", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_krb5_init_creds", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, + /* use the same parm name as the krb5 module so we set it only once */ +diff --git a/src/providers/ldap/ldap_opts.c b/src/providers/ldap/ldap_opts.c +index ffd0c6baa..d1b4e98ad 100644 +--- a/src/providers/ldap/ldap_opts.c ++++ b/src/providers/ldap/ldap_opts.c +@@ -74,6 +74,7 @@ struct dp_option default_basic_opts[] = { + { "ldap_sasl_authid", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_sasl_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_sasl_minssf", DP_OPT_NUMBER, { .number = -1 }, NULL_NUMBER }, ++ { "ldap_sasl_maxssf", DP_OPT_NUMBER, { .number = -1 }, NULL_NUMBER }, + { "ldap_krb5_keytab", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_krb5_init_creds", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, + /* use the same parm name as the krb5 module so we set it only once */ +diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h +index f27b3c480..808a2c400 100644 +--- a/src/providers/ldap/sdap.h ++++ b/src/providers/ldap/sdap.h +@@ -192,6 +192,7 @@ enum sdap_basic_opt { + SDAP_SASL_AUTHID, + SDAP_SASL_REALM, + SDAP_SASL_MINSSF, ++ SDAP_SASL_MAXSSF, + SDAP_KRB5_KEYTAB, + SDAP_KRB5_KINIT, + SDAP_KRB5_KDC, +diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c +index 7438d14a7..5f69cedcc 100644 +--- a/src/providers/ldap/sdap_async_connection.c ++++ b/src/providers/ldap/sdap_async_connection.c +@@ -148,6 +148,8 @@ static void sdap_sys_connect_done(struct tevent_req *subreq) + const char *sasl_mech; + int sasl_minssf; + ber_len_t ber_sasl_minssf; ++ int sasl_maxssf; ++ ber_len_t ber_sasl_maxssf; + + ret = sss_ldap_init_recv(subreq, &state->sh->ldap, &sd); + talloc_zfree(subreq); +@@ -291,6 +293,18 @@ static void sdap_sys_connect_done(struct tevent_req *subreq) + goto fail; + } + } ++ ++ sasl_maxssf = dp_opt_get_int(state->opts->basic, SDAP_SASL_MAXSSF); ++ if (sasl_maxssf >= 0) { ++ ber_sasl_maxssf = (ber_len_t)sasl_maxssf; ++ lret = ldap_set_option(state->sh->ldap, LDAP_OPT_X_SASL_SSF_MAX, ++ &ber_sasl_maxssf); ++ if (lret != LDAP_OPT_SUCCESS) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set LDAP MAX SSF option " ++ "to %d\n", sasl_maxssf); ++ goto fail; ++ } ++ } + } + + /* if we do not use start_tls the connection is not really connected yet +-- +2.20.1 + diff --git a/0015-ad-set-min-and-max-ssf-for-ldaps.patch b/0015-ad-set-min-and-max-ssf-for-ldaps.patch new file mode 100644 index 0000000..c4a3003 --- /dev/null +++ b/0015-ad-set-min-and-max-ssf-for-ldaps.patch @@ -0,0 +1,91 @@ +From 24387e19f065e6a585b1120d5568cb4df271d102 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 27 Sep 2019 13:45:13 +0200 +Subject: [PATCH 15/15] ad: set min and max ssf for ldaps +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +AD does not allow to use encryption in the TLS and SASL layer at the +same time. To be able to use ldaps this patch sets min and max ssf to 0 +if ldaps should be used. + +Related to https://pagure.io/SSSD/sssd/issue/4131 + +Reviewed-by: Pavel Březina +--- + src/providers/ad/ad_common.c | 21 +++++++++++++++++++++ + src/providers/ad/ad_common.h | 2 ++ + src/providers/ad/ad_subdomains.c | 4 ++++ + 3 files changed, 27 insertions(+) + +diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c +index a2369166a..51300f5b2 100644 +--- a/src/providers/ad/ad_common.c ++++ b/src/providers/ad/ad_common.c +@@ -1021,6 +1021,23 @@ done: + return; + } + ++void ad_set_ssf_for_ldaps(struct sdap_options *id_opts) ++{ ++ int ret; ++ ++ DEBUG(SSSDBG_TRACE_ALL, "Setting ssf for ldaps usage.\n"); ++ ret = dp_opt_set_int(id_opts->basic, SDAP_SASL_MINSSF, 0); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "Failed to set SASL minssf for ldaps usage, ignored.\n"); ++ } ++ ret = dp_opt_set_int(id_opts->basic, SDAP_SASL_MAXSSF, 0); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "Failed to set SASL maxssf for ldaps usage, ignored.\n"); ++ } ++} ++ + static errno_t + ad_set_sdap_options(struct ad_options *ad_opts, + struct sdap_options *id_opts) +@@ -1079,6 +1096,10 @@ ad_set_sdap_options(struct ad_options *ad_opts, + goto done; + } + ++ if (dp_opt_get_bool(ad_opts->basic, AD_USE_LDAPS)) { ++ ad_set_ssf_for_ldaps(id_opts); ++ } ++ + /* Warn if the user is doing something silly like overriding the schema + * with the AD provider + */ +diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h +index 44da58fa0..8b7a86102 100644 +--- a/src/providers/ad/ad_common.h ++++ b/src/providers/ad/ad_common.h +@@ -182,6 +182,8 @@ errno_t + ad_get_dyndns_options(struct be_ctx *be_ctx, + struct ad_options *ad_opts); + ++void ad_set_ssf_for_ldaps(struct sdap_options *id_opts); ++ + struct ad_id_ctx * + ad_id_ctx_init(struct ad_options *ad_opts, struct be_ctx *bectx); + +diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c +index d8c201437..a9c6b9f28 100644 +--- a/src/providers/ad/ad_subdomains.c ++++ b/src/providers/ad/ad_subdomains.c +@@ -328,6 +328,10 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx, + return ret; + } + ++ if (dp_opt_get_bool(ad_options->basic, AD_USE_LDAPS)) { ++ ad_set_ssf_for_ldaps(ad_options->id); ++ } ++ + ret = ad_inherit_opts_if_needed(id_ctx->sdap_id_ctx->opts->basic, + ad_options->id->basic, + be_ctx->cdb, subdom_conf_path, +-- +2.20.1 + diff --git a/sssd.spec b/sssd.spec index 63d6011..45d3292 100644 --- a/sssd.spec +++ b/sssd.spec @@ -36,7 +36,7 @@ Name: sssd Version: 2.2.3 -Release: 8%{?dist} +Release: 9%{?dist} Summary: System Security Services Daemon License: GPLv3+ URL: https://pagure.io/SSSD/sssd/ @@ -54,6 +54,10 @@ Patch0008: 0008-data_provider_be-got-rid-of-duplicating-SIGTERM-hand.patch Patch0009: 0009-util-server-improved-debug-at-shutdown.patch Patch0010: 0010-util-sss_ptr_hash-fixed-double-free-in-sss_ptr_hash_.patch Patch0011: 0011-sdap-Add-randomness-to-ldap-connection-timeout.patch +Patch0012: 0012-ad-allow-booleans-for-ad_inherit_opts_if_needed.patch +Patch0013: 0013-ad-add-ad_use_ldaps.patch +Patch0014: 0014-ldap-add-new-option-ldap_sasl_maxssf.patch +Patch0015: 0015-ad-set-min-and-max-ssf-for-ldaps.patch ### Downstream only patches ### Patch0502: 0502-SYSTEMD-Use-capabilities.patch @@ -1081,6 +1085,9 @@ fi %{_libdir}/%{name}/modules/libwbclient.so %changelog +* Wed Feb 26 2020 Michal Židek - 2.2.3-9 +- Resolves: upstream#4131 Force LDAPS over 636 with AD Provider + * Wed Feb 26 2020 Michal Židek - 2.2.3-8 - Resolves: upstream#3630 - Randomize ldap_connection_expire_timeout either by default or w/ a configure option