changeset 6317:3cee177eced6 HEAD

Extra fields from userdb lookup should override everything. Fixed the code to work the same way as master process handles it, so there should be no more differences.
author Timo Sirainen <tss@iki.fi>
date Fri, 24 Aug 2007 21:43:27 +0300
parents fcd14b4cf941
children 5313cbcfccc6
files src/deliver/auth-client.c src/deliver/auth-client.h src/deliver/deliver.c
diffstat 3 files changed, 60 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/src/deliver/auth-client.c	Fri Aug 24 21:23:00 2007 +0300
+++ b/src/deliver/auth-client.c	Fri Aug 24 21:43:27 2007 +0300
@@ -1,6 +1,7 @@
 /* Copyright (C) 2005-2006 Timo Sirainen */
 
 #include "lib.h"
+#include "array.h"
 #include "ioloop.h"
 #include "network.h"
 #include "istream.h"
@@ -29,6 +30,7 @@
 	struct ioloop *ioloop;
 	uid_t euid;
 	const char *user;
+	ARRAY_TYPE(string) *extra_fields;
 
 	unsigned int handshaked:1;
 };
@@ -49,10 +51,9 @@
 
 static void auth_parse_input(struct auth_connection *conn, const char *args)
 {
-	const char *const *tmp, *key, *value;
+	const char *const *tmp;
 	uid_t uid = 0;
 	gid_t gid = 0;
-	int home_found = FALSE;
 	const char *chroot = getenv("MAIL_CHROOT");
 	bool debug = getenv("DEBUG") != NULL;
 
@@ -87,14 +88,9 @@
 			}
 		} else if (strncmp(*tmp, "chroot=", 7) == 0) {
 			chroot = *tmp + 7;
-		} else if (strncmp(*tmp, "home=", 5) == 0) {
-			home_found = TRUE;
-			env_put(t_strconcat("HOME=", *tmp + 5, NULL));
 		} else {
-			key = t_str_ucase(t_strcut(*tmp, '='));
-			value = strchr(*tmp, '=');
-			if (value != NULL)
-				env_put(t_strconcat(key, "=", value+1, NULL));
+			char *field = i_strdup(*tmp);
+			array_append(conn->extra_fields, &field, 1);
 		}
 	}
 
@@ -194,8 +190,10 @@
 	auth_connection_destroy(conn);
 }
 
-int auth_client_put_user_env(struct ioloop *ioloop, const char *auth_socket,
-			     const char *user, uid_t euid)
+int auth_client_lookup_and_restrict(struct ioloop *ioloop,
+				    const char *auth_socket,
+				    const char *user, uid_t euid,
+				    ARRAY_TYPE(string) *extra_fields_r)
 {
         struct auth_connection *conn;
 
@@ -208,6 +206,7 @@
 	conn->user = user;
 	conn->to = timeout_add(1000*AUTH_REQUEST_TIMEOUT,
 			       auth_client_timeout, conn);
+	conn->extra_fields = extra_fields_r;
 
 	o_stream_send_str(conn->output,
 			  t_strconcat("VERSION\t1\t0\n"
@@ -218,4 +217,3 @@
 	io_loop_run(ioloop);
 	return return_value;
 }
-
--- a/src/deliver/auth-client.h	Fri Aug 24 21:23:00 2007 +0300
+++ b/src/deliver/auth-client.h	Fri Aug 24 21:43:27 2007 +0300
@@ -1,7 +1,9 @@
 #ifndef __AUTH_CLIENT_H
 #define __AUTH_CLIENT_H
 
-int auth_client_put_user_env(struct ioloop *ioloop, const char *auth_socket,
-			     const char *user, uid_t euid);
+int auth_client_lookup_and_restrict(struct ioloop *ioloop,
+				    const char *auth_socket,
+				    const char *user, uid_t euid,
+				    ARRAY_TYPE(string) *extra_fields_r);
 
 #endif
--- a/src/deliver/deliver.c	Fri Aug 24 21:23:00 2007 +0300
+++ b/src/deliver/deliver.c	Fri Aug 24 21:43:27 2007 +0300
@@ -529,23 +529,32 @@
 		env_put(str_c(str));
 	}
 
-	/* get the table again in case plugin provided the home directory
-	   (yea, kludgy) */
-	table = get_var_expand_table(destination, getenv("HOME"));
+	mail_env = getenv("MAIL_LOCATION");
+	if (mail_env != NULL) {
+		/* get the table again in case plugin envs provided the home
+		   directory (yea, kludgy) */
+		table = get_var_expand_table(destination, getenv("HOME"));
+		mail_env = expand_mail_env(mail_env, table);
+	}
+	env_put(t_strconcat("MAIL=", mail_env, NULL));
+}
 
-	/* MAIL comes from userdb, MAIL_LOCATION from dovecot.conf.
-	   We don't want to expand settings coming from userdb.
-	   FIXME: should remove these and support namespaces.. */
-	mail_env = getenv("MAIL");
-	if (mail_env == NULL)  {
-		mail_env = getenv("MAIL_LOCATION");
-		if (mail_env == NULL)  {
-			/* Keep this for backwards compatibility */
-			mail_env = getenv("DEFAULT_MAIL_ENV");
+static void putenv_extra_fields(ARRAY_TYPE(string) *extra_fields)
+{
+	char **fields;
+	const char *key, *p;
+	unsigned int i, count;
+
+	fields = array_get_modifiable(extra_fields, &count);
+	for (i = 0; i < count; i++) {
+		p = strchr(fields[i], '=');
+		if (p == NULL)
+			env_put(t_strconcat(fields[i], "=1", NULL));
+		else {
+			key = t_str_ucase(t_strdup_until(fields[i], p));
+			env_put(t_strconcat(key, p, NULL));
 		}
-		if (mail_env != NULL)
-			mail_env = expand_mail_env(mail_env, table);
-		env_put(t_strconcat("MAIL=", mail_env, NULL));
+		i_free(fields[i]);
 	}
 }
 
@@ -556,6 +565,7 @@
 	const char *mailbox = "INBOX";
 	const char *auth_socket;
 	const char *home, *destination, *user, *value, *error;
+	ARRAY_TYPE(string) extra_fields;
 	struct mail_namespace *ns, *mbox_ns;
 	struct mail_storage *storage;
 	struct mailbox *box;
@@ -674,31 +684,38 @@
 					  TRUE, version);
 	}
 
+	t_array_init(&extra_fields, 64);
 	if (destination != NULL) {
 		auth_socket = getenv("AUTH_SOCKET_PATH");
 		if (auth_socket == NULL)
 			auth_socket = DEFAULT_AUTH_SOCKET_PATH;
 
-		ret = auth_client_put_user_env(ioloop, auth_socket,
-					       destination, process_euid);
+		ret = auth_client_lookup_and_restrict(ioloop, auth_socket,
+						      destination, process_euid,
+						      &extra_fields);
 		if (ret != 0)
 			return ret;
-
-		/* If possible chdir to home directory, so that core file
-		   could be written in case we crash. */
-		home = getenv("HOME");
-		if (home != NULL) {
-			if (chdir(home) < 0) {
-				if (errno != ENOENT)
-					i_error("chdir(%s) failed: %m", home);
-				else if (getenv("DEBUG") != NULL)
-					i_info("Home dir not found: %s", home);
-			}
-		}
 	} else {
 		destination = user;
 	}
 
+	expand_envs(destination);
+	putenv_extra_fields(&extra_fields);
+
+	/* If possible chdir to home directory, so that core file
+	   could be written in case we crash. */
+	home = getenv("HOME");
+	if (home != NULL) {
+		if (chdir(home) < 0) {
+			if (errno != ENOENT)
+				i_error("chdir(%s) failed: %m", home);
+			else if (getenv("DEBUG") != NULL)
+				i_info("Home dir not found: %s", home);
+		}
+	}
+
+	env_put(t_strconcat("USER=", destination, NULL));
+
 	value = getenv("UMASK");
 	if (value == NULL || sscanf(value, "%i", &i) != 1 || i < 0)
 		i = 0077;
@@ -722,8 +739,6 @@
 			DEFAULT_MAIL_REJECTION_HUMAN_REASON;
 	}
 
-	expand_envs(destination);
-
 	dict_driver_register(&dict_driver_client);
         duplicate_init();
         mail_storage_init();