[dovecot-cvs] dovecot/src/master mail-process.c, 1.53, 1.54 mail-process.h, 1.5, 1.6 main.c, 1.51, 1.52 master-settings.c, 1.56, 1.57 master-settings.h, 1.36, 1.37

cras at dovecot.org cras at dovecot.org
Fri Jul 9 22:59:05 EEST 2004


Update of /home/cvs/dovecot/src/master
In directory talvi:/tmp/cvs-serv7425/master

Modified Files:
	mail-process.c mail-process.h main.c master-settings.c 
	master-settings.h 
Log Message:
Added --exec-mail option to master. It can be used to parse Dovecot config
file and exec() imap/pop3 process directly. Moved --inetd option into
environment as it's only for internal use.



Index: mail-process.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/mail-process.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -d -r1.53 -r1.54
--- mail-process.c	6 Jul 2004 08:08:44 -0000	1.53
+++ mail-process.c	9 Jul 2004 19:59:02 -0000	1.54
@@ -75,10 +75,9 @@
 }
 
 static const struct var_expand_table *
-get_var_expand_table(enum process_type process_type,
+get_var_expand_table(const char *protocol,
 		     const char *user, const char *home,
-		     const struct ip_addr *local_ip,
-		     const struct ip_addr *remote_ip, pid_t pid)
+		     const char *local_ip, const char *remote_ip, pid_t pid)
 {
 	static struct var_expand_table static_tab[] = {
 		{ 'u', NULL },
@@ -100,10 +99,10 @@
 	tab[1].value = t_strcut(user, '@');
 	tab[2].value = strchr(user, '@');
 	if (tab[2].value != NULL) tab[2].value++;
-	tab[3].value = t_str_ucase(process_names[process_type]);
+	tab[3].value = t_str_ucase(protocol);
 	tab[4].value = home;
-	tab[5].value = net_ip2addr(local_ip);
-	tab[6].value = net_ip2addr(remote_ip);
+	tab[5].value = local_ip;
+	tab[6].value = remote_ip;
 	tab[7].value = dec2str(pid);
 
 	return tab;
@@ -180,6 +179,133 @@
 	}
 }
 
+static void
+mail_process_set_environment(struct settings *set, const char *mail,
+			     const struct var_expand_table *var_expand_table)
+{
+	env_put(t_strconcat("MAIL_CACHE_FIELDS=",
+			    set->mail_cache_fields, NULL));
+	env_put(t_strconcat("MAIL_NEVER_CACHE_FIELDS=",
+			    set->mail_never_cache_fields, NULL));
+	env_put(t_strdup_printf("MAILBOX_CHECK_INTERVAL=%u",
+				set->mailbox_check_interval));
+	env_put(t_strdup_printf("MAILBOX_IDLE_CHECK_INTERVAL=%u",
+				set->mailbox_idle_check_interval));
+	env_put(t_strconcat("CLIENT_WORKAROUNDS=",
+			    set->client_workarounds, NULL));
+	env_put(t_strdup_printf("MAIL_MAX_KEYWORD_LENGTH=%u",
+				set->mail_max_keyword_length));
+	env_put(t_strdup_printf("IMAP_MAX_LINE_LENGTH=%u",
+				set->imap_max_line_length));
+	env_put(t_strconcat("IMAP_CAPABILITY=",
+			    set->imap_capability, NULL));
+
+	if (set->mail_save_crlf)
+		env_put("MAIL_SAVE_CRLF=1");
+	if (set->mail_read_mmaped)
+		env_put("MAIL_READ_MMAPED=1");
+	if (set->mmap_disable)
+		env_put("MMAP_DISABLE=1");
+	if (set->mmap_no_write)
+		env_put("MMAP_NO_WRITE=1");
+	if (set->fcntl_locks_disable)
+		env_put("FCNTL_LOCKS_DISABLE=1");
+	if (set->maildir_stat_dirs)
+		env_put("MAILDIR_STAT_DIRS=1");
+	if (set->maildir_copy_with_hardlinks)
+		env_put("MAILDIR_COPY_WITH_HARDLINKS=1");
+	if (set->maildir_check_content_changes)
+		env_put("MAILDIR_CHECK_CONTENT_CHANGES=1");
+	if (set->mail_full_filesystem_access)
+		env_put("FULL_FILESYSTEM_ACCESS=1");
+	if (set->pop3_mails_keep_recent)
+		env_put("POP3_MAILS_KEEP_RECENT=1");
+	(void)umask(set->umask);
+
+	env_put(t_strconcat("MBOX_READ_LOCKS=", set->mbox_read_locks, NULL));
+	env_put(t_strconcat("MBOX_WRITE_LOCKS=", set->mbox_write_locks, NULL));
+	env_put(t_strdup_printf("MBOX_LOCK_TIMEOUT=%u",
+				set->mbox_lock_timeout));
+	env_put(t_strdup_printf("MBOX_DOTLOCK_CHANGE_TIMEOUT=%u",
+				set->mbox_dotlock_change_timeout));
+
+	if (set->mail_use_modules &&
+	    set->mail_modules != NULL && *set->mail_modules != '\0') {
+		env_put(t_strconcat("MODULE_DIR=",
+				    set->mail_modules, NULL));
+	}
+
+	/* user given environment - may be malicious. virtual_user comes from
+	   auth process, but don't trust that too much either. Some auth
+	   mechanism might allow leaving extra data there. */
+	if ((mail == NULL || *mail == '\0') && set->default_mail_env != NULL)
+		mail = expand_mail_env(set->default_mail_env, var_expand_table);
+	env_put(t_strconcat("MAIL=", mail, NULL));
+
+	if (set->server->namespaces != NULL) {
+		env_put_namespace(set->server->namespaces,
+				  mail, var_expand_table);
+	}
+}
+
+static void mail_process_exec_set(struct settings *set, const char *title)
+{
+	const char *executable, *p, *argv[4];
+	int i;
+
+	/* very simple argument splitting. */
+	i = 0;
+	argv[i++] = executable = t_strcut(set->mail_executable, ' ');
+	argv[i] = strchr(set->mail_executable, ' ');
+	if (argv[i] != NULL) {
+		argv[i]++;
+		i++;
+	}
+	if (title[0] != '\0')
+		argv[i++] = title;
+	argv[i] = NULL;
+
+	/* hide the path, it's ugly */
+	p = strrchr(argv[0], '/');
+	if (p != NULL) argv[0] = p+1;
+
+	execv(executable, (char **) argv);
+}
+
+void mail_process_exec(const char *protocol, const char *section)
+{
+	struct server_settings *server = settings_root;
+	const struct var_expand_table *var_expand_table;
+	struct settings *set;
+
+	if (section != NULL) {
+		for (; server != NULL; server = server->next) {
+			if (strcmp(server->name, section) == 0)
+				break;
+		}
+		if (server == NULL)
+			i_fatal("Section not found: '%s'", section);
+	}
+
+	if (strcmp(protocol, "imap") == 0)
+		set = server->imap;
+	else if (strcmp(protocol, "pop3") == 0)
+		set = server->pop3;
+	else
+		i_fatal("Unknown protocol: '%s'", protocol);
+
+	var_expand_table =
+		get_var_expand_table(protocol, getenv("USER"), getenv("HOME"),
+				     getenv("TCPLOCALIP"),
+				     getenv("TCPREMOTEIP"), getpid());
+
+	mail_process_set_environment(set, getenv("MAIL"), var_expand_table);
+	mail_process_exec_set(set, "");
+
+	i_fatal_status(FATAL_EXEC, "execv(%s) failed: %m",
+		       set->mail_executable);
+}
+
 int create_mail_process(struct login_group *group, int socket,
 			const struct ip_addr *local_ip,
 			const struct ip_addr *remote_ip,
@@ -187,11 +313,9 @@
 {
 	struct settings *set = group->set;
 	const struct var_expand_table *var_expand_table;
-	const char *argv[4];
 	const char *addr, *mail, *user, *chroot_dir, *home_dir, *full_home_dir;
-	const char *executable, *p;
-	struct log_io *log;
 	char title[1024];
+	struct log_io *log;
 	string_t *str;
 	pid_t pid;
 	int i, err, ret, log_fd;
@@ -231,8 +355,10 @@
 	}
 
 	var_expand_table =
-		get_var_expand_table(group->process_type, user, home_dir,
-				     local_ip, remote_ip,
+		get_var_expand_table(process_names[group->process_type],
+				     user, home_dir,
+				     net_ip2addr(local_ip),
+				     net_ip2addr(remote_ip),
 				     pid != 0 ? pid : getpid());
 	str = t_str_new(128);
 
@@ -271,7 +397,7 @@
 				set->first_valid_gid, set->last_valid_gid,
 				set->mail_extra_groups);
 
-	restrict_process_size(group->set->mail_process_size, (unsigned int)-1);
+	restrict_process_size(set->mail_process_size, (unsigned int)-1);
 
 	if (*home_dir == '\0')
 		ret = -1;
@@ -302,73 +428,10 @@
 			i_fatal("chdir(/tmp) failed: %m");
 	}
 
+        mail_process_set_environment(set, mail, var_expand_table);
+
 	env_put("LOGGED_IN=1");
 	env_put(t_strconcat("HOME=", home_dir, NULL));
-	env_put(t_strconcat("MAIL_CACHE_FIELDS=",
-			    set->mail_cache_fields, NULL));
-	env_put(t_strconcat("MAIL_NEVER_CACHE_FIELDS=",
-			    set->mail_never_cache_fields, NULL));
-	env_put(t_strdup_printf("MAILBOX_CHECK_INTERVAL=%u",
-				set->mailbox_check_interval));
-	env_put(t_strdup_printf("MAILBOX_IDLE_CHECK_INTERVAL=%u",
-				set->mailbox_idle_check_interval));
-	env_put(t_strconcat("CLIENT_WORKAROUNDS=",
-			    set->client_workarounds, NULL));
-	env_put(t_strdup_printf("MAIL_MAX_KEYWORD_LENGTH=%u",
-				set->mail_max_keyword_length));
-	env_put(t_strdup_printf("IMAP_MAX_LINE_LENGTH=%u",
-				set->imap_max_line_length));
-	env_put(t_strconcat("IMAP_CAPABILITY=",
-			    set->imap_capability, NULL));
-
-	if (set->mail_save_crlf)
-		env_put("MAIL_SAVE_CRLF=1");
-	if (set->mail_read_mmaped)
-		env_put("MAIL_READ_MMAPED=1");
-	if (set->mmap_disable)
-		env_put("MMAP_DISABLE=1");
-	if (set->mmap_no_write)
-		env_put("MMAP_NO_WRITE=1");
-	if (set->fcntl_locks_disable)
-		env_put("FCNTL_LOCKS_DISABLE=1");
-	if (set->maildir_stat_dirs)
-		env_put("MAILDIR_STAT_DIRS=1");
-	if (set->maildir_copy_with_hardlinks)
-		env_put("MAILDIR_COPY_WITH_HARDLINKS=1");
-	if (set->maildir_check_content_changes)
-		env_put("MAILDIR_CHECK_CONTENT_CHANGES=1");
-	if (set->mail_full_filesystem_access)
-		env_put("FULL_FILESYSTEM_ACCESS=1");
-	if (set->pop3_mails_keep_recent)
-		env_put("POP3_MAILS_KEEP_RECENT=1");
-	(void)umask(set->umask);
-
-	env_put(t_strconcat("MBOX_READ_LOCKS=", set->mbox_read_locks, NULL));
-	env_put(t_strconcat("MBOX_WRITE_LOCKS=", set->mbox_write_locks, NULL));
-	env_put(t_strdup_printf("MBOX_LOCK_TIMEOUT=%u",
-				set->mbox_lock_timeout));
-	env_put(t_strdup_printf("MBOX_DOTLOCK_CHANGE_TIMEOUT=%u",
-				set->mbox_dotlock_change_timeout));
-
-	if (group->set->mail_use_modules &&
-	    group->set->mail_modules != NULL &&
-	    *group->set->mail_modules != '\0') {
-		env_put(t_strconcat("MODULE_DIR=",
-				    group->set->mail_modules, NULL));
-	}
-
-	/* user given environment - may be malicious. virtual_user comes from
-	   auth process, but don't trust that too much either. Some auth
-	   mechanism might allow leaving extra data there. */
-	if (*mail == '\0' && set->default_mail_env != NULL)
-		mail = expand_mail_env(set->default_mail_env, var_expand_table);
-
-	if (set->server->namespaces != NULL) {
-		env_put_namespace(set->server->namespaces,
-				  mail, var_expand_table);
-	}
-
-	env_put(t_strconcat("MAIL=", mail, NULL));
 	env_put(t_strconcat("USER=", data + reply->virtual_user_idx, NULL));
 
 	addr = net_ip2addr(remote_ip);
@@ -391,23 +454,7 @@
 	if (set->mail_drop_priv_before_exec)
 		restrict_access_by_env(TRUE);
 
-	/* very simple argument splitting. */
-	i = 0;
-	argv[i++] = executable = t_strcut(group->set->mail_executable, ' ');
-	argv[i] = strchr(group->set->mail_executable, ' ');
-	if (argv[i] != NULL) {
-		argv[i]++;
-		i++;
-	}
-	if (title[0] != '\0')
-		argv[i++] = title;
-	argv[i] = NULL;
-
-	/* hide the path, it's ugly */
-	p = strrchr(argv[0], '/');
-	if (p != NULL) argv[0] = p+1;
-
-	execv(executable, (char **) argv);
+	mail_process_exec_set(set, title);
 	err = errno;
 
 	for (i = 0; i < 3; i++)
@@ -415,7 +462,7 @@
 
 	errno = err;
 	i_fatal_status(FATAL_EXEC, "execv(%s) failed: %m",
-		       group->set->mail_executable);
+		       set->mail_executable);
 
 	/* not reached */
 	return FALSE;

Index: mail-process.h
===================================================================
RCS file: /home/cvs/dovecot/src/master/mail-process.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- mail-process.h	31 May 2004 18:04:47 -0000	1.5
+++ mail-process.h	9 Jul 2004 19:59:02 -0000	1.6
@@ -4,6 +4,8 @@
 struct login_group;
 struct auth_master_reply;
 
+void mail_process_exec(const char *protocol, const char *section);
+
 int create_mail_process(struct login_group *group, int socket,
 			const struct ip_addr *local_ip,
 			const struct ip_addr *remote_ip,

Index: main.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/main.c,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -r1.51 -r1.52
--- main.c	9 Jul 2004 19:09:17 -0000	1.51
+++ main.c	9 Jul 2004 19:59:02 -0000	1.52
@@ -99,7 +99,7 @@
         login_processes_destroy_all();
         auth_processes_destroy_all();
 
-	if (!master_settings_read(configfile))
+	if (!master_settings_read(configfile, FALSE))
 		i_warning("Invalid configuration, keeping old one");
 	else {
 		listen_fds_close(old_set);
@@ -482,9 +482,13 @@
 int main(int argc, char *argv[])
 {
 	/* parse arguments */
+	const char *exec_protocol = NULL, *exec_section = NULL;
 	int foreground = FALSE;
 	int i;
 
+#ifdef DEBUG
+	gdb = getenv("GDB") != NULL;
+#endif
 	lib_init();
 
 	master_uid = geteuid();
@@ -498,13 +502,14 @@
 			i++;
 			if (i == argc) i_fatal("Missing config file argument");
 			configfile = argv[i];
-		} else if (strcmp(argv[i], "--inetd") == 0) {
-			/* starting through inetd. */
-			inetd_login_fd = dup(0);
-			if (inetd_login_fd == -1)
-				i_fatal("dup(0) failed: %m");
-			fd_close_on_exec(inetd_login_fd, TRUE);
-			foreground = TRUE;
+		} else if (strcmp(argv[i], "--exec-mail") == 0) {
+			/* <protocol> [<server section>]
+			   read configuration and execute mail process */
+			i++;
+			if (i == argc) i_fatal("Missing protocol argument");
+			exec_protocol = argv[i];
+			if (i+1 != argc) 
+				exec_section = argv[i++];
 		} else if (strcmp(argv[i], "--version") == 0) {
 			printf("%s\n", VERSION);
 			return 0;
@@ -514,18 +519,28 @@
 		}
 	}
 
+	if (getenv("DOVECOT_INETD") != NULL) {
+		/* starting through inetd. */
+		inetd_login_fd = dup(0);
+		if (inetd_login_fd == -1)
+			i_fatal("dup(0) failed: %m");
+		fd_close_on_exec(inetd_login_fd, TRUE);
+		foreground = TRUE;
+	}
+
 	/* read and verify settings before forking */
 	master_settings_init();
-	if (!master_settings_read(configfile))
+	if (!master_settings_read(configfile, exec_protocol != NULL))
 		exit(FATAL_DEFAULT);
-	open_fds();
 
-#ifdef DEBUG
-	gdb = getenv("GDB") != NULL;
-#endif
-	/* we don't need any environment */
+	if (exec_protocol != NULL)
+		mail_process_exec(exec_protocol, exec_section);
+
+	/* we don't need any environment anymore */
 	env_clean();
 
+	open_fds();
+
 	if (!foreground)
 		daemonize(settings_root->defaults);
 

Index: master-settings.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/master-settings.c,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -d -r1.56 -r1.57
--- master-settings.c	23 Jun 2004 17:50:44 -0000	1.56
+++ master-settings.c	9 Jul 2004 19:59:02 -0000	1.57
@@ -908,7 +908,7 @@
 	return FALSE;
 }
 
-int master_settings_read(const char *path)
+int master_settings_read(const char *path, int nochecks)
 {
 	struct settings_parse_ctx ctx;
 	struct server_settings *server, *prev;
@@ -949,7 +949,7 @@
 		if (!settings_is_active(server->imap))
 			server->imap = NULL;
 		else {
-			if (!settings_verify(server->imap))
+			if (!nochecks && !settings_verify(server->imap))
 				return FALSE;
 			server->defaults = server->imap;
 		}
@@ -957,7 +957,7 @@
 		if (!settings_is_active(server->pop3))
 			server->pop3 = NULL;
 		else {
-			if (!settings_verify(server->pop3))
+			if (!nochecks && !settings_verify(server->pop3))
 				return FALSE;
 			if (server->defaults == NULL)
 				server->defaults = server->pop3;
@@ -976,14 +976,16 @@
 				return FALSE;
 			}
 
-			for (; auth != NULL; auth = auth->next) {
-				if (!auth_settings_verify(auth))
-					return FALSE;
-			}
-                        ns = server->namespaces;
-			for (; ns != NULL; ns = ns->next) {
-				if (!namespace_settings_verify(ns))
-					return FALSE;
+			if (!nochecks) {
+				for (; auth != NULL; auth = auth->next) {
+					if (!auth_settings_verify(auth))
+						return FALSE;
+				}
+				ns = server->namespaces;
+				for (; ns != NULL; ns = ns->next) {
+					if (!namespace_settings_verify(ns))
+						return FALSE;
+				}
 			}
 			prev = server;
 		}

Index: master-settings.h
===================================================================
RCS file: /home/cvs/dovecot/src/master/master-settings.h,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- master-settings.h	23 Jun 2004 17:50:44 -0000	1.36
+++ master-settings.h	9 Jul 2004 19:59:02 -0000	1.37
@@ -171,7 +171,7 @@
 
 extern struct server_settings *settings_root;
 
-int master_settings_read(const char *path);
+int master_settings_read(const char *path, int nochecks);
 
 void master_settings_init(void);
 void master_settings_deinit(void);



More information about the dovecot-cvs mailing list