[dovecot-cvs] dovecot/src/auth auth-client-connection.c, 1.14, 1.15 mech.c, 1.43, 1.44 mech.h, 1.23, 1.24 passdb-sql.c, 1.1, 1.2

cras at dovecot.org cras at dovecot.org
Mon Oct 18 04:00:44 EEST 2004


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

Modified Files:
	auth-client-connection.c mech.c mech.h passdb-sql.c 
Log Message:
Authentication OK and FAIL replies can now contain extra fields from passdb.
Implemented this for sql passdb. Special fields are "nologin" (user can't
actually login) and "nodelay" (don't delay failure replies).



Index: auth-client-connection.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-client-connection.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- auth-client-connection.c	13 Oct 2004 19:11:33 -0000	1.14
+++ auth-client-connection.c	18 Oct 2004 01:00:42 -0000	1.15
@@ -73,13 +73,20 @@
 			str_append(str, "\tresp=");
 			base64_encode(reply, reply_size, str);
 		}
+		if (request->extra_fields) {
+			str_append_c(str, '\t');
+			str_append(str, request->extra_fields);
+		}
 		break;
 	case AUTH_CLIENT_RESULT_FAILURE:
 		str = t_str_new(128);
 		str_printfa(str, "FAIL\t%u", request->id);
-		if (reply != NULL) {
-			str_append_c(str, '\t');
+		str_append_c(str, '\t');
+		if (reply != NULL)
 			str_append(str, reply);
+		if (request->extra_fields) {
+			str_append_c(str, '\t');
+			str_append(str, request->extra_fields);
 		}
 		break;
 	}

Index: mech.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/mech.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- mech.c	15 Oct 2004 22:56:10 -0000	1.43
+++ mech.c	18 Oct 2004 01:00:42 -0000	1.44
@@ -116,6 +116,15 @@
 		      const void *data, size_t data_size, int success)
 {
 	if (!success) {
+		if (request->no_failure_delay) {
+			/* passdb specifically requested to to delay the
+			   reply. */
+			request->callback(request, AUTH_CLIENT_RESULT_FAILURE,
+					  NULL, 0);
+			auth_request_destroy(request);
+			return;
+		}
+
 		/* failure. don't announce it immediately to avoid
 		   a) timing attacks, b) flooding */
 		if (auth_failures_buf->used > 0) {
@@ -134,7 +143,7 @@
 				  data, data_size);
 	}
 
-	if (request->conn == NULL ||
+	if (request->no_login || request->conn == NULL ||
 	    AUTH_MASTER_IS_DUMMY(request->conn->master)) {
 		/* we don't have master process, the request is no longer
 		   needed */

Index: mech.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/mech.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- mech.h	13 Oct 2004 16:38:32 -0000	1.23
+++ mech.h	18 Oct 2004 01:00:42 -0000	1.24
@@ -22,6 +22,7 @@
 
 	pool_t pool;
 	char *user;
+	const char *extra_fields;
 
 	struct mech_module *mech;
 	struct auth_client_connection *conn;
@@ -34,6 +35,8 @@
 	mech_callback_t *callback;
 
 	unsigned int accept_input:1;
+	unsigned int no_failure_delay:1;
+	unsigned int no_login:1;
 	/* ... mechanism specific data ... */
 };
 

Index: passdb-sql.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-sql.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- passdb-sql.c	15 Oct 2004 23:12:52 -0000	1.1
+++ passdb-sql.c	18 Oct 2004 01:00:42 -0000	1.2
@@ -29,12 +29,60 @@
 
 static struct sql_connection *passdb_sql_conn;
 
+static void result_save_extra_fields(struct sql_result *result,
+				     struct auth_request *auth_request)
+{
+	unsigned int i, fields_count;
+	const char *name, *value;
+	string_t *str;
+
+	fields_count = sql_result_get_fields_count(result);
+	if (fields_count == 1)
+		return;
+
+	str = NULL;
+	for (i = 0; i < fields_count; i++) {
+		name = sql_result_get_field_name(result, i);
+		value = sql_result_get_field_value(result, i);
+
+		if (strcmp(name, "password") == 0)
+			continue;
+
+		if (strcmp(name, "nodelay") == 0) {
+			/* don't delay replying to client of the failure */
+			auth_request->no_failure_delay = *value == 'Y';
+			continue;
+		}
+
+		if (str == NULL)
+			str = str_new(auth_request->pool, 64);
+
+		if (strcmp(name, "nologin") == 0) {
+			if (*value == 'Y') {
+				/* user can't actually login - don't keep this
+				   reply for master */
+				auth_request->no_login = TRUE;
+				if (str_len(str) > 0)
+					str_append_c(str, '\t');
+				str_append(str, name);
+			}
+		} else {
+			if (str_len(str) > 0)
+				str_append_c(str, '\t');
+			str_printfa(str, "%s=%s", name, value);
+		}
+	}
+
+	if (str != NULL)
+		auth_request->extra_fields = str_c(str);
+}
+
 static void sql_query_callback(struct sql_result *result, void *context)
 {
 	struct passdb_sql_request *sql_request = context;
 	struct auth_request *auth_request = sql_request->auth_request;
 	const char *user, *password, *scheme;
-	int ret;
+	int ret, idx;
 
 	user = auth_request->user;
 	password = NULL;
@@ -49,16 +97,15 @@
 			i_info("sql(%s): Unknown user",
 			       get_log_prefix(auth_request));
 		}
+	} else if ((idx = sql_result_find_field(result, "password")) < 0) {
+		i_error("sql(%s): Password query didn't return password",
+			get_log_prefix(auth_request));
 	} else {
-		password = sql_result_find_field_value(result, "password");
-		if (password != NULL)
-			password = t_strdup(password);
-		else {
-			i_error("sql(%s): Password query didn't return "
-				"password, or it was NULL",
-				get_log_prefix(auth_request));
-		}
+		password = t_strdup(sql_result_get_field_value(result, idx));
+                result_save_extra_fields(result, auth_request);
+	}
 
+	if (ret > 0) {
 		/* make sure there was only one row returned */
 		if (sql_result_next_row(result) > 0) {
 			i_error("sql(%s): Password query returned multiple "



More information about the dovecot-cvs mailing list