[dovecot-cvs] dovecot/src/master mail-process.c,NONE,1.1 mail-process.h,NONE,1.1 .cvsignore,1.1.1.1,1.2 Makefile.am,1.7,1.8 auth-process.c,1.30,1.31 common.h,1.11,1.12 login-process.c,1.32,1.33 main.c,1.30,1.31 master-login-interface.h,1.1,1.2 settings.c,1.44,1.45 Message-Id: <20030130175934.4E638239A3@danu.procontrol.fi>
cras at procontrol.fi
cras at procontrol.fi
Thu Jan 30 19:59:34 EET 2003
Update of /home/cvs/dovecot/src/master
In directory danu:/tmp/cvs-serv27713/src/master
Modified Files:
.cvsignore Makefile.am auth-process.c common.h login-process.c
main.c master-login-interface.h settings.c settings.h
ssl-init.c
Added Files:
mail-process.c mail-process.h
Removed Files:
imap-process.c imap-process.h
Log Message:
Rewrote setting handling. Changed some existing settings also since POP3
support required changes anyway. POP3 seems to be really working now :)
--- NEW FILE: mail-process.c ---
/* Copyright (C) 2002 Timo Sirainen */
#include "common.h"
#include "fd-close-on-exec.h"
#include "env-util.h"
#include "str.h"
#include "network.h"
#include "restrict-access.h"
#include "restrict-process-size.h"
#include "var-expand.h"
#include "mail-process.h"
#include <stdlib.h>
#include <unistd.h>
#include <grp.h>
#include <syslog.h>
#include <sys/stat.h>
static unsigned int mail_process_count = 0;
static int validate_uid_gid(uid_t uid, gid_t gid)
{
if (uid == 0) {
i_error("mail process isn't allowed for root");
return FALSE;
}
if (uid != 0 && gid == 0) {
i_error("mail process isn't allowed to be in group 0");
return FALSE;
}
if (uid < (uid_t)set->first_valid_uid ||
(set->last_valid_uid != 0 && uid > (uid_t)set->last_valid_uid)) {
i_error("mail process isn't allowed to use UID %s",
dec2str(uid));
return FALSE;
}
if (gid < (gid_t)set->first_valid_gid ||
(set->last_valid_gid != 0 && gid > (gid_t)set->last_valid_gid)) {
i_error("mail process isn't allowed to use "
"GID %s (UID is %s)", dec2str(gid), dec2str(uid));
return FALSE;
}
return TRUE;
}
static int validate_chroot(const char *dir)
{
const char *const *chroot_dirs;
if (*dir == '\0')
return FALSE;
if (set->valid_chroot_dirs == NULL)
return FALSE;
chroot_dirs = t_strsplit(set->valid_chroot_dirs, ":");
while (*chroot_dirs != NULL) {
if (**chroot_dirs != '\0' &&
strncmp(dir, *chroot_dirs, strlen(*chroot_dirs)) == 0)
return TRUE;
chroot_dirs++;
}
return FALSE;
}
static const char *expand_mail_env(const char *env, const char *user,
const char *home)
{
string_t *str;
const char *p;
str = t_str_new(256);
/* it's either type:data or just data */
p = strchr(env, ':');
if (p != NULL) {
while (env != p) {
str_append_c(str, *env);
env++;
}
str_append_c(str, *env++);
}
if (env[0] == '~' && env[1] == '/') {
/* expand home */
str_append(str, home);
env++;
}
/* expand %vars */
var_expand(str, env, user, home);
return str_c(str);
}
int create_mail_process(int socket, struct ip_addr *ip,
const char *executable, unsigned int process_size,
struct auth_master_reply *reply, const char *data)
{
static const char *argv[] = { NULL, NULL, NULL };
const char *host, *mail;
char title[1024];
pid_t pid;
int i, err;
if (mail_process_count == set->max_mail_processes) {
i_error("Maximum number of mail processes exceeded");
return FALSE;
}
if (!validate_uid_gid(reply->uid, reply->gid))
return FALSE;
if (reply->chroot && !validate_chroot(data + reply->home_idx))
return FALSE;
pid = fork();
if (pid < 0) {
i_error("fork() failed: %m");
return FALSE;
}
if (pid != 0) {
/* master */
mail_process_count++;
PID_ADD_PROCESS_TYPE(pid, PROCESS_TYPE_MAIL);
return TRUE;
}
clean_child_process();
/* move the client socket into stdin and stdout fds */
fd_close_on_exec(socket, FALSE);
if (dup2(socket, 0) < 0)
i_fatal("mail: dup2(stdin) failed: %m");
if (dup2(socket, 1) < 0)
i_fatal("mail: dup2(stdout) failed: %m");
if (dup2(null_fd, 2) < 0)
i_fatal("mail: dup2(stderr) failed: %m");
if (close(socket) < 0)
i_error("mail: close(mail client) failed: %m");
/* setup environment - set the most important environment first
(paranoia about filling up environment without noticing) */
restrict_access_set_env(data + reply->system_user_idx,
reply->uid, reply->gid,
reply->chroot ? data + reply->home_idx : NULL);
restrict_process_size(process_size);
env_put("LOGGED_IN=1");
env_put(t_strconcat("HOME=", data + reply->home_idx, 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));
if (set->mail_save_crlf)
env_put("MAIL_SAVE_CRLF=1");
if (set->mail_read_mmaped)
env_put("MAIL_READ_MMAPED=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->overwrite_incompatible_index)
env_put("OVERWRITE_INCOMPATIBLE_INDEX=1");
if (umask(set->umask) != set->umask)
i_fatal("Invalid umask: %o", set->umask);
env_put(t_strconcat("MBOX_LOCKS=", set->mbox_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->mbox_read_dotlock)
env_put("MBOX_READ_DOTLOCK=1");
/* 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. */
mail = data + reply->mail_idx;
if (*mail == '\0' && set->default_mail_env != NULL) {
mail = expand_mail_env(set->default_mail_env,
data + reply->virtual_user_idx,
data + reply->home_idx);
}
env_put(t_strconcat("MAIL=", mail, NULL));
env_put(t_strconcat("USER=", data + reply->virtual_user_idx, NULL));
if (set->verbose_proctitle) {
host = net_ip2host(ip);
if (host == NULL)
host = "??";
i_snprintf(title, sizeof(title), "[%s %s]",
data + reply->virtual_user_idx, host);
argv[1] = title;
}
/* make sure we don't leak syslog fd, but do it last so that
any errors above will be logged */
closelog();
/* hide the path, it's ugly */
argv[0] = strrchr(executable, '/');
if (argv[0] == NULL) argv[0] = executable; else argv[0]++;
execv(executable, (char **) argv);
err = errno;
for (i = 0; i < 3; i++)
(void)close(i);
i_fatal_status(FATAL_EXEC, "execv(%s) failed: %m", executable);
/* not reached */
return FALSE;
}
void mail_process_destroyed(pid_t pid __attr_unused__)
{
mail_process_count--;
}
--- NEW FILE: mail-process.h ---
#ifndef __MAIL_PROCESS_H
#define __MAIL_PROCESS_H
struct auth_master_reply;
int create_mail_process(int socket, struct ip_addr *ip,
const char *executable, unsigned int process_size,
struct auth_master_reply *reply, const char *data);
void mail_process_destroyed(pid_t pid);
#endif
Index: .cvsignore
===================================================================
RCS file: /home/cvs/dovecot/src/master/.cvsignore,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- .cvsignore 9 Aug 2002 09:15:55 -0000 1.1.1.1
+++ .cvsignore 30 Jan 2003 17:59:31 -0000 1.2
@@ -6,4 +6,4 @@
Makefile
Makefile.in
so_locations
-imap-master
+dovecot
Index: Makefile.am
===================================================================
RCS file: /home/cvs/dovecot/src/master/Makefile.am,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- Makefile.am 27 Jan 2003 01:33:40 -0000 1.7
+++ Makefile.am 30 Jan 2003 17:59:31 -0000 1.8
@@ -1,6 +1,6 @@
pkglibexecdir = $(libexecdir)/dovecot
-sbin_PROGRAMS = imap-master
+sbin_PROGRAMS = dovecot
INCLUDES = \
-I$(top_srcdir)/src/lib \
@@ -9,14 +9,14 @@
-DPKG_LIBEXECDIR=\""$(pkglibexecdir)"\" \
-DSSLDIR=\""$(ssldir)\""
-imap_master_LDADD = \
+dovecot_LDADD = \
../lib/liblib.a \
$(SSL_LIBS)
-imap_master_SOURCES = \
+dovecot_SOURCES = \
auth-process.c \
- imap-process.c \
login-process.c \
+ mail-process.c \
main.c \
settings.c \
ssl-init.c \
@@ -26,8 +26,8 @@
noinst_HEADERS = \
auth-process.h \
common.h \
- imap-process.h \
login-process.h \
+ mail-process.h \
master-login-interface.h \
settings.h \
ssl-init.h
Index: auth-process.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/auth-process.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- auth-process.c 27 Jan 2003 02:42:02 -0000 1.30
+++ auth-process.c 30 Jan 2003 17:59:31 -0000 1.31
@@ -222,7 +222,7 @@
}
}
- (void)unlink(t_strconcat(set_login_dir, "/", p->name, NULL));
+ (void)unlink(t_strconcat(set->login_dir, "/", p->name, NULL));
hash_foreach(p->requests, request_hash_destroy, NULL);
hash_destroy(p->requests);
@@ -236,7 +236,7 @@
i_free(p);
}
-static pid_t create_auth_process(struct auth_config *config)
+static pid_t create_auth_process(struct auth_settings *auth_set)
{
static char *argv[] = { NULL, NULL };
const char *path;
@@ -244,8 +244,8 @@
pid_t pid;
int fd[2], listen_fd, i;
- if ((pwd = getpwnam(config->user)) == NULL)
- i_fatal("Auth user doesn't exist: %s", config->user);
+ if ((pwd = getpwnam(auth_set->user)) == NULL)
+ i_fatal("Auth user doesn't exist: %s", auth_set->user);
/* create communication to process with a socket pair */
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1) {
@@ -264,13 +264,13 @@
if (pid != 0) {
/* master */
fd_close_on_exec(fd[0], TRUE);
- auth_process_new(pid, fd[0], config->name);
+ auth_process_new(pid, fd[0], auth_set->name);
(void)close(fd[1]);
return pid;
}
- /* create socket for listening auth requests from imap-login */
- path = t_strconcat(set_login_dir, "/", config->name, NULL);
+ /* create socket for listening auth requests from login */
+ path = t_strconcat(set->login_dir, "/", auth_set->name, NULL);
(void)unlink(path);
(void)umask(0117); /* we want 0660 mode for the socket */
@@ -281,9 +281,9 @@
i_assert(listen_fd > 2);
/* set correct permissions */
- if (chown(path, geteuid(), set_login_gid) < 0) {
+ if (chown(path, geteuid(), set->login_gid) < 0) {
i_fatal("login: chown(%s, %s, %s) failed: %m",
- path, dec2str(set_login_uid), dec2str(set_login_gid));
+ path, dec2str(geteuid()), dec2str(set->login_gid));
}
/* move master communication handle to 0 */
@@ -315,34 +315,35 @@
/* setup access environment - needs to be done after
clean_child_process() since it clears environment */
- restrict_access_set_env(config->user, pwd->pw_uid, pwd->pw_gid,
- config->chroot);
+ restrict_access_set_env(auth_set->user, pwd->pw_uid, pwd->pw_gid,
+ auth_set->chroot);
/* set other environment */
env_put(t_strconcat("AUTH_PROCESS=", dec2str(getpid()), NULL));
- env_put(t_strconcat("MECHANISMS=", config->mechanisms, NULL));
- env_put(t_strconcat("REALMS=", config->realms, NULL));
- env_put(t_strconcat("USERDB=", config->userdb, NULL));
- env_put(t_strconcat("USERDB_ARGS=", config->userdb_args, NULL));
- env_put(t_strconcat("PASSDB=", config->passdb, NULL));
- env_put(t_strconcat("PASSDB_ARGS=", config->passdb_args, NULL));
+ env_put(t_strconcat("MECHANISMS=", auth_set->mechanisms, NULL));
+ env_put(t_strconcat("REALMS=", auth_set->realms, NULL));
+ env_put(t_strconcat("USERDB=", auth_set->userdb, NULL));
+ env_put(t_strconcat("PASSDB=", auth_set->passdb, NULL));
- if (config->use_cyrus_sasl)
+ if (auth_set->use_cyrus_sasl)
env_put("USE_CYRUS_SASL=1");
- if (config->verbose)
+ if (auth_set->verbose)
env_put("VERBOSE=1");
- restrict_process_size(config->process_size);
+ restrict_process_size(auth_set->process_size);
/* make sure we don't leak syslog fd, but do it last so that
any errors above will be logged */
closelog();
/* hide the path, it's ugly */
- argv[0] = strrchr(config->executable, '/');
- if (argv[0] == NULL) argv[0] = config->executable; else argv[0]++;
+ argv[0] = strrchr(auth_set->executable, '/');
+ if (argv[0] == NULL)
+ argv[0] = i_strdup(auth_set->executable);
+ else
+ argv[0]++;
- execv(config->executable, (char **) argv);
+ execv(auth_set->executable, argv);
i_fatal_status(FATAL_EXEC, "execv(%s) failed: %m", argv[0]);
return -1;
@@ -387,14 +388,14 @@
static void
auth_processes_start_missing(void *context __attr_unused__)
{
- struct auth_config *config;
+ struct auth_settings *auth_set;
unsigned int count;
- config = auth_processes_config;
- for (; config != NULL; config = config->next) {
- count = auth_process_get_count(config->name);
- for (; count < config->count; count++)
- (void)create_auth_process(config);
+ auth_set = set->auths;
+ for (; auth_set != NULL; auth_set = auth_set->next) {
+ count = auth_process_get_count(auth_set->name);
+ for (; count < auth_set->count; count++)
+ (void)create_auth_process(auth_set);
}
}
Index: common.h
===================================================================
RCS file: /home/cvs/dovecot/src/master/common.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- common.h 27 Jan 2003 01:33:40 -0000 1.11
+++ common.h 30 Jan 2003 17:59:32 -0000 1.12
@@ -13,15 +13,24 @@
PROCESS_TYPE_UNKNOWN,
PROCESS_TYPE_AUTH,
PROCESS_TYPE_LOGIN,
- PROCESS_TYPE_IMAP,
+ PROCESS_TYPE_MAIL,
PROCESS_TYPE_SSL_PARAM,
PROCESS_TYPE_MAX
};
+enum {
+ FD_IMAP,
+ FD_IMAPS,
+ FD_POP3,
+ FD_POP3S,
+
+ FD_MAX
+};
+
extern struct ioloop *ioloop;
extern struct hash_table *pids;
-extern int null_fd, imap_fd, imaps_fd;
+extern int null_fd, mail_fd[FD_MAX];
/* processes */
#define PID_GET_PROCESS_TYPE(pid) \
Index: login-process.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/login-process.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- login-process.c 27 Jan 2003 02:05:32 -0000 1.32
+++ login-process.c 30 Jan 2003 17:59:32 -0000 1.33
@@ -11,13 +11,31 @@
#include "restrict-process-size.h"
#include "login-process.h"
#include "auth-process.h"
-#include "imap-process.h"
+#include "mail-process.h"
#include "master-login-interface.h"
#include <unistd.h>
#include <syslog.h>
+struct login_group {
+ struct login_group *next;
+
+ struct login_settings *set;
+
+ unsigned int processes;
+ unsigned int listening_processes;
+ unsigned int wanted_processes_count;
+
+ struct login_process *oldest_nonlisten_process;
+ struct login_process *newest_nonlisten_process;
+
+ const char *executable;
+ unsigned int process_size;
+ int *listen_fd, *ssl_listen_fd;
+};
+
struct login_process {
+ struct login_group *group;
struct login_process *prev_nonlisten, *next_nonlisten;
int refcount;
@@ -44,14 +62,40 @@
static struct timeout *to;
static struct hash_table *processes;
-static struct login_process *oldest_nonlisten_process;
-static struct login_process *newest_nonlisten_process;
-static unsigned int listening_processes;
-static unsigned int wanted_processes_count;
+static struct login_group *login_groups;
static void login_process_destroy(struct login_process *p);
static void login_process_unref(struct login_process *p);
+static void login_group_create(struct login_settings *login_set)
+{
+ struct login_group *group;
+
+ group = i_new(struct login_group, 1);
+ group->set = login_set;
+
+ if (strcmp(login_set->name, "imap") == 0) {
+ group->executable = set->imap_executable;
+ group->process_size = set->imap_process_size;
+ group->listen_fd = &mail_fd[FD_IMAP];
+ group->ssl_listen_fd = &mail_fd[FD_IMAPS];
+ } else if (strcmp(login_set->name, "pop3") == 0) {
+ group->executable = set->pop3_executable;
+ group->process_size = set->pop3_process_size;
+ group->listen_fd = &mail_fd[FD_POP3];
+ group->ssl_listen_fd = &mail_fd[FD_POP3S];
+ } else
+ i_panic("Unknown login group name '%s'", login_set->name);
+
+ group->next = login_groups;
+ login_groups = group;
+}
+
+static void login_group_destroy(struct login_group *group)
+{
+ i_free(group);
+}
+
void auth_master_callback(struct auth_master_reply *reply,
const unsigned char *data, void *context)
{
@@ -61,9 +105,13 @@
if (reply == NULL || !reply->success)
master_reply.success = FALSE;
else {
+ struct login_group *group = request->process->group;
+
master_reply.success =
- create_imap_process(request->fd, &request->ip, reply,
- (const char *) data);
+ create_mail_process(request->fd, &request->ip,
+ group->executable,
+ group->process_size,
+ reply, (const char *) data);
}
/* reply to login */
@@ -74,7 +122,7 @@
login_process_destroy(request->process);
if (close(request->fd) < 0)
- i_error("close(imap client) failed: %m");
+ i_error("close(mail client) failed: %m");
login_process_unref(request->process);
i_free(request);
}
@@ -88,16 +136,16 @@
}
p->listening = FALSE;
- listening_processes--;
+ p->group->listening_processes--;
- p->prev_nonlisten = newest_nonlisten_process;
+ p->prev_nonlisten = p->group->newest_nonlisten_process;
- if (newest_nonlisten_process != NULL)
- newest_nonlisten_process->next_nonlisten = p;
- newest_nonlisten_process = p;
+ if (p->group->newest_nonlisten_process != NULL)
+ p->group->newest_nonlisten_process->next_nonlisten = p;
+ p->group->newest_nonlisten_process = p;
- if (oldest_nonlisten_process == NULL)
- oldest_nonlisten_process = p;
+ if (p->group->oldest_nonlisten_process == NULL)
+ p->group->oldest_nonlisten_process = p;
}
static void login_process_input(void *context)
@@ -121,7 +169,7 @@
if (client_fd != -1) {
if (close(client_fd) < 0)
- i_error("close(imap client) failed: %m");
+ i_error("close(mail client) failed: %m");
}
login_process_destroy(p);
@@ -162,13 +210,15 @@
}
}
-static struct login_process *login_process_new(pid_t pid, int fd)
+static struct login_process *
+login_process_new(struct login_group *group, pid_t pid, int fd)
{
struct login_process *p;
PID_ADD_PROCESS_TYPE(pid, PROCESS_TYPE_LOGIN);
p = i_new(struct login_process, 1);
+ p->group = group;
p->refcount = 1;
p->pid = pid;
p->fd = fd;
@@ -179,19 +229,20 @@
IO_PRIORITY_DEFAULT, FALSE);
hash_insert(processes, POINTER_CAST(pid), p);
- listening_processes++;
+ p->group->processes++;
+ p->group->listening_processes++;
return p;
}
static void login_process_remove_from_lists(struct login_process *p)
{
- if (p == oldest_nonlisten_process)
- oldest_nonlisten_process = p->next_nonlisten;
+ if (p == p->group->oldest_nonlisten_process)
+ p->group->oldest_nonlisten_process = p->next_nonlisten;
else
p->prev_nonlisten->next_nonlisten = p->next_nonlisten;
- if (p == newest_nonlisten_process)
- newest_nonlisten_process = p->prev_nonlisten;
+ if (p == p->group->newest_nonlisten_process)
+ p->group->newest_nonlisten_process = p->prev_nonlisten;
else
p->next_nonlisten->prev_nonlisten = p->prev_nonlisten;
@@ -209,7 +260,7 @@
io_loop_stop(ioloop);
}
if (p->listening)
- listening_processes--;
+ p->group->listening_processes--;
o_stream_close(p->output);
io_remove(p->io);
@@ -219,6 +270,7 @@
if (!p->listening)
login_process_remove_from_lists(p);
+ p->group->processes--;
hash_remove(processes, POINTER_CAST(p->pid));
login_process_unref(p);
@@ -233,19 +285,20 @@
i_free(p);
}
-static pid_t create_login_process(void)
+static pid_t create_login_process(struct login_group *group)
{
- static char *argv[] = { NULL, NULL };
+ static const char *argv[] = { NULL, NULL };
pid_t pid;
int fd[2];
- if (set_login_process_per_connection &&
- hash_size(processes)-listening_processes >= set_max_logging_users) {
- if (oldest_nonlisten_process != NULL)
- login_process_destroy(oldest_nonlisten_process);
+ if (group->set->process_per_connection &&
+ group->processes - group->listening_processes >=
+ group->set->max_logging_users) {
+ if (group->oldest_nonlisten_process != NULL)
+ login_process_destroy(group->oldest_nonlisten_process);
}
- if (set_login_uid == 0)
+ if (group->set->uid == 0)
i_fatal("Login process must not run as root");
/* create communication to process with a socket pair */
@@ -265,7 +318,7 @@
if (pid != 0) {
/* master */
fd_close_on_exec(fd[0], TRUE);
- login_process_new(pid, fd[0]);
+ login_process_new(group, pid, fd[0]);
(void)close(fd[1]);
return pid;
}
@@ -276,21 +329,21 @@
fd_close_on_exec(LOGIN_MASTER_SOCKET_FD, FALSE);
/* move the listen handle */
- if (dup2(imap_fd, LOGIN_IMAP_LISTEN_FD) < 0)
- i_fatal("login: dup2(imap) failed: %m");
- fd_close_on_exec(LOGIN_IMAP_LISTEN_FD, FALSE);
+ if (dup2(*group->listen_fd, LOGIN_LISTEN_FD) < 0)
+ i_fatal("login: dup2(listen_fd) failed: %m");
+ fd_close_on_exec(LOGIN_LISTEN_FD, FALSE);
/* move the SSL listen handle */
- if (!set_ssl_disable) {
- if (dup2(imaps_fd, LOGIN_IMAPS_LISTEN_FD) < 0)
- i_fatal("login: dup2(imaps) failed: %m");
+ if (!set->ssl_disable) {
+ if (dup2(*group->ssl_listen_fd, LOGIN_SSL_LISTEN_FD) < 0)
+ i_fatal("login: dup2(ssl_listen_fd) failed: %m");
} else {
- if (dup2(null_fd, LOGIN_IMAPS_LISTEN_FD) < 0)
- i_fatal("login: dup2(imaps) failed: %m");
+ if (dup2(null_fd, LOGIN_SSL_LISTEN_FD) < 0)
+ i_fatal("login: dup2(ssl_listen_fd) failed: %m");
}
- fd_close_on_exec(LOGIN_IMAPS_LISTEN_FD, FALSE);
+ fd_close_on_exec(LOGIN_SSL_LISTEN_FD, FALSE);
- /* imap_fd and imaps_fd are closed by clean_child_process() */
+ /* listen_fds are closed by clean_child_process() */
(void)close(fd[0]);
(void)close(fd[1]);
@@ -299,58 +352,64 @@
/* setup access environment - needs to be done after
clean_child_process() since it clears environment */
- restrict_access_set_env(set_login_user, set_login_uid, set_login_gid,
- set_login_chroot ? set_login_dir : NULL);
+ restrict_access_set_env(group->set->user,
+ group->set->uid, set->login_gid,
+ set->login_chroot ? set->login_dir : NULL);
- if (!set_login_chroot) {
+ if (!set->login_chroot) {
/* no chrooting, but still change to the directory */
- if (chdir(set_login_dir) < 0)
- i_fatal("chdir(%s) failed: %m", set_login_dir);
+ if (chdir(set->login_dir) < 0)
+ i_fatal("chdir(%s) failed: %m", set->login_dir);
}
- if (!set_ssl_disable) {
- env_put(t_strconcat("SSL_CERT_FILE=", set_ssl_cert_file, NULL));
- env_put(t_strconcat("SSL_KEY_FILE=", set_ssl_key_file, NULL));
+ if (!set->ssl_disable) {
+ env_put(t_strconcat("SSL_CERT_FILE=",
+ set->ssl_cert_file, NULL));
+ env_put(t_strconcat("SSL_KEY_FILE=", set->ssl_key_file, NULL));
env_put(t_strconcat("SSL_PARAM_FILE=",
- set_ssl_parameters_file, NULL));
+ set->ssl_parameters_file, NULL));
}
- if (set_disable_plaintext_auth)
+ if (set->disable_plaintext_auth)
env_put("DISABLE_PLAINTEXT_AUTH=1");
- if (set_verbose_proctitle)
+ if (set->verbose_proctitle)
env_put("VERBOSE_PROCTITLE=1");
- if (set_login_process_per_connection) {
+ if (group->set->process_per_connection) {
env_put("PROCESS_PER_CONNECTION=1");
env_put("MAX_LOGGING_USERS=1");
} else {
env_put(t_strdup_printf("MAX_LOGGING_USERS=%u",
- set_max_logging_users));
+ group->set->max_logging_users));
}
env_put(t_strdup_printf("PROCESS_UID=%s", dec2str(getpid())));
- restrict_process_size(set_login_process_size);
+ restrict_process_size(group->set->process_size);
/* make sure we don't leak syslog fd, but do it last so that
any errors above will be logged */
closelog();
/* hide the path, it's ugly */
- argv[0] = strrchr(set_login_executable, '/');
- if (argv[0] == NULL) argv[0] = set_login_executable; else argv[0]++;
+ argv[0] = strrchr(group->set->executable, '/');
+ if (argv[0] == NULL) argv[0] = group->set->executable; else argv[0]++;
- execv(set_login_executable, (char **) argv);
+ execv(group->set->executable, (char **) argv);
i_fatal_status(FATAL_EXEC, "execv(%s) failed: %m", argv[0]);
return -1;
}
-void login_process_abormal_exit(pid_t pid __attr_unused__)
+void login_process_abormal_exit(pid_t pid)
{
+ struct login_process *p;
+
/* don't start raising the process count if they're dying all
the time */
- wanted_processes_count = 0;
+ p = hash_lookup(processes, POINTER_CAST(pid));
+ if (p != NULL)
+ p->group->wanted_processes_count = 0;
}
static void login_hash_destroy(void *key __attr_unused__, void *value,
@@ -363,47 +422,64 @@
{
hash_foreach(processes, login_hash_destroy, NULL);
- /* don't double their amount when restarting */
- wanted_processes_count = 0;
+ while (login_groups != NULL) {
+ struct login_group *group = login_groups;
+
+ login_groups = group->next;
+ login_group_destroy(group);
+ }
}
-static void
-login_processes_start_missing(void *context __attr_unused__)
+static void login_group_start_missings(struct login_group *group)
{
- if (!set_login_process_per_connection) {
+ if (!group->set->process_per_connection) {
/* create max. one process every second, that way if it keeps
dying all the time we don't eat all cpu with fork()ing. */
- if (listening_processes < set_login_processes_count)
- (void)create_login_process();
- } else {
- /* we want to respond fast when multiple clients are connecting
- at once, but we also want to prevent fork-bombing. use the
- same method as apache: check once a second if we need new
- processes. if yes and we've used all the existing processes,
- double their amount (unless we've hit the high limit).
- Then for each second that didn't use all existing processes,
- drop the max. process count by one. */
- if (wanted_processes_count < set_login_processes_count)
- wanted_processes_count = set_login_processes_count;
- else if (listening_processes == 0)
- wanted_processes_count *= 2;
- else if (wanted_processes_count > set_login_processes_count)
- wanted_processes_count--;
+ if (group->listening_processes < group->set->processes_count)
+ (void)create_login_process(group);
+ return;
+ }
- if (wanted_processes_count > set_login_max_processes_count)
- wanted_processes_count = set_login_max_processes_count;
+ /* we want to respond fast when multiple clients are connecting
+ at once, but we also want to prevent fork-bombing. use the
+ same method as apache: check once a second if we need new
+ processes. if yes and we've used all the existing processes,
+ double their amount (unless we've hit the high limit).
+ Then for each second that didn't use all existing processes,
+ drop the max. process count by one. */
+ if (group->wanted_processes_count < group->set->processes_count)
+ group->wanted_processes_count = group->set->processes_count;
+ else if (group->listening_processes == 0)
+ group->wanted_processes_count *= 2;
+ else if (group->wanted_processes_count > group->set->processes_count)
+ group->wanted_processes_count--;
- while (listening_processes < wanted_processes_count)
- (void)create_login_process();
+ if (group->wanted_processes_count > group->set->max_processes_count)
+ group->wanted_processes_count = group->set->max_processes_count;
+
+ while (group->listening_processes < group->wanted_processes_count)
+ (void)create_login_process(group);
+}
+
+static void
+login_processes_start_missing(void *context __attr_unused__)
+{
+ struct login_group *group;
+ struct login_settings *login;
+
+ if (login_groups == NULL) {
+ for (login = set->logins; login != NULL; login = login->next)
+ login_group_create(login);
}
+
+ for (group = login_groups; group != NULL; group = group->next)
+ login_group_start_missings(group);
}
void login_processes_init(void)
{
auth_id_counter = 0;
- listening_processes = 0;
- wanted_processes_count = 0;
- oldest_nonlisten_process = newest_nonlisten_process = NULL;
+ login_groups = NULL;
processes = hash_create(default_pool, default_pool, 128, NULL, NULL);
to = timeout_add(1000, login_processes_start_missing, NULL);
Index: main.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/main.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- main.c 27 Jan 2003 01:44:34 -0000 1.30
+++ main.c 30 Jan 2003 17:59:32 -0000 1.31
@@ -9,7 +9,7 @@
#include "auth-process.h"
#include "login-process.h"
-#include "imap-process.h"
+#include "mail-process.h"
#include "ssl-init.h"
#include <stdio.h>
@@ -33,7 +33,7 @@
struct ioloop *ioloop;
struct hash_table *pids;
-int null_fd, imap_fd, imaps_fd;
+int null_fd, mail_fd[FD_MAX];
int validate_str(const char *str, size_t max_len)
{
@@ -53,18 +53,20 @@
env_clean();
/* set the failure log */
- if (set_log_path == NULL)
- env_put("IMAP_USE_SYSLOG=1");
+ if (set->log_path == NULL)
+ env_put("USE_SYSLOG=1");
else
- env_put(t_strconcat("IMAP_LOGFILE=", set_log_path, NULL));
+ env_put(t_strconcat("LOGFILE=", set->log_path, NULL));
- if (set_info_log_path != NULL) {
- env_put(t_strconcat("IMAP_INFOLOGFILE=",
- set_info_log_path, NULL));
+ if (set->info_log_path != NULL) {
+ env_put(t_strconcat("INFOLOGFILE=",
+ set->info_log_path, NULL));
}
- if (set_log_timestamp != NULL)
- env_put(t_strconcat("IMAP_LOGSTAMP=", set_log_timestamp, NULL));
+ if (set->log_timestamp != NULL) {
+ env_put(t_strconcat("LOGSTAMP=",
+ set->log_timestamp, NULL));
+ }
}
static void sig_quit(int signo __attr_unused__)
@@ -120,8 +122,8 @@
process_type = PID_GET_PROCESS_TYPE(pid);
PID_REMOVE_PROCESS_TYPE(pid);
- if (process_type == PROCESS_TYPE_IMAP)
- imap_process_destroyed(pid);
+ if (process_type == PROCESS_TYPE_MAIL)
+ mail_process_destroyed(pid);
if (process_type == PROCESS_TYPE_SSL_PARAM)
ssl_parameter_process_destroyed(pid);
@@ -153,13 +155,37 @@
i_warning("waitpid() failed: %m");
}
-static struct ip_addr *resolve_ip(const char *name)
+static struct ip_addr *resolve_ip(const char *name, unsigned int *port)
{
+ const char *p;
struct ip_addr *ip;
int ret, ips_count;
if (name == NULL)
- return NULL; /* defaults to "*" or "::" */
+ return NULL; /* defaults to "*" or "[::]" */
+
+ if (name[0] == '[') {
+ /* IPv6 address */
+ p = strchr(name, ']');
+ if (p == NULL)
+ i_fatal("Missing ']' in address %s", name);
+
+ name = t_strdup_until(name, p);
+
+ p++;
+ if (*p != '\0' && *p != ':')
+ i_fatal("Invalid data after ']' in address %s", name);
+ } else {
+ p = strrchr(name, ':');
+ if (p != NULL)
+ name = t_strdup_until(name, p);
+ }
+
+ if (p != NULL) {
+ if (!is_numeric(p+1, '\0'))
+ i_fatal("Invalid port in address %s", name);
+ *port = atoi(p+1);
+ }
if (strcmp(name, "*") == 0) {
/* IPv4 any */
@@ -168,7 +194,7 @@
return ip;
}
- if (strcmp(name, "::") == 0) {
+ if (strcmp(name, "[::]") == 0) {
/* IPv6 any */
ip = t_new(struct ip_addr, 1);
net_get_ip_any6(ip);
@@ -190,49 +216,86 @@
static void open_fds(void)
{
- struct ip_addr *imap_ip, *imaps_ip;
+ struct ip_addr *imap_ip, *imaps_ip, *pop3_ip, *pop3s_ip, *ip;
+ const char *const *proto;
+ unsigned int imap_port = 143;
+ unsigned int pop3_port = 110;
+#ifdef HAVE_SSL
+ unsigned int imaps_port = 993;
+ unsigned int pop3s_port = 995;
+#else
+ unsigned int imaps_port = 0;
+ unsigned int pop3s_port = 0;
+#endif
+ unsigned int port;
+ int *fd, i;
- imap_ip = resolve_ip(set_imap_listen);
- imaps_ip = resolve_ip(set_imaps_listen);
+ /* resolve */
+ imap_ip = resolve_ip(set->imap_listen, &imap_port);
+ imaps_ip = resolve_ip(set->imaps_listen, &imaps_port);
+ pop3_ip = resolve_ip(set->pop3_listen, &pop3_port);
+ pop3s_ip = resolve_ip(set->pop3s_listen, &pop3s_port);
- if (imaps_ip == NULL && set_imaps_listen == NULL)
+ if (imaps_ip == NULL && set->imaps_listen == NULL)
imaps_ip = imap_ip;
+ if (pop3s_ip == NULL && set->pop3s_listen == NULL)
+ pop3s_ip = pop3_ip;
+ /* initialize fds */
null_fd = open("/dev/null", O_RDONLY);
if (null_fd == -1)
i_fatal("Can't open /dev/null: %m");
fd_close_on_exec(null_fd, TRUE);
- imap_fd = set_imap_port == 0 ? dup(null_fd) :
- net_listen(imap_ip, &set_imap_port);
- if (imap_fd == -1)
- i_fatal("listen(%d) failed: %m", set_imap_port);
- fd_close_on_exec(imap_fd, TRUE);
+ for (i = 0; i < FD_MAX; i++)
+ mail_fd[i] = -1;
-#ifdef HAVE_SSL
- imaps_fd = set_ssl_disable || set_imaps_port == 0 ? dup(null_fd) :
- net_listen(imaps_ip, &set_imaps_port);
-#else
- imaps_fd = dup(null_fd);
-#endif
- if (imaps_fd == -1)
- i_fatal("listen(%d) failed: %m", set_imaps_port);
- fd_close_on_exec(imaps_fd, TRUE);
+ /* register wanted protocols */
+ for (proto = t_strsplit(set->protocols, " "); *proto != NULL; proto++) {
+ if (strcasecmp(*proto, "imap") == 0) {
+ fd = &mail_fd[FD_IMAP]; ip = imap_ip; port = imap_port;
+ } else if (strcasecmp(*proto, "imaps") == 0) {
+ fd = &mail_fd[FD_IMAPS]; ip = imaps_ip; port = imaps_port;
+ } else if (strcasecmp(*proto, "pop3") == 0) {
+ fd = &mail_fd[FD_POP3]; ip = pop3_ip; port = pop3_port;
+ } else if (strcasecmp(*proto, "pop3s") == 0) {
+ fd = &mail_fd[FD_POP3S]; ip = pop3s_ip; port = pop3s_port;
+ } else {
+ i_fatal("Unknown protocol %s", *proto);
+ }
+
+ if (*fd != -1)
+ i_fatal("Protocol %s given more than once", *proto);
+
+ *fd = port == 0 ? dup(null_fd) : net_listen(ip, &port);
+ if (*fd == -1)
+ i_fatal("listen(%d) failed: %m", port);
+ fd_close_on_exec(*fd, TRUE);
+ }
+
+ for (i = 0; i < FD_MAX; i++) {
+ if (mail_fd[i] == -1) {
+ mail_fd[i] = dup(null_fd);
+ if (mail_fd[i] == -1)
+ i_fatal("dup(mail_fd[%d]) failed: %m", i);
+ fd_close_on_exec(mail_fd[i], TRUE);
+ }
+ }
}
static void open_logfile(void)
{
- if (set_log_path == NULL)
- i_set_failure_syslog("imap-master", LOG_NDELAY, LOG_MAIL);
+ if (set->log_path == NULL)
+ i_set_failure_syslog("dovecot", LOG_NDELAY, LOG_MAIL);
else {
/* log to file or stderr */
- i_set_failure_file(set_log_path, "imap-master");
+ i_set_failure_file(set->log_path, "dovecot");
}
- if (set_info_log_path != NULL)
- i_set_info_file(set_info_log_path);
+ if (set->info_log_path != NULL)
+ i_set_info_file(set->info_log_path);
- i_set_failure_timestamp_format(set_log_timestamp);
+ i_set_failure_timestamp_format(set->log_timestamp);
i_info("Dovecot starting up");
}
@@ -256,6 +319,8 @@
static void main_deinit(void)
{
+ int i;
+
if (lib_signal_kill != 0)
i_warning("Killed with signal %d", lib_signal_kill);
@@ -270,10 +335,11 @@
if (close(null_fd) < 0)
i_error("close(null_fd) failed: %m");
- if (close(imap_fd) < 0)
- i_error("close(imap_fd) failed: %m");
- if (close(imaps_fd) < 0)
- i_error("close(imaps_fd) failed: %m");
+
+ for (i = 0; i < FD_MAX; i++) {
+ if (close(mail_fd[i]) < 0)
+ i_error("close(mail_fd[%d]) failed: %m", i);
+ }
hash_destroy(pids);
closelog();
@@ -296,7 +362,7 @@
static void print_help(void)
{
- printf("Usage: imap-master [-F] [-c <config file>]\n");
+ printf("Usage: dovecot [-F] [-c <config file>]\n");
}
int main(int argc, char *argv[])
Index: master-login-interface.h
===================================================================
RCS file: /home/cvs/dovecot/src/master/master-login-interface.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- master-login-interface.h 27 Jan 2003 01:33:40 -0000 1.1
+++ master-login-interface.h 30 Jan 2003 17:59:32 -0000 1.2
@@ -4,8 +4,8 @@
#include "network.h"
#define LOGIN_MASTER_SOCKET_FD 0
-#define LOGIN_IMAP_LISTEN_FD 1
-#define LOGIN_IMAPS_LISTEN_FD 2
+#define LOGIN_LISTEN_FD 1
+#define LOGIN_SSL_LISTEN_FD 2
struct master_login_request {
unsigned int tag;
Index: settings.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/settings.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -d -r1.44 -r1.45
--- settings.c 27 Jan 2003 02:42:02 -0000 1.44
+++ settings.c 30 Jan 2003 17:59:32 -0000 1.45
@@ -7,6 +7,7 @@
#include "settings.h"
#include <stdio.h>
+#include <stddef.h>
#include <unistd.h>
#include <fcntl.h>
#include <pwd.h>
@@ -17,157 +18,224 @@
SET_BOOL
};
-struct setting {
- const char *name;
+struct setting_def {
enum setting_type type;
- void *ptr;
+ const char *name;
+ size_t offset;
};
-static struct setting settings[] = {
- { "base_dir", SET_STR, &set_base_dir },
- { "log_path", SET_STR, &set_log_path },
- { "info_log_path", SET_STR, &set_info_log_path },
- { "log_timestamp", SET_STR, &set_log_timestamp },
+#define DEF(type, name) \
+ { type, #name, offsetof(struct settings, name) }
- { "imap_port", SET_INT, &set_imap_port },
- { "imaps_port", SET_INT, &set_imaps_port },
- { "imap_listen", SET_STR, &set_imap_listen },
- { "imaps_listen", SET_STR, &set_imaps_listen },
- { "ssl_disable", SET_BOOL,&set_ssl_disable, },
- { "ssl_cert_file", SET_STR, &set_ssl_cert_file },
- { "ssl_key_file", SET_STR, &set_ssl_key_file },
- { "ssl_parameters_file",SET_STR, &set_ssl_parameters_file },
- { "ssl_parameters_regenerate",
- SET_INT, &set_ssl_parameters_regenerate },
- { "disable_plaintext_auth",
- SET_BOOL,&set_disable_plaintext_auth },
+static struct setting_def setting_defs[] = {
+ /* common */
+ DEF(SET_STR, base_dir),
+ DEF(SET_STR, log_path),
+ DEF(SET_STR, info_log_path),
+ DEF(SET_STR, log_timestamp),
- { "login_executable", SET_STR, &set_login_executable },
- { "login_user", SET_STR, &set_login_user },
- { "login_process_size", SET_INT, &set_login_process_size },
- { "login_dir", SET_STR, &set_login_dir },
- { "login_chroot", SET_BOOL,&set_login_chroot },
- { "login_process_per_connection",
- SET_BOOL,&set_login_process_per_connection },
- { "login_processes_count",
- SET_INT, &set_login_processes_count },
- { "max_logging_users", SET_INT, &set_max_logging_users },
+ /* general */
+ DEF(SET_STR, protocols),
+ DEF(SET_STR, imap_listen),
+ DEF(SET_STR, imaps_listen),
+ DEF(SET_STR, pop3_listen),
+ DEF(SET_STR, pop3s_listen),
- { "imap_executable", SET_STR, &set_imap_executable },
- { "imap_process_size", SET_INT, &set_imap_process_size },
- { "valid_chroot_dirs", SET_STR, &set_valid_chroot_dirs },
- { "max_imap_processes", SET_INT, &set_max_imap_processes },
- { "verbose_proctitle", SET_BOOL,&set_verbose_proctitle },
- { "first_valid_uid", SET_INT, &set_first_valid_uid },
- { "last_valid_uid", SET_INT, &set_last_valid_uid },
- { "first_valid_gid", SET_INT, &set_first_valid_gid },
- { "last_valid_gid", SET_INT, &set_last_valid_gid },
- { "default_mail_env", SET_STR, &set_default_mail_env },
- { "mail_cache_fields", SET_STR, &set_mail_cache_fields },
- { "mail_never_cache_fields",
- SET_STR, &set_mail_never_cache_fields },
- { "mailbox_check_interval",
- SET_INT, &set_mailbox_check_interval },
- { "mail_save_crlf", SET_BOOL,&set_mail_save_crlf },
- { "mail_read_mmaped", SET_BOOL,&set_mail_read_mmaped },
- { "maildir_copy_with_hardlinks",
- SET_BOOL,&set_maildir_copy_with_hardlinks },
- { "maildir_check_content_changes",
- SET_BOOL,&set_maildir_check_content_changes },
- { "mbox_locks", SET_STR, &set_mbox_locks, },
- { "mbox_read_dotlock", SET_BOOL,&set_mbox_read_dotlock, },
- { "mbox_lock_timeout", SET_INT, &set_mbox_lock_timeout, },
- { "mbox_dotlock_change_timeout",
- SET_INT, &set_mbox_dotlock_change_timeout, },
- { "overwrite_incompatible_index",
- SET_BOOL,&set_overwrite_incompatible_index },
- { "umask", SET_INT, &set_umask },
+ DEF(SET_BOOL, ssl_disable),
+ DEF(SET_STR, ssl_cert_file),
+ DEF(SET_STR, ssl_key_file),
+ DEF(SET_STR, ssl_parameters_file),
+ DEF(SET_STR, ssl_parameters_regenerate),
+ DEF(SET_BOOL, disable_plaintext_auth),
- { NULL, 0, NULL }
+ /* login */
+ DEF(SET_STR, login_dir),
+ DEF(SET_BOOL, login_chroot),
+
+ /* mail */
+ DEF(SET_STR, valid_chroot_dirs),
+ DEF(SET_INT, max_mail_processes),
+ DEF(SET_BOOL, verbose_proctitle),
+
+ DEF(SET_INT, first_valid_uid),
+ DEF(SET_INT, last_valid_uid),
+ DEF(SET_INT, first_valid_gid),
+ DEF(SET_INT, last_valid_gid),
+
+ DEF(SET_STR, default_mail_env),
+ DEF(SET_STR, mail_cache_fields),
+ DEF(SET_STR, mail_never_cache_fields),
+ DEF(SET_STR, mailbox_check_interval),
+ DEF(SET_STR, mail_save_crlf),
+ DEF(SET_STR, mail_read_mmaped),
+ DEF(SET_STR, maildir_copy_with_hardlinks),
+ DEF(SET_STR, maildir_check_content_changes),
+ DEF(SET_STR, mbox_locks),
+ DEF(SET_STR, mbox_read_dotlock),
+ DEF(SET_STR, mbox_lock_timeout),
+ DEF(SET_STR, mbox_dotlock_change_timeout),
+ DEF(SET_STR, overwrite_incompatible_index),
+ DEF(SET_STR, umask),
+
+ /* imap */
+ DEF(SET_STR, imap_executable),
+ DEF(SET_INT, imap_process_size),
+
+ /* pop3 */
+ DEF(SET_STR, pop3_executable),
+ DEF(SET_INT, pop3_process_size),
+
+ { 0, NULL, 0 }
};
-/* common */
-char *set_base_dir = PKG_RUNDIR;
-char *set_log_path = NULL;
-char *set_info_log_path = NULL;
-char *set_log_timestamp = DEFAULT_FAILURE_STAMP_FORMAT;
+#undef DEF
+#define DEF(type, name) \
+ { type, #name, offsetof(struct login_settings, name) }
-/* general */
-unsigned int set_imap_port = 143;
-unsigned int set_imaps_port = 993;
-char *set_imap_listen = "*";
-char *set_imaps_listen = NULL;
+static struct setting_def login_setting_defs[] = {
+ DEF(SET_STR, executable),
+ DEF(SET_STR, user),
-int set_ssl_disable = FALSE;
-char *set_ssl_cert_file = SSLDIR"/certs/imapd.pem";
-char *set_ssl_key_file = SSLDIR"/private/imapd.pem";
-char *set_ssl_parameters_file = "ssl-parameters.dat";
-unsigned int set_ssl_parameters_regenerate = 24;
-int set_disable_plaintext_auth = FALSE;
+ DEF(SET_BOOL, process_per_connection),
-/* login */
-char *set_login_executable = PKG_LIBEXECDIR"/imap-login";
-unsigned int set_login_process_size = 16;
-char *set_login_user = "imapd";
-char *set_login_dir = "login";
+ DEF(SET_INT, process_size),
+ DEF(SET_INT, processes_count),
+ DEF(SET_INT, max_processes_count),
+ DEF(SET_INT, max_logging_users),
-int set_login_chroot = TRUE;
-int set_login_process_per_connection = TRUE;
-unsigned int set_login_processes_count = 3;
-unsigned int set_login_max_processes_count = 128;
-unsigned int set_max_logging_users = 256;
+ { 0, NULL, 0 }
+};
-uid_t set_login_uid; /* generated from set_login_user */
-gid_t set_login_gid; /* generated from set_login_user */
+#undef DEF
+#define DEF(type, name) \
+ { type, #name, offsetof(struct auth_settings, name) }
-/* imap */
-char *set_imap_executable = PKG_LIBEXECDIR"/imap";
-unsigned int set_imap_process_size = 256;
-char *set_valid_chroot_dirs = NULL;
-unsigned int set_max_imap_processes = 1024;
-int set_verbose_proctitle = FALSE;
+static struct setting_def auth_setting_defs[] = {
+ DEF(SET_STR, mechanisms),
+ DEF(SET_STR, realms),
+ DEF(SET_STR, userdb),
+ DEF(SET_STR, passdb),
+ DEF(SET_STR, executable),
+ DEF(SET_STR, user),
+ DEF(SET_STR, chroot),
-unsigned int set_first_valid_uid = 500, set_last_valid_uid = 0;
-unsigned int set_first_valid_gid = 1, set_last_valid_gid = 0;
+ DEF(SET_BOOL, use_cyrus_sasl),
+ DEF(SET_BOOL, verbose),
-char *set_default_mail_env = NULL;
-char *set_mail_cache_fields = "MessagePart";
-char *set_mail_never_cache_fields = NULL;
-unsigned int set_mailbox_check_interval = 0;
-int set_mail_save_crlf = FALSE;
-int set_mail_read_mmaped = FALSE;
-int set_maildir_copy_with_hardlinks = FALSE;
-int set_maildir_check_content_changes = FALSE;
-char *set_mbox_locks = "dotlock fcntl flock";
-int set_mbox_read_dotlock = FALSE;
-unsigned int set_mbox_lock_timeout = 300;
-unsigned int set_mbox_dotlock_change_timeout = 30;
-int set_overwrite_incompatible_index = FALSE;
-unsigned int set_umask = 0077;
+ DEF(SET_INT, count),
+ DEF(SET_INT, process_size),
-/* auth */
-struct auth_config *auth_processes_config = NULL;
+ { 0, NULL, 0 }
+};
-static void fix_base_path(char **str)
-{
- char *fullpath;
+struct settings default_settings = {
+ /* common */
+ MEMBER(base_dir) PKG_RUNDIR,
+ MEMBER(log_path) NULL,
+ MEMBER(info_log_path) NULL,
+ MEMBER(log_timestamp) DEFAULT_FAILURE_STAMP_FORMAT,
+ /* general */
+ MEMBER(protocols) "imap imaps",
+ MEMBER(imap_listen) "*",
+ MEMBER(imaps_listen) NULL,
+ MEMBER(pop3_listen) "*",
+ MEMBER(pop3s_listen) NULL,
+
+ MEMBER(ssl_disable) FALSE,
+ MEMBER(ssl_cert_file) SSLDIR"/certs/dovecot.pem",
+ MEMBER(ssl_key_file) SSLDIR"/private/dovecot.pem",
+ MEMBER(ssl_parameters_file) "ssl-parameters.dat",
+ MEMBER(ssl_parameters_regenerate) 24,
+ MEMBER(disable_plaintext_auth) FALSE,
+
+ /* login */
+ MEMBER(login_dir) "login",
+ MEMBER(login_chroot) TRUE,
+
+ /* mail */
+ MEMBER(valid_chroot_dirs) NULL,
+ MEMBER(max_mail_processes) 1024,
+ MEMBER(verbose_proctitle) FALSE,
+
+ MEMBER(first_valid_uid) 500,
+ MEMBER(last_valid_uid) 0,
+ MEMBER(first_valid_gid) 1,
+ MEMBER(last_valid_gid) 0,
+
+ MEMBER(default_mail_env) NULL,
+ MEMBER(mail_cache_fields) "MessagePart",
+ MEMBER(mail_never_cache_fields) NULL,
+ MEMBER(mailbox_check_interval) 0,
+ MEMBER(mail_save_crlf) FALSE,
+ MEMBER(mail_read_mmaped) FALSE,
+ MEMBER(maildir_copy_with_hardlinks) FALSE,
+ MEMBER(maildir_check_content_changes) FALSE,
+ MEMBER(mbox_locks) "dotlock fcntl flock",
+ MEMBER(mbox_read_dotlock) FALSE,
+ MEMBER(mbox_lock_timeout) 300,
+ MEMBER(mbox_dotlock_change_timeout) 30,
+ MEMBER(overwrite_incompatible_index) FALSE,
+ MEMBER(umask) 0077,
+
+ /* imap */
+ MEMBER(imap_executable) PKG_LIBEXECDIR"/imap",
+ MEMBER(imap_process_size) 256,
+
+ /* pop3 */
+ MEMBER(pop3_executable) PKG_LIBEXECDIR"/pop3",
+ MEMBER(pop3_process_size) 256,
+
+ MEMBER(login_gid) 0,
+ MEMBER(auths) NULL,
+ MEMBER(logins) NULL
+};
+
+struct login_settings default_login_settings = {
+ MEMBER(next) NULL,
+ MEMBER(name) NULL,
+
+ MEMBER(executable) NULL,
+ MEMBER(user) "dovecot",
+
+ MEMBER(process_per_connection) TRUE,
+
+ MEMBER(process_size) 16,
+ MEMBER(processes_count) 3,
+ MEMBER(max_processes_count) 128,
+ MEMBER(max_logging_users) 256,
+
+ MEMBER(uid) 0 /* generated */
+};
+
+static pool_t settings_pool;
+struct settings *set = NULL;
+
+static void fix_base_path(struct settings *set, const char **str)
+{
if (*str != NULL && **str != '\0' && **str != '/') {
- fullpath = i_strconcat(set_base_dir, "/", *str, NULL);
- i_free(*str);
- *str = i_strdup(fullpath);
+ *str = p_strconcat(settings_pool,
+ set->base_dir, "/", *str, NULL);
}
}
-static void get_login_uid(void)
+static void get_login_uid(struct settings *set,
+ struct login_settings *login_set)
{
struct passwd *pw;
- if ((pw = getpwnam(set_login_user)) == NULL)
- i_fatal("Login user doesn't exist: %s", set_login_user);
+ if ((pw = getpwnam(login_set->user)) == NULL)
+ i_fatal("Login user doesn't exist: %s", login_set->user);
- set_login_uid = pw->pw_uid;
- set_login_gid = pw->pw_gid;
+ if (set->login_gid == 0)
+ set->login_gid = pw->pw_gid;
+ else if (set->login_gid != pw->pw_gid) {
+ i_fatal("All login process users must belong to same group "
+ "(%s vs %s)", dec2str(set->login_gid),
+ dec2str(pw->pw_gid));
+ }
+
+ login_set->uid = pw->pw_uid;
}
static const char *get_bool(const char *value, int *result)
@@ -182,24 +250,39 @@
return NULL;
}
-static void auth_settings_verify(void)
+static const char *get_uint(const char *value, unsigned int *result)
{
- struct auth_config *auth;
+ int num;
- for (auth = auth_processes_config; auth != NULL; auth = auth->next) {
- if (access(auth->executable, X_OK) < 0) {
- i_fatal("Can't use auth executable %s: %m",
- auth->executable);
- }
+ if (!sscanf(value, "%i", &num) || num < 0)
+ return t_strconcat("Invalid number: ", value, NULL);
+ *result = num;
+ return NULL;
+}
- fix_base_path(&auth->chroot);
- if (auth->chroot != NULL && access(auth->chroot, X_OK) < 0) {
- i_fatal("Can't access auth chroot directory %s: %m",
- auth->chroot);
- }
+static void auth_settings_verify(struct auth_settings *auth)
+{
+ if (access(auth->executable, X_OK) < 0)
+ i_fatal("Can't use auth executable %s: %m", auth->executable);
+
+ fix_base_path(set, &auth->chroot);
+ if (auth->chroot != NULL && access(auth->chroot, X_OK) < 0) {
+ i_fatal("Can't access auth chroot directory %s: %m",
+ auth->chroot);
}
}
+static void login_settings_verify(struct login_settings *login)
+{
+ if (access(login->executable, X_OK) < 0)
+ i_fatal("Can't use login executable %s: %m", login->executable);
+
+ if (login->processes_count < 1)
+ i_fatal("login_processes_count must be at least 1");
+ if (login->max_logging_users < 1)
+ i_fatal("max_logging_users must be at least 1");
+}
+
static const char *get_directory(const char *path)
{
char *str, *p;
@@ -214,86 +297,91 @@
}
}
-static void settings_verify(void)
+static void settings_verify(struct settings *set)
{
+ struct login_settings *login;
+ struct auth_settings *auth;
const char *const *str;
const char *dir;
int dotlock_got, fcntl_got, flock_got;
- get_login_uid();
+ for (login = set->logins; login != NULL; login = login->next) {
+ get_login_uid(set, login);
+ login_settings_verify(login);
+ }
- if (access(set_login_executable, X_OK) < 0) {
- i_fatal("Can't use login executable %s: %m",
- set_login_executable);
+ if (strstr(set->protocols, "imap") != NULL) {
+ if (access(set->imap_executable, X_OK) < 0) {
+ i_fatal("Can't use imap executable %s: %m",
+ set->imap_executable);
+ }
}
- if (access(set_imap_executable, X_OK) < 0) {
- i_fatal("Can't use imap executable %s: %m",
- set_imap_executable);
+ if (strstr(set->protocols, "pop3") != NULL) {
+ if (access(set->pop3_executable, X_OK) < 0) {
+ i_fatal("Can't use pop3 executable %s: %m",
+ set->pop3_executable);
+ }
}
- if (set_log_path != NULL) {
- dir = get_directory(set_log_path);
+ if (set->log_path != NULL) {
+ dir = get_directory(set->log_path);
if (access(dir, W_OK) < 0)
i_fatal("Can't access log directory %s: %m", dir);
}
- if (set_info_log_path != NULL) {
- dir = get_directory(set_info_log_path);
+ if (set->info_log_path != NULL) {
+ dir = get_directory(set->info_log_path);
if (access(dir, W_OK) < 0)
i_fatal("Can't access info log directory %s: %m", dir);
}
#ifdef HAVE_SSL
- if (!set_ssl_disable) {
- if (access(set_ssl_cert_file, R_OK) < 0) {
+ if (!set->ssl_disable) {
+ if (access(set->ssl_cert_file, R_OK) < 0) {
i_fatal("Can't use SSL certificate %s: %m",
- set_ssl_cert_file);
+ set->ssl_cert_file);
}
- if (access(set_ssl_key_file, R_OK) < 0) {
+ if (access(set->ssl_key_file, R_OK) < 0) {
i_fatal("Can't use SSL key file %s: %m",
- set_ssl_key_file);
+ set->ssl_key_file);
}
}
#endif
/* fix relative paths */
- fix_base_path(&set_ssl_parameters_file);
- fix_base_path(&set_login_dir);
+ fix_base_path(set, &set->ssl_parameters_file);
+ fix_base_path(set, &set->login_dir);
/* since they're under /var/run by default, they may have been
deleted. */
- if (safe_mkdir(set_base_dir, 0700, geteuid(), getegid()) == 0) {
+ if (safe_mkdir(set->base_dir, 0700, geteuid(), getegid()) == 0) {
i_warning("Corrected permissions for base directory %s",
PKG_RUNDIR);
}
/* wipe out contents of login directory, if it exists */
- if (unlink_directory(set_login_dir, FALSE) < 0)
- i_fatal("unlink_directory() failed for %s: %m", set_login_dir);
+ if (unlink_directory(set->login_dir, FALSE) < 0)
+ i_fatal("unlink_directory() failed for %s: %m", set->login_dir);
- if (safe_mkdir(set_login_dir, 0750, geteuid(), set_login_gid) == 0) {
+ if (safe_mkdir(set->login_dir, 0750, geteuid(), set->login_gid) == 0) {
i_warning("Corrected permissions for login directory %s",
- set_login_dir);
+ set->login_dir);
}
- if (set_max_imap_processes < 1)
- i_fatal("max_imap_processes must be at least 1");
- if (set_login_processes_count < 1)
- i_fatal("login_processes_count must be at least 1");
- if (set_max_logging_users < 1)
- i_fatal("max_logging_users must be at least 1");
+ if (set->max_mail_processes < 1)
+ i_fatal("max_mail_processes must be at least 1");
- if (set_last_valid_uid != 0 &&
- set_first_valid_uid > set_last_valid_uid)
+ if (set->last_valid_uid != 0 &&
+ set->first_valid_uid > set->last_valid_uid)
i_fatal("first_valid_uid can't be larger than last_valid_uid");
- if (set_last_valid_gid != 0 &&
- set_first_valid_gid > set_last_valid_gid)
+ if (set->last_valid_gid != 0 &&
+ set->first_valid_gid > set->last_valid_gid)
i_fatal("first_valid_gid can't be larger than last_valid_gid");
dotlock_got = fcntl_got = flock_got = FALSE;
- for (str = t_strsplit(set_mbox_locks, " "); *str != NULL; str++) {
+ for (str = t_strsplit(set->mbox_locks, " "); *str != NULL; str++) {
if (strcasecmp(*str, "dotlock") == 0)
dotlock_got = TRUE;
else if (strcasecmp(*str, "fcntl") == 0)
@@ -315,189 +403,140 @@
if (!dotlock_got && !fcntl_got && !flock_got)
i_fatal("mbox_locks: No mbox locking methods selected");
- if (dotlock_got && !set_mbox_read_dotlock && !fcntl_got && !flock_got) {
+ if (dotlock_got && !set->mbox_read_dotlock &&
+ !fcntl_got && !flock_got) {
i_warning("mbox_locks: Only dotlock selected, forcing "
"mbox_read_dotlock = yes to avoid corruption.");
- set_mbox_read_dotlock = TRUE;
+ set->mbox_read_dotlock = TRUE;
}
- auth_settings_verify();
+ for (auth = set->auths; auth != NULL; auth = auth->next)
+ auth_settings_verify(auth);
}
-static struct auth_config *auth_config_new(const char *name)
+static void auth_settings_new(struct settings *set, const char *name)
{
- struct auth_config *auth;
+ struct auth_settings *auth;
- auth = i_new(struct auth_config, 1);
- auth->name = i_strdup(name);
- auth->executable = i_strdup(PKG_LIBEXECDIR"/imap-auth");
+ auth = p_new(settings_pool, struct auth_settings, 1);
+ auth->name = p_strdup(settings_pool, name);
+ auth->executable = p_strdup(settings_pool,
+ PKG_LIBEXECDIR"/dovecot-auth");
auth->count = 1;
- auth->next = auth_processes_config;
- auth_processes_config = auth;
- return auth;
-}
-
-static void auth_config_free(struct auth_config *auth)
-{
- i_free(auth->name);
- i_free(auth->mechanisms);
- i_free(auth->realms);
- i_free(auth->userdb);
- i_free(auth->userdb_args);
- i_free(auth->passdb);
- i_free(auth->passdb_args);
- i_free(auth->executable);
- i_free(auth->user);
- i_free(auth->chroot);
- i_free(auth);
+ auth->next = set->auths;
+ set->auths = auth;
}
-static const char *parse_new_auth(const char *name)
+static const char *parse_new_auth(struct settings *set, const char *name)
{
- struct auth_config *auth;
+ struct auth_settings *auth;
if (strchr(name, '/') != NULL)
return "Authentication process name must not contain '/'";
- for (auth = auth_processes_config; auth != NULL; auth = auth->next) {
+ for (auth = set->auths; auth != NULL; auth = auth->next) {
if (strcmp(auth->name, name) == 0) {
return "Authentication process already exists "
"with the same name";
}
}
- (void)auth_config_new(name);
+ auth_settings_new(set, name);
return NULL;
}
-static const char *parse_auth(const char *key, const char *value)
+static void login_settings_new(struct settings *set, const char *name)
{
- struct auth_config *auth = auth_processes_config;
- const char *p;
- char **ptr;
-
- if (auth == NULL)
- return "Authentication process name not defined yet";
-
- /* check the easy string values first */
- if (strcmp(key, "auth_mechanisms") == 0)
- ptr = &auth->mechanisms;
- else if (strcmp(key, "auth_realms") == 0)
- ptr = &auth->realms;
- else if (strcmp(key, "auth_executable") == 0)
- ptr = &auth->executable;
- else if (strcmp(key, "auth_user") == 0)
- ptr = &auth->user;
- else if (strcmp(key, "auth_chroot") == 0)
- ptr = &auth->chroot;
- else
- ptr = NULL;
-
- if (ptr != NULL) {
- i_free(*ptr);
- *ptr = i_strdup(value);
- return NULL;
- }
-
- if (strcmp(key, "auth_userdb") == 0) {
- /* split it into userdb + userdb_args */
- for (p = value; *p != ' ' && *p != '\0'; )
- p++;
-
- i_free(auth->userdb);
- auth->userdb = i_strdup_until(value, p);
-
- while (*p == ' ') p++;
-
- i_free(auth->userdb_args);
- auth->userdb_args = i_strdup(p);
- return NULL;
- }
-
- if (strcmp(key, "auth_passdb") == 0) {
- /* split it into passdb + passdb_args */
- for (p = value; *p != ' ' && *p != '\0'; )
- p++;
+ struct login_settings *login;
- i_free(auth->passdb);
- auth->passdb = i_strdup_until(value, p);
+ login = p_new(settings_pool, struct login_settings, 1);
- while (*p == ' ') p++;
+ /* copy defaults */
+ *login = set->logins != NULL ? *set->logins :
+ default_login_settings;
- i_free(auth->passdb_args);
- auth->passdb_args = i_strdup(p);
- return NULL;
+ if (strcasecmp(name, "imap") == 0) {
+ login->name = "imap";
+ login->executable = PKG_LIBEXECDIR"/imap-login";
+ } else if (strcasecmp(name, "pop3") == 0) {
+ login->name = "pop3";
+ login->executable = PKG_LIBEXECDIR"/pop3-login";
+ } else {
+ i_fatal("Unknown login process type '%s'", name);
}
- if (strcmp(key, "auth_cyrus_sasl") == 0)
- return get_bool(value, &auth->use_cyrus_sasl);
-
- if (strcmp(key, "auth_verbose") == 0)
- return get_bool(value, &auth->verbose);
-
- if (strcmp(key, "auth_count") == 0) {
- int num;
-
- if (!sscanf(value, "%i", &num) || num < 0)
- return t_strconcat("Invalid number: ", value, NULL);
- auth->count = num;
- return NULL;
- }
+ login->next = set->logins;
+ set->logins = login;
+}
- if (strcmp(key, "auth_process_size") == 0) {
- int num;
+static const char *parse_new_login(struct settings *set, const char *name)
+{
+ struct login_settings *login;
- if (!sscanf(value, "%i", &num) || num < 0)
- return t_strconcat("Invalid number: ", value, NULL);
- auth->process_size = num;
- return NULL;
+ for (login = set->logins; login != NULL; login = login->next) {
+ if (strcmp(login->name, name) == 0) {
+ return "Login process already exists "
+ "with the same name";
+ }
}
- return t_strconcat("Unknown setting: ", key, NULL);
+ login_settings_new(set, name);
+ return NULL;
}
-static const char *parse_setting(const char *key, const char *value)
+static const char *
+parse_setting_from_defs(struct setting_def *defs, void *base,
+ const char *key, const char *value)
{
- struct setting *set;
+ struct setting_def *def;
- if (strcmp(key, "auth") == 0)
- return parse_new_auth(value);
- if (strncmp(key, "auth_", 5) == 0)
- return parse_auth(key, value);
+ for (def = defs; def->name != NULL; def++) {
+ if (strcmp(def->name, key) == 0) {
+ void *ptr = STRUCT_MEMBER_P(base, def->offset);
- for (set = settings; set->name != NULL; set++) {
- if (strcmp(set->name, key) == 0) {
- switch (set->type) {
+ switch (def->type) {
case SET_STR:
- i_free(*((char **)set->ptr));
- *((char **)set->ptr) = i_strdup_empty(value);
- break;
+ *((char **) ptr) =
+ p_strdup_empty(settings_pool, value);
+ return NULL;
case SET_INT:
/* use %i so we can handle eg. 0600
as octal value with umasks */
- if (!sscanf(value, "%i", (int *) set->ptr))
- return t_strconcat("Invalid number: ",
- value, NULL);
- break;
+ return get_uint(value, (unsigned int *) ptr);
case SET_BOOL:
- return get_bool(value, set->ptr);
+ return get_bool(value, (int *) ptr);
}
- return NULL;
}
}
return t_strconcat("Unknown setting: ", key, NULL);
}
-static void settings_free(void)
+static const char *parse_setting(struct settings *set,
+ const char *key, const char *value)
{
- while (auth_processes_config != NULL) {
- struct auth_config *auth = auth_processes_config;
+ if (strcmp(key, "auth") == 0)
+ return parse_new_auth(set, value);
+ if (strncmp(key, "auth_", 5) == 0) {
+ if (set->auths == NULL)
+ return "Authentication process name not defined yet";
- auth_processes_config = auth->next;
- auth_config_free(auth);
+ return parse_setting_from_defs(auth_setting_defs,
+ set->auths, key + 5, value);
+ }
+
+ if (strcmp(key, "login") == 0)
+ return parse_new_login(set, value);
+ if (strncmp(key, "login_", 6) == 0) {
+ if (set->logins == NULL)
+ return "Login process name not defined yet";
+
+ return parse_setting_from_defs(login_setting_defs,
+ set->logins, key + 6, value);
}
+
+ return parse_setting_from_defs(setting_defs, set, key, value);
}
#define IS_WHITE(c) ((c) == ' ' || (c) == '\t')
@@ -509,7 +548,9 @@
char *line, *key, *p;
int fd, linenum;
- settings_free();
+ p_clear(settings_pool);
+ set = p_new(settings_pool, struct settings, 1);
+ *set = default_settings;
fd = open(path, O_RDONLY);
if (fd < 0)
@@ -558,7 +599,7 @@
p--;
*p = '\0';
- errormsg = parse_setting(key, line);
+ errormsg = parse_setting(set, key, line);
}
if (errormsg != NULL) {
@@ -569,18 +610,10 @@
i_stream_unref(input);
- settings_verify();
+ settings_verify(set);
}
void settings_init(void)
{
- struct setting *set;
-
- /* strdup() all default settings */
- for (set = settings; set->name != NULL; set++) {
- if (set->type == SET_STR) {
- char **str = set->ptr;
- *str = i_strdup(*str);
- }
- }
+ settings_pool = pool_alloconly_create("settings", 1024);
}
Index: settings.h
===================================================================
RCS file: /home/cvs/dovecot/src/master/settings.h,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- settings.h 27 Jan 2003 01:33:40 -0000 1.24
+++ settings.h 30 Jan 2003 17:59:32 -0000 1.25
@@ -1,76 +1,97 @@
#ifndef __SETTINGS_H
#define __SETTINGS_H
-/* common */
-extern char *set_base_dir;
-extern char *set_log_path;
-extern char *set_info_log_path;
-extern char *set_log_timestamp;
+struct settings {
+ /* common */
+ const char *base_dir;
+ const char *log_path;
+ const char *info_log_path;
+ const char *log_timestamp;
-/* general */
-extern unsigned int set_imap_port;
-extern unsigned int set_imaps_port;
-extern char *set_imap_listen;
-extern char *set_imaps_listen;
+ /* general */
+ const char *protocols;
+ const char *imap_listen;
+ const char *imaps_listen;
+ const char *pop3_listen;
+ const char *pop3s_listen;
-extern int set_ssl_disable;
-extern char *set_ssl_cert_file;
-extern char *set_ssl_key_file;
-extern char *set_ssl_parameters_file;
-extern unsigned int set_ssl_parameters_regenerate;
-extern int set_disable_plaintext_auth;
+ int ssl_disable;
+ const char *ssl_cert_file;
+ const char *ssl_key_file;
+ const char *ssl_parameters_file;
+ unsigned int ssl_parameters_regenerate;
+ int disable_plaintext_auth;
-/* login */
-extern char *set_login_executable;
-extern char *set_login_user;
-extern unsigned int set_login_process_size;
-extern char *set_login_dir;
-extern int set_login_chroot;
-extern int set_login_process_per_connection;
-extern unsigned int set_login_processes_count;
-extern unsigned int set_login_max_processes_count;
-extern unsigned int set_max_logging_users;
+ /* login */
+ const char *login_dir;
+ int login_chroot;
-extern uid_t set_login_uid;
-extern gid_t set_login_gid;
+ /* mail */
+ const char *valid_chroot_dirs;
+ unsigned int max_mail_processes;
+ int verbose_proctitle;
-/* imap */
-extern char *set_imap_executable;
-extern unsigned int set_imap_process_size;
-extern char *set_valid_chroot_dirs;
-extern unsigned int set_max_imap_processes;
-extern int set_verbose_proctitle;
+ unsigned int first_valid_uid, last_valid_uid;
+ unsigned int first_valid_gid, last_valid_gid;
-extern unsigned int set_first_valid_uid, set_last_valid_uid;
-extern unsigned int set_first_valid_gid, set_last_valid_gid;
+ const char *default_mail_env;
+ const char *mail_cache_fields;
+ const char *mail_never_cache_fields;
+ unsigned int mailbox_check_interval;
+ int mail_save_crlf;
+ int mail_read_mmaped;
+ int maildir_copy_with_hardlinks;
+ int maildir_check_content_changes;
+ char *mbox_locks;
+ int mbox_read_dotlock;
+ unsigned int mbox_lock_timeout;
+ unsigned int mbox_dotlock_change_timeout;
+ int overwrite_incompatible_index;
+ unsigned int umask;
-extern char *set_default_mail_env;
-extern char *set_mail_cache_fields;
-extern char *set_mail_never_cache_fields;
-extern unsigned int set_mailbox_check_interval;
-extern int set_mail_save_crlf;
-extern int set_mail_read_mmaped;
-extern int set_maildir_copy_with_hardlinks;
-extern int set_maildir_check_content_changes;
-extern char *set_mbox_locks;
-extern int set_mbox_read_dotlock;
-extern unsigned int set_mbox_lock_timeout;
-extern unsigned int set_mbox_dotlock_change_timeout;
-extern int set_overwrite_incompatible_index;
-extern unsigned int set_umask;
+ /* imap */
+ const char *imap_executable;
+ unsigned int imap_process_size;
-/* auth */
-struct auth_config {
- struct auth_config *next;
+ /* imap */
+ const char *pop3_executable;
+ unsigned int pop3_process_size;
- char *name;
- char *mechanisms;
- char *realms;
- char *userdb, *userdb_args;
- char *passdb, *passdb_args;
- char *executable;
- char *user;
- char *chroot;
+ /* .. */
+ gid_t login_gid;
+
+ struct auth_settings *auths;
+ struct login_settings *logins;
+};
+
+struct login_settings {
+ struct login_settings *next;
+
+ const char *name;
+ const char *executable;
+ const char *user;
+
+ int process_per_connection;
+
+ unsigned int process_size;
+ unsigned int processes_count;
+ unsigned int max_processes_count;
+ unsigned int max_logging_users;
+
+ uid_t uid; /* gid must be always same with all login processes */
+};
+
+struct auth_settings {
+ struct auth_settings *next;
+
+ const char *name;
+ const char *mechanisms;
+ const char *realms;
+ const char *userdb;
+ const char *passdb;
+ const char *executable;
+ const char *user;
+ const char *chroot;
int use_cyrus_sasl, verbose;
@@ -78,7 +99,7 @@
unsigned int process_size;
};
-extern struct auth_config *auth_processes_config;
+extern struct settings *set;
void settings_read(const char *path);
Index: ssl-init.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/ssl-init.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- ssl-init.c 27 Jan 2003 01:44:34 -0000 1.9
+++ ssl-init.c 30 Jan 2003 17:59:32 -0000 1.10
@@ -50,7 +50,7 @@
if (pid == 0) {
/* child */
- generate_parameters_file(set_ssl_parameters_file);
+ generate_parameters_file(set->ssl_parameters_file);
exit(0);
} else {
/* parent */
@@ -69,13 +69,13 @@
struct stat st;
time_t regen_time;
- if (set_ssl_parameters_file == NULL || set_ssl_disable || generating)
+ if (set->ssl_parameters_file == NULL || set->ssl_disable || generating)
return;
- if (lstat(set_ssl_parameters_file, &st) < 0) {
+ if (lstat(set->ssl_parameters_file, &st) < 0) {
if (errno != ENOENT) {
i_error("lstat() failed for SSL parameters file %s: %m",
- set_ssl_parameters_file);
+ set->ssl_parameters_file);
return;
}
@@ -83,7 +83,8 @@
}
/* make sure it's new enough and the permissions are correct */
- regen_time = st.st_mtime + (time_t)(set_ssl_parameters_regenerate*3600);
+ regen_time = st.st_mtime +
+ (time_t)(set->ssl_parameters_regenerate*3600);
if (regen_time < ioloop_time || (st.st_mode & 077) != 0 ||
st.st_uid != geteuid() || st.st_gid != getegid())
start_generate_process();
--- imap-process.c DELETED ---
--- imap-process.h DELETED ---
More information about the dovecot-cvs
mailing list