[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