changeset 10004:4c532d8222f3 HEAD

authtest binary is now accessed via "doveadm auth" and "doveadm user".
author Timo Sirainen <tss@iki.fi>
date Thu, 08 Oct 2009 18:43:17 -0400
parents 3721ae3917fc
children 910059d94bbc
files .hgignore src/doveadm/Makefile.am src/doveadm/doveadm-auth.c src/doveadm/doveadm.c src/doveadm/doveadm.h src/util/Makefile.am src/util/authtest.c
diffstat 7 files changed, 237 insertions(+), 222 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Thu Oct 08 18:33:50 2009 -0400
+++ b/.hgignore	Thu Oct 08 18:43:17 2009 -0400
@@ -78,7 +78,6 @@
 src/plugins/fts-squat/squat-test
 src/pop3-login/pop3-login
 src/pop3/pop3
-src/util/authtest
 src/util/gdbhelper
 src/util/idxview
 src/util/imap-utf7
--- a/src/doveadm/Makefile.am	Thu Oct 08 18:33:50 2009 -0400
+++ b/src/doveadm/Makefile.am	Thu Oct 08 18:43:17 2009 -0400
@@ -29,8 +29,9 @@
 
 doveadm_SOURCES = \
 	doveadm.c \
-	doveadm-pw.c \
-	doveadm-mail.c
+	doveadm-auth.c \
+	doveadm-mail.c \
+	doveadm-pw.c
 
 noinst_HEADERS = \
 	doveadm-mail.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/doveadm/doveadm-auth.c	Thu Oct 08 18:43:17 2009 -0400
@@ -0,0 +1,229 @@
+/* Copyright (c) 2009 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "ioloop.h"
+#include "array.h"
+#include "askpass.h"
+#include "base64.h"
+#include "str.h"
+#include "auth-client.h"
+#include "auth-master.h"
+#include "auth-server-connection.h"
+#include "doveadm.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+struct authtest_input {
+	const char *username;
+	const char *password;
+	struct auth_user_info info;
+};
+
+static int
+cmd_user_input(const char *auth_socket_path, const struct authtest_input *input)
+{
+	struct auth_master_connection *conn;
+	pool_t pool;
+	struct auth_user_reply reply;
+	const char *const *fields;
+	unsigned int i, count;
+	int ret;
+
+	if (auth_socket_path == NULL)
+		auth_socket_path = PKG_RUNDIR"/auth-userdb";
+
+	pool = pool_alloconly_create("auth master lookup", 1024);
+
+	conn = auth_master_init(auth_socket_path, FALSE);
+	ret = auth_master_user_lookup(conn, input->username, &input->info,
+				      pool, &reply);
+	if (ret < 0)
+		i_fatal("userdb lookup failed");
+	else if (ret == 0) {
+		printf("userdb lookup: user %s doesn't exist\n",
+		       input->username);
+	} else {
+		printf("userdb: %s\n", input->username);
+
+		if (reply.uid != (uid_t)-1)
+			printf("uid   : %s\n", dec2str(reply.uid));
+		if (reply.gid != (gid_t)-1)
+			printf("gid   : %s\n", dec2str(reply.gid));
+		if (reply.user != NULL)
+			printf("user  : %s\n", reply.user);
+		if (reply.home != NULL)
+			printf("home  : %s\n", reply.home);
+		if (reply.chroot != NULL)
+			printf("chroot: %s\n", reply.chroot);
+		fields = array_get(&reply.extra_fields, &count);
+		if (count > 0) {
+			printf("extra fields:\n");
+			for (i = 0; i < count; i++)
+				printf("  %s\n", fields[i]);
+		}
+	}
+	auth_master_deinit(&conn);
+	return ret == 0 ? 1 : 0;
+}
+static void
+auth_callback(struct auth_client_request *request ATTR_UNUSED,
+	      enum auth_request_status status,
+	      const char *data_base64 ATTR_UNUSED,
+	      const char *const *args, void *context)
+{
+	const struct authtest_input *input = context;
+
+	if (!io_loop_is_running(current_ioloop))
+		return;
+
+	if (status == 0)
+		i_fatal("passdb expects SASL continuation");
+
+	if (status < 0)
+		printf("passdb: %s auth failed\n", input->username);
+	else
+		printf("passdb: %s auth succeeded\n", input->username);
+
+	if (*args != NULL) {
+		printf("extra fields:\n");
+		for (; *args != NULL; args++)
+			printf("  %s\n", *args);
+	}
+	io_loop_stop(current_ioloop);
+}
+
+static void auth_connected(struct auth_client *client,
+			   bool connected, void *context)
+{
+	struct authtest_input *input = context;
+	struct auth_request_info info;
+	string_t *init_resp, *base64_resp;
+
+	if (!connected)
+		i_fatal("Couldn't connect to auth socket");
+
+	init_resp = t_str_new(128);
+	str_append_c(init_resp, '\0');
+	str_append(init_resp, input->username);
+	str_append_c(init_resp, '\0');
+	str_append(init_resp, input->password);
+
+	base64_resp = t_str_new(128);
+	base64_encode(str_data(init_resp), str_len(init_resp), base64_resp);
+
+	memset(&info, 0, sizeof(info));
+	info.mech = "PLAIN";
+	info.service = input->info.service;
+	info.local_ip = input->info.local_ip;
+	info.local_port = input->info.local_port;
+	info.remote_ip = input->info.remote_ip;
+	info.remote_port = input->info.remote_port;
+	info.initial_resp_base64 = str_c(base64_resp);
+
+	(void)auth_client_request_new(client, &info,
+				      auth_callback, input);
+}
+
+static int
+cmd_auth_input(const char *auth_socket_path, struct authtest_input *input)
+{
+	struct auth_client *client;
+
+	if (auth_socket_path == NULL)
+		auth_socket_path = PKG_RUNDIR"/auth-client";
+
+	client = auth_client_init(auth_socket_path, getpid(), FALSE);
+	auth_client_set_connect_notify(client, auth_connected, input);
+
+	io_loop_run(current_ioloop);
+
+	auth_client_set_connect_notify(client, NULL, NULL);
+	auth_client_deinit(&client);
+	return 0;
+}
+
+static void auth_user_info_parse(struct auth_user_info *info, const char *arg)
+{
+	if (strncmp(arg, "service=", 8) == 0)
+		info->service = arg + 8;
+	else if (strncmp(arg, "lip=", 4) == 0) {
+		if (net_addr2ip(arg + 4, &info->local_ip) < 0)
+			i_fatal("lip: Invalid ip");
+	} else if (strncmp(arg, "rip=", 4) == 0) {
+		if (net_addr2ip(arg + 4, &info->remote_ip) < 0)
+			i_fatal("rip: Invalid ip");
+	} else if (strncmp(arg, "lport=", 6) == 0) {
+		info->local_port = atoi(arg + 6);
+	} else if (strncmp(arg, "rport=", 6) == 0) {
+		info->remote_port = atoi(arg + 6);
+	} else {
+		i_fatal("Unknown -x argument: %s", arg);
+	}
+}
+
+static void
+auth_cmd_common(const struct doveadm_cmd *cmd, int argc, char *argv[])
+{
+	const char *auth_socket_path = NULL;
+	struct authtest_input input;
+	int c;
+
+	memset(&input, 0, sizeof(input));
+	input.info.service = "doveadm";
+
+	while ((c = getopt(argc, argv, "a:x:")) > 0) {
+		switch (c) {
+		case 'a':
+			auth_socket_path = optarg;
+			break;
+		case 'x':
+			auth_user_info_parse(&input.info, optarg);
+			break;
+		default:
+			help(cmd);
+		}
+	}
+	if (optind == argc)
+		help(cmd);
+
+	if (cmd == &doveadm_cmd_auth) {
+		input.username = argv[optind++];
+		input.password = argv[optind] != NULL ? argv[optind] :
+			t_askpass("Password: ");
+		if (cmd_auth_input(auth_socket_path, &input) < 0)
+			exit(1);
+	} else {
+		bool first = TRUE;
+
+		while ((input.username = argv[optind++]) != NULL) {
+			if (first)
+				first = FALSE;
+			else
+				putchar('\n');
+			if (cmd_user_input(auth_socket_path, &input) < 0)
+				exit(1);
+		}
+	}
+}
+
+static void cmd_auth(int argc, char *argv[])
+{
+	auth_cmd_common(&doveadm_cmd_auth, argc, argv);
+}
+
+static void cmd_user(int argc, char *argv[])
+{
+	auth_cmd_common(&doveadm_cmd_user, argc, argv);
+}
+
+struct doveadm_cmd doveadm_cmd_auth = {
+	cmd_auth, "auth",
+	"[-a <auth socket path>] [-x <auth info>] <user> [<password>]", NULL
+};
+
+struct doveadm_cmd doveadm_cmd_user = {
+	cmd_user, "user",
+	"[-a <auth socket path>] [-x <auth info>] <user> [<user> ...]", NULL
+};
--- a/src/doveadm/doveadm.c	Thu Oct 08 18:33:50 2009 -0400
+++ b/src/doveadm/doveadm.c	Thu Oct 08 18:43:17 2009 -0400
@@ -79,6 +79,8 @@
 	i_array_init(&doveadm_cmds, 32);
 	doveadm_mail_init();
 	doveadm_register_cmd(&doveadm_cmd_help);
+	doveadm_register_cmd(&doveadm_cmd_auth);
+	doveadm_register_cmd(&doveadm_cmd_user);
 	doveadm_register_cmd(&doveadm_cmd_pw);
 
 	/* "+" is GNU extension to stop at the first non-option.
@@ -96,7 +98,7 @@
 	argv += optind;
 
 	if (!doveadm_try_run(cmd_name, argc, argv) &&
-	    doveadm_mail_try_run(cmd_name, argc, argv))
+	    !doveadm_mail_try_run(cmd_name, argc, argv))
 		usage();
 
 	master_service_deinit(&master_service);
--- a/src/doveadm/doveadm.h	Thu Oct 08 18:33:50 2009 -0400
+++ b/src/doveadm/doveadm.h	Thu Oct 08 18:43:17 2009 -0400
@@ -12,6 +12,8 @@
 	const char *long_usage;
 };
 
+extern struct doveadm_cmd doveadm_cmd_auth;
+extern struct doveadm_cmd doveadm_cmd_user;
 extern struct doveadm_cmd doveadm_cmd_pw;
 
 void doveadm_register_cmd(const struct doveadm_cmd *cmd);
--- a/src/util/Makefile.am	Thu Oct 08 18:33:50 2009 -0400
+++ b/src/util/Makefile.am	Thu Oct 08 18:43:17 2009 -0400
@@ -1,7 +1,6 @@
 pkglibexecdir = $(libexecdir)/dovecot
 
 pkglibexec_PROGRAMS = \
-	authtest \
 	rawlog \
 	gdbhelper \
 	idxview \
@@ -24,11 +23,6 @@
 	-I$(top_srcdir)/src/auth \
 	-DPKG_RUNDIR=\""$(rundir)"\"
 
-authtest_LDADD = $(LIBDOVECOT)
-authtest_DEPENDENCIES = $(LIBDOVECOT)
-authtest_SOURCES = \
-	authtest.c
-
 rawlog_LDADD = $(LIBDOVECOT)
 rawlog_DEPENDENCIES = $(LIBDOVECOT)
 rawlog_SOURCES = \
--- a/src/util/authtest.c	Thu Oct 08 18:33:50 2009 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,212 +0,0 @@
-/* Copyright (c) 2009 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "ioloop.h"
-#include "array.h"
-#include "base64.h"
-#include "str.h"
-#include "master-service.h"
-#include "auth-client.h"
-#include "auth-server-connection.h"
-#include "auth-master.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-struct authtest_input {
-	const char *username;
-	const char *password;
-	struct auth_user_info info;
-};
-
-static const char *auth_socket_path = NULL;
-
-static int authtest_userdb(const struct authtest_input *input)
-{
-	struct auth_master_connection *conn;
-	pool_t pool;
-	struct auth_user_reply reply;
-	const char *const *fields;
-	unsigned int i, count;
-	int ret;
-
-	if (auth_socket_path == NULL)
-		auth_socket_path = PKG_RUNDIR"/auth-userdb";
-
-	pool = pool_alloconly_create("auth master lookup", 1024);
-
-	conn = auth_master_init(auth_socket_path, FALSE);
-	ret = auth_master_user_lookup(conn, input->username, &input->info,
-				      pool, &reply);
-	if (ret < 0)
-		i_fatal("userdb lookup failed");
-	else if (ret == 0) {
-		printf("userdb lookup: user %s doesn't exist\n",
-		       input->username);
-	} else {
-		printf("userdb: %s\n", input->username);
-
-		if (reply.uid != (uid_t)-1)
-			printf("uid   : %s\n", dec2str(reply.uid));
-		if (reply.gid != (gid_t)-1)
-			printf("gid   : %s\n", dec2str(reply.gid));
-		if (reply.user != NULL)
-			printf("user  : %s\n", reply.user);
-		if (reply.home != NULL)
-			printf("home  : %s\n", reply.home);
-		if (reply.chroot != NULL)
-			printf("chroot: %s\n", reply.chroot);
-		fields = array_get(&reply.extra_fields, &count);
-		if (count > 0) {
-			printf("extra fields:\n");
-			for (i = 0; i < count; i++)
-				printf("  %s\n", fields[i]);
-		}
-	}
-	auth_master_deinit(&conn);
-	return ret == 0 ? 1 : 0;
-}
-
-static void
-auth_callback(struct auth_client_request *request ATTR_UNUSED,
-	      enum auth_request_status status,
-	      const char *data_base64 ATTR_UNUSED,
-	      const char *const *args, void *context)
-{
-	const struct authtest_input *input = context;
-
-	if (!io_loop_is_running(current_ioloop))
-		return;
-
-	if (status == 0)
-		i_fatal("passdb expects SASL continuation");
-
-	if (status < 0)
-		printf("passdb: %s auth failed\n", input->username);
-	else
-		printf("passdb: %s auth succeeded\n", input->username);
-
-	if (*args != NULL) {
-		printf("extra fields:\n");
-		for (; *args != NULL; args++)
-			printf("  %s\n", *args);
-	}
-	io_loop_stop(current_ioloop);
-}
-
-static void auth_connected(struct auth_client *client,
-			   bool connected, void *context)
-{
-	struct authtest_input *input = context;
-	struct auth_request_info info;
-	string_t *init_resp, *base64_resp;
-
-	if (!connected)
-		i_fatal("Couldn't connect to auth socket");
-
-	init_resp = t_str_new(128);
-	str_append_c(init_resp, '\0');
-	str_append(init_resp, input->username);
-	str_append_c(init_resp, '\0');
-	str_append(init_resp, input->password);
-
-	base64_resp = t_str_new(128);
-	base64_encode(str_data(init_resp), str_len(init_resp), base64_resp);
-
-	memset(&info, 0, sizeof(info));
-	info.mech = "PLAIN";
-	info.service = input->info.service;
-	info.local_ip = input->info.local_ip;
-	info.local_port = input->info.local_port;
-	info.remote_ip = input->info.remote_ip;
-	info.remote_port = input->info.remote_port;
-	info.initial_resp_base64 = str_c(base64_resp);
-
-	(void)auth_client_request_new(client, &info,
-				      auth_callback, input);
-}
-
-static int
-authtest_passdb(struct authtest_input *input)
-{
-	struct auth_client *client;
-
-	if (auth_socket_path == NULL)
-		auth_socket_path = PKG_RUNDIR"/auth-client";
-
-	client = auth_client_init(auth_socket_path, getpid(), FALSE);
-	auth_client_set_connect_notify(client, auth_connected, input);
-
-	io_loop_run(current_ioloop);
-
-	auth_client_set_connect_notify(client, NULL, NULL);
-	auth_client_deinit(&client);
-	return 0;
-}
-
-static void auth_user_info_parse(struct auth_user_info *info, const char *arg)
-{
-	if (strncmp(arg, "service=", 8) == 0)
-		info->service = arg + 8;
-	else if (strncmp(arg, "lip=", 4) == 0) {
-		if (net_addr2ip(arg + 4, &info->local_ip) < 0)
-			i_fatal("lip: Invalid ip");
-	} else if (strncmp(arg, "rip=", 4) == 0) {
-		if (net_addr2ip(arg + 4, &info->remote_ip) < 0)
-			i_fatal("rip: Invalid ip");
-	} else if (strncmp(arg, "lport=", 6) == 0) {
-		info->local_port = atoi(arg + 6);
-	} else if (strncmp(arg, "rport=", 6) == 0) {
-		info->remote_port = atoi(arg + 6);
-	} else {
-		i_fatal("Unknown -x argument: %s", arg);
-	}
-}
-
-static void usage(void)
-{
-	i_fatal(
-"usage: authtest [-a <auth socket path>] [-x <auth info>] <user> [<password]");
-}
-
-int main(int argc, char *argv[])
-{
-	const char *getopt_str;
-	struct authtest_input input;
-	int c, ret;
-
-	memset(&input, 0, sizeof(input));
-	input.info.service = "authtest";
-
-	master_service = master_service_init("authtest",
-					     MASTER_SERVICE_FLAG_STANDALONE,
-					     argc, argv);
-	getopt_str = t_strconcat("a:x:", master_service_getopt_string(), NULL);
-	while ((c = getopt(argc, argv, getopt_str)) > 0) {
-		switch (c) {
-		case 'a':
-			auth_socket_path = optarg;
-			break;
-		case 'x':
-			auth_user_info_parse(&input.info, optarg);
-			break;
-		default:
-			if (!master_service_parse_option(master_service,
-							 c, optarg))
-				usage();
-		}
-	}
-	if (optind == argc)
-		usage();
-
-	input.username = argv[optind++];
-	if (argv[optind] == NULL)
-		ret = authtest_userdb(&input);
-	else {
-		input.password = argv[optind];
-		ret = authtest_passdb(&input);
-	}
-	master_service_deinit(&master_service);
-	return ret;
-}