[dovecot-cvs] dovecot/src/master imap-process.h,NONE,1.1 master-login-interface.h,NONE,1.1 Makefile.am,1.6,1.7 auth-process.c,1.27,1.28 auth-process.h,1.7,1.8 common.h,1.10,1.11 imap-process.c,1.23,1.24 login-process.c,1.29,1.30 login-process.h,1.4,1.5 Message-Id: <20030127013343.20CE1238E1@danu.procontrol.fi>

cras at procontrol.fi cras at procontrol.fi
Mon Jan 27 03:33:43 EET 2003


Update of /home/cvs/dovecot/src/master
In directory danu:/tmp/cvs-serv22317/src/master

Modified Files:
	Makefile.am auth-process.c auth-process.h common.h 
	imap-process.c login-process.c login-process.h main.c 
	settings.c settings.h 
Added Files:
	imap-process.h master-login-interface.h 
Removed Files:
	master-interface.h 
Log Message:
We have now separate "userdb" and "passdb". They aren't tied to each others
in any way, so it's possible to use whatever user database with whatever
password database.

Added "static" userdb, which uses same uid/gid for everyone and generates
home directory from given template. This could be useful with PAM, although
insecure since everyone uses same uid.

Not too well tested, and userdb/passdb API still needs to be changed to
asynchronous for sql/ldap/etc lookups.



--- NEW FILE: imap-process.h ---
#ifndef __IMAP_PROCESS_H
#define __IMAP_PROCESS_H

struct auth_master_reply;

int create_imap_process(int socket, struct ip_addr *ip,
			struct auth_master_reply *reply,
			const unsigned char *data);
void imap_process_destroyed(pid_t pid);

#endif

--- NEW FILE: master-login-interface.h ---
#ifndef __MASTER_LOGIN_INTERFACE_H
#define __MASTER_LOGIN_INTERFACE_H

#include "network.h"

#define LOGIN_MASTER_SOCKET_FD 0
#define LOGIN_IMAP_LISTEN_FD 1
#define LOGIN_IMAPS_LISTEN_FD 2

struct master_login_request {
	unsigned int tag;

	unsigned int auth_pid;
	unsigned int auth_id;

	struct ip_addr ip;
};

struct master_login_reply {
	unsigned int tag;
	int success;
};

#endif

Index: Makefile.am
===================================================================
RCS file: /home/cvs/dovecot/src/master/Makefile.am,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- Makefile.am	26 Nov 2002 13:31:22 -0000	1.6
+++ Makefile.am	27 Jan 2003 01:33:40 -0000	1.7
@@ -26,7 +26,8 @@
 noinst_HEADERS = \
 	auth-process.h \
 	common.h \
+	imap-process.h \
 	login-process.h \
-	master-interface.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.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- auth-process.c	21 Jan 2003 07:58:49 -0000	1.27
+++ auth-process.c	27 Jan 2003 01:33:40 -0000	1.28
@@ -5,6 +5,7 @@
 #include "env-util.h"
 #include "fd-close-on-exec.h"
 #include "network.h"
+#include "istream.h"
 #include "ostream.h"
 #include "restrict-access.h"
 #include "restrict-process-size.h"
@@ -16,6 +17,9 @@
 #include <syslog.h>
 #include <sys/stat.h>
 
+#define MAX_INBUF_SIZE \
+	(sizeof(struct auth_master_reply) + AUTH_MASTER_MAX_REPLY_DATA_SIZE)
+
 struct auth_process {
 	struct auth_process *next;
 
@@ -23,113 +27,154 @@
 	pid_t pid;
 	int fd;
 	struct io *io;
+	struct istream *input;
 	struct ostream *output;
 
-	unsigned int reply_pos;
-	char reply_buf[sizeof(struct auth_cookie_reply_data)];
+	struct auth_master_reply auth_reply;
 
-	struct waiting_request *requests, **next_request;
+	struct hash_table *requests;
 
 	unsigned int initialized:1;
-};
-
-struct waiting_request {
-        struct waiting_request *next;
-	unsigned int id;
-
-	auth_callback_t callback;
-	void *context;
+	unsigned int in_auth_reply:1;
 };
 
 static struct timeout *to;
 static struct auth_process *processes;
+static unsigned int auth_tag;
 
 static void auth_process_destroy(struct auth_process *p);
 
-static void push_request(struct auth_process *process, unsigned int id,
-			 auth_callback_t callback, void *context)
+static int handle_request(struct auth_process *process,
+			  struct auth_master_reply *reply,
+			  const unsigned char *data)
 {
-	struct waiting_request *req;
+	size_t nul_pos;
+	void *context;
 
-	req = i_new(struct waiting_request, 1);
-	req->id = id;
-	req->callback = callback;
-	req->context = context;
+	context = hash_lookup(process->requests, POINTER_CAST(reply->tag));
+	if (context == NULL) {
+		i_error("Auth process %s sent unrequested reply with tag %u",
+			dec2str(process->pid), reply->tag);
+		return TRUE;
+	}
 
-	*process->next_request = req;
-	process->next_request = &req->next;
+	/* make sure the reply looks OK */
+	if (reply->data_size == 0) {
+		nul_pos = 0;
+		data = (const unsigned char *) "";
+	} else {
+		nul_pos = reply->data_size-1;
+	}
+
+	if (data[nul_pos] != '\0') {
+		i_error("Auth process %s sent invalid reply",
+			dec2str(process->pid));
+		return FALSE;
+	}
+
+	/* fix the request so that all the values point to \0 terminated
+	   strings */
+	if (reply->system_user_idx >= reply->data_size)
+		reply->system_user_idx = nul_pos;
+	if (reply->virtual_user_idx >= reply->data_size)
+		reply->virtual_user_idx = nul_pos;
+	if (reply->home_idx >= reply->data_size)
+		reply->home_idx = nul_pos;
+	if (reply->mail_idx >= reply->data_size)
+		reply->mail_idx = nul_pos;
+
+	auth_master_callback(reply, data, context);
+	hash_remove(process->requests, POINTER_CAST(reply->tag));
+	return TRUE;
 }
 
-static void pop_request(struct auth_process *process,
-			struct auth_cookie_reply_data *reply)
+void auth_process_request(struct auth_process *process, unsigned int login_pid,
+			  unsigned int login_id, void *context)
 {
-	struct waiting_request *req;
-
-	req = process->requests;
-	if (req == NULL) {
-		i_warning("imap-auth %s sent us unrequested reply for id %d",
-			  dec2str(process->pid), reply->id);
-		return;
-	}
+	struct auth_master_request req;
+	ssize_t ret;
 
-	if (reply->id != req->id) {
-		i_fatal("imap-auth %s sent invalid id for reply "
-			"(got %d, expecting %d)",
-			dec2str(process->pid), reply->id, req->id);
-	}
+	req.tag = ++auth_tag;
+	req.id = login_id;
+	req.login_pid = login_pid;
 
-	/* auth process isn't trusted, validate all data to make sure
-	   it's not trying to exploit us */
-	if (!VALIDATE_STR(reply->system_user) ||
-	    !VALIDATE_STR(reply->virtual_user) || !VALIDATE_STR(reply->mail) ||
-	    !VALIDATE_STR(reply->home)) {
-		i_error("auth: Received corrupted data");
+	ret = o_stream_send(process->output, &req, sizeof(req));
+	if ((size_t)ret != sizeof(req)) {
+		if (ret >= 0) {
+			/* FIXME: well .. I'm not sure if it'd be better to
+			   just block here. I don't think this condition should
+			   happen often, so this could mean that the auth
+			   process is stuck. Or that the computer is just
+			   too heavily loaded. Possibility to block infinitely
+			   is annoying though, so for now don't do it. */
+			i_warning("Auth process %s transmit buffer full, "
+				  "killing..", dec2str(process->pid));
+		}
 		auth_process_destroy(process);
 		return;
 	}
 
-	process->requests = req->next;
-	if (process->requests == NULL)
-		process->next_request = &process->requests;
-
-	req->callback(reply, req->context);
-
-	i_free(req);
+	hash_insert(process->requests, POINTER_CAST(req.tag), context);
 }
 
-static void auth_process_input(void *context, int fd,
+static void auth_process_input(void *context, int fd __attr_unused__,
 			       struct io *io __attr_unused__)
 {
 	struct auth_process *p = context;
-	int ret;
+	const unsigned char *data;
+	size_t size;
 
-	ret = net_receive(fd, p->reply_buf + p->reply_pos,
-			  sizeof(p->reply_buf) - p->reply_pos);
-	if (ret < 0) {
+	switch (i_stream_read(p->input)) {
+	case 0:
+		return;
+	case -1:
 		/* disconnected */
 		auth_process_destroy(p);
 		return;
+	case -2:
+		/* buffer full */
+		i_error("BUG: Auth process %s sent us more than %d "
+			"bytes of data", dec2str(p->pid), (int)MAX_INBUF_SIZE);
+		auth_process_destroy(p);
+		return;
 	}
 
 	if (!p->initialized) {
-		if (p->reply_buf[0] != 'O') {
+		data = i_stream_get_data(p->input, &size);
+		i_assert(size > 0);
+
+		if (data[0] != 'O') {
 			i_fatal("Auth process sent invalid initialization "
 				"notification");
 		}
 
+		i_stream_skip(p->input, 1);
+
 		p->initialized = TRUE;
+	}
 
-		ret--;
-		memmove(p->reply_buf, p->reply_buf + 1, ret);
+	if (!p->in_auth_reply) {
+		data = i_stream_get_data(p->input, &size);
+		if (size < sizeof(struct auth_master_reply))
+			return;
+
+		p->in_auth_reply = TRUE;
+		memcpy(&p->auth_reply, data, sizeof(p->auth_reply));
+
+		i_stream_skip(p->input, sizeof(p->auth_reply));
 	}
 
-	p->reply_pos += ret;
-	if (p->reply_pos < sizeof(p->reply_buf))
+	data = i_stream_get_data(p->input, &size);
+	if (p->auth_reply.data_size < size)
 		return;
 
 	/* reply is now read */
-	pop_request(p, (struct auth_cookie_reply_data *) p->reply_buf);
-	p->reply_pos = 0;
+	if (!handle_request(p, &p->auth_reply, data))
+		auth_process_destroy(p);
+	else {
+		p->in_auth_reply = FALSE;
+		i_stream_skip(p->input, p->auth_reply.data_size);
+	}
 }
 
 static struct auth_process *
@@ -144,23 +189,29 @@
 	p->pid = pid;
 	p->fd = fd;
 	p->io = io_add(fd, IO_READ, auth_process_input, p);
+	p->input = i_stream_create_file(fd, default_pool,
+					MAX_INBUF_SIZE, FALSE);
 	p->output = o_stream_create_file(fd, default_pool,
-				sizeof(struct auth_cookie_request_data)*100,
-				IO_PRIORITY_DEFAULT, FALSE);
-
-	p->next_request = &p->requests;
+					 sizeof(struct auth_master_request)*100,
+					 IO_PRIORITY_DEFAULT, FALSE);
+	p->requests = hash_create(default_pool, default_pool, 0, NULL, NULL);
 
 	p->next = processes;
 	processes = p;
 	return p;
 }
 
+static void request_hash_destroy(void *key __attr_unused__,
+				 void *value, void *context __attr_unused__)
+{
+	auth_master_callback(NULL, NULL, value);
+}
+
 static void auth_process_destroy(struct auth_process *p)
 {
 	struct auth_process **pos;
-	struct waiting_request *next;
 
-	if (!p->initialized) {
+	if (!p->initialized && io_loop_is_running(ioloop)) {
 		i_error("Auth process died too early - shutting down");
 		io_loop_stop(ioloop);
 	}
@@ -172,15 +223,12 @@
 		}
 	}
 
-	for (; p->requests != NULL; p->requests = next) {
-		next = p->requests->next;
-
-		p->requests->callback(NULL, p->requests->context);
-		i_free(p->requests);
-	}
-
 	(void)unlink(t_strconcat(set_login_dir, "/", p->name, NULL));
 
+	hash_foreach(p->requests, request_hash_destroy, NULL);
+	hash_destroy(p->requests);
+
+	i_stream_unref(p->input);
 	o_stream_unref(p->output);
 	io_remove(p->io);
 	if (close(p->fd) < 0)
@@ -275,8 +323,10 @@
 	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("USERINFO=", config->userinfo, NULL));
-	env_put(t_strconcat("USERINFO_ARGS=", config->userinfo_args, 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));
 
 	if (config->use_cyrus_sasl)
 		env_put("USE_CYRUS_SASL=1");
@@ -299,33 +349,16 @@
 	return -1;
 }
 
-struct auth_process *auth_process_find(unsigned int id)
+struct auth_process *auth_process_find(unsigned int pid)
 {
 	struct auth_process *p;
 
 	for (p = processes; p != NULL; p = p->next) {
-		if ((unsigned int)p->pid == id)
+		if ((unsigned int)p->pid == pid)
 			return p;
 	}
 
 	return NULL;
-}
-
-void auth_process_request(unsigned int login_pid,
-			  struct auth_process *process, unsigned int id,
-			  unsigned char cookie[AUTH_COOKIE_SIZE],
-			  auth_callback_t callback, void *context)
-{
-	struct auth_cookie_request_data req;
-
-	req.id = id;
-	req.login_pid = login_pid;
-	memcpy(req.cookie, cookie, AUTH_COOKIE_SIZE);
-
-	if (o_stream_send(process->output, &req, sizeof(req)) < 0)
-		auth_process_destroy(process);
-
-	push_request(process, id, callback, context);
 }
 
 static unsigned int auth_process_get_count(const char *name)

Index: auth-process.h
===================================================================
RCS file: /home/cvs/dovecot/src/master/auth-process.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- auth-process.h	11 Jan 2003 19:55:57 -0000	1.7
+++ auth-process.h	27 Jan 2003 01:33:40 -0000	1.8
@@ -1,18 +1,15 @@
 #ifndef __AUTH_PROCESS_H
 #define __AUTH_PROCESS_H
 
-/* cookie_reply is NULL if some error occured */
-typedef void (*auth_callback_t)(struct auth_cookie_reply_data *cookie_reply,
-				void *context);
+void auth_master_callback(struct auth_master_reply *reply,
+			  const unsigned char *data, void *context);
 
 /* Find process for given id */
-struct auth_process *auth_process_find(unsigned int id);
+struct auth_process *auth_process_find(unsigned int pid);
 
 /* Request information about given cookie */
-void auth_process_request(unsigned int login_pid,
-			  struct auth_process *process, unsigned int id,
-			  unsigned char cookie[AUTH_COOKIE_SIZE],
-			  auth_callback_t callback, void *context);
+void auth_process_request(struct auth_process *process, unsigned int login_pid,
+			  unsigned int login_id, void *context);
 
 /* Close any fds used by auth processes */
 void auth_processes_destroy_all(void);

Index: common.h
===================================================================
RCS file: /home/cvs/dovecot/src/master/common.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- common.h	21 Jan 2003 07:58:49 -0000	1.10
+++ common.h	27 Jan 2003 01:33:40 -0000	1.11
@@ -1,12 +1,13 @@
 #ifndef __COMMON_H
 #define __COMMON_H
 
+struct ip_addr;
+
 #include "lib.h"
 #include "hash.h"
 #include "settings.h"
 
-#include "../auth/auth-interface.h"
-#include "master-interface.h"
+#include "../auth/auth-master-interface.h"
 
 enum {
 	PROCESS_TYPE_UNKNOWN,
@@ -33,13 +34,6 @@
 	hash_remove(pids, POINTER_CAST(pid))
 
 void clean_child_process(void);
-
-enum master_reply_result
-create_imap_process(int socket, struct ip_addr *ip,
-		    const char *system_user, const char *virtual_user,
-		    uid_t uid, gid_t gid, const char *home, int chroot,
-		    const char *mail, const char *login_tag);
-void imap_process_destroyed(pid_t pid);
 
 /* misc */
 #define VALIDATE_STR(str) \

Index: imap-process.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/imap-process.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- imap-process.c	5 Jan 2003 13:09:53 -0000	1.23
+++ imap-process.c	27 Jan 2003 01:33:40 -0000	1.24
@@ -1,10 +1,14 @@
 /* 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 "imap-process.h"
 
 #include <stdlib.h>
 #include <unistd.h>
@@ -48,7 +52,7 @@
 	const char *const *chroot_dirs;
 
 	if (*dir == '\0')
-		return TRUE;
+		return FALSE;
 
 	if (set_valid_chroot_dirs == NULL)
 		return FALSE;
@@ -68,8 +72,7 @@
 				   const char *home)
 {
 	string_t *str;
-	const char *p, *var;
-	unsigned int width;
+	const char *p;
 
 	str = t_str_new(256);
 
@@ -91,93 +94,48 @@
 	}
 
 	/* expand %vars */
-	for (; *env != '\0'; env++) {
-		if (*env != '%')
-			str_append_c(str, *env);
-		else {
-			width = 0;
-			while (env[1] >= '0' && env[1] <= '9') {
-				width = width*10 + (env[1] - '0');
-				env++;
-			}
-
-			switch (env[1]) {
-			case '%':
-				var = "%";
-				break;
-			case 'u':
-				var = user;
-				break;
-			case 'h':
-				var = home;
-				break;
-			case 'n':
-				var = t_strcut(user, '@');
-				break;
-			case 'd':
-				var = strchr(user, '@');
-				if (var != NULL) var++;
-				break;
-			default:
-				var = NULL;
-				break;
-			}
-
-			if (var == NULL)
-				str_append_c(str, '%');
-			else {
-				env++;
-				if (width == 0)
-					str_append(str, var);
-				else
-					str_append_n(str, var, width);
-			}
-		}
-	}
-
-
+        var_expand(str, env, user, home);
 	return str_c(str);
 }
 
-enum master_reply_result
-create_imap_process(int socket, struct ip_addr *ip,
-		    const char *system_user, const char *virtual_user,
-		    uid_t uid, gid_t gid, const char *home, int chroot,
-		    const char *mail, const char *login_tag)
+int create_imap_process(int socket, struct ip_addr *ip,
+			struct auth_master_reply *reply,
+			const unsigned char *data)
 {
 	static char *argv[] = { NULL, NULL, NULL };
-	const char *host;
+	const char *host, *mail;
 	char title[1024];
 	pid_t pid;
 	int i, err;
 
 	if (imap_process_count == set_max_imap_processes) {
 		i_error("Maximum number of imap processes exceeded");
-		return MASTER_RESULT_INTERNAL_FAILURE;
+		return FALSE;
 	}
 
-	if (!validate_uid_gid(uid, gid))
-		return MASTER_RESULT_FAILURE;
+	if (!validate_uid_gid(reply->uid, reply->gid))
+		return FALSE;
 
-	if (chroot && !validate_chroot(home))
-		return MASTER_RESULT_FAILURE;
+	if (reply->chroot && !validate_chroot(data + reply->home_idx))
+		return FALSE;
 
 	pid = fork();
 	if (pid < 0) {
 		i_error("fork() failed: %m");
-		return MASTER_RESULT_INTERNAL_FAILURE;
+		return FALSE;
 	}
 
 	if (pid != 0) {
 		/* master */
 		imap_process_count++;
 		PID_ADD_PROCESS_TYPE(pid, PROCESS_TYPE_IMAP);
-		return MASTER_RESULT_SUCCESS;
+		return TRUE;
 	}
 
 	clean_child_process();
 
 	/* move the imap socket into stdin, stdout and stderr fds */
+	fd_close_on_exec(socket, FALSE);
 	for (i = 0; i < 3; i++) {
 		if (dup2(socket, i) < 0)
 			i_fatal("imap: dup2(%d) failed: %m", i);
@@ -188,10 +146,13 @@
 
 	/* setup environment - set the most important environment first
 	   (paranoia about filling up environment without noticing) */
-	restrict_access_set_env(system_user, uid, gid, chroot ? home : NULL);
+	restrict_access_set_env(data + reply->system_user_idx,
+				reply->uid, reply->gid,
+				reply->chroot ? data + reply->home_idx : NULL);
 	restrict_process_size(set_imap_process_size);
 
-	env_put(t_strconcat("HOME=", home, NULL));
+	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));
@@ -221,22 +182,23 @@
 	/* 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 = data + reply->mail_idx;
+	if (*mail == '\0' && set_default_mail_env != NULL) {
 		mail = expand_mail_env(set_default_mail_env,
-				       virtual_user, home);
-		env_put(t_strconcat("MAIL=", mail, NULL));
+				       data + reply->virtual_user_idx,
+				       data + reply->home_idx);
 	}
 
 	env_put(t_strconcat("MAIL=", mail, NULL));
-	env_put(t_strconcat("USER=", virtual_user, NULL));
-	env_put(t_strconcat("LOGIN_TAG=", login_tag, 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]", virtual_user, host);
+		i_snprintf(title, sizeof(title), "[%s %s]",
+			   data + reply->virtual_user_idx, host);
 		argv[1] = title;
 	}
 
@@ -257,7 +219,7 @@
 	i_fatal_status(FATAL_EXEC, "execv(%s) failed: %m", set_imap_executable);
 
 	/* not reached */
-	return 0;
+	return FALSE;
 }
 
 void imap_process_destroyed(pid_t pid __attr_unused__)

Index: login-process.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/login-process.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- login-process.c	21 Jan 2003 07:58:49 -0000	1.29
+++ login-process.c	27 Jan 2003 01:33:40 -0000	1.30
@@ -11,7 +11,8 @@
 #include "restrict-process-size.h"
 #include "login-process.h"
 #include "auth-process.h"
-#include "master-interface.h"
+#include "imap-process.h"
+#include "master-login-interface.h"
 
 #include <unistd.h>
 #include <syslog.h>
@@ -31,12 +32,12 @@
 
 struct login_auth_request {
 	struct login_process *process;
-	unsigned int login_id;
-	unsigned int auth_id;
+	unsigned int tag;
+
+	unsigned int login_tag;
 	int fd;
 
 	struct ip_addr ip;
-	char login_tag[LOGIN_TAG_SIZE];
 };
 
 static unsigned int auth_id_counter;
@@ -51,38 +52,30 @@
 static void login_process_destroy(struct login_process *p);
 static void login_process_unref(struct login_process *p);
 
-static void auth_callback(struct auth_cookie_reply_data *cookie_reply,
-			  void *context)
+void auth_master_callback(struct auth_master_reply *reply,
+			  const unsigned char *data, void *context)
 {
 	struct login_auth_request *request = context;
-        struct login_process *process;
-	struct master_reply reply;
+	struct master_login_reply master_reply;
 
-	if (cookie_reply == NULL || !cookie_reply->success)
-		reply.result = MASTER_RESULT_FAILURE;
+	if (reply == NULL || !reply->success)
+		master_reply.success = FALSE;
 	else {
-		reply.result = create_imap_process(request->fd,
-						   &request->ip,
-						   cookie_reply->system_user,
-						   cookie_reply->virtual_user,
-						   cookie_reply->uid,
-						   cookie_reply->gid,
-						   cookie_reply->home,
-						   cookie_reply->chroot,
-						   cookie_reply->mail,
-						   request->login_tag);
+		master_reply.success = create_imap_process(request->fd,
+							   &request->ip,
+							   reply, data);
 	}
 
 	/* reply to login */
-	reply.id = request->login_id;
+	master_reply.tag = request->login_tag;
 
-	process = request->process;
-	if (o_stream_send(process->output, &reply, sizeof(reply)) < 0)
-		login_process_destroy(process);
+	if (o_stream_send(request->process->output, &master_reply,
+			  sizeof(master_reply)) < 0)
+		login_process_destroy(request->process);
 
 	if (close(request->fd) < 0)
 		i_error("close(imap client) failed: %m");
-	login_process_unref(process);
+	login_process_unref(request->process);
 	i_free(request);
 }
 
@@ -113,7 +106,7 @@
 	struct login_process *p = context;
 	struct auth_process *auth_process;
 	struct login_auth_request *authreq;
-	struct master_request req;
+	struct master_login_request req;
 	int client_fd, ret;
 
 	ret = fd_read(p->fd, &req, sizeof(req), &client_fd);
@@ -148,36 +141,25 @@
 		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)) {
-		i_error("login: Received corrupted data");
-		if (close(client_fd) < 0)
-			i_error("close(imap client) failed: %m");
-		login_process_destroy(p);
-		return;
-	}
+	fd_close_on_exec(client_fd, TRUE);
 
 	/* ask the cookie from the auth process */
 	authreq = i_new(struct login_auth_request, 1);
 	p->refcount++;
 	authreq->process = p;
-	authreq->login_id = req.id;
-	authreq->auth_id = ++auth_id_counter;
+	authreq->tag = ++auth_id_counter;
+	authreq->login_tag = req.tag;
 	authreq->fd = client_fd;
-	memcpy(&authreq->ip, &req.ip, sizeof(struct ip_addr));
-	if (strocpy(authreq->login_tag, req.login_tag,
-		    sizeof(authreq->login_tag)) < 0)
-		i_panic("login_tag overflow");
+	authreq->ip = req.ip;
 
-	auth_process = auth_process_find(req.auth_process);
+	auth_process = auth_process_find(req.auth_pid);
 	if (auth_process == NULL) {
 		i_error("login: Authentication process %u doesn't exist",
-			req.auth_process);
-		auth_callback(NULL, authreq);
+			req.auth_pid);
+		auth_master_callback(NULL, NULL, authreq);
 	} else {
-		auth_process_request(p->pid, auth_process, authreq->auth_id,
-				     req.cookie, auth_callback, authreq);
+		auth_process_request(auth_process, p->pid,
+				     req.auth_id, authreq);
 	}
 }
 
@@ -194,7 +176,7 @@
 	p->listening = TRUE;
 	p->io = io_add(fd, IO_READ, login_process_input, p);
 	p->output = o_stream_create_file(fd, default_pool,
-					 sizeof(struct master_reply)*10,
+					 sizeof(struct master_login_reply)*10,
 					 IO_PRIORITY_DEFAULT, FALSE);
 
 	hash_insert(processes, POINTER_CAST(pid), p);
@@ -223,7 +205,7 @@
 		return;
 	p->destroyed = TRUE;
 
-	if (!p->initialized) {
+	if (!p->initialized && io_loop_is_running(ioloop)) {
 		i_error("Login process died too early - shutting down");
 		io_loop_stop(ioloop);
 	}

Index: login-process.h
===================================================================
RCS file: /home/cvs/dovecot/src/master/login-process.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- login-process.h	1 Dec 2002 15:39:21 -0000	1.4
+++ login-process.h	27 Jan 2003 01:33:40 -0000	1.5
@@ -1,5 +1,5 @@
-#ifndef __CHILD_LOGIN_H
-#define __CHILD_LOGIN_H
+#ifndef __LOGIN_PROCESS_H
+#define __LOGIN_PROCESS_H
 
 void login_process_abormal_exit(pid_t pid);
 void login_processes_destroy_all(void);

Index: main.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/main.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- main.c	21 Jan 2003 07:58:49 -0000	1.28
+++ main.c	27 Jan 2003 01:33:40 -0000	1.29
@@ -9,6 +9,7 @@
 
 #include "auth-process.h"
 #include "login-process.h"
+#include "imap-process.h"
 #include "ssl-init.h"
 
 #include <stdio.h>

Index: settings.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/settings.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- settings.c	21 Jan 2003 07:40:54 -0000	1.42
+++ settings.c	27 Jan 2003 01:33:40 -0000	1.43
@@ -342,8 +342,10 @@
 	i_free(auth->name);
 	i_free(auth->mechanisms);
 	i_free(auth->realms);
-	i_free(auth->userinfo);
-	i_free(auth->userinfo_args);
+	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);
@@ -380,8 +382,6 @@
 	/* check the easy string values first */
 	if (strcmp(key, "auth_mechanisms") == 0)
 		ptr = &auth->mechanisms;
-	else if (strcmp(key, "auth_methods") == 0) /* backwards compatibility */
-		ptr = &auth->mechanisms;
 	else if (strcmp(key, "auth_realms") == 0)
 		ptr = &auth->realms;
 	else if (strcmp(key, "auth_executable") == 0)
@@ -399,18 +399,33 @@
 		return NULL;
 	}
 
-	if (strcmp(key, "auth_userinfo") == 0) {
-		/* split it into userinfo + userinfo_args */
+	if (strcmp(key, "auth_userdb") == 0) {
+		/* split it into userdb + userdb_args */
 		for (p = value; *p != ' ' && *p != '\0'; )
 			p++;
 
-		i_free(auth->userinfo);
-		auth->userinfo = i_strdup_until(value, p);
+		i_free(auth->userdb);
+		auth->userdb = i_strdup_until(value, p);
 
 		while (*p == ' ') p++;
 
-		i_free(auth->userinfo_args);
-		auth->userinfo_args = i_strdup(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++;
+
+		i_free(auth->passdb);
+		auth->passdb = i_strdup_until(value, p);
+
+		while (*p == ' ') p++;
+
+		i_free(auth->passdb_args);
+		auth->passdb_args = i_strdup(p);
 		return NULL;
 	}
 

Index: settings.h
===================================================================
RCS file: /home/cvs/dovecot/src/master/settings.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- settings.h	21 Jan 2003 07:40:54 -0000	1.23
+++ settings.h	27 Jan 2003 01:33:40 -0000	1.24
@@ -66,7 +66,8 @@
 	char *name;
 	char *mechanisms;
 	char *realms;
-	char *userinfo, *userinfo_args;
+	char *userdb, *userdb_args;
+	char *passdb, *passdb_args;
 	char *executable;
 	char *user;
 	char *chroot;

--- master-interface.h DELETED ---




More information about the dovecot-cvs mailing list