void mail_storage_service_user_free(struct mail_storage_service_user **_user) { struct mail_storage_service_user *user = *_user; *_user = NULL; if (user->ioloop_ctx != NULL) { if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) == 0) { io_loop_context_remove_callbacks(user->ioloop_ctx, mail_storage_service_io_activate_user, mail_storage_service_io_deactivate_user, user); if (io_loop_get_current_context(current_ioloop) == user->ioloop_ctx) mail_storage_service_io_deactivate_user(user); } io_loop_context_unref(&user->ioloop_ctx); } settings_parser_deinit(&user->set_parser); pool_unref(&user->pool); }
int mail_storage_service_lookup(struct mail_storage_service_ctx *ctx, const struct mail_storage_service_input *input, struct mail_storage_service_user **user_r, const char **error_r) { char *old_log_prefix = i_strdup(i_get_failure_prefix()); bool update_log_prefix; int ret; if (io_loop_get_current_context(current_ioloop) == NULL) { /* no user yet. log prefix should be just "imap:" or something equally unhelpful. we don't know the proper log format yet, but initialize it to something better until we know it. */ const char *session_id = input->session_id != NULL ? input->session_id : (input->session_id_prefix != NULL ? input->session_id_prefix : NULL); i_set_failure_prefix("%s(%s%s,%s)", master_service_get_name(ctx->service), input->username, session_id == NULL ? "" : t_strdup_printf(",%s", session_id), input->remote_ip.family == 0 ? "" : t_strdup_printf(",%s", net_ip2addr(&input->remote_ip))); update_log_prefix = TRUE; } else { /* we might be here because we're doing a user lookup for a shared user. the log prefix is likely already usable, so just append our own without replacing the whole thing. */ i_set_failure_prefix("%suser-lookup(%s)", old_log_prefix, input->username); update_log_prefix = FALSE; } ret = mail_storage_service_lookup_real(ctx, input, update_log_prefix, user_r, error_r); i_set_failure_prefix("%s", old_log_prefix); i_free(old_log_prefix); return ret; }
static void stats_user_created(struct mail_user *user) { struct ioloop_context *ioloop_ctx = io_loop_get_current_context(current_ioloop); struct stats_user *suser; struct mail_user_vfuncs *v = user->vlast; const char *path, *str, *error; unsigned int refresh_secs; if (ioloop_ctx == NULL) { /* we're probably running some test program, or at least mail-storage-service wasn't used to create this user. disable stats tracking. */ return; } if (user->autocreated) { /* lda / shared user. we're not tracking this one. */ return; } /* get refresh time */ str = mail_user_plugin_getenv(user, "stats_refresh"); if (str == NULL) return; if (settings_get_time(str, &refresh_secs, &error) < 0) { i_error("stats: Invalid stats_refresh setting: %s", error); return; } if (refresh_secs == 0) return; if (refresh_secs > SESSION_STATS_FORCE_REFRESH_SECS) { i_warning("stats: stats_refresh too large, changing to %u", SESSION_STATS_FORCE_REFRESH_SECS); refresh_secs = SESSION_STATS_FORCE_REFRESH_SECS; } if (global_stats_conn == NULL) { path = t_strconcat(user->set->base_dir, "/"MAIL_STATS_SOCKET_NAME, NULL); global_stats_conn = stats_connection_create(path); } stats_connection_ref(global_stats_conn); if (stats_user_count == 0) { /* first user connection */ stats_global_user = user; } else if (stats_user_count == 1) { /* second user connection. we'll need to start doing per-io callback tracking now. (we might have been doing it also previously but just temporarily quickly dropped to having 1 user, in which case stats_global_user=NULL) */ if (stats_global_user != NULL) { stats_add_session(stats_global_user); stats_global_user = NULL; } } stats_user_count++; suser = p_new(user->pool, struct stats_user, 1); suser->module_ctx.super = *v; user->vlast = &suser->module_ctx.super; v->deinit = stats_user_deinit; v->stats_fill = stats_user_stats_fill; suser->refresh_secs = refresh_secs; str = mail_user_plugin_getenv(user, "stats_track_cmds"); if (str != NULL && strcmp(str, "yes") == 0) suser->track_commands = TRUE; suser->stats_conn = global_stats_conn; if (user->session_id != NULL && user->session_id[0] != '\0') suser->stats_session_id = user->session_id; else { guid_128_t guid; guid_128_generate(guid); suser->stats_session_id = p_strdup(user->pool, guid_128_to_string(guid)); } suser->last_session_update = time(NULL); user->stats_enabled = TRUE; suser->ioloop_ctx = ioloop_ctx; io_loop_context_add_callbacks(ioloop_ctx, stats_io_activate, stats_io_deactivate, user); suser->pre_io_stats = stats_alloc(user->pool); suser->session_stats = stats_alloc(user->pool); suser->last_sent_session_stats = stats_alloc(user->pool); MODULE_CONTEXT_SET(user, stats_user_module, suser); mail_stats_connection_connect(suser->stats_conn, user); suser->to_stats_timeout = timeout_add(suser->refresh_secs*1000, session_stats_refresh_timeout, user); /* fill the initial values. this is necessary for the process-global values (e.g. getrusage()) if the process is reused for multiple users. otherwise the next user will start with the previous one's last values. */ mail_user_stats_fill(user, suser->pre_io_stats); }
static void stats_user_created(struct mail_user *user) { struct ioloop_context *ioloop_ctx = io_loop_get_current_context(current_ioloop); struct stats_user *suser; struct mail_user_vfuncs *v = user->vlast; const char *path, *str, *error; unsigned int refresh_secs; if (ioloop_ctx == NULL) { /* we're probably running some test program, or at least mail-storage-service wasn't used to create this user. disable stats tracking. */ return; } if (user->autocreated) { /* lda / shared user. we're not tracking this one. */ return; } /* get refresh time */ str = mail_user_plugin_getenv(user, "stats_refresh"); if (str == NULL) return; if (settings_get_time(str, &refresh_secs, &error) < 0) { i_error("stats: Invalid stats_refresh setting: %s", error); return; } if (refresh_secs == 0) return; if (global_stats_conn == NULL) { path = t_strconcat(user->set->base_dir, "/"MAIL_STATS_SOCKET_NAME, NULL); global_stats_conn = stats_connection_create(path); } stats_connection_ref(global_stats_conn); if (stats_user_count == 0) { /* first user connection */ stats_global_user = user; } else if (stats_user_count == 1) { /* second user connection. we'll need to start doing per-io callback tracking now. (we might have been doing it also previously but just temporarily quickly dropped to having 1 user, in which case stats_global_user=NULL) */ if (stats_global_user != NULL) { stats_add_session(stats_global_user); stats_global_user = NULL; } } stats_user_count++; suser = p_new(user->pool, struct stats_user, 1); suser->module_ctx.super = *v; user->vlast = &suser->module_ctx.super; v->deinit = stats_user_deinit; suser->refresh_secs = refresh_secs; str = mail_user_plugin_getenv(user, "stats_track_cmds"); if (str != NULL && strcmp(str, "yes") == 0) suser->track_commands = TRUE; suser->stats_conn = global_stats_conn; guid_128_generate(suser->session_guid); suser->last_session_update = time(NULL); suser->ioloop_ctx = ioloop_ctx; io_loop_context_add_callbacks(ioloop_ctx, stats_io_activate, stats_io_deactivate, user); MODULE_CONTEXT_SET(user, stats_user_module, suser); stats_connection_connect(suser->stats_conn, user); }