changeset 6214:974066ba68a3 HEAD

Pass extra_fields from auth worker to server also if authentication failed.
author Timo Sirainen <tss@iki.fi>
date Tue, 07 Aug 2007 13:17:50 +0300
parents e33a87152c41
children a9c934833374
files src/auth/auth-worker-client.c src/auth/passdb-blocking.c
diffstat 2 files changed, 52 insertions(+), 92 deletions(-) [+]
line wrap: on
line diff
--- a/src/auth/auth-worker-client.c	Tue Aug 07 13:15:28 2007 +0300
+++ b/src/auth/auth-worker-client.c	Tue Aug 07 13:17:50 2007 +0300
@@ -93,9 +93,11 @@
 	str = t_str_new(64);
 	str_printfa(str, "%u\t", request->id);
 
-	if (result != PASSDB_RESULT_OK)
-		str_printfa(str, "FAIL\t%d", result);
-	else {
+	if (result != PASSDB_RESULT_OK) {
+		str_printfa(str, "FAIL\t%d\t", result);
+		if (request->passdb_password != NULL)
+			str_append(str, request->passdb_password);
+	} else {
 		str_append(str, "OK\t");
 		str_append(str, request->user);
 		str_append_c(str, '\t');
@@ -103,19 +105,19 @@
 			str_append(str, request->passdb_password);
 		if (request->no_password)
 			str_append(str, "\tnopassword");
-		if (request->extra_fields != NULL) {
-			const char *field =
-				auth_stream_reply_export(request->extra_fields);
-
-			str_append_c(str, '\t');
-			str_append(str, field);
-		}
 		if (request->userdb_reply != NULL) {
 			const char *data =
 				auth_stream_reply_export(request->userdb_reply);
 			add_userdb_replies(str, data);
 		}
 	}
+	if (request->extra_fields != NULL) {
+		const char *field =
+			auth_stream_reply_export(request->extra_fields);
+
+		str_append_c(str, '\t');
+		str_append(str, field);
+	}
 	str_append_c(str, '\n');
 	o_stream_send(client->output, str_data(str), str_len(str));
 
--- a/src/auth/passdb-blocking.c	Tue Aug 07 13:15:28 2007 +0300
+++ b/src/auth/passdb-blocking.c	Tue Aug 07 13:17:50 2007 +0300
@@ -9,104 +9,56 @@
 
 #include <stdlib.h>
 
-static enum passdb_result
-check_failure(struct auth_request *request, const char **reply)
+static void
+auth_worker_reply_parse_args(struct auth_request *request,
+			     const char *const *args)
 {
-	enum passdb_result ret;
-	const char *p;
-
-	/* OK / FAIL */
-	if (strncmp(*reply, "OK\t", 3) == 0) {
-		*reply += 3;
-		return PASSDB_RESULT_OK;
-	}
+	if (**args != '\0')
+		request->passdb_password = p_strdup(request->pool, *args);
+	args++;
 
-	/* FAIL \t result \t password */
-	if (strncmp(*reply, "FAIL\t", 5) == 0) {
-		*reply += 5;
-		ret = atoi(t_strcut(*reply, '\t'));
-
-		p = strchr(*reply, '\t');
-		if (p == NULL)
-			*reply += strlen(*reply);
-		else
-			*reply = p + 1;
-		if (ret != PASSDB_RESULT_OK)
-			return ret;
-
-		auth_request_log_error(request, "blocking",
-			"Received invalid FAIL result from worker: %d", ret);
-		return PASSDB_RESULT_INTERNAL_FAILURE;
-	} else {
-		auth_request_log_error(request, "blocking",
-			"Received unknown reply from worker: %s", *reply);
-		return PASSDB_RESULT_INTERNAL_FAILURE;
+	if (*args != NULL) {
+		i_assert(auth_stream_is_empty(request->extra_fields) ||
+			 request->master_user != NULL);
+		auth_request_set_fields(request, args, NULL);
 	}
 }
 
-static int get_pass_reply(struct auth_request *request, const char *reply,
-			  const char **password_r, const char **scheme_r)
+static enum passdb_result
+auth_worker_reply_parse(struct auth_request *request, const char *reply)
 {
-	const char *p, *p2;
-
-	/* user \t {scheme}password [\t extra] */
-	p = strchr(reply, '\t');
+	enum passdb_result ret;
+	const char *const *args;
 
-	/* username may have changed, update it */
-	auth_request_set_field(request, "user", p == NULL ? reply :
-			       t_strdup_until(reply, p), NULL);
-	if (p == NULL) {
-		/* we didn't get a password. */
-		*password_r = NULL;
-		*scheme_r = NULL;
-		return 0;
-	}
-	p2 = strchr(++p, '\t');
-	if (p2 == NULL) {
-		*password_r = p;
-		reply = "";
-	} else {
-		*password_r = t_strdup_until(p, p2);
-		reply = p2 + 1;
+	args = t_strsplit(reply, "\t");
+
+	if (strcmp(*args, "OK") == 0 && args[1] != NULL && args[2] != NULL) {
+		/* OK \t user \t password [\t extra] */
+		auth_request_set_field(request, "user", args[1], NULL);
+		auth_worker_reply_parse_args(request, args + 2);
+		return PASSDB_RESULT_OK;
 	}
 
-	if (**password_r == '\0') {
-		*password_r = NULL;
-		*scheme_r = NULL;
-	} else {
-		request->passdb_password =
-			p_strdup(request->pool, *password_r);
-
-		*scheme_r = password_get_scheme(password_r);
-		if (*scheme_r == NULL) {
-			auth_request_log_error(request, "blocking",
-				"Received reply from worker without "
-				"password scheme");
-			return -1;
+	if (strcmp(*args, "FAIL") == 0 && args[1] != NULL && args[2] != NULL) {
+		/* FAIL \t result \t password [\t extra] */
+		ret = atoi(args[1]);
+		if (ret != PASSDB_RESULT_OK) {
+			auth_worker_reply_parse_args(request, args + 2);
+			return ret;
 		}
 	}
 
-	if (*reply != '\0') {
-		i_assert(auth_stream_is_empty(request->extra_fields) ||
-			 request->master_user != NULL);
-
-		auth_request_set_fields(request, t_strsplit(reply, "\t"), NULL);
-	}
-	return 0;
+	auth_request_log_error(request, "blocking",
+		"Received invalid reply from worker: %s", reply);
+	return PASSDB_RESULT_INTERNAL_FAILURE;
 }
 
 static void
 verify_plain_callback(struct auth_request *request, const char *reply)
 {
 	enum passdb_result result;
-	const char *password, *scheme;
 
-	result = check_failure(request, &reply);
-	if (result > 0) {
-		if (get_pass_reply(request, reply, &password, &scheme) < 0)
-			result = PASSDB_RESULT_INTERNAL_FAILURE;
-	}
-
+	result = auth_worker_reply_parse(request, reply);
 	auth_request_verify_plain_callback(result, request);
 }
 
@@ -132,10 +84,16 @@
 	enum passdb_result result;
 	const char *password = NULL, *scheme = NULL;
 
-	result = check_failure(request, &reply);
-	if (result > 0) {
-		if (get_pass_reply(request, reply, &password, &scheme) < 0)
+	result = auth_worker_reply_parse(request, reply);
+	if (result == PASSDB_RESULT_OK && request->passdb_password != NULL) {
+		password = request->passdb_password;
+		scheme = password_get_scheme(&password);
+		if (scheme == NULL) {
+			auth_request_log_error(request, "blocking",
+				"Received reply from worker without "
+				"password scheme");
 			result = PASSDB_RESULT_INTERNAL_FAILURE;
+		}
 	}
 
 	passdb_handle_credentials(result, password, scheme,