URL: https://github.com/SSSD/sssd/pull/966 Author: sumit-bose Title: #966: ad: add ad_use_ldaps Action: opened
PR body: """ 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 """ To pull the PR as Git branch: git remote add ghsssd https://github.com/SSSD/sssd git fetch ghsssd pull/966/head:pr966 git checkout pr966
From 3dadb248440f2e7a02c68049001f848459dd1bdf Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Thu, 26 Sep 2019 20:24:34 +0200 Subject: [PATCH 1/4] ad: allow booleans for ad_inherit_opts_if_needed() 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 --- 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 5540066d4e..600e3ceb2c 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) { From 33c8757087b8649926e53cf494e2a775ad100302 Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Thu, 26 Sep 2019 20:27:09 +0200 Subject: [PATCH 2/4] ad: add ad_use_ldaps 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 --- 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 92e6141170..6c2a1ce441 100644 --- a/src/config/SSSDConfig/__init__.py.in +++ b/src/config/SSSDConfig/__init__.py.in @@ -253,6 +253,7 @@ option_strings = { '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_update_samba_machine_account_password' : _('Whether to update the machine account password in the Samba database'), + '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 f7c1d4ce2c..478ca9eb43 100644 --- a/src/config/cfg_rules.ini +++ b/src/config/cfg_rules.ini @@ -465,6 +465,7 @@ option = ad_maximum_machine_account_password_age option = ad_server option = ad_site option = ad_update_samba_machine_account_password +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 33f040c8e6..51cdad536e 100644 --- a/src/config/etc/sssd.api.d/sssd-ad.conf +++ b/src/config/etc/sssd.api.d/sssd-ad.conf @@ -21,6 +21,7 @@ ad_site = str, None, false ad_maximum_machine_account_password_age = int, None, false ad_machine_account_password_renewal_opts = str, None, false ad_update_samba_machine_account_password = bool, 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 30c7d07cfa..a634d4f41c 100644 --- a/src/man/sssd-ad.5.xml +++ b/src/man/sssd-ad.5.xml @@ -1031,6 +1031,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 600e3ceb2c..a2369166a2 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 36366e3292..44da58fa0b 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" @@ -68,6 +69,7 @@ enum ad_basic_opt { AD_MAXIMUM_MACHINE_ACCOUNT_PASSWORD_AGE, AD_MACHINE_ACCOUNT_PASSWORD_RENEWAL_OPTS, AD_UPDATE_SAMBA_MACHINE_ACCOUNT_PASSWORD, + AD_USE_LDAPS, AD_OPTS_BASIC /* opts counter */ }; @@ -83,6 +85,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 { @@ -148,6 +153,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 290d5b5c1f..2b4b9e2e70 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 de134927e7..26420d6554 100644 --- a/src/providers/ad/ad_opts.c +++ b/src/providers/ad/ad_opts.c @@ -55,6 +55,7 @@ struct dp_option ad_basic_opts[] = { { "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_update_samba_machine_account_password", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, + { "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 5fd25f60e8..ca15d3715a 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 e553d594d7..8e410ec269 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 2ce34489f6..d8c2014374 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 fd998877b3..9aebf72a5a 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; From 3b95c39819591428b1e535e5dc874268cf5630c5 Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Fri, 27 Sep 2019 11:49:59 +0200 Subject: [PATCH 3/4] ldap: add new option ldap_sasl_maxssf 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 --- 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 6c2a1ce441..b3035fcffb 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 478ca9eb43..286443be42 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 51cdad536e..4d10e69d73 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 7ed153d363..839f9f4716 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 4f73e901e9..6db9828b9d 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 f8bb973c7a..0dc6754109 100644 --- a/src/man/sssd-ldap.5.xml +++ b/src/man/sssd-ldap.5.xml @@ -612,6 +612,22 @@ </listitem> </varlistentry> + <varlistentry> + <term>ldap_sasl_maxssf (integer)</term> + <listitem> + <para> + 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. + </para> + <para> + Default: Use the system default (usually specified + by ldap.conf) + </para> + </listitem> + </varlistentry> + <varlistentry> <term>ldap_deref_threshold (integer)</term> <listitem> diff --git a/src/providers/ad/ad_opts.c b/src/providers/ad/ad_opts.c index 26420d6554..e9a3dd6ef5 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 4fafa073da..55de6e600e 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 ffd0c6baa2..d1b4e98ad5 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 f27b3c4806..808a2c400f 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 7438d14a7f..5f69cedcc6 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 From 50a92f65c4823d272240ef416f2b05874b2b7918 Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Fri, 27 Sep 2019 13:45:13 +0200 Subject: [PATCH 4/4] ad: set min and max ssf for ldaps 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 --- 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 a2369166a2..51300f5b2a 100644 --- a/src/providers/ad/ad_common.c +++ b/src/providers/ad/ad_common.c @@ -1021,6 +1021,23 @@ ad_resolve_callback(void *private_data, struct fo_server *server) 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 44da58fa0b..8b7a86102f 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 d8c2014374..a9c6b9f287 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,
_______________________________________________ sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/sssd-devel@lists.fedorahosted.org