From: Timo Sirainen Date: Sat, 1 Nov 2008 12:49:12 +0000 (+0200) Subject: expire-tool: Use the new auth-master API instead of doing the lookup ourself. X-Git-Tag: 1.2.alpha4~119 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=34e7467e72d8a2e6b91ee6b2a50dd44570e12567;p=thirdparty%2Fdovecot%2Fcore.git expire-tool: Use the new auth-master API instead of doing the lookup ourself. --HG-- branch : HEAD --- diff --git a/src/plugins/expire/Makefile.am b/src/plugins/expire/Makefile.am index f8b5ab4683..15115a0211 100644 --- a/src/plugins/expire/Makefile.am +++ b/src/plugins/expire/Makefile.am @@ -2,6 +2,7 @@ pkglibexecdir = $(libexecdir)/dovecot 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 @@ libs = \ $(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 diff --git a/src/plugins/expire/auth-client.c b/src/plugins/expire/auth-client.c index c460795b79..2d55ae6c60 100644 --- a/src/plugins/expire/auth-client.c +++ b/src/plugins/expire/auth-client.c @@ -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 #include -#define MAX_INBUF_SIZE 8192 -#define MAX_OUTBUF_SIZE 512 +static uid_t current_uid = 0; -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; - - 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) -{ - if (conn->fd == -1) - return; - - io_remove(&conn->io); - i_stream_unref(&conn->input); - o_stream_unref(&conn->output); - - 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); -} - -static void auth_parse_input(struct auth_connection *conn, const char *args) +static void auth_set_env(const char *user, struct auth_user_reply *reply) { - 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); + const char *const *fields, *key, *value; + unsigned int i, count; - 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->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)); - if (!home_found) { + if (reply->home == NULL) { /* we must have a home directory */ - i_error("userdb(%s) didn't return a home directory", - conn->current_user); + i_error("userdb(%s) didn't return a home directory", user); return; } - - if (uid == (uid_t)-1) { - i_error("userdb(%s) didn't return uid", conn->current_user); + if (reply->uid == (uid_t)-1) { + i_error("userdb(%s) didn't return uid", 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 @@ static void auth_parse_input(struct auth_connection *conn, const char *args) /* 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; - } - } - } - - 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); + 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)); } + 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; - - 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; + struct auth_user_reply reply; + pool_t pool; + int ret; + + 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; } diff --git a/src/plugins/expire/expire-tool.c b/src/plugins/expire/expire-tool.c index 708683987e..35c9a51537 100644 --- a/src/plugins/expire/expire-tool.c +++ b/src/plugins/expire/expire-tool.c @@ -204,7 +204,7 @@ static void expire_run(bool testrun) 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 @@ static void expire_run(bool testrun) 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();