From: Timo Sirainen Date: Mon, 20 Apr 2009 23:07:24 +0000 (-0400) Subject: Pass remote/local IPs to mail_users. Standalone mail programs now log with mail_log_p... X-Git-Tag: 2.0.alpha1~905 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d1fff80640050631b06bfab904a34b2ad24601e8;p=thirdparty%2Fdovecot%2Fcore.git Pass remote/local IPs to mail_users. Standalone mail programs now log with mail_log_prefix. --HG-- branch : HEAD --- diff --git a/src/imap/main.c b/src/imap/main.c index 518047471d..44eccc3489 100644 --- a/src/imap/main.c +++ b/src/imap/main.c @@ -138,10 +138,11 @@ int main(int argc, char *argv[], char *envp[]) }; enum master_service_flags service_flags = 0; enum mail_storage_service_flags storage_service_flags = 0; + struct mail_storage_service_input input; struct mail_user *mail_user; const struct imap_settings *set; - const char *user; bool dump_capability; + const char *value; int c; #ifdef DEBUG @@ -172,18 +173,23 @@ int main(int argc, char *argv[], char *envp[]) i_fatal("Unknown argument: %c", c); } - user = getenv("USER"); - if (user == NULL) { + memset(&input, 0, sizeof(input)); + input.username = getenv("USER"); + if (input.username == NULL) { if (IS_STANDALONE()) - user = getlogin(); - if (user == NULL) + input.username = getlogin(); + if (input.username == NULL) i_fatal("USER environment missing"); } + if ((value = getenv("IP")) != NULL) + net_addr2ip(value, &input.remote_ip); + if ((value = getenv("LOCAL_IP")) != NULL) + net_addr2ip(value, &input.local_ip); /* plugins may want to add commands, so this needs to be called early */ commands_init(); - mail_user = mail_storage_service_init_user(service, user, set_roots, + mail_user = mail_storage_service_init_user(service, &input, set_roots, storage_service_flags); set = mail_storage_service_get_settings(service); restrict_access_allow_coredumps(TRUE); diff --git a/src/lda/main.c b/src/lda/main.c index c7fe0fb99f..0b8d0af83c 100644 --- a/src/lda/main.c +++ b/src/lda/main.c @@ -183,6 +183,7 @@ int main(int argc, char *argv[]) struct mail_deliver_context ctx; enum mail_storage_service_flags service_flags = 0; const char *user, *errstr, *path, *getopt_str; + struct mail_storage_service_input service_input; struct mail_user *raw_mail_user; struct mail_namespace *raw_ns; struct mail_namespace_settings raw_ns_set; @@ -317,8 +318,12 @@ int main(int argc, char *argv[]) "destination user parameter (-d user) not given"); } + memset(&service_input, 0, sizeof(service_input)); + service_input.username = user; + service_flags |= MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT; - ctx.dest_user = mail_storage_service_init_user(service, user, set_roots, + ctx.dest_user = mail_storage_service_init_user(service, &service_input, + set_roots, service_flags); ctx.set = mail_storage_service_get_settings(service); duplicate_init(mail_user_set_get_storage_set(ctx.dest_user->set)); diff --git a/src/lib-storage/mail-storage-service.c b/src/lib-storage/mail-storage-service.c index cff0c6d729..db0b9b8b9c 100644 --- a/src/lib-storage/mail-storage-service.c +++ b/src/lib-storage/mail-storage-service.c @@ -31,7 +31,8 @@ struct mail_storage_service_multi_ctx { struct mail_storage_service_multi_user { pool_t pool; - const char *user; + struct mail_storage_service_input input; + const char *system_groups_user; const struct mail_user_settings *user_set; struct setting_parser_context *set_parser; @@ -178,7 +179,6 @@ service_auth_userdb_lookup(struct setting_parser_context *set_parser, if (ret > 0 && strcmp(*user, orig_user) != 0) { if (mail_user_set_get_storage_set(user_set)->mail_debug) i_info("changed username to %s", *user); - i_set_failure_prefix(t_strdup_printf("%s(%s): ", name, *user)); } auth_master_deinit(&conn); @@ -336,7 +336,8 @@ mail_storage_service_init_settings(struct master_service *service, static int mail_storage_service_init_post(struct master_service *service, - const char *user, const char *home, + const struct mail_storage_service_input *input, + const char *home, const struct mail_user_settings *user_set, bool setuid_root, struct mail_user **mail_user_r, const char **error_r) @@ -367,9 +368,10 @@ mail_storage_service_init_post(struct master_service *service, } } - mail_user = mail_user_alloc(user, user_set); + mail_user = mail_user_alloc(input->username, user_set); mail_user_set_home(mail_user, *home == '\0' ? NULL : home); - mail_user_set_vars(mail_user, geteuid(), service->name, NULL, NULL); + mail_user_set_vars(mail_user, geteuid(), service->name, + &input->local_ip, &input->remote_ip); if (mail_user_init(mail_user, error_r) < 0) { mail_user_unref(&mail_user); return -1; @@ -383,13 +385,16 @@ mail_storage_service_init_post(struct master_service *service, } static const struct var_expand_table * -get_var_expand_table(struct master_service *service, const char *user) +get_var_expand_table(struct master_service *service, + struct mail_storage_service_input *input) { static struct var_expand_table static_tab[] = { { 'u', NULL, "user" }, { 'n', NULL, "username" }, { 'd', NULL, "domain" }, { 's', NULL, "service" }, + { 'l', NULL, "lip" }, + { 'r', NULL, "rip" }, { 'p', NULL, "pid" }, { 'i', NULL, "uid" }, { '\0', NULL, NULL } @@ -399,19 +404,21 @@ get_var_expand_table(struct master_service *service, const char *user) tab = t_malloc(sizeof(static_tab)); memcpy(tab, static_tab, sizeof(static_tab)); - tab[0].value = user; - tab[1].value = t_strcut(user, '@'); - tab[2].value = strchr(user, '@'); + tab[0].value = input->username; + tab[1].value = t_strcut(input->username, '@'); + tab[2].value = strchr(input->username, '@'); if (tab[2].value != NULL) tab[2].value++; tab[3].value = service->name; - tab[4].value = my_pid; - tab[5].value = dec2str(geteuid()); + tab[4].value = net_ip2addr(&input->local_ip); + tab[5].value = net_ip2addr(&input->remote_ip); + tab[6].value = my_pid; + tab[7].value = dec2str(geteuid()); return tab; } static const char * -user_expand_varstr(struct master_service *service, const char *user, - const char *str) +user_expand_varstr(struct master_service *service, + struct mail_storage_service_input *input, const char *str) { string_t *ret; @@ -421,21 +428,43 @@ user_expand_varstr(struct master_service *service, const char *user, i_assert(*str == SETTING_STRVAR_UNEXPANDED[0]); ret = t_str_new(256); - var_expand(ret, str + 1, get_var_expand_table(service, user)); + var_expand(ret, str + 1, get_var_expand_table(service, input)); return str_c(ret); } +static void +mail_storage_service_init_log(struct master_service *service, + struct mail_storage_service_input *input) +{ + const struct mail_user_settings *user_set; + void **sets; + + sets = master_service_settings_get_others(service); + user_set = sets[0]; + + T_BEGIN { + string_t *str; + + str = t_str_new(256); + var_expand(str, user_set->mail_log_prefix, + get_var_expand_table(service, input)); + master_service_init_log(service, str_c(str)); + } T_END; +} + struct mail_user * -mail_storage_service_init_user(struct master_service *service, const char *user, +mail_storage_service_init_user(struct master_service *service, + const struct mail_storage_service_input *_input, const struct setting_parser_info *set_roots[], enum mail_storage_service_flags flags) { + struct mail_storage_service_input input = *_input; const struct master_service_settings *set; const struct mail_user_settings *user_set; const struct mail_storage_settings *mail_set; struct mail_user *mail_user; void **sets; - const char *orig_user, *home, *system_groups_user, *error; + const char *user, *orig_user, *home, *system_groups_user, *error; unsigned int len; bool userdb_lookup; @@ -446,8 +475,7 @@ mail_storage_service_init_user(struct master_service *service, const char *user, set_keyval(service->set_parser, "mail_debug", "yes"); /* now that we've read settings, we can set up logging */ - master_service_init_log(service, - t_strdup_printf("%s(%s): ", service->name, user)); + mail_storage_service_init_log(service, &input); set = master_service_settings_get(service); sets = master_service_settings_get_others(service); @@ -457,17 +485,21 @@ mail_storage_service_init_user(struct master_service *service, const char *user, if (userdb_lookup) { /* userdb lookup may change settings, do it as soon as possible. */ - orig_user = user; + orig_user = user = input.username; if (service_auth_userdb_lookup(service->set_parser, service->name, user_set, &user, &system_groups_user, &error) <= 0) i_fatal("%s", error); + input.username = user; + + /* set up logging again in case username changed */ + mail_storage_service_init_log(service, &input); } /* variable strings are expanded in mail_user_init(), but we need the home sooner so do it separately here. */ - home = user_expand_varstr(service, user, user_set->mail_home); + home = user_expand_varstr(service, &input, user_set->mail_home); if (!userdb_lookup) { system_groups_user = NULL; @@ -500,8 +532,8 @@ mail_storage_service_init_user(struct master_service *service, const char *user, dict_drivers_register_builtin(); module_dir_init(modules); mail_users_init(user_set->auth_socket_path, mail_set->mail_debug); - if (mail_storage_service_init_post(service, user, home, user_set, FALSE, - &mail_user, &error) < 0) + if (mail_storage_service_init_post(service, &input, home, user_set, + FALSE, &mail_user, &error) < 0) i_fatal("%s", error); return mail_user; } @@ -552,36 +584,37 @@ mail_storage_service_multi_init(struct master_service *service, } int mail_storage_service_multi_lookup(struct mail_storage_service_multi_ctx *ctx, - const char *username, pool_t pool, + const struct mail_storage_service_input *input, + pool_t pool, struct mail_storage_service_multi_user **user_r, const char **error_r) { struct mail_storage_service_multi_user *user; - const char *orig_user; + const char *orig_user, *username; void **sets; int ret; user = p_new(pool, struct mail_storage_service_multi_user, 1); memset(user_r, 0, sizeof(user_r)); user->pool = pool; - user->user = username; + user->input = *input; + user->input.username = p_strdup(pool, input->username); user->set_parser = settings_parser_dup(ctx->service->set_parser, pool); sets = settings_parser_get_list(user->set_parser); user->user_set = sets[1]; if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0) { - orig_user = user->user; + orig_user = username = user->input.username; ret = service_auth_userdb_lookup(user->set_parser, ctx->service->name, - user->user_set, - &user->user, + user->user_set, &username, &user->system_groups_user, error_r); if (ret <= 0) return ret; + user->input.username = p_strdup(pool, username); } - user->user = p_strdup(pool, user->user); *user_r = user; return 1; } @@ -597,9 +630,11 @@ int mail_storage_service_multi_next(struct mail_storage_service_multi_ctx *ctx, /* variable strings are expanded in mail_user_init(), but we need the home sooner so do it separately here. */ - home = user_expand_varstr(ctx->service, user->user, + home = user_expand_varstr(ctx->service, &user->input, user_set->mail_home); + mail_storage_service_init_log(ctx->service, &user->input); + if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS) == 0) { service_drop_privileges(user_set, user->system_groups_user, home, (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT) != 0, @@ -622,8 +657,8 @@ int mail_storage_service_multi_next(struct mail_storage_service_multi_ctx *ctx, set_keyval(user->set_parser, "mail_home", t_strconcat(user_set->mail_chroot, "/", home, NULL)); } - if (mail_storage_service_init_post(ctx->service, user->user, home, - user_set, TRUE, + if (mail_storage_service_init_post(ctx->service, &user->input, + home, user_set, TRUE, mail_user_r, error_r) < 0) return -1; return 0; diff --git a/src/lib-storage/mail-storage-service.h b/src/lib-storage/mail-storage-service.h index ce6dce5146..4933f5c177 100644 --- a/src/lib-storage/mail-storage-service.h +++ b/src/lib-storage/mail-storage-service.h @@ -1,6 +1,8 @@ #ifndef MAIL_STORAGE_SERVICE_H #define MAIL_STORAGE_SERVICE_H +#include "network.h" + struct master_service; enum mail_storage_service_flags { @@ -14,11 +16,17 @@ enum mail_storage_service_flags { MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS = 0x08 }; +struct mail_storage_service_input { + const char *username; + struct ip_addr local_ip, remote_ip; +}; + struct setting_parser_info; struct mail_storage_service_multi_user; struct mail_user * -mail_storage_service_init_user(struct master_service *service, const char *user, +mail_storage_service_init_user(struct master_service *service, + const struct mail_storage_service_input *input, const struct setting_parser_info *set_roots[], enum mail_storage_service_flags flags); void mail_storage_service_deinit_user(void); @@ -29,7 +37,8 @@ mail_storage_service_multi_init(struct master_service *service, enum mail_storage_service_flags flags); /* Returns 1 if ok, 0 if user wasn't found, -1 if error. */ int mail_storage_service_multi_lookup(struct mail_storage_service_multi_ctx *ctx, - const char *username, pool_t pool, + const struct mail_storage_service_input *input, + pool_t pool, struct mail_storage_service_multi_user **user_r, const char **error_r); int mail_storage_service_multi_next(struct mail_storage_service_multi_ctx *ctx, diff --git a/src/lib-storage/mail-storage-settings.c b/src/lib-storage/mail-storage-settings.c index c5befd02c0..e0eece37a5 100644 --- a/src/lib-storage/mail-storage-settings.c +++ b/src/lib-storage/mail-storage-settings.c @@ -149,6 +149,8 @@ static struct setting_define mail_user_setting_defines[] = { DEF(SET_STR, mail_plugins), DEF(SET_STR, mail_plugin_dir), + DEF(SET_STR, mail_log_prefix), + DEFLIST(namespaces, "namespace", &mail_namespace_setting_parser_info), { SET_STRLIST, "plugin", offsetof(struct mail_user_settings, plugin_envs), NULL }, @@ -175,6 +177,8 @@ static struct mail_user_settings mail_user_default_settings = { MEMBER(mail_plugins) "", MEMBER(mail_plugin_dir) MODULEDIR, + MEMBER(mail_log_prefix) "%Us(%u): ", + MEMBER(namespaces) ARRAY_INIT, MEMBER(plugin_envs) ARRAY_INIT }; diff --git a/src/lib-storage/mail-storage-settings.h b/src/lib-storage/mail-storage-settings.h index d6f24d66f7..dacea13391 100644 --- a/src/lib-storage/mail-storage-settings.h +++ b/src/lib-storage/mail-storage-settings.h @@ -57,6 +57,8 @@ struct mail_user_settings { const char *mail_plugins; const char *mail_plugin_dir; + const char *mail_log_prefix; + ARRAY_DEFINE(namespaces, struct mail_namespace_settings *); ARRAY_DEFINE(plugin_envs, const char *); }; diff --git a/src/lib-storage/mail-user.c b/src/lib-storage/mail-user.c index 15d60ca7f6..28e80ed151 100644 --- a/src/lib-storage/mail-user.c +++ b/src/lib-storage/mail-user.c @@ -143,11 +143,11 @@ void mail_user_set_vars(struct mail_user *user, uid_t uid, const char *service, { user->uid = uid; user->service = p_strdup(user->pool, service); - if (local_ip != NULL) { + if (local_ip != NULL && local_ip->family != 0) { user->local_ip = p_new(user->pool, struct ip_addr, 1); *user->local_ip = *local_ip; } - if (remote_ip != NULL) { + if (remote_ip != NULL && remote_ip->family != 0) { user->remote_ip = p_new(user->pool, struct ip_addr, 1); *user->remote_ip = *remote_ip; } diff --git a/src/lib/failures.c b/src/lib/failures.c index 776bbdfc95..bba5e83e51 100644 --- a/src/lib/failures.c +++ b/src/lib/failures.c @@ -397,6 +397,7 @@ void i_set_failure_prefix(const char *prefix) { i_free(log_prefix); log_prefix = i_strdup(prefix); + i_warning("new prefix=%s", prefix); } static int ATTR_FORMAT(2, 0) diff --git a/src/lmtp/commands.c b/src/lmtp/commands.c index 79169a3a81..953d883df4 100644 --- a/src/lmtp/commands.c +++ b/src/lmtp/commands.c @@ -79,6 +79,7 @@ static bool rcpt_is_duplicate(struct client *client, const char *name) int cmd_rcpt(struct client *client, const char *args) { struct mail_recipient rcpt; + struct mail_storage_service_input input; const char *name, *error; unsigned int len; int ret; @@ -102,7 +103,12 @@ int cmd_rcpt(struct client *client, const char *args) return 0; } - ret = mail_storage_service_multi_lookup(multi_service, name, + memset(&input, 0, sizeof(input)); + input.username = name; + input.local_ip = client->local_ip; + input.remote_ip = client->remote_ip; + + ret = mail_storage_service_multi_lookup(multi_service, &input, client->state_pool, &rcpt.multi_user, &error); if (ret < 0) { diff --git a/src/plugins/convert/convert-tool.c b/src/plugins/convert/convert-tool.c index 0ba2de2f4b..341103f62f 100644 --- a/src/plugins/convert/convert-tool.c +++ b/src/plugins/convert/convert-tool.c @@ -18,6 +18,7 @@ int main(int argc, char *argv[]) { struct master_service *service; + struct mail_storage_service_input input; struct mail_user *user; struct convert_plugin_settings set; struct mail_namespace *dest_ns; @@ -50,9 +51,12 @@ int main(int argc, char *argv[]) i_fatal(USAGE_STRING); } + memset(&input, 0, sizeof(input)); + input.username = argv[optind]; + master_service_init_log(service, - t_strdup_printf("convert-tool(%s): ", argv[optind])); - user = mail_storage_service_init_user(service, argv[optind], NULL, 0); + t_strdup_printf("convert-tool(%s): ", input.username)); + user = mail_storage_service_init_user(service, &input, NULL, 0); memset(&ns_set, 0, sizeof(ns_set)); ns_set.location = argv[4]; diff --git a/src/plugins/expire/expire-tool.c b/src/plugins/expire/expire-tool.c index 6a3238d67f..df9ed61829 100644 --- a/src/plugins/expire/expire-tool.c +++ b/src/plugins/expire/expire-tool.c @@ -29,6 +29,7 @@ mailbox_delete_old_mails(struct expire_context *ctx, const char *user, unsigned int expunge_secs, unsigned int altmove_secs, time_t *oldest_r) { + struct mail_storage_service_input input; struct mail_storage_service_multi_user *multi_user; struct mail_namespace *ns; struct mail_storage *storage; @@ -43,6 +44,9 @@ mailbox_delete_old_mails(struct expire_context *ctx, const char *user, enum mail_flags flags; int ret; + memset(&input, 0, sizeof(input)); + input.username = user; + *oldest_r = 0; if (ctx->mail_user != NULL && @@ -52,7 +56,7 @@ mailbox_delete_old_mails(struct expire_context *ctx, const char *user, i_set_failure_prefix(t_strdup_printf("expire-tool(%s): ", user)); p_clear(ctx->multi_user_pool); - ret = mail_storage_service_multi_lookup(ctx->multi, user, + ret = mail_storage_service_multi_lookup(ctx->multi, &input, ctx->multi_user_pool, &multi_user, &errstr); if (ret <= 0) { diff --git a/src/pop3/main.c b/src/pop3/main.c index 5e68fa16c2..1ff3db28b3 100644 --- a/src/pop3/main.c +++ b/src/pop3/main.c @@ -146,9 +146,10 @@ int main(int argc, char *argv[], char *envp[]) enum master_service_flags service_flags = 0; enum mail_storage_service_flags storage_service_flags = MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT; + struct mail_storage_service_input input; struct mail_user *mail_user; const struct pop3_settings *set; - const char *user; + const char *value; int c; #ifdef DEBUG @@ -172,15 +173,21 @@ int main(int argc, char *argv[], char *envp[]) if (!master_service_parse_option(service, c, optarg)) i_fatal("Unknown argument: %c", c); } - user = getenv("USER"); - if (user == NULL) { + + memset(&input, 0, sizeof(input)); + input.username = getenv("USER"); + if (input.username == NULL) { if (IS_STANDALONE()) - user = getlogin(); - if (user == NULL) + input.username = getlogin(); + if (input.username == NULL) i_fatal("USER environment missing"); } + if ((value = getenv("IP")) != NULL) + net_addr2ip(value, &input.remote_ip); + if ((value = getenv("LOCAL_IP")) != NULL) + net_addr2ip(value, &input.local_ip); - mail_user = mail_storage_service_init_user(service, user, set_roots, + mail_user = mail_storage_service_init_user(service, &input, set_roots, storage_service_flags); set = mail_storage_service_get_settings(service); restrict_access_allow_coredumps(TRUE); diff --git a/src/util/doveadm.c b/src/util/doveadm.c index c6729cfde5..69471801c3 100644 --- a/src/util/doveadm.c +++ b/src/util/doveadm.c @@ -82,7 +82,8 @@ int main(int argc, char *argv[]) { enum mail_storage_service_flags service_flags = 0; struct master_service *service; - const char *getopt_str, *user; + struct mail_storage_service_input input; + const char *getopt_str; int c; service = master_service_init("doveadm", @@ -90,12 +91,13 @@ int main(int argc, char *argv[]) MASTER_SERVICE_FLAG_LOG_TO_STDERR, argc, argv); - user = getenv("USER"); + memset(&input, 0, sizeof(input)); + input.username = getenv("USER"); getopt_str = t_strconcat("u:v", master_service_getopt_string(), NULL); while ((c = getopt(argc, argv, getopt_str)) > 0) { switch (c) { case 'u': - user = optarg; + input.username = optarg; service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; break; case 'v': @@ -109,10 +111,10 @@ int main(int argc, char *argv[]) if (optind == argc) usage(); - if (user == NULL) + if (input.username == NULL) i_fatal("USER environment is missing and -u option not used"); - mail_user = mail_storage_service_init_user(service, user, NULL, + mail_user = mail_storage_service_init_user(service, &input, NULL, service_flags); if (strcmp(argv[optind], "purge") == 0)