Mercurial > dovecot > core-2.2
changeset 20840:1b4a57403aef
*-login: Store user_* passdb fields to client->alt_usernames.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Wed, 05 Oct 2016 23:22:56 +0300 |
parents | 78d312e6abdc |
children | c3cc30b7eda6 |
files | src/login-common/client-common-auth.c src/login-common/client-common.h src/login-common/login-common.h src/login-common/main.c |
diffstat | 4 files changed, 66 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/src/login-common/client-common-auth.c Mon Oct 10 17:37:27 2016 +0300 +++ b/src/login-common/client-common-auth.c Wed Oct 05 23:22:56 2016 +0300 @@ -2,6 +2,7 @@ #include "hostpid.h" #include "login-common.h" +#include "array.h" #include "iostream.h" #include "istream.h" #include "ostream.h" @@ -59,12 +60,45 @@ client_auth_waiting_timeout, client); } -static void client_auth_parse_args(struct client *client, +static void alt_username_set(ARRAY_TYPE(const_string) *alt_usernames, pool_t pool, + const char *key, const char *value) +{ + char *const *fields; + unsigned int i, count; + + fields = array_get(&global_alt_usernames, &count); + for (i = 0; i < count; i++) { + if (strcmp(fields[i], key) == 0) + break; + } + if (i == count) { + char *new_key = i_strdup(key); + array_append(&global_alt_usernames, &new_key, 1); + } + + value = p_strdup(pool, value); + if (i < array_count(alt_usernames)) { + array_idx_set(alt_usernames, i, &value); + return; + } + + /* array is NULL-terminated, so if there are unused fields in + the middle set them as "" */ + while (array_count(alt_usernames) < i) { + const char *empty_str = ""; + array_append(alt_usernames, &empty_str, 1); + } + array_append(alt_usernames, &value, 1); +} + +static void client_auth_parse_args(struct client *client, bool success, const char *const *args, struct client_auth_reply *reply_r) { const char *key, *value, *p; + ARRAY_TYPE(const_string) alt_usernames; + t_array_init(&alt_usernames, 4); memset(reply_r, 0, sizeof(*reply_r)); for (; *args != NULL; args++) { @@ -136,9 +170,23 @@ } else if (strcmp(key, "user") == 0 || strcmp(key, "postlogin_socket") == 0) { /* already handled in sasl-server.c */ + } else if (strncmp(key, "user_", 5) == 0) { + if (success) { + alt_username_set(&alt_usernames, client->pool, + key, value); + } } else if (client->set->auth_debug) i_debug("Ignoring unknown passdb extra field: %s", key); } + if (array_count(&alt_usernames) > 0) { + const char **alt; + + alt = p_new(client->pool, const char *, + array_count(&alt_usernames) + 1); + memcpy(alt, array_idx(&alt_usernames, 0), + sizeof(*alt) * array_count(&alt_usernames)); + client->alt_usernames = alt; + } if (reply_r->port == 0) reply_r->port = login_binary->default_port; @@ -564,7 +612,7 @@ if (client->to_auth_waiting != NULL) timeout_remove(&client->to_auth_waiting); if (args != NULL) { - client_auth_parse_args(client, args, &reply); + client_auth_parse_args(client, TRUE, args, &reply); reply.all_fields = args; if (client_auth_handle_reply(client, &reply, TRUE)) break; @@ -578,7 +626,7 @@ if (client->to_auth_waiting != NULL) timeout_remove(&client->to_auth_waiting); if (args != NULL) { - client_auth_parse_args(client, args, &reply); + client_auth_parse_args(client, FALSE, args, &reply); reply.nologin = TRUE; reply.all_fields = args; if (client_auth_handle_reply(client, &reply, FALSE))
--- a/src/login-common/client-common.h Mon Oct 10 17:37:27 2016 +0300 +++ b/src/login-common/client-common.h Wed Oct 05 23:22:56 2016 +0300 @@ -154,6 +154,11 @@ ARRAY(union login_client_module_context *) module_contexts; char *virtual_user, *virtual_user_orig, *virtual_auth_user; + /* passdb user_* fields are set here after a successful auth. + This is a NULL-terminated array where fields are in the same order + as in global_alt_usernames. If some field doesn't exist, it's "". + Can also be NULL if there are no user_* fields. */ + const char **alt_usernames; unsigned int destroyed:1; unsigned int input_blocked:1; unsigned int login_success:1;
--- a/src/login-common/login-common.h Mon Oct 10 17:37:27 2016 +0300 +++ b/src/login-common/login-common.h Wed Oct 05 23:22:56 2016 +0300 @@ -50,6 +50,9 @@ extern struct anvil_client *anvil; extern const char *login_rawlog_dir; extern unsigned int initial_service_count; +/* NULL-terminated array of all alt_usernames seen so far. Existing fields are + never removed. */ +extern ARRAY_TYPE(string) global_alt_usernames; extern const struct login_settings *global_login_settings; extern const struct master_service_ssl_settings *global_ssl_settings;
--- a/src/login-common/main.c Mon Oct 10 17:37:27 2016 +0300 +++ b/src/login-common/main.c Wed Oct 05 23:22:56 2016 +0300 @@ -41,6 +41,7 @@ const char *login_rawlog_dir = NULL; unsigned int initial_service_count; struct login_module_register login_module_register; +ARRAY_TYPE(string) global_alt_usernames; const struct login_settings *global_login_settings; const struct master_service_ssl_settings *global_ssl_settings; @@ -397,6 +398,7 @@ /* make sure we can't fork() */ restrict_process_count(1); + i_array_init(&global_alt_usernames, 4); master_service_set_avail_overflow_callback(master_service, client_destroy_oldest); master_service_set_die_callback(master_service, login_die); @@ -419,6 +421,11 @@ auth_client_deinit(&auth_client); master_auth_deinit(&master_auth); + char **strp; + array_foreach_modifiable(&global_alt_usernames, strp) + i_free(*strp); + array_free(&global_alt_usernames); + if (anvil != NULL) anvil_client_deinit(&anvil); if (auth_client_to != NULL)