Stephen Gallagher <[email protected]> wrote: > On Fri, 2012-02-03 at 15:45 +0100, Jan Zelený wrote: > > Please note that I haven't fully tested this yet, the LDAP server > > configuration needed for this is a little bit twisted ;-) I will perform > > more testing during the weekend. Consider this patch being preliminary > > and don't push it until it's tested. > > Nack. > > You need to update the IPA LDAP options as well: > Running suite(s): ipa_ldap_opt > 50%: Checks: 2, Failures: 1, Errors: 0 > /home/sgallagh/workspace/sssd/src/tests/ipa_ldap_opt-tests.c:79:F:ipa_ldap_ > opt:test_check_num_opts:0: Failure 'IPA_OPTS_BASIC_TEST != SDAP_OPTS_BASIC' > occured
Done > Just for aesthetic reasons, please don't use the prefix sdap_ldap_*. > "sdap" is already shorthand for SSSD LDAP. sdap_ldap_result() is a > special case, since it's specifically a handler for "ldap_result" > structures. In general, I'd prefer that you call it something like > sdap_modify_shadow_lastchange_send(). Done > Why are you changing the user's password? That's not only out of scope, > but you're setting their password in plaintext on the server, if I'm > reading this correctly (you're modifying the entry with the raw text of > the new password). We ONLY support password modification via > password-change extended operation. > > The scope of https://fedorahosted.org/sssd/ticket/1019 is ONLY to update > the last change time. We absolutely don't want people using shadow > passwords; they're extremely insecure (highly vulnerable to offline > dictionary attack). As I wrote before, I'd like to consult this with you because I have no idea how to test this and all my attempts were unsuccessful - I didn't even manage to reproduce the original behavior. > Please modify the manpage for ldap_pwd_policy in sssd-ldap(5) as "Note > that the current version of sssd cannot update this attribute during a > password change." is no longer accurate. Done > Please don't conflate LDAP errors and errno errors in the "ret" variable > in sdap_ldap_modify_passwd_done(). If for some reason openldap changed > the value of LDAP_SUCCESS, this would break under our noses. Done > The logic of the functions looks good. Thanks for the review Jan
From 7883578568dcb33ab7c3dab9dc24754d34c54e41 Mon Sep 17 00:00:00 2001 From: Jan Zeleny <[email protected]> Date: Fri, 3 Feb 2012 09:33:08 -0500 Subject: [PATCH] Update shadowLastChanged attribute during LDAP password change https://fedorahosted.org/sssd/ticket/1019 --- src/man/sssd-ldap.5.xml | 2 - src/providers/ipa/ipa_common.h | 2 +- src/providers/ldap/ldap_auth.c | 46 +++++++++++++ src/providers/ldap/ldap_common.c | 1 + src/providers/ldap/sdap.h | 1 + src/providers/ldap/sdap_async.c | 132 ++++++++++++++++++++++++++++++++++++++ src/providers/ldap/sdap_async.h | 9 +++ 7 files changed, 190 insertions(+), 3 deletions(-) diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml index fc396d94e01168c3e273f70272bce9c95334128c..8d7f293d1768027796b9c778ff6444a63371a99d 100644 --- a/src/man/sssd-ldap.5.xml +++ b/src/man/sssd-ldap.5.xml @@ -1407,8 +1407,6 @@ <citerefentry><refentrytitle>shadow</refentrytitle> <manvolnum>5</manvolnum></citerefentry> style attributes to evaluate if the password has expired. - Note that the current version of sssd cannot - update this attribute during a password change. </para> <para> <emphasis>mit_kerberos</emphasis> - Use the attributes diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h index 5bf1b7c9d49641db755171dffa52ca8a6ec9d8ed..9cbd993f547e76d53e6d46747c7181fe6592061a 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 59 +#define IPA_OPTS_BASIC_TEST 60 #define IPA_OPTS_SVC_TEST 5 diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c index f58d52feed5c28b63864e42a2f6e04223c57afe1..e0ef68aa6fbb18b85ba7ecff3f2d79ac7400717f 100644 --- a/src/providers/ldap/ldap_auth.c +++ b/src/providers/ldap/ldap_auth.c @@ -45,6 +45,7 @@ #include "db/sysdb.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async.h" +#include "providers/ldap/sdap_async_private.h" /* MIT Kerberos has the same hardcoded warning interval of 7 days. Due to the * fact that using the expiration time of a Kerberos password with LDAP @@ -705,6 +706,8 @@ struct sdap_pam_chpass_state { char *password; char *new_password; struct sdap_handle *sh; + + struct sdap_auth_ctx *ctx; }; static void sdap_auth4chpass_done(struct tevent_req *req); @@ -754,6 +757,7 @@ void sdap_pam_chpass_handler(struct be_req *breq) state->breq = breq; state->pd = pd; state->username = pd->user; + state->ctx = ctx; state->password = talloc_strndup(state, (char *)pd->authtok, pd->authtok_size); if (!state->password) goto done; @@ -782,6 +786,7 @@ done: sdap_pam_auth_reply(breq, dp_err, pd->pam_status); } +static void sdap_ldap_passwd_change_done(struct tevent_req *req); static void sdap_auth4chpass_done(struct tevent_req *req) { struct sdap_pam_chpass_state *state = @@ -898,6 +903,8 @@ static void sdap_pam_chpass_done(struct tevent_req *req) int dp_err = DP_ERR_FATAL; int ret; char *user_error_message = NULL; + char *lastchanged_name; + struct tevent_req *subreq; size_t msg_len; uint8_t *msg; @@ -935,9 +942,48 @@ static void sdap_pam_chpass_done(struct tevent_req *req) } } + if (dp_opt_get_bool(state->ctx->opts->basic, + SDAP_CHPASS_UPDATE_LAST_CHANGE)) { + lastchanged_name = state->ctx->opts->user_map[SDAP_AT_SP_LSTCHG].name; + + subreq = sdap_modify_shadow_lastchange_send(state, + state->breq->be_ctx->ev, + state->sh, + state->dn, + lastchanged_name); + if (subreq == NULL) { + state->pd->pam_status = PAM_SYSTEM_ERR; + goto done; + } + + tevent_req_set_callback(subreq, sdap_ldap_passwd_change_done, state); + return; + } + done: sdap_pam_auth_reply(state->breq, dp_err, state->pd->pam_status); } + +static void sdap_ldap_passwd_change_done(struct tevent_req *req) +{ + struct sdap_pam_chpass_state *state = + tevent_req_callback_data(req, struct sdap_pam_chpass_state); + int dp_err = DP_ERR_FATAL; + errno_t ret; + + ret = sdap_modify_shadow_lastchange_recv(req); + if (ret != EOK) { + state->pd->pam_status = PAM_SYSTEM_ERR; + goto done; + } + + dp_err = DP_ERR_OK; + state->pd->pam_status = PAM_SUCCESS; + +done: + sdap_pam_auth_reply(state->breq, dp_err, state->pd->pam_status); +} + /* ==Perform-User-Authentication-and-Password-Caching===================== */ struct sdap_pam_auth_state { diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c index cce3c0bcfc0e87e7d2f4a3f0d613c7472cdec656..1efb699292e4b0fd478c3abbd4b391c36ceeed11 100644 --- a/src/providers/ldap/ldap_common.c +++ b/src/providers/ldap/ldap_common.c @@ -89,6 +89,7 @@ struct dp_option default_basic_opts[] = { { "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 }, + { "ldap_chpass_update_last_change", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_enumeration_search_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER }, /* Do not include ldap_auth_disable_tls_never_use_in_production in the * manpages or SSSDConfig API diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index 2e1dfa959d5c6117cae00eb0752c9e31daef1d2f..68bcf1591bb5b271d7a5ee926955f4b8e52cfab1 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -201,6 +201,7 @@ enum sdap_basic_opt { SDAP_ACCESS_ORDER, SDAP_CHPASS_URI, SDAP_CHPASS_DNS_SERVICE_NAME, + SDAP_CHPASS_UPDATE_LAST_CHANGE, SDAP_ENUM_SEARCH_TIMEOUT, SDAP_DISABLE_AUTH_TLS, SDAP_PAGE_SIZE, diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c index c2f616bef13744916d2b0c5bab92524566959af9..020ba32aec57801f253e0eef148206ebbf53cc92 100644 --- a/src/providers/ldap/sdap_async.c +++ b/src/providers/ldap/sdap_async.c @@ -691,6 +691,138 @@ int sdap_exop_modify_passwd_recv(struct tevent_req *req, return EOK; } +/* ==Update-passwordLastChanged-attribute====================== */ +struct update_last_changed_state { + struct tevent_context *ev; + struct sdap_handle *sh; + struct sdap_op *op; + + const char *dn; + LDAPMod **mods; +}; + +static void sdap_modify_shadow_lastchange_done(struct sdap_op *op, + struct sdap_msg *reply, + int error, void *pvt); + +struct tevent_req * +sdap_modify_shadow_lastchange_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sdap_handle *sh, + const char *dn, + char *lastchanged_name) +{ + struct tevent_req *req; + struct update_last_changed_state *state; + char **values; + errno_t ret; + int msgid; + + req = tevent_req_create(mem_ctx, &state, struct update_last_changed_state); + if (req == NULL) { + return NULL; + } + + state->ev = ev; + state->sh = sh; + state->dn = dn; + state->mods = talloc_zero_array(state, LDAPMod *, 2); + if (state->mods == NULL) { + ret = ENOMEM; + goto done; + } + state->mods[0] = talloc_zero(state->mods, LDAPMod); + state->mods[1] = talloc_zero(state->mods, LDAPMod); + if (!state->mods[0] || !state->mods[1]) { + ret = ENOMEM; + goto done; + } + values = talloc_zero_array(state->mods[0], char *, 2); + if (values == NULL) { + ret = ENOMEM; + goto done; + } + values[0] = talloc_asprintf(values, "%ld", (long)time(NULL)); + if (values[0] == NULL) { + ret = ENOMEM; + goto done; + } + state->mods[0]->mod_op = LDAP_MOD_REPLACE; + state->mods[0]->mod_type = lastchanged_name; + state->mods[0]->mod_vals.modv_strvals = values; + state->mods[1] = NULL; + + ret = ldap_modify_ext(state->sh->ldap, state->dn, state->mods, + NULL, NULL, &msgid); + if (ret) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to send operation!\n")); + goto done; + } + + ret = sdap_op_add(state, state->ev, state->sh, msgid, + sdap_modify_shadow_lastchange_done, req, 5, &state->op); + if (ret) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to set up operation!\n")); + goto done; + } + +done: + if (ret != EOK) { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + return req; +} + +static void sdap_modify_shadow_lastchange_done(struct sdap_op *op, + struct sdap_msg *reply, + int error, void *pvt) +{ + struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); + struct update_last_changed_state *state; + state = tevent_req_data(req, struct update_last_changed_state); + char *errmsg; + int result; + errno_t ret = EOK; + errno_t lret; + + if (error) { + tevent_req_error(req, error); + return; + } + + lret = ldap_parse_result(state->sh->ldap, reply->msg, + &result, NULL, &errmsg, NULL, + NULL, 0); + if (lret != LDAP_SUCCESS) { + DEBUG(SSSDBG_OP_FAILURE, ("ldap_parse_result failed (%d)\n", + state->op->msgid)); + ret = EIO; + goto done; + } + + DEBUG(SSSDBG_OP_FAILURE, ("Updating lastPwdChange result: %s(%d), %s\n", + sss_ldap_err2string(result), + result, errmsg)); + +done: + ldap_memfree(errmsg); + + if (ret == EOK) { + tevent_req_done(req); + } else { + tevent_req_error(req, ret); + } +} + +errno_t sdap_modify_shadow_lastchange_recv(struct tevent_req *req) +{ + TEVENT_REQ_RETURN_ON_ERROR(req); + + return EOK; +} + + /* ==Fetch-RootDSE============================================= */ struct sdap_get_rootdse_state { diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h index 8f8af47d5b17792325eb504d0b25f3658bb766ba..47d1014925932ae93c5c9d4c45b78d3babe394dd 100644 --- a/src/providers/ldap/sdap_async.h +++ b/src/providers/ldap/sdap_async.h @@ -132,6 +132,15 @@ int sdap_exop_modify_passwd_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, enum sdap_result *result, char **user_error_msg); +struct tevent_req * +sdap_modify_shadow_lastchange_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sdap_handle *sh, + const char *dn, + char *lastchanged_name); + +errno_t sdap_modify_shadow_lastchange_recv(struct tevent_req *req); + enum connect_tls { CON_TLS_DFL, CON_TLS_ON, -- 1.7.6.4
_______________________________________________ sssd-devel mailing list [email protected] https://fedorahosted.org/mailman/listinfo/sssd-devel
