dovecot-2.0: Added auth_master_pass_lookup() and changed auth_ma...

dovecot at dovecot.org dovecot at dovecot.org
Mon Aug 31 18:38:53 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/0919ab922086
changeset: 9830:0919ab922086
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Aug 31 11:37:25 2009 -0400
description:
Added auth_master_pass_lookup() and changed auth_master_used_lookup() API.
User lookup can now send local/remote IPs and ports to auth process.

diffstat:

5 files changed, 162 insertions(+), 42 deletions(-)
src/lib-auth/auth-master.c             |  154 ++++++++++++++++++++++++--------
src/lib-auth/auth-master.h             |   16 ++-
src/lib-storage/mail-storage-service.c |   22 +++-
src/lib-storage/mail-storage-service.h |    2 
src/lib-storage/mail-user.c            |   10 +-

diffs (truncated from 363 to 300 lines):

diff -r 46adc15b33d9 -r 0919ab922086 src/lib-auth/auth-master.c
--- a/src/lib-auth/auth-master.c	Mon Aug 31 11:33:42 2009 -0400
+++ b/src/lib-auth/auth-master.c	Mon Aug 31 11:37:25 2009 -0400
@@ -7,6 +7,7 @@
 #include "network.h"
 #include "istream.h"
 #include "ostream.h"
+#include "str.h"
 #include "auth-master.h"
 
 #include <stdlib.h>
@@ -49,9 +50,16 @@ struct auth_master_user_lookup_ctx {
 struct auth_master_user_lookup_ctx {
 	struct auth_master_connection *conn;
 	pool_t pool;
-	const char *user;
 	struct auth_user_reply *user_reply;
 	int return_value;
+};
+
+struct auth_master_pass_lookup_ctx {
+	struct auth_master_connection *conn;
+	int return_value;
+
+	pool_t pool;
+	const char **fields;
 };
 
 struct auth_master_user_list_ctx {
@@ -162,27 +170,34 @@ static int auth_input_handshake(struct a
 	return 0;
 }
 
+static int parse_reply(struct auth_master_connection *conn,
+		       const char *cmd, const char *const *args,
+		       const char *expected_reply)
+{
+	io_loop_stop(conn->ioloop);
+
+	if (strcmp(cmd, expected_reply) == 0)
+		return 1;
+	if (strcmp(cmd, "NOTFOUND") == 0)
+		return 0;
+	if (strcmp(cmd, "FAIL") == 0) {
+		i_error("Lookup failed: %s",
+			*args != NULL ? *args : "Internal failure");
+		return -1;
+	}
+	i_error("Unknown reply: %s", cmd);
+	return -1;
+}
+
 static bool auth_user_reply_callback(const char *cmd, const char *const *args,
 				     void *context)
 {
 	struct auth_master_user_lookup_ctx *ctx = context;
 
-	io_loop_stop(ctx->conn->ioloop);
-	if (strcmp(cmd, "USER") == 0) {
+	ctx->return_value = parse_reply(ctx->conn, cmd, args, "USER");
+	if (ctx->return_value > 0)
 		auth_parse_input(ctx, args);
-		ctx->return_value = 1;
-		return TRUE;
-	}
-	if (strcmp(cmd, "NOTFOUND") == 0) {
-		ctx->return_value = 0;
-		return TRUE;
-	}
-	if (strcmp(cmd, "FAIL") == 0) {
-		i_error("userdb lookup(%s) failed: %s", ctx->user,
-			*args != NULL ? *args : "Internal failure");
-		return TRUE;
-	}
-	return FALSE;
+	return TRUE;
 }
 
 static bool
@@ -373,14 +388,40 @@ static int auth_master_run_cmd(struct au
 	return 0;
 }
 
+static unsigned int
+auth_master_next_request_id(struct auth_master_connection *conn)
+{
+	if (++conn->request_counter == 0) {
+		/* avoid zero */
+		conn->request_counter++;
+	}
+	return conn->request_counter;
+}
+
+static void
+auth_user_info_export(string_t *str, const struct auth_user_info *info)
+{
+	str_append(str, "service=");
+	str_append(str, info->service);
+
+	if (info->local_ip.family != 0)
+		str_printfa(str, "\tlip=%s", net_ip2addr(&info->local_ip));
+	if (info->local_port != 0)
+		str_printfa(str, "\tlport=%d", info->local_port);
+	if (info->remote_ip.family != 0)
+		str_printfa(str, "\trip=%s", net_ip2addr(&info->remote_ip));
+	if (info->remote_port != 0)
+		str_printfa(str, "\trport=%d", info->remote_port);
+}
+
 int auth_master_user_lookup(struct auth_master_connection *conn,
-			    const char *user, const char *service,
+			    const char *user, const struct auth_user_info *info,
 			    pool_t pool, struct auth_user_reply *reply_r)
 {
 	struct auth_master_user_lookup_ctx ctx;
-	const char *str;
-
-	if (!is_valid_string(user) || !is_valid_string(service)) {
+	string_t *str;
+
+	if (!is_valid_string(user) || !is_valid_string(info->service)) {
 		/* non-allowed characters, the user can't exist */
 		return 0;
 	}
@@ -389,23 +430,71 @@ int auth_master_user_lookup(struct auth_
 	ctx.conn = conn;
 	ctx.return_value = -1;
 	ctx.pool = pool;
-	ctx.user = user;
 	ctx.user_reply = reply_r;
-
-	if (++conn->request_counter == 0) {
-		/* avoid zero */
-		conn->request_counter++;
-	}
 
 	conn->reply_callback = auth_user_reply_callback;
 	conn->reply_context = &ctx;
 
+	str = t_str_new(128);
+	str_printfa(str, "USER\t%u\t%s\t",
+		    auth_master_next_request_id(conn), user);
+	auth_user_info_export(str, info);
+	str_append_c(str, '\n');
+
 	conn->prefix = t_strdup_printf("userdb lookup(%s)", user);
-	str = t_strdup_printf("USER\t%u\t%s\tservice=%s\n",
-			      conn->request_counter, user, service);
-	(void)auth_master_run_cmd(conn, str);
+	(void)auth_master_run_cmd(conn, str_c(str));
 	conn->prefix = DEFAULT_USERDB_LOOKUP_PREFIX;
 
+	return ctx.return_value;
+}
+
+static bool auth_pass_reply_callback(const char *cmd, const char *const *args,
+				     void *context)
+{
+	struct auth_master_pass_lookup_ctx *ctx = context;
+	unsigned int i, len;
+
+	ctx->return_value = parse_reply(ctx->conn, cmd, args, "PASS");
+	if (ctx->return_value > 0) {
+		len = str_array_length(args);
+		ctx->fields = p_new(ctx->pool, const char *, len + 1);
+		for (i = 0; i < len; i++)
+			ctx->fields[i] = p_strdup(ctx->pool, args[i]);
+	}
+	return TRUE;
+}
+
+int auth_master_pass_lookup(struct auth_master_connection *conn,
+			    const char *user, const struct auth_user_info *info,
+			    pool_t pool, const char *const **fields_r)
+{
+	struct auth_master_pass_lookup_ctx ctx;
+	string_t *str;
+
+	if (!is_valid_string(user) || !is_valid_string(info->service)) {
+		/* non-allowed characters, the user can't exist */
+		return 0;
+	}
+
+	memset(&ctx, 0, sizeof(ctx));
+	ctx.conn = conn;
+	ctx.return_value = -1;
+	ctx.pool = pool;
+
+	conn->reply_callback = auth_pass_reply_callback;
+	conn->reply_context = &ctx;
+
+	str = t_str_new(128);
+	str_printfa(str, "PASS\t%u\t%s\t",
+		    auth_master_next_request_id(conn), user);
+	auth_user_info_export(str, info);
+	str_append_c(str, '\n');
+
+	conn->prefix = t_strdup_printf("passdb lookup(%s)", user);
+	(void)auth_master_run_cmd(conn, str_c(str));
+	conn->prefix = DEFAULT_USERDB_LOOKUP_PREFIX;
+
+	*fields_r = ctx.fields;
 	return ctx.return_value;
 }
 
@@ -449,15 +538,10 @@ auth_master_user_list_init(struct auth_m
 	ctx->conn = conn;
 	i_array_init(&ctx->users, 128);
 
-	if (++conn->request_counter == 0) {
-		/* avoid zero */
-		conn->request_counter++;
-	}
-
 	conn->reply_callback = auth_user_list_reply_callback;
 	conn->reply_context = ctx;
 
-	str = t_strdup_printf("LIST\t%u\n", conn->request_counter);
+	str = t_strdup_printf("LIST\t%u\n", auth_master_next_request_id(conn));
 	conn->prefix = "userdb list";
 	if (auth_master_run_cmd(conn, str) < 0)
 		ctx->failed = TRUE;
diff -r 46adc15b33d9 -r 0919ab922086 src/lib-auth/auth-master.h
--- a/src/lib-auth/auth-master.h	Mon Aug 31 11:33:42 2009 -0400
+++ b/src/lib-auth/auth-master.h	Mon Aug 31 11:37:25 2009 -0400
@@ -1,5 +1,13 @@
 #ifndef AUTH_MASTER_H
 #define AUTH_MASTER_H
+
+#include "network.h"
+
+struct auth_user_info {
+	const char *service;
+	struct ip_addr local_ip, remote_ip;
+	unsigned int local_port, remote_port;
+};
 
 struct auth_user_reply {
 	uid_t uid;
@@ -12,10 +20,14 @@ auth_master_init(const char *auth_socket
 auth_master_init(const char *auth_socket_path, bool debug);
 void auth_master_deinit(struct auth_master_connection **conn);
 
-/* Returns -1 = error, 0 = user not found, 1 = ok */
+/* Do a USER lookup. Returns -1 = error, 0 = user not found, 1 = ok */
 int auth_master_user_lookup(struct auth_master_connection *conn,
-			    const char *user, const char *service,
+			    const char *user, const struct auth_user_info *info,
 			    pool_t pool, struct auth_user_reply *reply_r);
+/* Do a PASS lookup (the actual password isn't returned). */
+int auth_master_pass_lookup(struct auth_master_connection *conn,
+			    const char *user, const struct auth_user_info *info,
+			    pool_t pool, const char *const **fields_r);
 
 /* Iterate through all users. */
 struct auth_master_user_list_ctx *
diff -r 46adc15b33d9 -r 0919ab922086 src/lib-storage/mail-storage-service.c
--- a/src/lib-storage/mail-storage-service.c	Mon Aug 31 11:33:42 2009 -0400
+++ b/src/lib-storage/mail-storage-service.c	Mon Aug 31 11:37:25 2009 -0400
@@ -149,19 +149,26 @@ static int
 static int
 service_auth_userdb_lookup(struct auth_master_connection *conn,
 			   struct setting_parser_context *set_parser,
-			   const char *name,
+			   const char *service_name,
+			   const struct mail_storage_service_input *input,
 			   const struct mail_user_settings *user_set,
 			   const char **user, const char **system_groups_user_r,
 			   const char **error_r)
 {
+	struct auth_user_info info;
 	struct auth_user_reply reply;
 	const char *system_groups_user, *orig_user = *user;
 	unsigned int len;
 	pool_t pool;
 	int ret;
 
+	memset(&info, 0, sizeof(info));
+	info.service = service_name;
+	info.local_ip = input->local_ip;
+	info.remote_ip = input->remote_ip;
+
 	pool = pool_alloconly_create("userdb lookup", 1024);
-	ret = auth_master_user_lookup(conn, *user, name, pool, &reply);
+	ret = auth_master_user_lookup(conn, *user, &info, pool, &reply);
 	if (ret > 0) {
 		len = reply.chroot == NULL ? 0 : strlen(reply.chroot);
 
@@ -539,7 +546,8 @@ init_user_real(struct master_service *se
 		conn = auth_master_init(user_set->auth_socket_path,
 					mail_set->mail_debug);
 		if (service_auth_userdb_lookup(conn, service->set_parser,
-					       service->name, user_set, &user,
+					       service->name, &input,
+					       user_set, &user,
 					       &system_groups_user,
 					       &error) <= 0)
 			i_fatal("%s", error);
@@ -660,6 +668,12 @@ mail_storage_service_multi_init(struct m
 	return ctx;


More information about the dovecot-cvs mailing list