dovecot-1.2: expire-tool: Use the new auth-master API instead of...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Nov 1 14:49:35 EET 2008
details: http://hg.dovecot.org/dovecot-1.2/rev/ffe34451c01a
changeset: 8370:ffe34451c01a
user: Timo Sirainen <tss at iki.fi>
date: Sat Nov 01 14:49:12 2008 +0200
description:
expire-tool: Use the new auth-master API instead of doing the lookup ourself.
diffstat:
3 files changed, 49 insertions(+), 188 deletions(-)
src/plugins/expire/Makefile.am | 2
src/plugins/expire/auth-client.c | 231 +++++++-------------------------------
src/plugins/expire/expire-tool.c | 4
diffs (truncated from 310 to 300 lines):
diff -r 6db401560d37 -r ffe34451c01a src/plugins/expire/Makefile.am
--- 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 @@ 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 -r 6db401560d37 -r ffe34451c01a src/plugins/expire/auth-client.c
--- 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
+static uid_t current_uid = 0;
-struct auth_connection {
- char *auth_socket;
+static void auth_set_env(const char *user, struct auth_user_reply *reply)
+{
+ const char *const *fields, *key, *value;
+ unsigned int i, count;
- int fd;
- struct io *io;
- struct istream *input;
- struct ostream *output;
+ 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));
- 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;
+ if (reply->home == NULL) {
+ /* we must have a home directory */
+ i_error("userdb(%s) didn't return a home directory", user);
+ return;
}
-
- 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)
-{
- 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 (!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 @@ static void auth_parse_input(struct auth
/* 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;
+ if (reply->uid != current_uid) {
+ if (seteuid(reply->uid) < 0)
+ i_fatal("seteuid(%s) failed: %m", dec2str(reply->uid));
+ current_uid = reply->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;
+ 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));
}
-
- 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);
- }
+ 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;
+ struct auth_user_reply reply;
+ pool_t pool;
+ int ret;
- 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;
+ 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 -r 6db401560d37 -r ffe34451c01a src/plugins/expire/expire-tool.c
--- 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 @@ 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, "");
More information about the dovecot-cvs
mailing list