changeset 21743:6f75b9de84e1

auth: passdb/userdb lookups via auth-worker cached too much of the replies Only the fields returned by the lookup itself were supposed to be cached. This was especially problematic if the lookup via auth-worker didn't uniquely identify the user. For example doing a passdb lookup for an attribute shared by multiple users could have caused the reply to contain the previous cached user's all extra fields.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Mon, 13 Mar 2017 13:49:04 +0200
parents 0347ed67254e
children 38e0c1b1b1c1
files src/auth/auth-worker-client.c
diffstat 1 files changed, 15 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/auth/auth-worker-client.c	Wed Mar 15 13:29:11 2017 +0200
+++ b/src/auth/auth-worker-client.c	Mon Mar 13 13:49:04 2017 +0200
@@ -98,6 +98,11 @@
 			(void)auth_request_import(auth_request, key, value);
 		}
 	}
+	/* reset changed-fields, so we'll export only the ones that were
+	   changed by this lookup. */
+	auth_fields_snapshot(auth_request->extra_fields);
+	if (auth_request->userdb_reply != NULL)
+		auth_fields_snapshot(auth_request->userdb_reply);
 
 	auth_request_init(auth_request);
 	return auth_request;
@@ -129,7 +134,12 @@
 {
 	if (!auth_fields_is_empty(request->extra_fields)) {
 		str_append_c(str, '\t');
-		auth_fields_append(request->extra_fields, str, 0, 0);
+		/* export only the fields changed by this lookup, so the
+		   changed-flag gets preserved correctly on the master side as
+		   well. */
+		auth_fields_append(request->extra_fields, str,
+				   AUTH_FIELD_FLAG_CHANGED,
+				   AUTH_FIELD_FLAG_CHANGED);
 	}
 	if (request->userdb_reply != NULL &&
 	    auth_fields_is_empty(request->userdb_reply)) {
@@ -381,7 +391,10 @@
 		str_append(str, "OK\t");
 		str_append_tabescaped(str, auth_request->user);
 		str_append_c(str, '\t');
-		auth_fields_append(auth_request->userdb_reply, str, 0, 0);
+		/* export only the fields changed by this lookup */
+		auth_fields_append(auth_request->userdb_reply, str,
+				   AUTH_FIELD_FLAG_CHANGED,
+				   AUTH_FIELD_FLAG_CHANGED);
 		if (auth_request->userdb_lookup_tempfailed)
 			str_append(str, "\ttempfail");
 		break;