static int client_create_from_input(const struct mail_storage_service_input *input, int fd_in, int fd_out, const buffer_t *input_buf, const char **error_r) { const char *lookup_error_str = "-ERR [SYS/TEMP] "MAIL_ERRSTR_CRITICAL_MSG"\r\n"; struct mail_storage_service_user *user; struct mail_user *mail_user; struct client *client; const struct pop3_settings *set; if (mail_storage_service_lookup_next(storage_service, input, &user, &mail_user, error_r) <= 0) { (void)write(fd_out, lookup_error_str, strlen(lookup_error_str)); return -1; } restrict_access_allow_coredumps(TRUE); set = mail_storage_service_user_get_set(user)[1]; if (set->verbose_proctitle) verbose_proctitle = TRUE; if (client_create(fd_in, fd_out, input->session_id, mail_user, user, set, &client) == 0) client_add_input(client, input_buf); return 0; }
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; }
static void cmd_import_init(struct doveadm_mail_cmd_context *_ctx, const char *const args[]) { struct import_cmd_context *ctx = (struct import_cmd_context *)_ctx; struct mail_storage_service_input input; struct mail_storage_service_user *service_user; struct mail_user *user; const char *src_location, *error; if (str_array_length(args) < 3) doveadm_mail_help_name("import"); src_location = args[0]; ctx->dest_parent = p_strdup(_ctx->pool, args[1]); ctx->ctx.search_args = doveadm_mail_build_search_args(args+2); /* create a user for accessing the source storage */ memset(&input, 0, sizeof(input)); input.module = "mail"; input.username = "******"; input.flags_override_add = MAIL_STORAGE_SERVICE_FLAG_NO_NAMESPACES | MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS; input.flags_override_remove = MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; if (mail_storage_service_lookup_next(ctx->ctx.storage_service, &input, &service_user, &user, &error) < 0) i_fatal("Import user initialization failed: %s", error); if (mail_namespaces_init_location(user, src_location, &error) < 0) i_fatal("Import namespace initialization failed: %s", error); ctx->src_user = user; mail_storage_service_user_free(&service_user); }
static void cmd_import_init(struct doveadm_mail_cmd_context *_ctx, const char *const args[]) { struct import_cmd_context *ctx = (struct import_cmd_context *)_ctx; struct mail_storage_service_input input; struct mail_storage_service_user *service_user; struct mail_user *user; const char *src_location, *error, *userdb_fields[2]; if (str_array_length(args) < 3) doveadm_mail_help_name("import"); src_location = args[0]; ctx->dest_parent = p_strdup(_ctx->pool, args[1]); ctx->ctx.search_args = doveadm_mail_build_search_args(args+2); /* @UNSAFE */ userdb_fields[0] = t_strconcat("mail=", src_location, NULL); userdb_fields[1] = NULL; /* create a user for accessing the source storage */ memset(&input, 0, sizeof(input)); input.module = "module"; input.username = "******"; input.no_userdb_lookup = TRUE; input.userdb_fields = userdb_fields; if (mail_storage_service_lookup_next(ctx->ctx.storage_service, &input, &service_user, &user, &error) < 0) i_fatal("Import user initialization failed: %s", error); ctx->src_user = user; mail_storage_service_user_free(&service_user); }
static void cmd_copy_alloc_source_user(struct copy_cmd_context *ctx, const char *username) { struct mail_storage_service_input input; const char *error; input = ctx->ctx.storage_service_input; input.username = username; if (mail_storage_service_lookup_next(ctx->ctx.storage_service, &input, &ctx->source_service_user, &ctx->source_user, &error) < 0) i_fatal("Couldn't lookup user %s: %s", input.username, error); }
static int master_connection_input_line(struct master_connection *conn, const char *line) { const char *const *args = t_strsplit_tabescaped(line); struct mail_storage_service_input input; struct mail_storage_service_user *service_user; struct mail_user *user; const char *str, *error; unsigned int max_recent_msgs; int ret; /* <username> <mailbox> <session ID> <max_recent_msgs> [i][o] */ if (str_array_length(args) != 5 || str_to_uint(args[3], &max_recent_msgs) < 0 || args[4][0] == '\0') { i_error("Invalid input from master: %s", line); return -1; } i_zero(&input); input.module = "mail"; input.service = "indexer-worker"; input.username = args[0]; /* if session-id is given, use it as a prefix to a unique session ID. we can't use the session-id directly or stats process will complain about duplicates. (especially LMTP would use the same session-id for multiple users' indexing at the same time.) */ if (args[2][0] != '\0') input.session_id_prefix = args[2]; if (mail_storage_service_lookup_next(conn->storage_service, &input, &service_user, &user, &error) <= 0) { i_error("User %s lookup failed: %s", args[0], error); ret = -1; } else { indexer_worker_refresh_proctitle(user->username, args[1], 0, 0); ret = index_mailbox(conn, user, args[1], max_recent_msgs, args[4]); /* refresh proctitle before a potentially long-running user unref */ indexer_worker_refresh_proctitle(user->username, "(deinit)", 0, 0); mail_user_unref(&user); mail_storage_service_user_unref(&service_user); indexer_worker_refresh_proctitle(NULL, NULL, 0, 0); } str = ret < 0 ? "-1\n" : "100\n"; return write_full(conn->fd, str, strlen(str)); }
static int client_create_from_input(const struct mail_storage_service_input *input, int fd_in, int fd_out, const buffer_t *input_buf, const char **error_r) { const char *lookup_error_str = "-ERR [SYS/TEMP] "MAIL_ERRSTR_CRITICAL_MSG"\r\n"; struct mail_storage_service_user *user; struct mail_user *mail_user; struct client *client; const struct pop3_settings *set; const char *error; if (mail_storage_service_lookup_next(storage_service, input, &user, &mail_user, error_r) <= 0) { if (write(fd_out, lookup_error_str, strlen(lookup_error_str)) < 0) { /* ignored */ } return -1; } restrict_access_allow_coredumps(TRUE); set = mail_storage_service_user_get_set(user)[1]; if (set->verbose_proctitle) verbose_proctitle = TRUE; if (client_create(fd_in, fd_out, input->session_id, mail_user, user, set, &client) < 0) return 0; if (!IS_STANDALONE()) client_send_line(client, "+OK Logged in."); if (client_init_mailbox(client, &error) == 0) client_add_input(client, input_buf); else { i_error("%s", error); client_destroy(client, error); } return 0; }
static int master_connection_input_line(struct master_connection *conn, const char *line) { const char *const *args = t_strsplit_tabescaped(line); struct mail_storage_service_input input; struct mail_storage_service_user *service_user; struct mail_user *user; const char *str, *error; unsigned int max_recent_msgs; int ret; /* <username> <mailbox> <max_recent_msgs> [i][o] */ if (str_array_length(args) != 4 || str_to_uint(args[2], &max_recent_msgs) < 0 || args[3][0] == '\0') { i_error("Invalid input from master: %s", line); return -1; } memset(&input, 0, sizeof(input)); input.module = "mail"; input.service = "indexer-worker"; input.username = args[0]; if (mail_storage_service_lookup_next(conn->storage_service, &input, &service_user, &user, &error) <= 0) { i_error("User %s lookup failed: %s", args[0], error); ret = -1; } else { indexer_worker_refresh_proctitle(user->username, args[1], 0, 0); ret = index_mailbox(conn, user, args[1], max_recent_msgs, args[3]); indexer_worker_refresh_proctitle(NULL, NULL, 0, 0); mail_user_unref(&user); mail_storage_service_user_free(&service_user); } str = ret < 0 ? "-1\n" : "100\n"; return write_full(conn->fd, str, strlen(str)); }
static void cmd_import_init_source_user(struct import_cmd_context *ctx) { struct mail_storage_service_input input; struct mail_storage_service_user *service_user; struct mail_user *user; const char *error; /* create a user for accessing the source storage */ memset(&input, 0, sizeof(input)); input.module = "mail"; input.username = "******"; input.flags_override_add = MAIL_STORAGE_SERVICE_FLAG_NO_NAMESPACES | MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS; input.flags_override_remove = MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; if (mail_storage_service_lookup_next(ctx->ctx.storage_service, &input, &service_user, &user, &error) < 0) i_fatal("Import user initialization failed: %s", error); if (mail_namespaces_init_location(user, ctx->src_location, &error) < 0) i_fatal("Import namespace initialization failed: %s", error); ctx->src_user = user; mail_storage_service_user_free(&service_user); }
struct sieve_instance *sieve_tool_init_finish (struct sieve_tool *tool, bool init_mailstore, bool preserve_root) { enum mail_storage_service_flags storage_service_flags = MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR | MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT | MAIL_STORAGE_SERVICE_FLAG_USE_SYSEXITS; struct mail_storage_service_input service_input; struct sieve_environment svenv; const char *username = tool->username; const char *homedir = tool->homedir; const char *errstr; master_service_init_finish(master_service); if ( username == NULL ) { sieve_tool_get_user_data(&username, &homedir); username = tool->username = i_strdup(username); if ( tool->homedir != NULL ) i_free(tool->homedir); tool->homedir = i_strdup(homedir); if ( preserve_root ) { storage_service_flags |= MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS; } } else { storage_service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; } if ( !init_mailstore ) storage_service_flags |= MAIL_STORAGE_SERVICE_FLAG_NO_NAMESPACES; memset(&service_input, 0, sizeof(service_input)); service_input.module = "mail"; service_input.service = tool->name; service_input.username = username; tool->storage_service = mail_storage_service_init (master_service, NULL, storage_service_flags); if (mail_storage_service_lookup_next (tool->storage_service, &service_input, &tool->service_user, &tool->mail_user_dovecot, &errstr) <= 0) i_fatal("%s", errstr); if ( master_service_set (master_service, "mail_full_filesystem_access=yes") < 0 ) i_unreached(); memset((void *)&svenv, 0, sizeof(svenv)); svenv.username = username; (void)mail_user_get_home(tool->mail_user_dovecot, &svenv.home_dir); svenv.hostname = my_hostdomain(); svenv.base_dir = tool->mail_user_dovecot->set->base_dir; svenv.temp_dir = tool->mail_user_dovecot->set->mail_temp_dir; svenv.location = SIEVE_ENV_LOCATION_MS; svenv.delivery_phase = SIEVE_DELIVERY_PHASE_POST; /* Initialize Sieve Engine */ if ( (tool->svinst=sieve_init (&svenv, &sieve_tool_callbacks, tool, tool->debug)) == NULL ) i_fatal("failed to initialize sieve implementation"); /* Load Sieve plugins */ if ( array_count(&tool->sieve_plugins) > 0 ) { sieve_tool_load_plugins(tool); } /* Set active Sieve extensions */ if ( tool->sieve_extensions != NULL ) { sieve_set_extensions(tool->svinst, tool->sieve_extensions); } else if ( tool->no_config ) { sieve_set_extensions(tool->svinst, NULL); } return tool->svinst; }
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; }