Mercurial > dovecot > core-2.2
changeset 4782:2c1cc5bbc260 HEAD
Added auth_request_set_credentials() to modify credentials in passdb and
implemented it for SQL passdb. Added passdb_need_set_credentials boolean to
mechanisms to indicate that it's required (OTP will need it). Patch by
Andrey Panin.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 08 Nov 2006 22:22:08 +0200 |
parents | e55f5f2dbb2c |
children | db7983ff23b8 |
files | src/auth/auth-request.c src/auth/auth-request.h src/auth/auth-worker-client.c src/auth/auth.c src/auth/db-sql.c src/auth/db-sql.h src/auth/mech-anonymous.c src/auth/mech-apop.c src/auth/mech-cram-md5.c src/auth/mech-digest-md5.c src/auth/mech-gssapi.c src/auth/mech-login.c src/auth/mech-ntlm.c src/auth/mech-plain.c src/auth/mech-rpa.c src/auth/mech.h src/auth/passdb-blocking.c src/auth/passdb-blocking.h src/auth/passdb-bsdauth.c src/auth/passdb-checkpassword.c src/auth/passdb-ldap.c src/auth/passdb-pam.c src/auth/passdb-passwd-file.c src/auth/passdb-passwd.c src/auth/passdb-shadow.c src/auth/passdb-sia.c src/auth/passdb-sql.c src/auth/passdb-vpopmail.c src/auth/passdb.h |
diffstat | 29 files changed, 223 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/auth-request.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/auth-request.c Wed Nov 08 22:22:08 2006 +0200 @@ -536,6 +536,34 @@ } } +void auth_request_set_credentials(struct auth_request *request, + enum passdb_credentials credentials, + const char *data, + set_credentials_callback_t *callback) +{ + struct passdb_module *passdb = request->passdb->passdb; + const char *cache_key, *new_credentials; + + cache_key = passdb_cache == NULL ? NULL : passdb->cache_key; + if (cache_key != NULL) + auth_cache_remove(passdb_cache, request, cache_key); + + request->private_callback.set_credentials = callback; + + new_credentials = t_strconcat("{", + passdb_credentials_to_str(credentials), "}", data, NULL); + + if (passdb->blocking) + passdb_blocking_set_credentials(request, new_credentials); + else if (passdb->iface.set_credentials != NULL) { + passdb->iface.set_credentials(request, new_credentials, + callback); + } else { + /* this passdb doesn't support credentials update */ + callback(PASSDB_RESULT_INTERNAL_FAILURE, request); + } +} + void auth_request_userdb_callback(struct auth_stream_reply *reply, struct auth_request *request) {
--- a/src/auth/auth-request.h Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/auth-request.h Wed Nov 08 22:22:08 2006 +0200 @@ -59,6 +59,7 @@ union { verify_plain_callback_t *verify_plain; lookup_credentials_callback_t *lookup_credentials; + set_credentials_callback_t *set_credentials; userdb_callback_t *userdb; } private_callback; enum passdb_credentials credentials; @@ -149,6 +150,10 @@ void auth_request_lookup_credentials_callback(enum passdb_result result, const char *credentials, struct auth_request *request); +void auth_request_set_credentials(struct auth_request *request, + enum passdb_credentials credentials, + const char *data, + set_credentials_callback_t *callback); void auth_request_userdb_callback(struct auth_stream_reply *reply, struct auth_request *request);
--- a/src/auth/auth-worker-client.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/auth-worker-client.c Wed Nov 08 22:22:08 2006 +0200 @@ -234,6 +234,70 @@ } static void +set_credentials_callback(enum passdb_result result, + struct auth_request *request) +{ + struct auth_worker_client *client = request->context; + + string_t *str; + + str = t_str_new(64); + str_printfa(str, "%u\t", request->id); + + if (result != PASSDB_RESULT_OK) + str_printfa(str, "FAIL\t%d\t", result); + else + str_printfa(str, "OK\t%s\t", request->user); + str_append_c(str, '\n'); + o_stream_send(client->output, str_data(str), str_len(str)); + + auth_request_unref(&request); + auth_worker_client_check_throttle(client); + auth_worker_client_unref(&client); +} + +static void +auth_worker_handle_setcred(struct auth_worker_client *client, + unsigned int id, const char *args) +{ + struct auth_request *auth_request; + unsigned int passdb_id; + const char *data; + + passdb_id = atoi(t_strcut(args, '\t')); + args = strchr(args, '\t'); + if (args == NULL) { + i_error("BUG: Auth worker server sent us invalid SETCRED"); + return; + } + args++; + + data = t_strcut(args, '\t'); + args = strchr(args, '\t'); + if (args != NULL) args++; + + auth_request = worker_auth_request_new(client, id, args); + + if (auth_request->user == NULL || auth_request->service == NULL) { + i_error("BUG: SETCRED had missing parameters"); + auth_request_unref(&auth_request); + return; + } + + while (auth_request->passdb->id != passdb_id) { + auth_request->passdb = auth_request->passdb->next; + if (auth_request->passdb == NULL) { + i_error("BUG: SETCRED had invalid passdb ID"); + auth_request_unref(&auth_request); + return; + } + } + + auth_request->passdb->passdb->iface. + set_credentials(auth_request, data, set_credentials_callback); +} + +static void lookup_user_callback(struct auth_stream_reply *reply, struct auth_request *auth_request) { @@ -303,6 +367,8 @@ auth_worker_handle_passv(client, id, line + 6); else if (strncmp(line, "PASSL\t", 6) == 0) auth_worker_handle_passl(client, id, line + 6); + else if (strncmp(line, "SETCRED\t", 8) == 0) + auth_worker_handle_setcred(client, id, line + 8); else if (strncmp(line, "USER\t", 5) == 0) auth_worker_handle_user(client, id, line + 5);
--- a/src/auth/auth.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/auth.c Wed Nov 08 22:22:08 2006 +0200 @@ -143,6 +143,17 @@ return FALSE; } +static int auth_passdb_list_have_set_credentials(struct auth *auth) +{ + struct auth_passdb *passdb; + + for (passdb = auth->passdbs; passdb != NULL; passdb = passdb->next) { + if (passdb->passdb->iface.set_credentials != NULL) + return TRUE; + } + return FALSE; +} + static void auth_mech_list_verify_passdb(struct auth *auth) { struct mech_module_list *list; @@ -154,6 +165,9 @@ if (list->module.passdb_need_credentials && !auth_passdb_list_have_credentials(auth)) break; + if (list->module.passdb_need_set_credentials && + !auth_passdb_list_have_set_credentials(auth)) + break; } if (list != NULL) {
--- a/src/auth/db-sql.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/db-sql.c Wed Nov 08 22:22:08 2006 +0200 @@ -18,6 +18,7 @@ DEF(SET_STR, connect), DEF(SET_STR, password_query), DEF(SET_STR, user_query), + DEF(SET_STR, update_query), DEF(SET_STR, default_pass_scheme), { 0, NULL, 0 } @@ -28,6 +29,7 @@ MEMBER(connect) NULL, MEMBER(password_query) "SELECT password FROM users WHERE userid = '%u'", MEMBER(user_query) "SELECT home, uid, gid FROM users WHERE userid = '%u'", + MEMBER(update_query) "UPDATE users SET password = '%w' WHERE userid = '%u'", MEMBER(default_pass_scheme) "PLAIN-MD5" };
--- a/src/auth/db-sql.h Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/db-sql.h Wed Nov 08 22:22:08 2006 +0200 @@ -8,6 +8,7 @@ const char *connect; const char *password_query; const char *user_query; + const char *update_query; const char *default_pass_scheme; };
--- a/src/auth/mech-anonymous.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/mech-anonymous.c Wed Nov 08 22:22:08 2006 +0200 @@ -41,6 +41,7 @@ MEMBER(passdb_need_plain) FALSE, MEMBER(passdb_need_credentials) FALSE, + MEMBER(passdb_need_set_credentials) FALSE, mech_anonymous_auth_new, mech_generic_auth_initial,
--- a/src/auth/mech-apop.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/mech-apop.c Wed Nov 08 22:22:08 2006 +0200 @@ -156,6 +156,7 @@ MEMBER(passdb_need_plain) FALSE, MEMBER(passdb_need_credentials) TRUE, + MEMBER(passdb_need_set_credentials) FALSE, mech_apop_auth_new, mech_apop_auth_initial,
--- a/src/auth/mech-cram-md5.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/mech-cram-md5.c Wed Nov 08 22:22:08 2006 +0200 @@ -188,6 +188,7 @@ MEMBER(passdb_need_plain) FALSE, MEMBER(passdb_need_credentials) TRUE, + MEMBER(passdb_need_set_credentials) FALSE, mech_cram_md5_auth_new, mech_cram_md5_auth_initial,
--- a/src/auth/mech-digest-md5.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/mech-digest-md5.c Wed Nov 08 22:22:08 2006 +0200 @@ -619,6 +619,7 @@ MEMBER(passdb_need_plain) FALSE, MEMBER(passdb_need_credentials) TRUE, + MEMBER(passdb_need_set_credentials) FALSE, mech_digest_md5_auth_new, mech_digest_md5_auth_initial,
--- a/src/auth/mech-gssapi.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/mech-gssapi.c Wed Nov 08 22:22:08 2006 +0200 @@ -402,6 +402,7 @@ MEMBER(passdb_need_plain) FALSE, MEMBER(passdb_need_credentials) FALSE, + MEMBER(passdb_need_set_credentials) FALSE, mech_gssapi_auth_new, mech_gssapi_auth_initial,
--- a/src/auth/mech-login.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/mech-login.c Wed Nov 08 22:22:08 2006 +0200 @@ -84,6 +84,7 @@ MEMBER(passdb_need_plain) TRUE, MEMBER(passdb_need_credentials) FALSE, + MEMBER(passdb_need_set_credentials) FALSE, mech_login_auth_new, mech_login_auth_initial,
--- a/src/auth/mech-ntlm.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/mech-ntlm.c Wed Nov 08 22:22:08 2006 +0200 @@ -262,6 +262,7 @@ MEMBER(passdb_need_plain) FALSE, MEMBER(passdb_need_credentials) TRUE, + MEMBER(passdb_need_set_credentials) FALSE, mech_ntlm_auth_new, mech_generic_auth_initial,
--- a/src/auth/mech-plain.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/mech-plain.c Wed Nov 08 22:22:08 2006 +0200 @@ -91,6 +91,7 @@ MEMBER(passdb_need_plain) TRUE, MEMBER(passdb_need_credentials) FALSE, + MEMBER(passdb_need_set_credentials) FALSE, mech_plain_auth_new, mech_generic_auth_initial,
--- a/src/auth/mech-rpa.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/mech-rpa.c Wed Nov 08 22:22:08 2006 +0200 @@ -601,6 +601,7 @@ MEMBER(passdb_need_plain) FALSE, MEMBER(passdb_need_credentials) TRUE, + MEMBER(passdb_need_set_credentials) FALSE, mech_rpa_auth_new, mech_generic_auth_initial,
--- a/src/auth/mech.h Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/mech.h Wed Nov 08 22:22:08 2006 +0200 @@ -26,6 +26,7 @@ enum mech_security_flags flags; unsigned int passdb_need_plain:1; unsigned int passdb_need_credentials:1; + unsigned int passdb_need_set_credentials:1; struct auth_request *(*auth_new)(void); void (*auth_initial)(struct auth_request *request,
--- a/src/auth/passdb-blocking.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/passdb-blocking.c Wed Nov 08 22:22:08 2006 +0200 @@ -163,3 +163,24 @@ auth_worker_call(request, str_c(str), lookup_credentials_callback); } + +static void +set_credentials_callback(struct auth_request *request, const char *reply) +{ + enum passdb_result result = check_failure(request, &reply); + + request->private_callback.set_credentials(result, request); +} + +void passdb_blocking_set_credentials(struct auth_request *request, + const char *new_credentials) +{ + string_t *str; + + str = t_str_new(64); + str_printfa(str, "SETCRED\t%u\t%s\t", + request->passdb->id, new_credentials); + auth_request_export(request, str); + + auth_worker_call(request, str_c(str), set_credentials_callback); +}
--- a/src/auth/passdb-blocking.h Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/passdb-blocking.h Wed Nov 08 22:22:08 2006 +0200 @@ -3,5 +3,7 @@ void passdb_blocking_verify_plain(struct auth_request *request); void passdb_blocking_lookup_credentials(struct auth_request *request); +void passdb_blocking_set_credentials(struct auth_request *request, + const char *new_credentials); #endif
--- a/src/auth/passdb-bsdauth.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/passdb-bsdauth.c Wed Nov 08 22:22:08 2006 +0200 @@ -72,6 +72,7 @@ bsdauth_deinit, bsdauth_verify_plain, + NULL, NULL };
--- a/src/auth/passdb-checkpassword.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/passdb-checkpassword.c Wed Nov 08 22:22:08 2006 +0200 @@ -458,6 +458,7 @@ checkpassword_deinit, checkpassword_verify_plain, + NULL, NULL };
--- a/src/auth/passdb-ldap.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/passdb-ldap.c Wed Nov 08 22:22:08 2006 +0200 @@ -532,7 +532,8 @@ passdb_ldap_deinit, ldap_verify_plain, - ldap_lookup_credentials + ldap_lookup_credentials, + NULL }; #endif
--- a/src/auth/passdb-pam.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/passdb-pam.c Wed Nov 08 22:22:08 2006 +0200 @@ -490,6 +490,7 @@ pam_deinit, pam_verify_plain, + NULL, NULL };
--- a/src/auth/passdb-passwd-file.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/passdb-passwd-file.c Wed Nov 08 22:22:08 2006 +0200 @@ -162,7 +162,8 @@ passwd_file_deinit, passwd_file_verify_plain, - passwd_file_lookup_credentials + passwd_file_lookup_credentials, + NULL }; #endif
--- a/src/auth/passdb-passwd.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/passdb-passwd.c Wed Nov 08 22:22:08 2006 +0200 @@ -76,6 +76,7 @@ passwd_deinit, passwd_verify_plain, + NULL, NULL };
--- a/src/auth/passdb-shadow.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/passdb-shadow.c Wed Nov 08 22:22:08 2006 +0200 @@ -76,6 +76,7 @@ shadow_deinit, shadow_verify_plain, + NULL, NULL };
--- a/src/auth/passdb-sia.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/passdb-sia.c Wed Nov 08 22:22:08 2006 +0200 @@ -54,7 +54,8 @@ NULL, local_sia_verify_plain, - NULL + NULL, + NULL }; #endif
--- a/src/auth/passdb-sql.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/passdb-sql.c Wed Nov 08 22:22:08 2006 +0200 @@ -7,6 +7,7 @@ #include "str.h" #include "strescape.h" #include "var-expand.h" +#include "safe-memset.h" #include "password-scheme.h" #include "auth-cache.h" #include "db-sql.h" @@ -26,6 +27,7 @@ union { verify_plain_callback_t *verify_plain; lookup_credentials_callback_t *lookup_credentials; + set_credentials_callback_t *set_credentials; } callback; }; @@ -177,6 +179,56 @@ sql_lookup_pass(sql_request); } +static void sql_set_credentials_callback(const char *error, void *context) +{ + struct passdb_sql_request *sql_request = context; + enum passdb_result result; + + if (error == NULL) + result = PASSDB_RESULT_OK; + else { + result = PASSDB_RESULT_INTERNAL_FAILURE; + auth_request_log_error(sql_request->auth_request, "sql", + "Set credentials query failed: %s", + error); + } + sql_request->callback.set_credentials(result, + sql_request->auth_request); + i_free(sql_request); +} + +static int sql_set_credentials(struct auth_request *request, + const char *new_credentials, + set_credentials_callback_t *callback) +{ + struct sql_passdb_module *module = + (struct sql_passdb_module *) request->passdb->passdb; + struct sql_transaction_context *transaction; + struct passdb_sql_request *sql_request; + string_t *query; + + t_push(); + + request->mech_password = p_strdup(request->pool, new_credentials); + + query = t_str_new(512); + var_expand(query, module->conn->set.update_query, + auth_request_get_var_expand_table(request, + passdb_sql_escape)); + + sql_request = i_new(struct passdb_sql_request, 1); + sql_request->auth_request = request; + sql_request->callback.set_credentials = callback; + + transaction = sql_transaction_begin(module->conn->db); + sql_update(transaction, str_c(query)); + sql_transaction_commit(&transaction, + sql_set_credentials_callback, sql_request); + + t_pop(); + return 0; +} + static struct passdb_module * passdb_sql_preinit(struct auth_passdb *auth_passdb, const char *args) { @@ -223,7 +275,8 @@ passdb_sql_deinit, sql_verify_plain, - sql_lookup_credentials + sql_lookup_credentials, + sql_set_credentials }; #endif
--- a/src/auth/passdb-vpopmail.c Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/passdb-vpopmail.c Wed Nov 08 22:22:08 2006 +0200 @@ -153,7 +153,8 @@ vpopmail_deinit, vpopmail_verify_plain, - vpopmail_lookup_credentials + vpopmail_lookup_credentials, + NULL }; #endif
--- a/src/auth/passdb.h Wed Nov 08 22:02:34 2006 +0200 +++ b/src/auth/passdb.h Wed Nov 08 22:22:08 2006 +0200 @@ -35,6 +35,8 @@ typedef void lookup_credentials_callback_t(enum passdb_result result, const char *password, struct auth_request *request); +typedef void set_credentials_callback_t(enum passdb_result result, + struct auth_request *request); struct passdb_module_interface { const char *name; @@ -52,6 +54,11 @@ auth_request->credentials. */ void (*lookup_credentials)(struct auth_request *request, lookup_credentials_callback_t *callback); + + /* Update credentials */ + int (*set_credentials)(struct auth_request *request, + const char *new_credentials, + set_credentials_callback_t *callback); }; struct passdb_module {