diff options
-rw-r--r-- | src/config/SSSDConfig.py | 4 | ||||
-rw-r--r-- | src/config/etc/sssd.api.d/sssd-ldap.conf | 3 | ||||
-rw-r--r-- | src/man/sssd-ldap.5.xml | 34 | ||||
-rw-r--r-- | src/providers/ipa/ipa_common.c | 4 | ||||
-rw-r--r-- | src/providers/ipa/ipa_common.h | 2 | ||||
-rw-r--r-- | src/providers/ldap/ldap_auth.c | 19 | ||||
-rw-r--r-- | src/providers/ldap/ldap_common.c | 10 | ||||
-rw-r--r-- | src/providers/ldap/ldap_common.h | 1 | ||||
-rw-r--r-- | src/providers/ldap/ldap_init.c | 21 | ||||
-rw-r--r-- | src/providers/ldap/sdap.h | 2 |
10 files changed, 91 insertions, 9 deletions
diff --git a/src/config/SSSDConfig.py b/src/config/SSSDConfig.py index e48e83ab9..9584de176 100644 --- a/src/config/SSSDConfig.py +++ b/src/config/SSSDConfig.py @@ -163,6 +163,10 @@ option_strings = { 'ldap_account_expire_policy' : _('Which attributes shall be used to evaluate if an account is expired'), 'ldap_access_order' : _('Which rules should be used to evaluate access control'), + # [provider/ldap/chpass] + 'ldap_chpass_uri' : _('URI of an LDAP server where password changes are allowed'), + 'ldap_chpass_dns_service_name' : _('DNS service name for LDAP password change server'), + # [provider/simple/access] 'simple_allow_users' : _('Comma separated list of allowed users'), 'simple_deny_users' : _('Comma separated list of prohibited users'), diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf index b7d2f9b2b..2d44fb4ba 100644 --- a/src/config/etc/sssd.api.d/sssd-ldap.conf +++ b/src/config/etc/sssd.api.d/sssd-ldap.conf @@ -84,4 +84,5 @@ ldap_account_expire_policy = str, None, false ldap_access_order = str, None, false [provider/ldap/chpass] - +ldap_chpass_uri = str, None, false +ldap_chpass_dns_service_name = str, None, false diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml index 8936882c8..786d5fdaf 100644 --- a/src/man/sssd-ldap.5.xml +++ b/src/man/sssd-ldap.5.xml @@ -70,6 +70,26 @@ </varlistentry> <varlistentry> + <term>ldap_chpass_uri (string)</term> + <listitem> + <para> + Specifies the list of URIs of the LDAP servers to + which SSSD should connect in the order of preference + to change the password of a user. Refer to the + <quote>FAILOVER</quote> section for more information + on failover and server redundancy. + </para> + <para> + To enable service discovery + ldap_chpass_dns_service_name must be set. + </para> + <para> + Default: empty, i.e. ldap_uri is used. + </para> + </listitem> + </varlistentry> + + <varlistentry> <term>ldap_search_base (string)</term> <listitem> <para> @@ -988,6 +1008,20 @@ </varlistentry> <varlistentry> + <term>ldap_chpass_dns_service_name (string)</term> + <listitem> + <para> + Specifies the service name to use to find an LDAP + server which allows password changes when service + discovery is enabled. + </para> + <para> + Default: not set, i.e. service discovery is disabled + </para> + </listitem> + </varlistentry> + + <varlistentry> <term>ldap_access_filter (string)</term> <listitem> <para> diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c index 320587723..8da83ee08 100644 --- a/src/providers/ipa/ipa_common.c +++ b/src/providers/ipa/ipa_common.c @@ -79,7 +79,9 @@ struct dp_option ipa_def_ldap_opts[] = { { "ldap_group_nesting_level", DP_OPT_NUMBER, { .number = 2 }, NULL_NUMBER }, { "ldap_deref", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_account_expire_policy", DP_OPT_STRING, NULL_STRING, NULL_STRING }, - { "ldap_access_order", DP_OPT_STRING, NULL_STRING, NULL_STRING } + { "ldap_access_order", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_chpass_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_chpass_dns_service_name", DP_OPT_STRING, NULL_STRING, NULL_STRING } }; struct sdap_attr_map ipa_attr_map[] = { diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h index 0082b0659..451a1534d 100644 --- a/src/providers/ipa/ipa_common.h +++ b/src/providers/ipa/ipa_common.h @@ -35,7 +35,7 @@ struct ipa_service { /* the following defines are used to keep track of the options in the ldap * module, so that if they change and ipa is not updated correspondingly * this will trigger a runtime abort error */ -#define IPA_OPTS_BASIC_TEST 41 +#define IPA_OPTS_BASIC_TEST 43 /* the following define is used to keep track of the options in the krb5 * module, so that if they change and ipa is not updated correspondingly diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c index 5a85fe910..2d66b1d66 100644 --- a/src/providers/ldap/ldap_auth.c +++ b/src/providers/ldap/ldap_auth.c @@ -450,6 +450,7 @@ struct auth_state { struct sdap_auth_ctx *ctx; const char *username; struct dp_opt_blob password; + struct sdap_service *sdap_service; struct sdap_handle *sh; @@ -470,7 +471,8 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_auth_ctx *ctx, const char *username, - struct dp_opt_blob password) + struct dp_opt_blob password, + bool try_chpass_service) { struct tevent_req *req; struct auth_state *state; @@ -490,6 +492,12 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx, state->username = username; state->password = password; state->srv = NULL; + if (try_chpass_service && ctx->chpass_service != NULL && + ctx->chpass_service->name != NULL) { + state->sdap_service = ctx->chpass_service; + } else { + state->sdap_service = ctx->service; + } if (!auth_get_server(req)) goto fail; @@ -511,7 +519,7 @@ static struct tevent_req *auth_get_server(struct tevent_req *req) next_req = be_resolve_server_send(state, state->ev, state->ctx->be, - state->ctx->service->name); + state->sdap_service->name); if (!next_req) { DEBUG(1, ("be_resolve_server_send failed.\n")); return NULL; @@ -539,7 +547,7 @@ static void auth_resolve_done(struct tevent_req *subreq) } subreq = sdap_connect_send(state, state->ev, state->ctx->opts, - state->ctx->service->uri, true); + state->sdap_service->uri, true); if (!subreq) { tevent_req_error(req, ENOMEM); return; @@ -743,7 +751,7 @@ void sdap_pam_chpass_handler(struct be_req *breq) authtok.data = (uint8_t *)state->password; authtok.length = strlen(state->password); subreq = auth_send(breq, breq->be_ctx->ev, - ctx, state->username, authtok); + ctx, state->username, authtok, true); if (!subreq) goto done; tevent_req_set_callback(subreq, sdap_auth4chpass_done, state); @@ -950,7 +958,8 @@ void sdap_pam_auth_handler(struct be_req *breq) state->password.length = pd->authtok_size; subreq = auth_send(breq, breq->be_ctx->ev, ctx, - state->username, state->password); + state->username, state->password, + pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM ? true : false); if (!subreq) goto done; tevent_req_set_callback(subreq, sdap_pam_auth_done, state); diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c index dc012262d..4242a7e45 100644 --- a/src/providers/ldap/ldap_common.c +++ b/src/providers/ldap/ldap_common.c @@ -74,7 +74,9 @@ struct dp_option default_basic_opts[] = { { "ldap_group_nesting_level", DP_OPT_NUMBER, { .number = 2 }, NULL_NUMBER }, { "ldap_deref", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_account_expire_policy", DP_OPT_STRING, NULL_STRING, NULL_STRING }, - { "ldap_access_order", DP_OPT_STRING, { "filter" }, NULL_STRING } + { "ldap_access_order", DP_OPT_STRING, { "filter" }, NULL_STRING }, + { "ldap_chpass_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_chpass_dns_service_name", DP_OPT_STRING, NULL_STRING, NULL_STRING } }; struct sdap_attr_map generic_attr_map[] = { @@ -688,6 +690,12 @@ int sdap_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, /* now for each URI add a new server to the failover service */ for (i = 0; list[i]; i++) { if (be_fo_is_srv_identifier(list[i])) { + if (!dns_service_name) { + DEBUG(0, ("Missing DNS service name for service [%s].\n", + service_name)); + ret = EINVAL; + goto done; + } srv_user_data = talloc_strdup(service, dns_service_name); if (!srv_user_data) { ret = ENOMEM; diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h index d24a9839e..f1af8fc7e 100644 --- a/src/providers/ldap/ldap_common.h +++ b/src/providers/ldap/ldap_common.h @@ -65,6 +65,7 @@ struct sdap_auth_ctx { struct sdap_options *opts; struct fo_service *fo_service; struct sdap_service *service; + struct sdap_service *chpass_service; }; void sdap_check_online(struct be_req *breq); diff --git a/src/providers/ldap/ldap_init.c b/src/providers/ldap/ldap_init.c index d6407c419..58c12d081 100644 --- a/src/providers/ldap/ldap_init.c +++ b/src/providers/ldap/ldap_init.c @@ -212,6 +212,27 @@ int sssm_ldap_auth_init(struct be_ctx *bectx, goto done; } + dns_service_name = dp_opt_get_string(ctx->opts->basic, + SDAP_CHPASS_DNS_SERVICE_NAME); + if (dns_service_name) { + DEBUG(7, ("Service name for chpass discovery set to %s\n", + dns_service_name)); + } + + urls = dp_opt_get_string(ctx->opts->basic, SDAP_CHPASS_URI); + if (!urls && !dns_service_name) { + DEBUG(9, ("ldap_chpass_uri and ldap_chpass_dns_service_name not set, " + "using ldap_uri.\n")); + ctx->chpass_service = NULL; + } else { + ret = sdap_service_init(ctx, ctx->be, "LDAP_CHPASS", dns_service_name, + urls, &ctx->chpass_service); + if (ret != EOK) { + DEBUG(1, ("Failed to initialize failover service!\n")); + goto done; + } + } + ret = setup_tls_config(ctx->opts->basic); if (ret != EOK) { DEBUG(1, ("setup_tls_config failed [%d][%s].\n", diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index 4d52d5b3a..5c4f4a548 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -184,6 +184,8 @@ enum sdap_basic_opt { SDAP_DEREF, SDAP_ACCOUNT_EXPIRE_POLICY, SDAP_ACCESS_ORDER, + SDAP_CHPASS_URI, + SDAP_CHPASS_DNS_SERVICE_NAME, SDAP_OPTS_BASIC /* opts counter */ }; |