dovecot-2.2: lib-storage: Set the user log prefix earlier when i...

dovecot at dovecot.org dovecot at dovecot.org
Fri Feb 6 15:06:51 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/6be98d5d829a
changeset: 18223:6be98d5d829a
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Feb 06 17:06:36 2015 +0200
description:
lib-storage: Set the user log prefix earlier when initializing user.
So the full prefix with session and other useful information is included in
the log message as early as possible. Some fatal/panic errors wouldn't even
have shown the username.

diffstat:

 src/lib-storage/mail-storage-service.c |  117 ++++++++++++++++++++++++++------
 1 files changed, 94 insertions(+), 23 deletions(-)

diffs (212 lines):

diff -r 89c42f824f84 -r 6be98d5d829a src/lib-storage/mail-storage-service.c
--- a/src/lib-storage/mail-storage-service.c	Fri Feb 06 17:04:52 2015 +0200
+++ b/src/lib-storage/mail-storage-service.c	Fri Feb 06 17:06:36 2015 +0200
@@ -379,8 +379,8 @@
 static const struct var_expand_table *
 get_var_expand_table(struct master_service *service,
 		     struct mail_storage_service_user *user,
-		     struct mail_storage_service_input *input,
-		     struct mail_storage_service_privileges *priv)
+		     const struct mail_storage_service_input *input,
+		     const struct mail_storage_service_privileges *priv)
 {
 	static struct var_expand_table static_tab[] = {
 		{ 'u', NULL, "user" },
@@ -411,8 +411,10 @@
 	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(priv->uid == (uid_t)-1 ? geteuid() : priv->uid);
-	tab[8].value = dec2str(priv->gid == (gid_t)-1 ? getegid() : priv->gid);
+	tab[7].value = priv == NULL ? NULL :
+		dec2str(priv->uid == (uid_t)-1 ? geteuid() : priv->uid);
+	tab[8].value = priv == NULL ? NULL :
+		dec2str(priv->gid == (gid_t)-1 ? getegid() : priv->gid);
 	tab[9].value = input->session_id;
 	if (user == NULL || user->auth_user == NULL) {
 		tab[10].value = tab[0].value;
@@ -1006,10 +1008,27 @@
 	return *p1 - *p2;
 }
 
-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)
+static void
+mail_storage_service_set_log_prefix(struct mail_storage_service_ctx *ctx,
+				    const struct mail_user_settings *user_set,
+				    struct mail_storage_service_user *user,
+				    const struct mail_storage_service_input *input,
+				    const struct mail_storage_service_privileges *priv)
+{
+	string_t *str;
+
+	str = t_str_new(256);
+	var_expand(str, user_set->mail_log_prefix,
+		   get_var_expand_table(ctx->service, user, input, priv));
+	i_set_failure_prefix("%s", str_c(str));
+}
+
+static int
+mail_storage_service_lookup_real(struct mail_storage_service_ctx *ctx,
+				 const struct mail_storage_service_input *input,
+				 bool update_log_prefix,
+				 struct mail_storage_service_user **user_r,
+				 const char **error_r)
 {
 	enum mail_storage_service_flags flags;
 	struct mail_storage_service_user *user;
@@ -1040,9 +1059,9 @@
 		if (ctx->config_permission_denied) {
 			/* just restart and maybe next time we will open the
 			   config socket before dropping privileges */
-			i_fatal("user %s: %s", username, error);
+			i_fatal("%s", error);
 		}
-		i_error("user %s: %s", username, error);
+		i_error("%s", error);
 		pool_unref(&user_pool);
 		*error_r = MAIL_ERRSTR_CRITICAL_MSG;
 		return -1;
@@ -1055,11 +1074,15 @@
 		ctx->log_initialized = TRUE;
 		master_service_init_log(ctx->service,
 			t_strconcat(ctx->service->name, ": ", NULL));
+		update_log_prefix = TRUE;
 	}
 	sets = master_service_settings_parser_get_others(master_service,
 							 set_parser);
 	user_set = sets[0];
 
+	if (update_log_prefix)
+		mail_storage_service_set_log_prefix(ctx, user_set, NULL, input, NULL);
+
 	if (ctx->conn == NULL)
 		mail_storage_service_first_init(ctx, user_info, user_set);
 	/* load global plugins */
@@ -1120,8 +1143,7 @@
 		auth_user_fields_parse(userdb_fields, temp_pool, &reply);
 		array_sort(&reply.extra_fields, extra_field_key_cmp_p);
 		if (user_reply_handle(ctx, user, &reply, &error) < 0) {
-			i_error("user %s: Invalid settings in userdb: %s",
-				username, error);
+			i_error("Invalid settings in userdb: %s", error);
 			*error_r = ERRSTR_INVALID_USER_SETTINGS;
 			ret = -2;
 		}
@@ -1138,6 +1160,41 @@
 	return ret;
 }
 
+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)
+{
+	const char *old_log_prefix = 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. */
+		i_set_failure_prefix("%s(%s%s,%s)",
+			master_service_get_name(ctx->service), input->username,
+			input->session_id == NULL ? "" :
+				t_strdup_printf(",%s", input->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);
+	return ret;
+}
+
 void mail_storage_service_save_userdb_fields(struct mail_storage_service_ctx *ctx,
 					     pool_t pool, const char *const **userdb_fields_r)
 {
@@ -1149,9 +1206,10 @@
 	*userdb_fields_r = NULL;
 }
 
-int mail_storage_service_next(struct mail_storage_service_ctx *ctx,
-			      struct mail_storage_service_user *user,
-			      struct mail_user **mail_user_r)
+static int
+mail_storage_service_next_real(struct mail_storage_service_ctx *ctx,
+			       struct mail_storage_service_user *user,
+			       struct mail_user **mail_user_r)
 {
 	struct mail_storage_service_privileges priv;
 	const char *error;
@@ -1163,14 +1221,13 @@
 	bool use_chroot;
 
 	if (service_parse_privileges(ctx, user, &priv, &error) < 0) {
-		i_error("user %s: %s", user->input.username, error);
+		i_error("%s", error);
 		return -2;
 	}
 
 	if (*priv.home != '/' && *priv.home != '\0') {
-		i_error("user %s: "
-			"Relative home directory paths not supported: %s",
-			user->input.username, priv.home);
+		i_error("Relative home directory paths not supported: %s",
+			priv.home);
 		return -2;
 	}
 
@@ -1213,8 +1270,7 @@
 		if (service_drop_privileges(user, &priv,
 					    disallow_root, temp_priv_drop,
 					    FALSE, &error) < 0) {
-			i_error("user %s: Couldn't drop privileges: %s",
-				user->input.username, error);
+			i_error("Couldn't drop privileges: %s", error);
 			return -1;
 		}
 		if (!temp_priv_drop ||
@@ -1228,13 +1284,28 @@
 
 	if (mail_storage_service_init_post(ctx, user, &priv,
 					   mail_user_r, &error) < 0) {
-		i_error("user %s: Initialization failed: %s",
-			user->input.username, error);
+		i_error("User initialization failed: %s", error);
 		return -2;
 	}
 	return 0;
 }
 
+int mail_storage_service_next(struct mail_storage_service_ctx *ctx,
+			      struct mail_storage_service_user *user,
+			      struct mail_user **mail_user_r)
+{
+	const char *old_log_prefix = i_get_failure_prefix();
+	int ret;
+
+	mail_storage_service_set_log_prefix(ctx, user->user_set, user,
+					    &user->input, NULL);
+	i_set_failure_prefix("%s", old_log_prefix);
+	ret = mail_storage_service_next_real(ctx, user, mail_user_r);
+	if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) != 0)
+		i_set_failure_prefix("%s", old_log_prefix);
+	return ret;
+}
+
 void mail_storage_service_restrict_setenv(struct mail_storage_service_ctx *ctx,
 					  struct mail_storage_service_user *user)
 {


More information about the dovecot-cvs mailing list