Mercurial > dovecot > core-2.2
changeset 8370:ffe34451c01a HEAD
expire-tool: Use the new auth-master API instead of doing the lookup ourself.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 01 Nov 2008 14:49:12 +0200 |
parents | 6db401560d37 |
children | b46cf0979768 |
files | src/plugins/expire/Makefile.am src/plugins/expire/auth-client.c src/plugins/expire/expire-tool.c |
diffstat | 3 files changed, 48 insertions(+), 187 deletions(-) [+] |
line wrap: on
line diff
--- a/src/plugins/expire/Makefile.am Sat Nov 01 14:25:05 2008 +0200 +++ b/src/plugins/expire/Makefile.am Sat Nov 01 14:49:12 2008 +0200 @@ -2,6 +2,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-auth \ -I$(top_srcdir)/src/lib-dict \ -I$(top_srcdir)/src/lib-mail \ -I$(top_srcdir)/src/lib-imap \ @@ -37,6 +38,7 @@ $(top_builddir)/src/lib-imap/libimap.a \ $(top_builddir)/src/lib-mail/libmail.a \ $(top_builddir)/src/lib-dict/libdict.a \ + $(top_builddir)/src/lib-auth/libauth.a \ $(top_builddir)/src/lib-charset/libcharset.a \ $(top_builddir)/src/lib/liblib.a
--- a/src/plugins/expire/auth-client.c Sat Nov 01 14:25:05 2008 +0200 +++ b/src/plugins/expire/auth-client.c Sat Nov 01 14:49:12 2008 +0200 @@ -1,139 +1,43 @@ /* Copyright (c) 2005-2008 Dovecot authors, see the included COPYING file */ #include "lib.h" -#include "ioloop.h" -#include "network.h" -#include "istream.h" -#include "ostream.h" +#include "array.h" #include "env-util.h" #include "restrict-access.h" #include "auth-client.h" +#include "auth-master.h" -#include <stdlib.h> #include <unistd.h> -#define MAX_INBUF_SIZE 8192 -#define MAX_OUTBUF_SIZE 512 - -struct auth_connection { - char *auth_socket; - - int fd; - struct io *io; - struct istream *input; - struct ostream *output; - - uid_t orig_uid, current_uid; - const char *current_user; - int return_value; - - unsigned int handshaked:1; -}; - -static void auth_input(struct auth_connection *conn); - -static int auth_connection_connect(struct auth_connection *conn) -{ - int fd; +static uid_t current_uid = 0; - if (conn->fd != -1) - return 0; - - fd = net_connect_unix(conn->auth_socket); - if (fd < 0) { - i_error("net_connect(%s) failed: %m", conn->auth_socket); - return -1; - } - - conn->fd = fd; - conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); - conn->output = o_stream_create_fd(fd, MAX_OUTBUF_SIZE, FALSE); - conn->io = io_add(fd, IO_READ, auth_input, conn); - - o_stream_send_str(conn->output, "VERSION\t1\t0\n"); - return 0; -} - -static void auth_connection_close(struct auth_connection *conn) +static void auth_set_env(const char *user, struct auth_user_reply *reply) { - if (conn->fd == -1) - return; - - io_remove(&conn->io); - i_stream_unref(&conn->input); - o_stream_unref(&conn->output); + const char *const *fields, *key, *value; + unsigned int i, count; - if (close(conn->fd) < 0) - i_error("close() failed: %m"); - conn->fd = -1; -} - -struct auth_connection *auth_connection_init(const char *auth_socket) -{ - struct auth_connection *conn; - - conn = i_new(struct auth_connection, 1); - conn->auth_socket = i_strdup(auth_socket); - conn->orig_uid = conn->current_uid = geteuid(); - conn->fd = -1; - - (void)auth_connection_connect(conn); - return conn; -} - -void auth_connection_deinit(struct auth_connection *conn) -{ - auth_connection_close(conn); - i_free(conn->auth_socket); - i_free(conn); -} + if (reply->gid != (gid_t)-1 && getegid() != reply->gid) { + env_put(t_strconcat("RESTRICT_SETGID=", + dec2str(reply->gid), NULL)); + } + if (reply->chroot != NULL) + env_put(t_strconcat("RESTRICT_CHROOT=", reply->chroot, NULL)); -static void auth_parse_input(struct auth_connection *conn, const char *args) -{ - const char *const *tmp, *key, *value; - uid_t uid = (uid_t)-1; - int home_found = FALSE; - - for (tmp = t_strsplit(args, "\t"); *tmp != NULL; tmp++) { - if (strncmp(*tmp, "uid=", 4) == 0) - uid = strtoul(*tmp + 4, NULL, 10); - else if (strncmp(*tmp, "gid=", 4) == 0) { - gid_t gid = strtoul(*tmp + 4, NULL, 10); - - if (conn->orig_uid == 0 || getegid() != gid) { - env_put(t_strconcat("RESTRICT_SETGID=", - *tmp + 4, NULL)); - } - } else if (strncmp(*tmp, "chroot=", 7) == 0) { - env_put(t_strconcat("RESTRICT_CHROOT=", - *tmp + 7, NULL)); - } else if (strncmp(*tmp, "home=", 5) == 0) { - home_found = TRUE; - env_put(t_strconcat("HOME=", *tmp + 5, NULL)); - } else { - key = t_str_ucase(t_strcut(*tmp, '=')); - value = strchr(*tmp, '='); - if (value != NULL) - env_put(t_strconcat(key, "=", value+1, NULL)); - } + if (reply->home == NULL) { + /* we must have a home directory */ + i_error("userdb(%s) didn't return a home directory", user); + return; } - - if (!home_found) { - /* we must have a home directory */ - i_error("userdb(%s) didn't return a home directory", - conn->current_user); + if (reply->uid == (uid_t)-1) { + i_error("userdb(%s) didn't return uid", user); return; } - if (uid == (uid_t)-1) { - i_error("userdb(%s) didn't return uid", conn->current_user); - return; - } - - if (uid != conn->current_uid && conn->current_uid != 0) { + if (reply->uid != current_uid && current_uid != 0) { + /* we're changing the UID, switch back to root */ if (seteuid(0) != 0) i_fatal("seteuid(0) failed: %m"); - conn->current_uid = 0; + current_uid = 0; } /* change GID */ @@ -142,81 +46,36 @@ /* we'll change only effective UID. This is a bit unfortunate since it allows reverting back to root, but we'll have to be able to access different users' mailboxes.. */ - if (uid != conn->current_uid) { - if (seteuid(uid) < 0) - i_fatal("seteuid(%s) failed: %m", dec2str(uid)); - conn->current_uid = uid; - } - - conn->return_value = 1; -} - -static void auth_input(struct auth_connection *conn) -{ - const char *line; - - switch (i_stream_read(conn->input)) { - case 0: - return; - case -1: - /* disconnected */ - auth_connection_close(conn); - return; - case -2: - /* buffer full */ - i_error("BUG: Auth master sent us more than %d bytes", - MAX_INBUF_SIZE); - auth_connection_close(conn); - return; + if (reply->uid != current_uid) { + if (seteuid(reply->uid) < 0) + i_fatal("seteuid(%s) failed: %m", dec2str(reply->uid)); + current_uid = reply->uid; } - if (!conn->handshaked) { - while ((line = i_stream_next_line(conn->input)) != NULL) { - if (strncmp(line, "VERSION\t", 8) == 0) { - if (strncmp(line + 8, "1\t", 2) != 0) { - i_error("Auth master version mismatch"); - auth_connection_close(conn); - return; - } - } else if (strncmp(line, "SPID\t", 5) == 0) { - conn->handshaked = TRUE; - break; - } - } + fields = array_get(&reply->extra_fields, &count); + for (i = 0; i < count; i++) { + key = t_str_ucase(t_strcut(fields[i], '=')); + value = strchr(fields[i], '='); + if (value != NULL) + value++; + else + value = "1"; + env_put(t_strconcat(key, "=", value, NULL)); } - - line = i_stream_next_line(conn->input); - if (line != NULL) { - if (strncmp(line, "USER\t1\t", 7) == 0) { - auth_parse_input(conn, line + 7); - } else if (strcmp(line, "NOTFOUND\t1") == 0) - conn->return_value = 0; - else if (strncmp(line, "FAIL\t1\t", 7) == 0) - conn->return_value = -1; - else { - i_error("BUG: Unexpected input from auth master: %s", - line); - auth_connection_close(conn); - } - io_loop_stop(current_ioloop); - } + env_put(t_strconcat("HOME=", reply->home, NULL)); } int auth_client_put_user_env(struct auth_connection *conn, const char *user) { - if (auth_connection_connect(conn) < 0) - return -1; - - conn->current_user = user; - conn->return_value = -1; + struct auth_user_reply reply; + pool_t pool; + int ret; - o_stream_send_str(conn->output, - t_strconcat("USER\t1\t", user, "\t" - "service=expire\n", NULL)); - - io_loop_run(current_ioloop); - - conn->current_user = NULL; - return conn->return_value; + pool = pool_alloconly_create("userdb lookup", 512); + ret = auth_master_user_lookup(conn, user, "expire", pool, &reply); + if (ret > 0) + auth_set_env(user, &reply); + pool_unref(&pool); + return ret; }
--- a/src/plugins/expire/expire-tool.c Sat Nov 01 14:25:05 2008 +0200 +++ b/src/plugins/expire/expire-tool.c Sat Nov 01 14:49:12 2008 +0200 @@ -204,7 +204,7 @@ memset(&ctx, 0, sizeof(ctx)); ctx.testrun = testrun; - ctx.auth_conn = auth_connection_init(auth_socket); + ctx.auth_conn = auth_master_init(auth_socket, getenv("DEBUG") != NULL); env = expire_env_init(getenv("EXPIRE"), getenv("EXPIRE_ALTMOVE")); dict = dict_init(getenv("EXPIRE_DICT"), DICT_DATA_TYPE_UINT32, ""); if (dict == NULL) @@ -292,7 +292,7 @@ if (ctx.user != NULL) user_deinit(&ctx); - auth_connection_deinit(ctx.auth_conn); + auth_master_deinit(&ctx.auth_conn); mail_storage_deinit(); dict_drivers_unregister_builtin();