[dovecot-cvs] dovecot/src/master login-process.c,1.7,1.8 settings.c,1.13,1.14 settings.h,1.7,1.8
cras at procontrol.fi
cras at procontrol.fi
Sat Nov 16 07:21:23 EET 2002
- Previous message: [dovecot-cvs] dovecot dovecot-example.conf,1.13,1.14
- Next message: [dovecot-cvs] dovecot/src/login client.c,1.11,1.12 client.h,1.4,1.5 common.h,1.1.1.1,1.2 main.c,1.5,1.6 master.c,1.3,1.4 master.h,1.3,1.4 ssl-proxy.c,1.17,1.18
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /home/cvs/dovecot/src/master
In directory danu:/tmp/cvs-serv15320/src/master
Modified Files:
login-process.c settings.c settings.h
Log Message:
Finally support for handling each login connection in it's own process.
Enabled by default. Also a few bugfixes to master process.
Index: login-process.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/login-process.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- login-process.c 6 Nov 2002 14:20:50 -0000 1.7
+++ login-process.c 16 Nov 2002 05:21:21 -0000 1.8
@@ -14,15 +14,19 @@
#include <unistd.h>
#include <syslog.h>
-typedef struct {
+typedef struct _LoginProcess LoginProcess;
+
+struct _LoginProcess {
+ LoginProcess *prev_nonlisten, *next_nonlisten;
int refcount;
pid_t pid;
int fd;
IO io;
OBuffer *outbuf;
+ unsigned int listening:1;
unsigned int destroyed:1;
-} LoginProcess;
+};
typedef struct {
LoginProcess *process;
@@ -36,7 +40,10 @@
static int auth_id_counter;
static Timeout to;
-static HashTable *processes = NULL;
+
+static HashTable *processes;
+static LoginProcess *oldest_nonlisten_process, *newest_nonlisten_process;
+static unsigned int listening_processes;
static void login_process_destroy(LoginProcess *p);
static void login_process_unref(LoginProcess *p);
@@ -103,6 +110,28 @@
return;
}
+ if (client_fd == -1) {
+ /* just a notification that the login process isn't
+ listening for new connections anymore */
+ if (!p->listening) {
+ i_error("login: received another \"not listening\" "
+ "notification");
+ } else {
+ p->listening = FALSE;
+ listening_processes--;
+
+ p->prev_nonlisten = newest_nonlisten_process;
+
+ if (newest_nonlisten_process != NULL)
+ newest_nonlisten_process->next_nonlisten = p;
+ newest_nonlisten_process = p;
+
+ if (oldest_nonlisten_process == NULL)
+ oldest_nonlisten_process = p;
+ }
+ return;
+ }
+
/* login process isn't trusted, validate all data to make sure
it's not trying to exploit us */
if (!VALIDATE_STR(req.login_tag)) {
@@ -125,7 +154,7 @@
if (auth_process == NULL) {
i_error("login: Authentication process %u doesn't exist",
req.auth_process);
- auth_callback(NULL, &authreq);
+ auth_callback(NULL, authreq);
} else {
auth_process_request(auth_process, authreq->auth_id, req.cookie,
auth_callback, authreq);
@@ -142,26 +171,50 @@
p->refcount = 1;
p->pid = pid;
p->fd = fd;
+ p->listening = TRUE;
p->io = io_add(fd, IO_READ, login_process_input, p);
p->outbuf = o_buffer_create_file(fd, default_pool,
sizeof(MasterReply)*10,
IO_PRIORITY_DEFAULT, FALSE);
hash_insert(processes, POINTER_CAST(pid), p);
+ listening_processes++;
return p;
}
+void login_process_remove_from_lists(LoginProcess *p)
+{
+ if (p == oldest_nonlisten_process)
+ 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;
+ else
+ p->next_nonlisten->prev_nonlisten = p->prev_nonlisten;
+
+ p->next_nonlisten = p->prev_nonlisten = NULL;
+}
+
static void login_process_destroy(LoginProcess *p)
{
if (p->destroyed)
return;
p->destroyed = TRUE;
+ if (p->listening)
+ listening_processes--;
+
o_buffer_close(p->outbuf);
io_remove(p->io);
(void)close(p->fd);
+ if (!p->listening)
+ login_process_remove_from_lists(p);
+
hash_remove(processes, POINTER_CAST(p->pid));
+
login_process_unref(p);
}
@@ -180,6 +233,12 @@
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 (set_login_uid == 0)
i_fatal("Login process must not run as root");
@@ -249,8 +308,13 @@
if (set_disable_plaintext_auth)
putenv("DISABLE_PLAINTEXT_AUTH=1");
- putenv((char *) t_strdup_printf("MAX_LOGGING_USERS=%d",
- set_max_logging_users));
+ if (set_login_process_per_connection) {
+ putenv("PROCESS_PER_CONNECTION=1");
+ putenv("MAX_LOGGING_USERS=1");
+ } else {
+ putenv((char *) t_strdup_printf("MAX_LOGGING_USERS=%d",
+ set_max_logging_users));
+ }
/* hide the path, it's ugly */
argv[0] = strrchr(set_login_executable, '/');
@@ -280,14 +344,17 @@
{
/* 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 (hash_size(processes) < set_login_processes_count)
+ if (listening_processes < set_login_processes_count)
(void)create_login_process();
}
void login_processes_init(void)
{
auth_id_counter = 0;
- processes = hash_create(default_pool, 128, NULL, NULL);
+ listening_processes = 0;
+ oldest_nonlisten_process = newest_nonlisten_process = NULL;
+
+ processes = hash_create(default_pool, 128, NULL, NULL);
to = timeout_add(1000, login_processes_start_missing, NULL);
}
Index: settings.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/settings.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- settings.c 12 Nov 2002 05:27:30 -0000 1.13
+++ settings.c 16 Nov 2002 05:21:21 -0000 1.14
@@ -39,6 +39,8 @@
{ "login_user", SET_STR, &set_login_user },
{ "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 },
@@ -88,7 +90,8 @@
char *set_login_dir = PKG_RUNDIR;
int set_login_chroot = TRUE;
-unsigned int set_login_processes_count = 1;
+int set_login_process_per_connection = TRUE;
+unsigned int set_login_processes_count = 3;
unsigned int set_max_logging_users = 256;
uid_t set_login_uid; /* generated from set_login_user */
@@ -176,11 +179,18 @@
if (access(set_login_dir, X_OK) < 0)
i_fatal("Can't access login directory %s: %m", 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_first_valid_uid < set_last_valid_uid)
+ if (set_max_logging_users < 1)
+ i_fatal("max_logging_users must be at least 1");
+
+ 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_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");
auth_settings_verify();
Index: settings.h
===================================================================
RCS file: /home/cvs/dovecot/src/master/settings.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- settings.h 12 Nov 2002 05:27:30 -0000 1.7
+++ settings.h 16 Nov 2002 05:21:21 -0000 1.8
@@ -20,6 +20,7 @@
extern char *set_login_user;
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_max_logging_users;
- Previous message: [dovecot-cvs] dovecot dovecot-example.conf,1.13,1.14
- Next message: [dovecot-cvs] dovecot/src/login client.c,1.11,1.12 client.h,1.4,1.5 common.h,1.1.1.1,1.2 main.c,1.5,1.6 master.c,1.3,1.4 master.h,1.3,1.4 ssl-proxy.c,1.17,1.18
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list