changeset 9147:bf448752f6c4 HEAD

Pass remote/local IPs to mail_users. Standalone mail programs now log with mail_log_prefix.
author Timo Sirainen <tss@iki.fi>
date Mon, 20 Apr 2009 19:07:24 -0400
parents 1e26166a3cf8
children e3f61d434616
files src/imap/main.c src/lda/main.c src/lib-storage/mail-storage-service.c src/lib-storage/mail-storage-service.h src/lib-storage/mail-storage-settings.c src/lib-storage/mail-storage-settings.h src/lib-storage/mail-user.c src/lib/failures.c src/lmtp/commands.c src/plugins/convert/convert-tool.c src/plugins/expire/expire-tool.c src/pop3/main.c src/util/doveadm.c
diffstat 13 files changed, 143 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/src/imap/main.c	Mon Apr 20 18:07:46 2009 -0400
+++ b/src/imap/main.c	Mon Apr 20 19:07:24 2009 -0400
@@ -138,10 +138,11 @@
 	};
 	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 @@
 			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);
--- a/src/lda/main.c	Mon Apr 20 18:07:46 2009 -0400
+++ b/src/lda/main.c	Mon Apr 20 19:07:24 2009 -0400
@@ -183,6 +183,7 @@
 	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 @@
 			"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));
--- a/src/lib-storage/mail-storage-service.c	Mon Apr 20 18:07:46 2009 -0400
+++ b/src/lib-storage/mail-storage-service.c	Mon Apr 20 19:07:24 2009 -0400
@@ -31,7 +31,8 @@
 
 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 @@
 	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 @@
 
 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_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 @@
 }
 
 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 @@
 	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 @@
 	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 @@
 		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 @@
 	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 @@
 	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 @@
 }
 
 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 @@
 
 	/* 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 @@
 		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;
--- a/src/lib-storage/mail-storage-service.h	Mon Apr 20 18:07:46 2009 -0400
+++ b/src/lib-storage/mail-storage-service.h	Mon Apr 20 19:07:24 2009 -0400
@@ -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 @@
 	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 @@
 				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,
--- a/src/lib-storage/mail-storage-settings.c	Mon Apr 20 18:07:46 2009 -0400
+++ b/src/lib-storage/mail-storage-settings.c	Mon Apr 20 19:07:24 2009 -0400
@@ -149,6 +149,8 @@
 	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 @@
 	MEMBER(mail_plugins) "",
 	MEMBER(mail_plugin_dir) MODULEDIR,
 
+	MEMBER(mail_log_prefix) "%Us(%u): ",
+
 	MEMBER(namespaces) ARRAY_INIT,
 	MEMBER(plugin_envs) ARRAY_INIT
 };
--- a/src/lib-storage/mail-storage-settings.h	Mon Apr 20 18:07:46 2009 -0400
+++ b/src/lib-storage/mail-storage-settings.h	Mon Apr 20 19:07:24 2009 -0400
@@ -57,6 +57,8 @@
 	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 *);
 };
--- a/src/lib-storage/mail-user.c	Mon Apr 20 18:07:46 2009 -0400
+++ b/src/lib-storage/mail-user.c	Mon Apr 20 19:07:24 2009 -0400
@@ -143,11 +143,11 @@
 {
 	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;
 	}
--- a/src/lib/failures.c	Mon Apr 20 18:07:46 2009 -0400
+++ b/src/lib/failures.c	Mon Apr 20 19:07:24 2009 -0400
@@ -397,6 +397,7 @@
 {
 	i_free(log_prefix);
 	log_prefix = i_strdup(prefix);
+	i_warning("new prefix=%s", prefix);
 }
 
 static int ATTR_FORMAT(2, 0)
--- a/src/lmtp/commands.c	Mon Apr 20 18:07:46 2009 -0400
+++ b/src/lmtp/commands.c	Mon Apr 20 19:07:24 2009 -0400
@@ -79,6 +79,7 @@
 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 @@
 		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) {
--- a/src/plugins/convert/convert-tool.c	Mon Apr 20 18:07:46 2009 -0400
+++ b/src/plugins/convert/convert-tool.c	Mon Apr 20 19:07:24 2009 -0400
@@ -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 @@
 			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];
--- a/src/plugins/expire/expire-tool.c	Mon Apr 20 18:07:46 2009 -0400
+++ b/src/plugins/expire/expire-tool.c	Mon Apr 20 19:07:24 2009 -0400
@@ -29,6 +29,7 @@
 			 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 @@
 	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 @@
 		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) {
--- a/src/pop3/main.c	Mon Apr 20 18:07:46 2009 -0400
+++ b/src/pop3/main.c	Mon Apr 20 19:07:24 2009 -0400
@@ -146,9 +146,10 @@
 	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 @@
 		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);
--- a/src/util/doveadm.c	Mon Apr 20 18:07:46 2009 -0400
+++ b/src/util/doveadm.c	Mon Apr 20 19:07:24 2009 -0400
@@ -82,7 +82,8 @@
 {
 	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 @@
 				      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 @@
 	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)