[dovecot-cvs] dovecot/src/auth auth-master-connection.c, 1.5, 1.6 auth-master-connection.h, 1.1, 1.2 main.c, 1.22, 1.23 mech.c, 1.19, 1.20

cras at procontrol.fi cras at procontrol.fi
Sat May 29 19:43:24 EEST 2004


Update of /home/cvs/dovecot/src/auth
In directory talvi:/tmp/cvs-serv25557/auth

Modified Files:
	auth-master-connection.c auth-master-connection.h main.c 
	mech.c 
Log Message:
dovecot-auth can now be run by itself, it listens in UNIX sockets specified
in AUTH_SOCKETS environment. Added extra_sockets auth setting which can be
used to do the same thing while started through dovecot master.



Index: auth-master-connection.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/auth-master-connection.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- a/auth-master-connection.c	24 May 2004 22:33:50 -0000	1.5
+++ b/auth-master-connection.c	29 May 2004 16:43:22 -0000	1.6
@@ -11,6 +11,8 @@
 #include "auth-client-connection.h"
 #include "auth-master-connection.h"
 
+#include <unistd.h>
+
 #define MAX_OUTBUF_SIZE (1024*50)
 
 static struct auth_master_reply failure_reply =
@@ -189,26 +191,56 @@
 	conn->refcount = 1;
 	conn->pid = pid;
 	conn->fd = fd;
-	conn->output = o_stream_create_file(MASTER_SOCKET_FD, default_pool,
-					    MAX_OUTBUF_SIZE, FALSE);
-	conn->io = io_add(MASTER_SOCKET_FD, IO_READ, master_input, conn);
+	conn->listeners_buf =
+		buffer_create_dynamic(default_pool, 64, (size_t)-1);
+	if (fd != -1) {
+		conn->output = o_stream_create_file(fd, default_pool,
+						    MAX_OUTBUF_SIZE, FALSE);
+		conn->io = io_add(fd, IO_READ, master_input, conn);
+	}
+	return conn;
+}
 
+void auth_master_connection_send_handshake(struct auth_master_connection *conn)
+{
 	/* just a note to master that we're ok. if we die before,
 	   master should shutdown itself. */
-	o_stream_send(conn->output, "O", 1);
-	return conn;
+	if (conn->output != NULL)
+		o_stream_send(conn->output, "O", 1);
 }
 
 void auth_master_connection_free(struct auth_master_connection *conn)
 {
-	if (conn->fd == -1)
+	struct auth_client_listener **l;
+	size_t i, size;
+
+	if (conn->destroyed)
 		return;
+	conn->destroyed = TRUE;
 
-	conn->fd = -1;
-	o_stream_close(conn->output);
+	if (conn->fd != -1) {
+		if (close(conn->fd) < 0)
+			i_error("close(): %m");
+		conn->fd = -1;
 
-	io_remove(conn->io);
-	conn->io = NULL;
+		o_stream_close(conn->output);
+
+		io_remove(conn->io);
+		conn->io = NULL;
+	}
+
+	l = buffer_get_modifyable_data(conn->listeners_buf, &size);
+	size /= sizeof(*l);
+	for (i = 0; i < size; i++) {
+		net_disconnect(l[i]->fd);
+		io_remove(l[i]->io);
+		if (l[i]->path != NULL) {
+			(void)unlink(l[i]->path);
+			i_free(l[i]->path);
+		}
+		i_free(l[i]);
+	}
+	buffer_free(conn->listeners_buf);
 
 	auth_master_connection_unref(conn);
 }
@@ -218,7 +250,37 @@
 	if (--conn->refcount > 0)
 		return TRUE;
 
-	o_stream_unref(conn->output);
+	if (conn->output != NULL)
+		o_stream_unref(conn->output);
 	i_free(conn);
 	return FALSE;
 }
+
+static void auth_accept(void *context)
+{
+	struct auth_client_listener *l = context;
+	int fd;
+
+	fd = net_accept(l->fd, NULL, NULL);
+	if (fd < 0) {
+		if (fd < -1)
+			i_fatal("accept() failed: %m");
+	} else {
+		net_set_nonblock(fd, TRUE);
+		(void)auth_client_connection_create(l->master, fd);
+	}
+}
+
+void auth_master_connection_add_listener(struct auth_master_connection *conn,
+					 int fd, const char *path)
+{
+	struct auth_client_listener *l;
+
+	l = i_new(struct auth_client_listener, 1);
+	l->master = conn;
+	l->fd = fd;
+	l->path = i_strdup(path);
+	l->io = io_add(fd, IO_READ, auth_accept, &l);
+
+	buffer_append(conn->listeners_buf, &l, sizeof(l));
+}

Index: auth-master-connection.h
===================================================================
RCS file: /home/cvs/dovecot/src/auth/auth-master-connection.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- a/auth-master-connection.h	22 Aug 2003 02:42:13 -0000	1.1
+++ b/auth-master-connection.h	29 May 2004 16:43:22 -0000	1.2
@@ -10,6 +10,7 @@
 	int fd;
 	struct ostream *output;
 	struct io *io;
+	buffer_t *listeners_buf;
 
 	unsigned int request_pos;
 	unsigned char request_buf[sizeof(struct auth_master_request)];
@@ -17,10 +18,25 @@
 	struct auth_client_handshake_reply handshake_reply;
 	struct auth_client_connection *clients;
 	struct timeout *to_clients;
+
+	unsigned int destroyed:1;
+};
+
+struct auth_client_listener {
+	struct auth_master_connection *master;
+	int fd;
+	char *path;
+	struct io *io;
 };
 
+#define AUTH_MASTER_IS_DUMMY(master) (master->fd == -1)
+
 struct auth_master_connection *
 auth_master_connection_new(int fd, unsigned int pid);
+void auth_master_connection_send_handshake(struct auth_master_connection *conn);
 void auth_master_connection_free(struct auth_master_connection *conn);
 
+void auth_master_connection_add_listener(struct auth_master_connection *conn,
+					 int fd, const char *path);
+
 #endif

Index: main.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/main.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- a/main.c	10 May 2004 16:05:09 -0000	1.22
+++ b/main.c	29 May 2004 16:43:22 -0000	1.23
@@ -1,6 +1,7 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "common.h"
+#include "buffer.h"
 #include "ioloop.h"
 #include "network.h"
 #include "lib-signals.h"
@@ -14,36 +15,42 @@
 #include "auth-client-connection.h"
 
 #include <stdlib.h>
+#include <unistd.h>
 #include <syslog.h>
 
 struct ioloop *ioloop;
 int verbose = FALSE, verbose_debug = FALSE;
 
-static struct auth_master_connection *master;
-static struct io *io_listen;
+static buffer_t *masters_buf;
 
 static void sig_quit(int signo __attr_unused__)
 {
 	io_loop_stop(ioloop);
 }
 
-static void auth_accept(void *context __attr_unused__)
+static void open_logfile(void)
 {
-	int fd;
+	if (getenv("LOG_TO_MASTER") != NULL) {
+		i_set_failure_internal();
+		return;
+	}
 
-	fd = net_accept(LOGIN_LISTEN_FD, NULL, NULL);
-	if (fd < 0) {
-		if (fd < -1)
-			i_fatal("accept() failed: %m");
-	} else {
-		net_set_nonblock(fd, TRUE);
-		(void)auth_client_connection_create(master, fd);
+	if (getenv("USE_SYSLOG") != NULL)
+		i_set_failure_syslog("dovecot-auth", LOG_NDELAY, LOG_MAIL);
+	else {
+		/* log to file or stderr */
+		i_set_failure_file(getenv("LOGFILE"), "dovecot-auth");
 	}
+
+	if (getenv("INFOLOGFILE") != NULL)
+		i_set_info_file(getenv("INFOLOGFILE"));
+
+	i_set_failure_timestamp_format(getenv("LOGSTAMP"));
 }
 
 static void drop_privileges(void)
 {
-	i_set_failure_internal();
+	open_logfile();
 
 	/* Open /dev/urandom before chrooting */
 	random_init();
@@ -52,8 +59,29 @@
 	restrict_access_by_env(FALSE);
 }
 
+static void master_add_unix_listeners(struct auth_master_connection *master,
+				      const char *sockets_list)
+{
+	const char *const *sockets;
+	int fd;
+
+	sockets = t_strsplit(sockets_list, ":");
+	while (*sockets != NULL) {
+		fd = net_listen_unix(*sockets);
+		if (fd == -1) {
+			i_fatal("net_listen_unix(%s) failed: %m",
+				*sockets);
+		}
+
+		auth_master_connection_add_listener(master, fd, *sockets);
+		sockets++;
+	}
+}
+
 static void main_init(void)
 {
+	struct auth_master_connection *master, **master_p;
+	size_t i, size;
 	const char *env;
 	unsigned int pid;
 
@@ -62,39 +90,81 @@
 	verbose = getenv("VERBOSE") != NULL;
 	verbose_debug = getenv("VERBOSE_DEBUG") != NULL;
 
-	env = getenv("AUTH_PROCESS");
-	if (env == NULL)
-		i_fatal("AUTH_PROCESS environment is unset");
-
-	pid = atoi(env);
-	if (pid == 0)
-		i_fatal("AUTH_PROCESS can't be 0");
-
 	mech_init();
 	userdb_init();
 	passdb_init();
 
-	io_listen = io_add(LOGIN_LISTEN_FD, IO_READ, auth_accept, NULL);
+	masters_buf = buffer_create_dynamic(default_pool, 64, (size_t)-1);
 
-	/* initialize master last - it sends the "we're ok" notification */
-	master = auth_master_connection_new(MASTER_SOCKET_FD, pid);
-	auth_client_connections_init(master);
+	env = getenv("AUTH_PROCESS");
+	if (env == NULL) {
+		/* starting standalone */
+		env = getenv("AUTH_SOCKETS");
+		if (env == NULL)
+			i_fatal("AUTH_SOCKETS environment not set");
+
+		switch (fork()) {
+		case -1:
+			i_fatal("fork() failed: %m");
+		case 0:
+			break;
+		default:
+			exit(0);
+		}
+
+		if (setsid() < 0)
+			i_fatal("setsid() failed: %m");
+
+		if (chdir("/") < 0)
+			i_fatal("chdir(/) failed: %m");
+       } else {
+		pid = atoi(env);
+		if (pid == 0)
+			i_fatal("AUTH_PROCESS can't be 0");
+
+		master = auth_master_connection_new(MASTER_SOCKET_FD, pid);
+		auth_master_connection_add_listener(master, LOGIN_LISTEN_FD,
+						    NULL);
+		auth_client_connections_init(master);
+		buffer_append(masters_buf, &master, sizeof(master));
+
+		/* accept also alternative listeners under dummy master */
+		env = getenv("AUTH_SOCKETS");
+	}
+
+	if (env != NULL) {
+		master = auth_master_connection_new(-1, 0);
+		master_add_unix_listeners(master, env);
+		auth_client_connections_init(master);
+		buffer_append(masters_buf, &master, sizeof(master));
+	}
+
+	/* everything initialized, notify masters that all is well */
+	master_p = buffer_get_modifyable_data(masters_buf, &size);
+	size /= sizeof(*master_p);
+	for (i = 0; i < size; i++)
+		auth_master_connection_send_handshake(master_p[i]);
 }
 
 static void main_deinit(void)
 {
+	struct auth_master_connection **master;
+	size_t i, size;
+
         if (lib_signal_kill != 0)
 		i_warning("Killed with signal %d", lib_signal_kill);
 
-	io_remove(io_listen);
-
-	auth_client_connections_deinit(master);
+	master = buffer_get_modifyable_data(masters_buf, &size);
+	size /= sizeof(*master);
+	for (i = 0; i < size; i++) {
+		auth_client_connections_deinit(master[i]);
+		auth_master_connection_free(master[i]);
+	}
 
 	passdb_deinit();
 	userdb_deinit();
 	mech_deinit();
 
-	auth_master_connection_free(master);
 	random_deinit();
 
 	closelog();

Index: mech.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/mech.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- a/mech.c	24 May 2004 22:33:50 -0000	1.19
+++ b/mech.c	29 May 2004 16:43:22 -0000	1.20
@@ -7,6 +7,7 @@
 #include "mech.h"
 #include "var-expand.h"
 #include "auth-client-connection.h"
+#include "auth-master-connection.h"
 
 #include <stdlib.h>
 
@@ -196,8 +197,12 @@
 
 	auth_request->callback(&reply, reply_data, auth_request->conn);
 
-	if (!success)
+	if (!success || AUTH_MASTER_IS_DUMMY(auth_request->conn->master)) {
+		/* request is no longer needed, either because the
+		   authentication failed or because we don't have master
+		   process */
 		mech_request_free(auth_request, auth_request->id);
+	}
 }
 
 int mech_is_valid_username(const char *username)



More information about the dovecot-cvs mailing list