[dovecot-cvs] dovecot/src/master auth-process.c, 1.61, 1.62 auth-process.h, 1.8, 1.9 common.h, 1.19, 1.20 login-process.c, 1.59, 1.60 mail-process.c, 1.60, 1.61 mail-process.h, 1.6, 1.7

cras at dovecot.org cras at dovecot.org
Wed Oct 13 19:38:38 EEST 2004


Update of /var/lib/cvs/dovecot/src/master
In directory talvi:/tmp/cvs-serv8894/master

Modified Files:
	auth-process.c auth-process.h common.h login-process.c 
	mail-process.c mail-process.h 
Log Message:
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
replacement server if needed by someone. Also cleaned up/made more
consistent auth code. The new code could still use some cleaning though..



Index: auth-process.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/auth-process.c,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -d -r1.61 -r1.62
--- auth-process.c	10 Oct 2004 13:55:13 -0000	1.61
+++ auth-process.c	13 Oct 2004 16:38:35 -0000	1.62
@@ -7,6 +7,7 @@
 #include "network.h"
 #include "istream.h"
 #include "ostream.h"
+#include "str.h"
 #include "restrict-access.h"
 #include "restrict-process-size.h"
 #include "auth-process.h"
@@ -18,8 +19,8 @@
 #include <syslog.h>
 #include <sys/stat.h>
 
-#define MAX_INBUF_SIZE \
-	(sizeof(struct auth_master_reply) + AUTH_MASTER_MAX_REPLY_DATA_SIZE)
+#define MAX_INBUF_SIZE 8192
+#define MAX_OUTBUF_SIZE 65536
 
 struct auth_process_group {
 	struct auth_process_group *next;
@@ -41,8 +42,6 @@
 	struct istream *input;
 	struct ostream *output;
 
-	struct auth_master_reply auth_reply;
-
 	struct hash_table *requests;
 
 	unsigned int external:1;
@@ -56,145 +55,171 @@
 
 static void auth_process_destroy(struct auth_process *p);
 
-static int handle_reply(struct auth_process *process,
-			struct auth_master_reply *reply,
-			const unsigned char *data)
+void auth_process_request(struct auth_process *process, unsigned int login_pid,
+			  unsigned int login_id, void *context)
+{
+	string_t *str;
+	ssize_t ret;
+
+	t_push();
+	str = t_str_new(256);
+	str_printfa(str, "REQUEST\t%u\t%u\t%u\n",
+		    ++auth_tag, login_pid, login_id);
+
+	ret = o_stream_send(process->output, str_data(str), str_len(str));
+	if (ret != (ssize_t)str_len(str)) {
+		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);
+	} else {
+		hash_insert(process->requests, POINTER_CAST(auth_tag), context);
+	}
+	t_pop();
+}
+
+static int
+auth_process_input_user(struct auth_process *process, const char *args)
 {
-	size_t nul_pos;
 	void *context;
+	const char *const *list;
+	unsigned int id;
 
-	context = hash_lookup(process->requests, POINTER_CAST(reply->tag));
+	/* <id> <userid> [..] */
+
+	list = t_strsplit(args, "\t");
+	if (list[0] == NULL || list[1] == NULL) {
+		i_error("BUG: Auth process %s sent corrupted USER line",
+			dec2str(process->pid));
+		return FALSE;
+	}
+	id = (unsigned int)strtoul(list[0], NULL, 10);
+
+	context = hash_lookup(process->requests, POINTER_CAST(id));
 	if (context == NULL) {
-		i_error("Auth process %s sent unrequested reply with tag %u",
-			dec2str(process->pid), reply->tag);
-		return TRUE;
+		i_error("BUG: Auth process %s sent unrequested reply with ID "
+			"%u", dec2str(process->pid), id);
+		return FALSE;
 	}
 
-	/* 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;
+	auth_master_callback(list[1], list + 2, context);
+	hash_remove(process->requests, POINTER_CAST(id));
+	return TRUE;
+}
+
+static int
+auth_process_input_notfound(struct auth_process *process, const char *args)
+{
+	void *context;
+	unsigned int id;
+
+	id = (unsigned int)strtoul(args, NULL, 10);
+
+	context = hash_lookup(process->requests, POINTER_CAST(id));
+	if (context == NULL) {
+		i_error("BUG: Auth process %s sent unrequested reply with ID "
+			"%u", dec2str(process->pid), id);
+		return FALSE;
 	}
 
-	if (data[nul_pos] != '\0') {
-		i_error("Auth process %s sent invalid reply",
-			dec2str(process->pid));
+	auth_master_callback(NULL, NULL, context);
+	hash_remove(process->requests, POINTER_CAST(id));
+	return TRUE;
+}
+
+static int
+auth_process_input_spid(struct auth_process *process, const char *args)
+{
+	unsigned int pid;
+
+	if (process->initialized) {
+		i_error("BUG: Authentication server re-handshaking");
 		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->chroot_idx >= reply->data_size)
-		reply->chroot_idx = nul_pos;
-	if (reply->mail_idx >= reply->data_size)
-		reply->mail_idx = nul_pos;
+	pid = (unsigned int)strtoul(args, NULL, 10);
+	if (pid == 0) {
+		i_error("BUG: Authentication server said it's PID 0");
+		return FALSE;
+	}
 
-	auth_master_callback(reply, data, context);
-	hash_remove(process->requests, POINTER_CAST(reply->tag));
+	process->pid = pid;
+	process->initialized = TRUE;
 	return TRUE;
 }
 
-void auth_process_request(struct auth_process *process, unsigned int login_pid,
-			  unsigned int login_id, void *context)
+static int
+auth_process_input_fail(struct auth_process *process, const char *args)
 {
-	struct auth_master_request req;
-	ssize_t ret;
+	void *context;
+ 	const char *error;
+	unsigned int id;
 
-	req.tag = ++auth_tag;
-	req.id = login_id;
-	req.client_pid = login_pid;
+	error = strchr(args, '\t');
+	if (error != NULL)
+		error++;
 
-	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;
+	id = (unsigned int)strtoul(args, NULL, 10);
+
+	context = hash_lookup(process->requests, POINTER_CAST(id));
+	if (context == NULL) {
+		i_error("BUG: Auth process %s sent unrequested reply with ID "
+			"%u", dec2str(process->pid), id);
+		return FALSE;
 	}
 
-	hash_insert(process->requests, POINTER_CAST(req.tag), context);
+	auth_master_callback(NULL, NULL, context);
+	hash_remove(process->requests, POINTER_CAST(id));
+	return TRUE;
 }
 
 static void auth_process_input(void *context)
 {
-	struct auth_process *p = context;
-	const unsigned char *data;
-	size_t size;
+	struct auth_process *process = context;
+	const char *line;
+	int ret;
 
-	switch (i_stream_read(p->input)) {
+	switch (i_stream_read(process->input)) {
 	case 0:
 		return;
 	case -1:
 		/* disconnected */
-		auth_process_destroy(p);
+		auth_process_destroy(process);
 		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);
+			"bytes of data", dec2str(process->pid),
+			(int)MAX_INBUF_SIZE);
+		auth_process_destroy(process);
 		return;
 	}
 
-	if (!p->initialized) {
-		struct auth_master_handshake_reply rec;
-
-		data = i_stream_get_data(p->input, &size);
-		if (size < sizeof(rec))
-			return;
-
-		memcpy(&rec, data, sizeof(rec));
-		i_stream_skip(p->input, sizeof(rec));
-
-		if (rec.server_pid == 0) {
-			i_fatal("Auth process sent invalid initialization "
-				"notification");
-		}
-
-		p->pid = rec.server_pid;
-		p->initialized = TRUE;
-	}
-
-	for (;;) {
-		if (!p->in_auth_reply) {
-			data = i_stream_get_data(p->input, &size);
-			if (size < sizeof(p->auth_reply))
-				break;
-
-			p->in_auth_reply = TRUE;
-			memcpy(&p->auth_reply, data, sizeof(p->auth_reply));
-
-			i_stream_skip(p->input, sizeof(p->auth_reply));
-		}
-
-		data = i_stream_get_data(p->input, &size);
-		if (size < p->auth_reply.data_size)
-			break;
+	while ((line = i_stream_next_line(process->input)) != NULL) {
+		t_push();
+		if (strncmp(line, "USER\t", 5) == 0)
+			ret = auth_process_input_user(process, line + 5);
+		else if (strncmp(line, "NOTFOUND\t", 9) == 0)
+			ret = auth_process_input_notfound(process, line + 9);
+		else if (strncmp(line, "FAIL\t", 5) == 0)
+			ret = auth_process_input_fail(process, line + 5);
+		else if (strncmp(line, "SPID\t", 5) == 0)
+			ret = auth_process_input_spid(process, line + 5);
+		else
+			ret = TRUE;
 
-		/* reply is now read */
-		if (!handle_reply(p, &p->auth_reply, data)) {
-			auth_process_destroy(p);
+		if (!ret) {
+			auth_process_destroy(process);
 			break;
 		}
-
-		p->in_auth_reply = FALSE;
-		i_stream_skip(p->input, p->auth_reply.data_size);
+		t_pop();
 	}
 }
 
@@ -213,8 +238,7 @@
 	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_master_request)*100,
+	p->output = o_stream_create_file(fd, default_pool, MAX_OUTBUF_SIZE,
 					 FALSE);
 	p->requests = hash_create(default_pool, default_pool, 0, NULL, NULL);
 

Index: auth-process.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/auth-process.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- auth-process.h	27 Jan 2003 01:33:40 -0000	1.8
+++ auth-process.h	13 Oct 2004 16:38:35 -0000	1.9
@@ -1,8 +1,8 @@
 #ifndef __AUTH_PROCESS_H
 #define __AUTH_PROCESS_H
 
-void auth_master_callback(struct auth_master_reply *reply,
-			  const unsigned char *data, void *context);
+void auth_master_callback(const char *user, const char *const *args,
+			  void *context);
 
 /* Find process for given id */
 struct auth_process *auth_process_find(unsigned int pid);

Index: common.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/common.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- common.h	24 May 2004 22:33:51 -0000	1.19
+++ common.h	13 Oct 2004 16:38:35 -0000	1.20
@@ -7,8 +7,6 @@
 #include "hash.h"
 #include "master-settings.h"
 
-#include "../auth/auth-master-interface.h"
-
 enum process_type {
 	PROCESS_TYPE_UNKNOWN,
 	PROCESS_TYPE_AUTH,

Index: login-process.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/login-process.c,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -d -r1.59 -r1.60
--- login-process.c	5 Oct 2004 16:00:18 -0000	1.59
+++ login-process.c	13 Oct 2004 16:38:36 -0000	1.60
@@ -71,14 +71,14 @@
 	i_free(group);
 }
 
-void auth_master_callback(struct auth_master_reply *reply,
-			  const unsigned char *data, void *context)
+void auth_master_callback(const char *user, const char *const *args,
+			  void *context)
 {
 	struct login_auth_request *request = context;
 	struct master_login_reply master_reply;
 	ssize_t ret;
 
-	if (reply == NULL || !reply->success)
+	if (user == NULL)
 		master_reply.success = FALSE;
 	else {
 		struct login_group *group = request->process->group;
@@ -87,8 +87,7 @@
 		master_reply.success =
 			create_mail_process(group, request->fd,
 					    &request->local_ip,
-					    &request->remote_ip,
-					    reply, (const char *) data);
+					    &request->remote_ip, user, args);
 		t_pop();
 	}
 

Index: mail-process.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/mail-process.c,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -d -r1.60 -r1.61
--- mail-process.c	10 Oct 2004 17:25:45 -0000	1.60
+++ mail-process.c	13 Oct 2004 16:38:36 -0000	1.61
@@ -312,15 +312,18 @@
 int create_mail_process(struct login_group *group, int socket,
 			const struct ip_addr *local_ip,
 			const struct ip_addr *remote_ip,
-			struct auth_master_reply *reply, const char *data)
+			const char *user, const char *const *args)
 {
 	struct settings *set = group->set;
 	const struct var_expand_table *var_expand_table;
-	const char *addr, *mail, *user, *chroot_dir, *home_dir, *full_home_dir;
+	const char *addr, *mail, *chroot_dir, *home_dir, *full_home_dir;
+	const char *system_user;
 	char title[1024];
 	struct log_io *log;
 	string_t *str;
 	pid_t pid;
+	uid_t uid;
+	gid_t gid;
 	int i, err, ret, log_fd;
 
 	// FIXME: per-group
@@ -329,14 +332,25 @@
 		return FALSE;
 	}
 
-	if (!validate_uid_gid(set, reply->uid, reply->gid,
-			      data + reply->virtual_user_idx))
-		return FALSE;
+	mail = home_dir = chroot_dir = system_user = "";
+	uid = gid = 0;
+	for (; *args != NULL; args++) {
+		if (strncmp(*args, "home=", 5) == 0)
+			home_dir = *args + 5;
+		else if (strncmp(*args, "mail=", 5) == 0)
+			mail = *args + 5;
+		else if (strncmp(*args, "chroot=", 7) == 0)
+			chroot_dir = *args + 7;
+		else if (strncmp(*args, "system_user=", 12) == 0)
+			system_user = *args + 12;
+		else if (strncmp(*args, "uid=", 4) == 0)
+			uid = (uid_t)strtoul(*args + 4, NULL, 10);
+		else if (strncmp(*args, "gid=", 4) == 0)
+			gid = (gid_t)strtoul(*args + 4, NULL, 10);
+	}
 
-	user = data + reply->virtual_user_idx;
-	mail = data + reply->mail_idx;
-	home_dir = data + reply->home_idx;
-	chroot_dir = data + reply->chroot_idx;
+	if (!validate_uid_gid(set, uid, gid, user))
+		return FALSE;
 
 	if (*chroot_dir == '\0' && set->mail_chroot != NULL)
 		chroot_dir = set->mail_chroot;
@@ -395,8 +409,7 @@
 
 	/* 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, chroot_dir,
+	restrict_access_set_env(system_user, uid, gid, chroot_dir,
 				set->first_valid_gid, set->last_valid_gid,
 				set->mail_extra_groups);
 
@@ -410,10 +423,10 @@
 		/* NOTE: if home directory is NFS-mounted, we might not
 		   have access to it as root. Change the effective UID
 		   temporarily to make it work. */
-		if (reply->uid != master_uid && seteuid(reply->uid) < 0)
-			i_fatal("seteuid(%s) failed: %m", dec2str(reply->uid));
+		if (uid != master_uid && seteuid(uid) < 0)
+			i_fatal("seteuid(%s) failed: %m", dec2str(uid));
 		ret = chdir(full_home_dir);
-		if (reply->uid != master_uid && seteuid(master_uid) < 0)
+		if (uid != master_uid && seteuid(master_uid) < 0)
 			i_fatal("seteuid(%s) failed: %m", dec2str(master_uid));
 
 		/* If user's home directory doesn't exist and we're not
@@ -421,7 +434,7 @@
 		   could be stored elsewhere. */
 		if (ret < 0 && (errno != ENOENT || *chroot_dir != '\0')) {
 			i_fatal("chdir(%s) failed with uid %s: %m",
-				full_home_dir, dec2str(reply->uid));
+				full_home_dir, dec2str(uid));
 		}
 	}
 	if (ret < 0) {
@@ -435,7 +448,7 @@
 
 	env_put("LOGGED_IN=1");
 	env_put(t_strconcat("HOME=", home_dir, NULL));
-	env_put(t_strconcat("USER=", data + reply->virtual_user_idx, NULL));
+	env_put(t_strconcat("USER=", user, NULL));
 
 	addr = net_ip2addr(remote_ip);
 	env_put(t_strconcat("IP=", addr, NULL));
@@ -446,8 +459,7 @@
 		if (addr == NULL)
 			addr = "??";
 
-		i_snprintf(title, sizeof(title), "[%s %s]",
-			   data + reply->virtual_user_idx, addr);
+		i_snprintf(title, sizeof(title), "[%s %s]", user, addr);
 	}
 
 	/* make sure we don't leak syslog fd, but do it last so that

Index: mail-process.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/mail-process.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- mail-process.h	9 Jul 2004 19:59:02 -0000	1.6
+++ mail-process.h	13 Oct 2004 16:38:36 -0000	1.7
@@ -9,7 +9,7 @@
 int create_mail_process(struct login_group *group, int socket,
 			const struct ip_addr *local_ip,
 			const struct ip_addr *remote_ip,
-			struct auth_master_reply *reply, const char *data);
+			const char *user, const char *const *args);
 
 void mail_process_destroyed(pid_t pid);
 



More information about the dovecot-cvs mailing list