summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/config/SSSDConfig.py4
-rw-r--r--src/config/etc/sssd.api.d/sssd-ldap.conf3
-rw-r--r--src/man/sssd-ldap.5.xml34
-rw-r--r--src/providers/ipa/ipa_common.c4
-rw-r--r--src/providers/ipa/ipa_common.h2
-rw-r--r--src/providers/ldap/ldap_auth.c19
-rw-r--r--src/providers/ldap/ldap_common.c10
-rw-r--r--src/providers/ldap/ldap_common.h1
-rw-r--r--src/providers/ldap/ldap_init.c21
-rw-r--r--src/providers/ldap/sdap.h2
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 */
};