dovecot-2.2: auth: Added userdb result_success/failure/tempfail ...

dovecot at dovecot.org dovecot at dovecot.org
Sun Dec 8 20:48:15 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/eeadb7b5045b
changeset: 17042:eeadb7b5045b
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Dec 08 20:48:03 2013 +0200
description:
auth: Added userdb result_success/failure/tempfail and skip settings, similar to passdb's.

diffstat:

 src/auth/auth-master-connection.c  |    4 +-
 src/auth/auth-postfix-connection.c |    4 +-
 src/auth/auth-request-handler.c    |    4 +-
 src/auth/auth-request.c            |  106 ++++++++++++++++++++++++++++++------
 src/auth/auth-request.h            |    4 +-
 src/auth/auth-settings.c           |   16 +++++-
 src/auth/auth-settings.h           |    8 ++-
 src/auth/auth-worker-client.c      |    3 +-
 src/auth/auth.c                    |   40 ++++++++++---
 src/auth/auth.h                    |   31 +++++++---
 src/auth/userdb-blocking.c         |    2 +-
 src/auth/userdb-dict.c             |    2 -
 src/auth/userdb-ldap.c             |    2 -
 src/auth/userdb-nss.c              |    1 -
 src/auth/userdb-passwd-file.c      |    1 -
 src/auth/userdb-passwd.c           |    1 -
 src/auth/userdb-sql.c              |    2 -
 src/auth/userdb-static.c           |    1 -
 src/auth/userdb-vpopmail.c         |    1 -
 19 files changed, 172 insertions(+), 61 deletions(-)

diffs (truncated from 612 to 300 lines):

diff -r 0595d54ab34a -r eeadb7b5045b src/auth/auth-master-connection.c
--- a/src/auth/auth-master-connection.c	Sun Dec 08 19:02:12 2013 +0200
+++ b/src/auth/auth-master-connection.c	Sun Dec 08 20:48:03 2013 +0200
@@ -252,7 +252,7 @@
 	string_t *str;
 	const char *value;
 
-	if (auth_request->userdb_lookup_failed)
+	if (auth_request->userdb_lookup_tempfailed)
 		result = USERDB_RESULT_INTERNAL_FAILURE;
 
 	if (result == USERDB_RESULT_OK) {
@@ -264,7 +264,7 @@
 	switch (result) {
 	case USERDB_RESULT_INTERNAL_FAILURE:
 		str_printfa(str, "FAIL\t%u", auth_request->id);
-		if (auth_request->userdb_lookup_failed) {
+		if (auth_request->userdb_lookup_tempfailed) {
 			value = auth_fields_find(auth_request->userdb_reply,
 						 "reason");
 			if (value != NULL)
diff -r 0595d54ab34a -r eeadb7b5045b src/auth/auth-postfix-connection.c
--- a/src/auth/auth-postfix-connection.c	Sun Dec 08 19:02:12 2013 +0200
+++ b/src/auth/auth-postfix-connection.c	Sun Dec 08 20:48:03 2013 +0200
@@ -69,13 +69,13 @@
 	string_t *str;
 	const char *value;
 
-	if (auth_request->userdb_lookup_failed)
+	if (auth_request->userdb_lookup_tempfailed)
 		result = USERDB_RESULT_INTERNAL_FAILURE;
 
 	str = t_str_new(128);
 	switch (result) {
 	case USERDB_RESULT_INTERNAL_FAILURE:
-		if (auth_request->userdb_lookup_failed)
+		if (auth_request->userdb_lookup_tempfailed)
 			value = auth_fields_find(auth_request->userdb_reply, "reason");
 		else
 			value = NULL;
diff -r 0595d54ab34a -r eeadb7b5045b src/auth/auth-request-handler.c
--- a/src/auth/auth-request-handler.c	Sun Dec 08 19:02:12 2013 +0200
+++ b/src/auth/auth-request-handler.c	Sun Dec 08 20:48:03 2013 +0200
@@ -633,14 +633,14 @@
 
 	auth_request_set_state(request, AUTH_REQUEST_STATE_FINISHED);
 
-	if (request->userdb_lookup_failed)
+	if (request->userdb_lookup_tempfailed)
 		result = USERDB_RESULT_INTERNAL_FAILURE;
 
 	str = t_str_new(128);
 	switch (result) {
 	case USERDB_RESULT_INTERNAL_FAILURE:
 		str_printfa(str, "FAIL\t%u", request->id);
-		if (request->userdb_lookup_failed) {
+		if (request->userdb_lookup_tempfailed) {
 			value = auth_fields_find(request->userdb_reply, "reason");
 			if (value != NULL)
 				auth_str_add_keyvalue(str, "reason", value);
diff -r 0595d54ab34a -r eeadb7b5045b src/auth/auth-request.c
--- a/src/auth/auth-request.c	Sun Dec 08 19:02:12 2013 +0200
+++ b/src/auth/auth-request.c	Sun Dec 08 20:48:03 2013 +0200
@@ -507,11 +507,26 @@
 }
 
 static bool
+auth_request_want_skip_userdb(struct auth_request *request,
+			      struct auth_userdb *userdb)
+{
+	switch (userdb->skip) {
+	case AUTH_USERDB_SKIP_NEVER:
+		return FALSE;
+	case AUTH_USERDB_SKIP_FOUND:
+		return request->userdb_success;
+	case AUTH_USERDB_SKIP_NOTFOUND:
+		return !request->userdb_success;
+	}
+	i_unreached();
+}
+
+static bool
 auth_request_handle_passdb_callback(enum passdb_result *result,
 				    struct auth_request *request)
 {
 	struct auth_passdb *next_passdb;
-	enum auth_passdb_rule result_rule;
+	enum auth_db_rule result_rule;
 	bool passdb_continue = FALSE;
 
 	if (request->passdb_password != NULL) {
@@ -557,22 +572,22 @@
 	}
 
 	switch (result_rule) {
-	case AUTH_PASSDB_RULE_RETURN:
+	case AUTH_DB_RULE_RETURN:
 		break;
-	case AUTH_PASSDB_RULE_RETURN_OK:
+	case AUTH_DB_RULE_RETURN_OK:
 		request->passdb_success = TRUE;
 		break;
-	case AUTH_PASSDB_RULE_RETURN_FAIL:
+	case AUTH_DB_RULE_RETURN_FAIL:
 		request->passdb_success = FALSE;
 		break;
-	case AUTH_PASSDB_RULE_CONTINUE:
+	case AUTH_DB_RULE_CONTINUE:
 		passdb_continue = TRUE;
 		break;
-	case AUTH_PASSDB_RULE_CONTINUE_OK:
+	case AUTH_DB_RULE_CONTINUE_OK:
 		passdb_continue = TRUE;
 		request->passdb_success = TRUE;
 		break;
-	case AUTH_PASSDB_RULE_CONTINUE_FAIL:
+	case AUTH_DB_RULE_CONTINUE_FAIL:
 		passdb_continue = TRUE;
 		request->passdb_success = FALSE;
 		break;
@@ -982,26 +997,79 @@
 				  struct auth_request *request)
 {
 	struct userdb_module *userdb = request->userdb->userdb;
+	struct auth_userdb *next_userdb;
+	enum auth_db_rule result_rule;
+	bool userdb_continue = FALSE;
 
-	if (result != USERDB_RESULT_OK && request->userdb->next != NULL) {
+	switch (result) {
+	case USERDB_RESULT_OK:
+		result_rule = request->userdb->result_success;
+		break;
+	case USERDB_RESULT_INTERNAL_FAILURE:
+		result_rule = request->userdb->result_internalfail;
+		break;
+	case USERDB_RESULT_USER_UNKNOWN:
+	default:
+		result_rule = request->userdb->result_failure;
+		break;
+	}
+
+	switch (result_rule) {
+	case AUTH_DB_RULE_RETURN:
+		break;
+	case AUTH_DB_RULE_RETURN_OK:
+		request->userdb_success = TRUE;
+		break;
+	case AUTH_DB_RULE_RETURN_FAIL:
+		request->userdb_success = FALSE;
+		break;
+	case AUTH_DB_RULE_CONTINUE:
+		userdb_continue = TRUE;
+		break;
+	case AUTH_DB_RULE_CONTINUE_OK:
+		userdb_continue = TRUE;
+		request->userdb_success = TRUE;
+		break;
+	case AUTH_DB_RULE_CONTINUE_FAIL:
+		userdb_continue = TRUE;
+		request->userdb_success = FALSE;
+		break;
+	}
+
+	next_userdb = request->userdb->next;
+	while (next_userdb != NULL &&
+	       auth_request_want_skip_userdb(request, next_userdb))
+		next_userdb = next_userdb->next;
+
+	if (userdb_continue && next_userdb != NULL) {
 		/* try next userdb. */
 		if (result == USERDB_RESULT_INTERNAL_FAILURE)
 			request->userdbs_seen_internal_failure = TRUE;
 
-		request->userdb = request->userdb->next;
+		if (result == USERDB_RESULT_OK) {
+			/* this userdb lookup succeeded, preserve its extra
+			   fields */
+			auth_fields_snapshot(request->userdb_reply);
+		} else {
+			/* this userdb lookup failed, remove any extra fields
+			   it set */
+			auth_fields_rollback(request->userdb_reply);
+		}
+
+		request->userdb = next_userdb;
 		auth_request_lookup_user(request,
 					 request->private_callback.userdb);
 		return;
 	}
 
-	if (result == USERDB_RESULT_OK)
+	if (request->userdb_success)
 		userdb_template_export(userdb->override_fields_tmpl, request);
-	else if (request->userdbs_seen_internal_failure) {
+	else if (request->userdbs_seen_internal_failure ||
+		 result == USERDB_RESULT_INTERNAL_FAILURE) {
 		/* one of the userdb lookups failed. the user might have been
 		   in there, so this is an internal failure */
 		result = USERDB_RESULT_INTERNAL_FAILURE;
-	} else if (result == USERDB_RESULT_USER_UNKNOWN &&
-		   request->client_pid != 0) {
+	} else if (request->client_pid != 0) {
 		/* this was an actual login attempt, the user should
 		   have been found. */
 		if (auth_request_get_auth(request)->userdbs->next == NULL) {
@@ -1014,7 +1082,7 @@
 		}
 	}
 
-	if (request->userdb_lookup_failed) {
+	if (request->userdb_lookup_tempfailed) {
 		/* no caching */
 	} else if (result != USERDB_RESULT_INTERNAL_FAILURE)
 		auth_request_userdb_save_cache(request, result);
@@ -1044,6 +1112,8 @@
 
 	request->private_callback.userdb = callback;
 	request->userdb_lookup = TRUE;
+	if (request->userdb_reply == NULL)
+		auth_request_init_userdb_reply(request);
 
 	/* (for now) auth_cache is shared between passdb and userdb */
 	cache_key = passdb_cache == NULL ? NULL : userdb->cache_key;
@@ -1496,19 +1566,19 @@
 	if (strcmp(name, "uid") == 0) {
 		uid = userdb_parse_uid(request, value);
 		if (uid == (uid_t)-1) {
-			request->userdb_lookup_failed = TRUE;
+			request->userdb_lookup_tempfailed = TRUE;
 			return;
 		}
 		value = dec2str(uid);
 	} else if (strcmp(name, "gid") == 0) {
 		gid = userdb_parse_gid(request, value);
 		if (gid == (gid_t)-1) {
-			request->userdb_lookup_failed = TRUE;
+			request->userdb_lookup_tempfailed = TRUE;
 			return;
 		}
 		value = dec2str(gid);
 	} else if (strcmp(name, "tempfail") == 0) {
-		request->userdb_lookup_failed = TRUE;
+		request->userdb_lookup_tempfailed = TRUE;
 		return;
 	} else if (auth_request_try_update_username(request, name, value)) {
 		return;
@@ -1549,7 +1619,7 @@
 		for (; *values != NULL; values++) {
 			gid = userdb_parse_gid(request, *values);
 			if (gid == (gid_t)-1) {
-				request->userdb_lookup_failed = TRUE;
+				request->userdb_lookup_tempfailed = TRUE;
 				return;
 			}
 
diff -r 0595d54ab34a -r eeadb7b5045b src/auth/auth-request.h
--- a/src/auth/auth-request.h	Sun Dec 08 19:02:12 2013 +0200
+++ b/src/auth/auth-request.h	Sun Dec 08 20:48:03 2013 +0200
@@ -130,10 +130,12 @@
 	   at the end. mechanisms that don't require passdb, but do a passdb
 	   lookup anyway (e.g. GSSAPI) need to set this to TRUE by default. */
 	unsigned int passdb_success:1;
+	/* userdb equivalent of passdb_success */
+	unsigned int userdb_success:1;
 	/* the last userdb lookup failed either due to "tempfail" extra field
 	   or because one of the returned uid/gid fields couldn't be translated
 	   to a number */
-	unsigned int userdb_lookup_failed:1;
+	unsigned int userdb_lookup_tempfailed:1;
 
 	/* ... mechanism specific data ... */
 };
diff -r 0595d54ab34a -r eeadb7b5045b src/auth/auth-settings.c
--- a/src/auth/auth-settings.c	Sun Dec 08 19:02:12 2013 +0200
+++ b/src/auth/auth-settings.c	Sun Dec 08 20:48:03 2013 +0200
@@ -111,10 +111,12 @@
 	DEF(SET_STR, args),
 	DEF(SET_STR, default_fields),
 	DEF(SET_STR, override_fields),
+
 	DEF(SET_ENUM, skip),
 	DEF(SET_ENUM, result_success),
 	DEF(SET_ENUM, result_failure),
 	DEF(SET_ENUM, result_internalfail),
+
 	DEF(SET_BOOL, deny),
 	DEF(SET_BOOL, pass),
 	DEF(SET_BOOL, master),
@@ -127,10 +129,12 @@
 	.args = "",
 	.default_fields = "",
 	.override_fields = "",
+
 	.skip = "never:authenticated:unauthenticated",
 	.result_success = "return-ok:return:return-fail:continue:continue-ok:continue-fail",
 	.result_failure = "continue:return:return-ok:return-fail:continue-ok:continue-fail",
 	.result_internalfail = "continue:return:return-ok:return-fail:continue-ok:continue-fail",
+
 	.deny = FALSE,


More information about the dovecot-cvs mailing list