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