static void mail_user_expand_plugins_envs(struct mail_user *user) { const char **envs, *home; string_t *str; unsigned int i, count; if (!array_is_created(&user->set->plugin_envs)) return; str = t_str_new(256); envs = array_get_modifiable(&user->set->plugin_envs, &count); i_assert((count % 2) == 0); for (i = 0; i < count; i += 2) { if (user->_home == NULL && var_has_key(envs[i+1], 'h', "home") && mail_user_get_home(user, &home) <= 0) { user->error = p_strdup_printf(user->pool, "userdb didn't return a home directory, " "but plugin setting %s used it (%%h): %s", envs[i], envs[i+1]); return; } str_truncate(str, 0); var_expand(str, envs[i+1], mail_user_var_expand_table(user)); envs[i+1] = p_strdup(user->pool, str_c(str)); } }
static int client_create_from_input(const struct mail_storage_service_input *input, const struct master_login_client *login_client, int fd_in, int fd_out, const buffer_t *input_buf, const char **error_r) { struct mail_storage_service_user *user; struct mail_user *mail_user; struct client *client; struct imap_settings *set; enum mail_auth_request_flags flags; if (mail_storage_service_lookup_next(storage_service, input, &user, &mail_user, error_r) <= 0) return -1; restrict_access_allow_coredumps(TRUE); set = mail_storage_service_user_get_set(user)[1]; if (set->verbose_proctitle) verbose_proctitle = TRUE; settings_var_expand(&imap_setting_parser_info, set, mail_user->pool, mail_user_var_expand_table(mail_user)); client = client_create(fd_in, fd_out, input->session_id, mail_user, user, set); T_BEGIN { client_add_input(client, input_buf); } T_END; flags = login_client->auth_req.flags; if ((flags & MAIL_AUTH_REQUEST_FLAG_TLS_COMPRESSION) != 0) client->tls_compression = TRUE; return 0; }
int mail_user_init(struct mail_user *user, const char **error_r) { const struct mail_storage_settings *mail_set; const char *home, *key, *value; bool need_home_dir; need_home_dir = user->_home == NULL && settings_vars_have_key(user->set_info, user->set, 'h', "home", &key, &value); if (need_home_dir && mail_user_get_home(user, &home) <= 0) { user->error = p_strdup_printf(user->pool, "userdb didn't return a home directory, " "but %s used it (%%h): %s", key, value); } /* expand settings after we can expand %h */ settings_var_expand_with_funcs(user->set_info, user->set, user->pool, mail_user_var_expand_table(user), mail_user_var_expand_func_table, user); user->settings_expanded = TRUE; mail_user_expand_plugins_envs(user); /* autocreated users for shared mailboxes need to be fully initialized if they don't exist, since they're going to be used anyway */ if (user->error == NULL || user->nonexistent) { mail_set = mail_user_set_get_storage_set(user); user->mail_debug = mail_set->mail_debug; user->initialized = TRUE; hook_mail_user_created(user); } if (user->error != NULL) { *error_r = t_strdup(user->error); return -1; } return 0; }
int mail_user_init(struct mail_user *user, const char **error_r) { const struct mail_storage_settings *mail_set; const char *home, *key, *value; bool need_home_dir; need_home_dir = user->_home == NULL && settings_vars_have_key(user->set_info, user->set, 'h', "home", &key, &value); /* expand mail_home setting before calling mail_user_get_home() */ settings_var_expand(user->set_info, user->set, user->pool, mail_user_var_expand_table(user)); if (need_home_dir && mail_user_get_home(user, &home) <= 0) { *error_r = t_strdup_printf( "userdb didn't return a home directory, " "but %s used it (%%h): %s", key, value); return -1; } if (mail_user_expand_plugins_envs(user, error_r) < 0) return -1; mail_set = mail_user_set_get_storage_set(user); user->mail_debug = mail_set->mail_debug; user->initialized = TRUE; hook_mail_user_created(user); if (user->error != NULL) { *error_r = t_strdup(user->error); return -1; } return 0; }
static int client_handle_user_command(struct client *client, const char *cmd, const char *const *args, const char **error_r) { struct mail_storage_service_input input; struct imap_urlauth_worker_settings *set; struct mail_storage_service_user *user; struct imap_urlauth_config config; struct mail_user *mail_user; const char *error; unsigned int count; int ret; /* "USER\t"<username> */ *error_r = NULL; /* check command syntax */ if (strcmp(cmd, "USER") != 0) { *error_r = t_strconcat("Unknown or inappropriate command: ", cmd, NULL); return -1; } if (args[0] == NULL || args[1] != NULL) { *error_r = "USER: Invalid number of parameters"; return -1; } /* lookup user */ memset(&input, 0, sizeof(input)); input.module = "imap-urlauth-worker"; input.service = "imap-urlauth-worker"; input.username = args[0]; if (client->debug) i_debug("Looking up user %s", input.username); ret = mail_storage_service_lookup_next(storage_service, &input, &user, &mail_user, &error); if (ret < 0) { i_error("Failed to lookup user %s: %s", input.username, error); client_abort(client, "Session aborted: Failed to lookup user"); return 0; } else if (ret == 0) { if (client->debug) i_debug("User %s doesn't exist", input.username); client_send_line(client, "NO"); timeout_remove(&client->to_delay); return 1; } client->debug = mail_user->mail_debug = client->debug || mail_user->mail_debug; /* drop privileges */ restrict_access_allow_coredumps(TRUE); set = mail_storage_service_user_get_set(user)[1]; settings_var_expand(&imap_urlauth_worker_setting_parser_info, set, mail_user->pool, mail_user_var_expand_table(mail_user)); if (set->verbose_proctitle) { verbose_proctitle = TRUE; imap_urlauth_worker_refresh_proctitle(); } client->service_user = user; client->mail_user = mail_user; client->set = set; if (client->debug) { i_debug("Found user account `%s' on behalf of user `%s'", mail_user->username, client->access_user); } /* initialize urlauth context */ if (*set->imap_urlauth_host == '\0') { i_error("imap_urlauth_host setting is not configured for user %s", mail_user->username); client_send_line(client, "NO"); client_abort(client, "Session aborted: URLAUTH not configured"); return 0; } memset(&config, 0, sizeof(config)); config.url_host = set->imap_urlauth_host; config.url_port = set->imap_urlauth_port; config.access_user = client->access_user; config.access_anonymous = client->access_anonymous; config.access_applications = (const void *)array_get(&client->access_apps, &count); client->urlauth_ctx = imap_urlauth_init(client->mail_user, &config); if (client->debug) { i_debug("Providing access to user account `%s' on behalf of `%s'", mail_user->username, client->access_user); } i_set_failure_prefix("imap-urlauth[%s](%s->%s): ", my_pid, client->access_user, mail_user->username); client_send_line(client, "OK"); return 1; }
static int cmd_user_mail_input(struct mail_storage_service_ctx *storage_service, const struct authtest_input *input, const char *show_field, const char *expand_field) { struct mail_storage_service_input service_input; struct mail_storage_service_user *service_user; struct mail_user *user; const char *error, *const *userdb_fields; pool_t pool; int ret; memset(&service_input, 0, sizeof(service_input)); service_input.module = "mail"; service_input.service = input->info.service; service_input.username = input->username; service_input.local_ip = input->info.local_ip; service_input.local_port = input->info.local_port; service_input.remote_ip = input->info.remote_ip; service_input.remote_port = input->info.remote_port; service_input.debug = input->info.debug; pool = pool_alloconly_create("userdb fields", 1024); mail_storage_service_save_userdb_fields(storage_service, pool, &userdb_fields); if ((ret = mail_storage_service_lookup_next(storage_service, &service_input, &service_user, &user, &error)) <= 0) { pool_unref(&pool); if (ret < 0) return -1; string_t *username = t_str_new(32); json_append_escaped(username, input->username); o_stream_nsend_str(doveadm_print_ostream, t_strdup_printf("\"error\":\"userdb lookup: user %s doesn't exist\"", str_c(username)) ); return 0; } if (expand_field == NULL) cmd_user_mail_print_fields(input, user, userdb_fields, show_field); else { string_t *str = t_str_new(128); if (var_expand_with_funcs(str, expand_field, mail_user_var_expand_table(user), mail_user_var_expand_func_table, user, &error) <= 0) { string_t *str = t_str_new(128); str_printfa(str, "\"error\":\"Failed to expand field: "); json_append_escaped(str, error); str_append_c(str, '"'); o_stream_nsend(doveadm_print_ostream, str_data(str), str_len(str)); } else { string_t *value = t_str_new(128); json_append_escaped(value, expand_field); o_stream_nsend_str(doveadm_print_ostream, "\""); o_stream_nsend_str(doveadm_print_ostream, str_c(value)); o_stream_nsend_str(doveadm_print_ostream, "\":\""); str_truncate(value, 0); json_append_escaped(value, str_c(str)); o_stream_nsend_str(doveadm_print_ostream, str_c(value)); o_stream_nsend_str(doveadm_print_ostream, "\""); } } mail_user_unref(&user); mail_storage_service_user_free(&service_user); pool_unref(&pool); return 1; }