changeset 8413:24c8bc8098ee HEAD

Give a different error message if authentication succeeds but authorization fails. Added a new "authz" parameter for FAIL result in the auth protocol for this.
author Timo Sirainen <tss@iki.fi>
date Sat, 15 Nov 2008 21:29:59 +0200
parents 6e9100795d89
children d486dfe02c1e
files doc/auth-protocol.txt src/auth/auth-request-handler.c src/imap-login/client-authenticate.c
diffstat 3 files changed, 26 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/doc/auth-protocol.txt	Sat Nov 15 21:10:17 2008 +0200
+++ b/doc/auth-protocol.txt	Sat Nov 15 21:29:59 2008 +0200
@@ -111,12 +111,18 @@
 		       security holes if user-given data is directly put to
 		       base64 string without filtering out tabs.
 
-FAIL parameters may contain "reason=.." parameter which should be sent to
-remote user instead of a standard "Authentication failed" message. For
-example "invalid base64 data". It should NOT be used to give exact reason
-for authentication failure (ie. "user not found" vs. "password mismatch").
-Sending "temp" parameter indicates that the error was a temporary internal
-failure, eg. connection was lost to SQL database.
+FAIL parameters may contain:
+
+ - reason=<str> : <str> should be sent to remote user instead of the standard
+                  "Authentication failed" messages. For example "invalid base64
+		  data". It must NOT be used to give exact reason for
+		  authentication failure (i.e. "user not found" vs. "password
+		  mismatch").
+ - temp         : This is a temporary internal failure, e.g. connection was
+                  lost to SQL database.
+ - authz        : Authentication succeeded, but authorization failed (master
+                  user's password was ok, but destnation user was not ok).
+		  Added in Dovecot v1.2.
 
 CONT command means that the authentication continues, and more data is
 expected from client to finish the authentication. Given base64 data should
@@ -124,7 +130,7 @@
 
 FAIL and OK may contain multiple unspecified parameters which
 authentication client may handle specially. The only one specified here is
-"user=<userid>" parameter, which should always be sent if userid is known.
+"user=<userid>" parameter, which should always be sent if the userid is known.
 
 
 Server <-> Master
--- a/src/auth/auth-request-handler.c	Sat Nov 15 21:10:17 2008 +0200
+++ b/src/auth/auth-request-handler.c	Sat Nov 15 21:29:59 2008 +0200
@@ -237,8 +237,14 @@
 		auth_stream_reply_add(reply, NULL, dec2str(request->id));
 		if (request->user != NULL)
 			auth_stream_reply_add(reply, "user", request->user);
+
 		if (request->internal_failure)
 			auth_stream_reply_add(reply, "temp", NULL);
+		else if (request->master_user != NULL) {
+			/* authentication succeeded, but we can't log in
+			   as the wanted user */
+			auth_stream_reply_add(reply, "authz", NULL);
+		}
 		get_client_extra_fields(request, reply);
 
 		auth_request_handle_failure(request, reply);
--- a/src/imap-login/client-authenticate.c	Sat Nov 15 21:10:17 2008 +0200
+++ b/src/imap-login/client-authenticate.c	Sat Nov 15 21:29:59 2008 +0200
@@ -20,6 +20,8 @@
 
 #define IMAP_SERVICE_NAME "imap"
 #define IMAP_AUTH_FAILED_MSG "["IMAP_RESP_CODE_AUTHFAILED"] "AUTH_FAILED_MSG
+#define IMAP_AUTHZ_FAILED_MSG \
+	"["IMAP_RESP_CODE_AUTHZFAILED"] Authorization failed"
 
 const char *client_authenticate_get_capabilities(bool secured)
 {
@@ -95,6 +97,7 @@
 	string_t *reply;
 	unsigned int port = 143;
 	bool proxy = FALSE, temp = FALSE, nologin = !success, proxy_self;
+	bool authz_failure = FALSE;
 
 	for (; *args != NULL; args++) {
 		if (strcmp(*args, "nologin") == 0)
@@ -103,6 +106,8 @@
 			proxy = TRUE;
 		else if (strcmp(*args, "temp") == 0)
 			temp = TRUE;
+		else if (strcmp(*args, "authz") == 0)
+			authz_failure = TRUE;
 		else if (strncmp(*args, "reason=", 7) == 0)
 			reason = *args + 7;
 		else if (strncmp(*args, "host=", 5) == 0)
@@ -183,6 +188,8 @@
 		else if (temp || proxy_self) {
 			str_append(reply, "NO ["IMAP_RESP_CODE_UNAVAILABLE"] "
 				   AUTH_TEMP_FAILED_MSG);
+		} else if (authz_failure) {
+			str_append(reply, "NO "IMAP_AUTHZ_FAILED_MSG);
 		} else {
 			str_append(reply, "NO "IMAP_AUTH_FAILED_MSG);
 		}