[dovecot-cvs] dovecot/src/auth auth-request-handler.c, 1.3, 1.4 auth-request.c, 1.12, 1.13 auth-request.h, 1.10, 1.11 passdb-blocking.c, 1.1, 1.2 passdb-cache.c, 1.7, 1.8 passdb-cache.h, 1.3, 1.4

cras at dovecot.org cras at dovecot.org
Sat Mar 5 13:48:16 EET 2005


Update of /var/lib/cvs/dovecot/src/auth
In directory talvi:/tmp/cvs-serv7327

Modified Files:
	auth-request-handler.c auth-request.c auth-request.h 
	passdb-blocking.c passdb-cache.c passdb-cache.h 
Log Message:
Added state variable for auth_request and several assertions to make sure
the state is always valid. Fixed assert crash when a user having cached
passdb entry expired tried to authenticate.



Index: auth-request-handler.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-request-handler.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- auth-request-handler.c	28 Feb 2005 22:19:21 -0000	1.3
+++ auth-request-handler.c	5 Mar 2005 11:48:13 -0000	1.4
@@ -384,6 +384,10 @@
         struct auth_request_handler *handler = request->context;
 	string_t *reply;
 
+	i_assert(request->state == AUTH_REQUEST_STATE_USERDB);
+
+	request->state = AUTH_REQUEST_STATE_FINISHED;
+
 	reply = t_str_new(256);
 	if (handler->prepend_connect_uid)
 		str_printfa(reply, "%u\t", request->connect_uid);
@@ -422,7 +426,8 @@
 	auth_request_ref(request);
 	auth_request_handler_remove(handler, request);
 
-	if (!request->successful) {
+	if (request->state != AUTH_REQUEST_STATE_FINISHED ||
+	    !request->successful) {
 		i_error("Master requested unfinished authentication request "
 			"%u.%u", handler->client_pid, client_id);
 		str_printfa(reply, "NOTFOUND\t%u", id);
@@ -431,6 +436,7 @@
 		/* the request isn't being referenced anywhere anymore,
 		   so we can do a bit of kludging.. replace the request's
 		   old client_id with master's id. */
+		request->state = AUTH_REQUEST_STATE_USERDB;
 		request->id = id;
 		request->context = handler;
 
@@ -449,6 +455,7 @@
 	size /= sizeof(*auth_request);
 
 	for (i = 0; i < size; i++) {
+		i_assert(auth_request[i]->state == AUTH_REQUEST_STATE_FINISHED);
 		auth_request[i]->callback(auth_request[i],
 					  AUTH_CLIENT_RESULT_FAILURE, NULL, 0);
 		auth_request_unref(auth_request[i]);

Index: auth-request.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-request.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- auth-request.c	28 Feb 2005 22:41:33 -0000	1.12
+++ auth-request.c	5 Mar 2005 11:48:13 -0000	1.13
@@ -23,6 +23,7 @@
 	struct auth_request *request;
 
 	request = mech->auth_new();
+	request->state = AUTH_REQUEST_STATE_NEW;
 
 	request->refcount = 1;
 	request->created = ioloop_time;
@@ -37,9 +38,9 @@
 void auth_request_success(struct auth_request *request,
 			  const void *data, size_t data_size)
 {
-	i_assert(!request->finished);
-	request->finished = TRUE;
+	i_assert(request->state == AUTH_REQUEST_STATE_MECH_CONTINUE);
 
+	request->state = AUTH_REQUEST_STATE_FINISHED;
 	request->successful = TRUE;
 	request->callback(request, AUTH_CLIENT_RESULT_SUCCESS,
 			  data, data_size);
@@ -47,9 +48,9 @@
 
 void auth_request_fail(struct auth_request *request)
 {
-	i_assert(!request->finished);
-	request->finished = TRUE;
+	i_assert(request->state == AUTH_REQUEST_STATE_MECH_CONTINUE);
 
+	request->state = AUTH_REQUEST_STATE_FINISHED;
 	request->callback(request, AUTH_CLIENT_RESULT_FAILURE, NULL, 0);
 }
 
@@ -89,12 +90,17 @@
 void auth_request_initial(struct auth_request *request,
 			  const unsigned char *data, size_t data_size)
 {
+	i_assert(request->state == AUTH_REQUEST_STATE_NEW);
+
+	request->state = AUTH_REQUEST_STATE_MECH_CONTINUE;
 	request->mech->auth_initial(request, data, data_size);
 }
 
 void auth_request_continue(struct auth_request *request,
 			   const unsigned char *data, size_t data_size)
 {
+	i_assert(request->state == AUTH_REQUEST_STATE_MECH_CONTINUE);
+
 	request->mech->auth_continue(request, data, data_size);
 }
 
@@ -149,7 +155,10 @@
 					struct auth_request *request)
 {
 	const char *cache_key;
-	int expired;
+
+	i_assert(request->state == AUTH_REQUEST_STATE_PASSDB);
+
+	request->state = AUTH_REQUEST_STATE_MECH_CONTINUE;
 
         auth_request_save_cache(request, result);
 
@@ -161,7 +170,7 @@
 		   expired record. */
 		if (passdb_cache_verify_plain(request, cache_key,
 					      request->mech_password,
-					      &result, &expired)) {
+					      &result, TRUE)) {
 			request->private_callback.verify_plain(result, request);
 			safe_memset(request->mech_password, 0,
 				    strlen(request->mech_password));
@@ -193,7 +202,8 @@
 	struct passdb_module *passdb = request->auth->passdb;
 	enum passdb_result result;
 	const char *cache_key;
-	int expired;
+
+	i_assert(request->state == AUTH_REQUEST_STATE_MECH_CONTINUE);
 
 	request->mech_password = p_strdup(request->pool, password);
 	request->private_callback.verify_plain = callback;
@@ -201,12 +211,14 @@
 	cache_key = passdb_cache == NULL ? NULL : passdb->cache_key;
 	if (cache_key != NULL) {
 		if (passdb_cache_verify_plain(request, cache_key, password,
-					      &result, &expired) && !expired) {
+					      &result, FALSE)) {
 			callback(result, request);
 			return;
 		}
 	}
 
+	request->state = AUTH_REQUEST_STATE_PASSDB;
+
 	if (passdb->blocking)
 		passdb_blocking_verify_plain(request);
 	else {
@@ -220,8 +232,10 @@
 					      struct auth_request *request)
 {
 	const char *cache_key, *scheme;
-	int expired;
 
+	i_assert(request->state == AUTH_REQUEST_STATE_PASSDB);
+
+	request->state = AUTH_REQUEST_STATE_MECH_CONTINUE;
         auth_request_save_cache(request, result);
 
 	if (request->passdb_password != NULL) {
@@ -237,7 +251,7 @@
 		   expired record. */
 		if (passdb_cache_lookup_credentials(request, cache_key,
 						    &credentials, &scheme,
-						    &expired)) {
+						    TRUE)) {
 			passdb_handle_credentials(credentials != NULL ?
 				PASSDB_RESULT_OK : PASSDB_RESULT_USER_UNKNOWN,
 				request->credentials, credentials, scheme,
@@ -257,13 +271,13 @@
 {
 	struct passdb_module *passdb = request->auth->passdb;
 	const char *cache_key, *result, *scheme;
-	int expired;
+
+	i_assert(request->state == AUTH_REQUEST_STATE_MECH_CONTINUE);
 
 	cache_key = passdb_cache == NULL ? NULL : passdb->cache_key;
 	if (cache_key != NULL) {
 		if (passdb_cache_lookup_credentials(request, cache_key,
-						    &result, &scheme,
-						    &expired) && !expired) {
+						    &result, &scheme, FALSE)) {
 			passdb_handle_credentials(result != NULL ?
 						  PASSDB_RESULT_OK :
 						  PASSDB_RESULT_USER_UNKNOWN,
@@ -273,6 +287,7 @@
 		}
 	}
 
+	request->state = AUTH_REQUEST_STATE_PASSDB;
 	request->credentials = credentials;
 	request->private_callback.lookup_credentials = callback;
 

Index: auth-request.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-request.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- auth-request.h	28 Feb 2005 22:19:21 -0000	1.10
+++ auth-request.h	5 Mar 2005 11:48:13 -0000	1.11
@@ -8,10 +8,19 @@
 
 struct auth_client_connection;
 
+enum auth_request_state {
+	AUTH_REQUEST_STATE_NEW,
+	AUTH_REQUEST_STATE_PASSDB,
+	AUTH_REQUEST_STATE_MECH_CONTINUE,
+	AUTH_REQUEST_STATE_FINISHED,
+	AUTH_REQUEST_STATE_USERDB
+};
+
 struct auth_request {
 	int refcount;
 
 	pool_t pool;
+        enum auth_request_state state;
 	char *user;
 	char *mech_password; /* set if verify_plain() is called */
 	char *passdb_password; /* set after password lookup if successful */
@@ -40,7 +49,6 @@
 
 	unsigned int successful:1;
 	unsigned int internal_failure:1;
-	unsigned int finished:1;
 	unsigned int delayed_failure:1;
 	unsigned int accept_input:1;
 	unsigned int no_failure_delay:1;

Index: passdb-blocking.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-blocking.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- passdb-blocking.c	2 Mar 2005 20:46:25 -0000	1.1
+++ passdb-blocking.c	5 Mar 2005 11:48:13 -0000	1.2
@@ -87,6 +87,8 @@
 {
 	string_t *str;
 
+	i_assert(request->extra_fields == NULL);
+
 	str = t_str_new(64);
 	str_append(str, "PASSV\t");
 	str_append(str, request->mech_password);
@@ -118,6 +120,8 @@
 {
 	string_t *str;
 
+	i_assert(request->extra_fields == NULL);
+
 	str = t_str_new(64);
 	str_printfa(str, "PASSL\t%d\t", request->credentials);
 	auth_request_export(request, str);

Index: passdb-cache.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-cache.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- passdb-cache.c	28 Feb 2005 22:41:33 -0000	1.7
+++ passdb-cache.c	5 Mar 2005 11:48:13 -0000	1.8
@@ -34,17 +34,17 @@
 
 int passdb_cache_verify_plain(struct auth_request *request, const char *key,
 			      const char *password,
-			      enum passdb_result *result_r, int *expired_r)
+			      enum passdb_result *result_r, int use_expired)
 {
 	const char *value, *cached_pw, *scheme, *const *list;
-	int ret;
+	int ret, expired;
 
 	if (passdb_cache == NULL)
 		return FALSE;
 
 	/* value = password \t ... */
-	value = auth_cache_lookup(passdb_cache, request, key, expired_r);
-	if (value == NULL)
+	value = auth_cache_lookup(passdb_cache, request, key, &expired);
+	if (value == NULL || (expired && !use_expired))
 		return FALSE;
 
 	if (*value == '\0') {
@@ -76,15 +76,16 @@
 
 int passdb_cache_lookup_credentials(struct auth_request *request,
 				    const char *key, const char **result_r,
-				    const char **scheme_r, int *expired_r)
+				    const char **scheme_r, int use_expired)
 {
 	const char *value, *const *list;
+	int expired;
 
 	if (passdb_cache == NULL)
 		return FALSE;
 
-	value = auth_cache_lookup(passdb_cache, request, key, expired_r);
-	if (value == NULL)
+	value = auth_cache_lookup(passdb_cache, request, key, &expired);
+	if (value == NULL || (expired && !use_expired))
 		return FALSE;
 
 	if (*value == '\0') {

Index: passdb-cache.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-cache.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- passdb-cache.h	28 Feb 2005 22:41:33 -0000	1.3
+++ passdb-cache.h	5 Mar 2005 11:48:13 -0000	1.4
@@ -8,10 +8,10 @@
 
 int passdb_cache_verify_plain(struct auth_request *request, const char *key,
 			      const char *password,
-			      enum passdb_result *result_r, int *expired_r);
+			      enum passdb_result *result_r, int use_expired);
 int passdb_cache_lookup_credentials(struct auth_request *request,
 				    const char *key, const char **result_r,
-				    const char **scheme_r, int *expired_r);
+				    const char **scheme_r, int use_expired);
 
 void passdb_cache_init(void);
 void passdb_cache_deinit(void);



More information about the dovecot-cvs mailing list