dovecot: Extra fields from userdb lookup should override everyth...

dovecot at dovecot.org dovecot at dovecot.org
Fri Aug 24 21:43:32 EEST 2007


details:   http://hg.dovecot.org/dovecot/rev/3cee177eced6
changeset: 6317:3cee177eced6
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Aug 24 21:43:27 2007 +0300
description:
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.

diffstat:

3 files changed, 62 insertions(+), 47 deletions(-)
src/deliver/auth-client.c |   22 +++++-------
src/deliver/auth-client.h |    6 ++-
src/deliver/deliver.c     |   81 ++++++++++++++++++++++++++-------------------

diffs (211 lines):

diff -r fcd14b4cf941 -r 3cee177eced6 src/deliver/auth-client.c
--- 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 auth_connection {
 	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_connection_destroy(stru
 
 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 @@ static void auth_parse_input(struct auth
 			}
 		} 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 @@ static void auth_client_timeout(struct a
 	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 @@ int auth_client_put_user_env(struct iolo
 	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 @@ int auth_client_put_user_env(struct iolo
 	io_loop_run(ioloop);
 	return return_value;
 }
-
diff -r fcd14b4cf941 -r 3cee177eced6 src/deliver/auth-client.h
--- 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
diff -r fcd14b4cf941 -r 3cee177eced6 src/deliver/deliver.c
--- 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 @@ static void expand_envs(const char *dest
 		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 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");
-		}
-		if (mail_env != NULL)
-			mail_env = expand_mail_env(mail_env, table);
-		env_put(t_strconcat("MAIL=", mail_env, NULL));
+	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));
+}
+
+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));
+		}
+		i_free(fields[i]);
 	}
 }
 
@@ -556,6 +565,7 @@ int main(int argc, char *argv[])
 	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,30 +684,37 @@ int main(int argc, char *argv[])
 					  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)
@@ -721,8 +738,6 @@ int main(int argc, char *argv[])
 		deliver_set->rejection_reason =
 			DEFAULT_MAIL_REJECTION_HUMAN_REASON;
 	}
-
-	expand_envs(destination);
 
 	dict_driver_register(&dict_driver_client);
         duplicate_init();


More information about the dovecot-cvs mailing list