[dovecot-cvs] dovecot/src/auth login-connection.c,1.15,1.16 master-connection.c,1.2,1.3 mech-digest-md5.c,1.1,1.2 mech-plain.c,1.2,1.3 mech.c,1.1,1.2 mech.h,1.1,1.2 passdb-pam.c,1.1,1.2 passdb-passwd-file.c,1.1,1.2 passdb-passwd.c,1.1,1.2 passdb-shadow.c,1.1,1.2 Message-Id: <20030127080816.D90A0238C6@danu.procontrol.fi>

cras at procontrol.fi cras at procontrol.fi
Mon Jan 27 10:08:16 EET 2003


Update of /home/cvs/dovecot/src/auth
In directory danu:/tmp/cvs-serv31911

Modified Files:
	login-connection.c master-connection.c mech-digest-md5.c 
	mech-plain.c mech.c mech.h passdb-pam.c passdb-passwd-file.c 
	passdb-passwd.c passdb-shadow.c passdb-vpopmail.c passdb.h 
	userdb-passwd-file.c userdb-passwd.c userdb-static.c 
	userdb-vpopmail.c userdb.h 
Log Message:
Async userdb and passdb interface.



Index: login-connection.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/login-connection.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- login-connection.c	27 Jan 2003 01:44:34 -0000	1.15
+++ login-connection.c	27 Jan 2003 08:08:14 -0000	1.16
@@ -209,6 +209,7 @@
 		}
 	}
 
+	//FIXME: hash_foreach(conn->auth_requests, auth_request_hash_destroy, NULL);
 	hash_destroy(conn->auth_requests);
 
 	i_stream_unref(conn->input);

Index: master-connection.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/master-connection.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- master-connection.c	27 Jan 2003 01:44:34 -0000	1.2
+++ master-connection.c	27 Jan 2003 08:08:14 -0000	1.3
@@ -60,35 +60,12 @@
 	return reply;
 }
 
-static void master_handle_request(struct auth_master_request *request,
-				  int fd __attr_unused__)
+static void send_reply(struct auth_master_reply *reply, size_t reply_size,
+		       unsigned int tag)
 {
-	struct login_connection *login_conn;
-	struct auth_request *auth_request;
-	struct user_data *user_data;
-	struct auth_master_reply *reply;
-	size_t reply_size;
 	ssize_t ret;
 
-	login_conn = login_connection_lookup(request->login_pid);
-	auth_request = login_conn == NULL ? NULL :
-		hash_lookup(login_conn->auth_requests,
-			    POINTER_CAST(request->id));
-
-	reply_size = sizeof(*reply);
-	if (request == NULL)
-		reply = &failure_reply;
-	else {
-		user_data = userdb->lookup(auth_request->user,
-					   auth_request->realm);
-		if (user_data == NULL)
-			reply = &failure_reply;
-		else
-			reply = fill_reply(user_data, &reply_size);
-		mech_request_free(login_conn, auth_request, request->id);
-	}
-
-	reply->tag = request->tag;
+	reply->tag = tag;
 	for (;;) {
 		ret = o_stream_send(output, reply, reply_size);
 		if (ret < 0) {
@@ -107,6 +84,40 @@
 			io_loop_stop(ioloop);
 			break;
 		}
+	}
+}
+
+static void userdb_callback(struct user_data *user, void *context)
+{
+	unsigned int tag = POINTER_CAST_TO(context, unsigned int);
+	struct auth_master_reply *reply;
+	size_t reply_size;
+
+	if (user == NULL)
+		send_reply(&failure_reply, sizeof(failure_reply), tag);
+	else {
+		reply = fill_reply(user, &reply_size);
+		send_reply(reply, reply_size, tag);
+	}
+}
+
+static void master_handle_request(struct auth_master_request *request,
+				  int fd __attr_unused__)
+{
+	struct login_connection *login_conn;
+	struct auth_request *auth_request;
+
+	login_conn = login_connection_lookup(request->login_pid);
+	auth_request = login_conn == NULL ? NULL :
+		hash_lookup(login_conn->auth_requests,
+			    POINTER_CAST(request->id));
+
+	if (request == NULL)
+		send_reply(&failure_reply, sizeof(failure_reply), request->tag);
+	else {
+		userdb->lookup(auth_request->user, auth_request->realm,
+			       userdb_callback, POINTER_CAST(request->tag));
+		mech_request_free(login_conn, auth_request, request->id);
 	}
 }
 

Index: mech-digest-md5.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/mech-digest-md5.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- mech-digest-md5.c	27 Jan 2003 01:33:40 -0000	1.1
+++ mech-digest-md5.c	27 Jan 2003 08:08:14 -0000	1.2
@@ -110,26 +110,22 @@
 	return str;
 }
 
-static int verify_auth(struct digest_auth_request *auth)
+static int verify_credentials(struct digest_auth_request *auth,
+			      const char *credentials)
 {
 	struct md5_context ctx;
 	unsigned char digest[16];
-	const char *a1_hex, *a2_hex, *response_hex, *data;
+	const char *a1_hex, *a2_hex, *response_hex;
 	buffer_t *digest_buf;
 	int i;
 
-	/* we should have taken care of this at startup */
-	i_assert(passdb->lookup_credentials != NULL);
-
 	/* get the MD5 password */
-	data = passdb->lookup_credentials(auth->username, auth->realm,
-					  PASSDB_CREDENTIALS_DIGEST_MD5);
-	if (data == NULL || strlen(data) != sizeof(digest)*2)
+	if (credentials == NULL || strlen(credentials) != sizeof(digest)*2)
 		return FALSE;
 
 	digest_buf = buffer_create_data(data_stack_pool,
 					digest, sizeof(digest));
-	if (hex_to_binary(data, digest_buf) <= 0)
+	if (hex_to_binary(credentials, digest_buf) <= 0)
 		return FALSE;
 
 	/*
@@ -487,6 +483,7 @@
 
 	t_push();
 
+	*error = NULL;
 	failed = FALSE;
 
 	copy = t_strdup_noconst(t_strndup(data, size));
@@ -518,19 +515,18 @@
 	if (auth->qop_value == NULL)
 		auth->qop_value = p_strdup(auth->pool, "auth");
 
-	if (!failed && !verify_auth(auth)) {
-		*error = NULL;
-		failed = TRUE;
-	}
-
 	t_pop();
 
-	/* error message is actually ignored here, we could send it to
-	   syslog or maybe to client, but it's not specified if that's
-	   allowed and how. */
 	return !failed;
 }
 
+static void credentials_callback(const char *result, void *context)
+{
+	struct digest_auth_request *auth = context;
+
+	mech_auth_finish(&auth->auth_request, verify_credentials(auth, result));
+}
+
 static int
 mech_digest_md5_auth_continue(struct login_connection *conn,
 			      struct auth_request *auth_request,
@@ -559,15 +555,13 @@
 
 	if (parse_digest_response(auth, (const char *) data,
 				  request->data_size, &error)) {
-		/* authentication ok */
-		auth->authenticated = TRUE;
-
-		reply.reply_idx = 0;
+		auth_request->conn = conn;
+		auth_request->id = request->id;
+		auth_request->callback = callback;
 
-		reply.result = AUTH_LOGIN_RESULT_CONTINUE;
-		reply.data_size = strlen(auth->rspauth);
-		callback(&reply, auth->rspauth, conn);
-		return TRUE;
+		passdb->lookup_credentials(auth->username, auth->realm,
+					   PASSDB_CREDENTIALS_DIGEST_MD5,
+					   credentials_callback, auth);
 	}
 
 	if (error == NULL)

Index: mech-plain.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/mech-plain.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- mech-plain.c	27 Jan 2003 02:05:32 -0000	1.2
+++ mech-plain.c	27 Jan 2003 08:08:14 -0000	1.3
@@ -6,26 +6,31 @@
 #include "mech.h"
 #include "passdb.h"
 
+static void verify_callback(enum passdb_result result, void *context)
+{
+	struct auth_request *auth_request = context;
+
+	mech_auth_finish(auth_request, result == PASSDB_RESULT_OK);
+}
+
 static int
 mech_plain_auth_continue(struct login_connection *conn,
 			 struct auth_request *auth_request,
 			 struct auth_login_request_continue *request,
 			 const unsigned char *data, mech_callback_t *callback)
 {
-	struct auth_login_reply reply;
 	const char *authid, *authenid;
 	char *pass;
-	void *reply_data = NULL;
 	size_t i, count, len;
 
-	memset(&reply, 0, sizeof(reply));
-	reply.id = request->id;
-	reply.result = AUTH_LOGIN_RESULT_FAILURE;
+	auth_request->conn = conn;
+	auth_request->id = request->id;
+	auth_request->callback = callback;
 
 	/* authorization ID \0 authentication ID \0 pass.
 	   we'll ignore authorization ID for now. */
 	authid = (const char *) data;
-	authenid = NULL; pass = NULL;
+	authenid = NULL; pass = "";
 
 	count = 0;
 	for (i = 0; i < request->data_size; i++) {
@@ -47,21 +52,12 @@
 	if (auth_request->realm != NULL)
                 auth_request->realm++;
 
-	if (pass != NULL) {
-		if (passdb->verify_plain(auth_request->user,
-					 auth_request->realm,
-					 pass) == PASSDB_RESULT_OK) {
-			reply_data = mech_auth_success(&reply, auth_request,
-						       NULL, 0);
-			reply.result = AUTH_LOGIN_RESULT_SUCCESS;
-		}
-
-		/* make sure it's cleared */
-		safe_memset(pass, 0, strlen(pass));
-	}
+	passdb->verify_plain(auth_request->user, auth_request->realm,
+			     pass, verify_callback, auth_request);
 
-	callback(&reply, reply_data, conn);
-	return reply.result == AUTH_LOGIN_RESULT_SUCCESS;
+	/* make sure it's cleared */
+	safe_memset(pass, 0, strlen(pass));
+	return TRUE;
 }
 
 static void

Index: mech.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/mech.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- mech.c	27 Jan 2003 01:33:40 -0000	1.1
+++ mech.c	27 Jan 2003 08:08:14 -0000	1.2
@@ -162,6 +162,30 @@
 	return buffer_get_modifyable_data(buf, NULL);
 }
 
+void mech_auth_finish(struct auth_request *auth_request, int success)
+{
+	struct auth_login_reply reply;
+	void *reply_data;
+
+	memset(&reply, 0, sizeof(reply));
+	reply.id = auth_request->id;
+
+	if (success) {
+		reply_data = mech_auth_success(&reply, auth_request, NULL, 0);
+		reply.result = AUTH_LOGIN_RESULT_SUCCESS;
+	} else {
+		reply_data = NULL;
+		reply.result = AUTH_LOGIN_RESULT_FAILURE;
+	}
+
+	auth_request->callback(&reply, reply_data, auth_request->conn);
+
+	if (!success) {
+		mech_request_free(auth_request->conn, auth_request,
+				  auth_request->id);
+	}
+}
+
 extern struct mech_module mech_plain;
 extern struct mech_module mech_digest_md5;
 

Index: mech.h
===================================================================
RCS file: /home/cvs/dovecot/src/auth/mech.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- mech.h	27 Jan 2003 01:33:40 -0000	1.1
+++ mech.h	27 Jan 2003 08:08:14 -0000	1.2
@@ -12,6 +12,10 @@
 	pool_t pool;
 	char *user, *realm;
 
+	struct login_connection *conn;
+	unsigned int id;
+	mech_callback_t *callback;
+
 	int (*auth_continue)(struct login_connection *conn,
 			     struct auth_request *auth_request,
 			     struct auth_login_request_continue *request,
@@ -49,6 +53,7 @@
 void *mech_auth_success(struct auth_login_reply *reply,
 			struct auth_request *auth_request,
 			const void *data, size_t data_size);
+void mech_auth_finish(struct auth_request *auth_request, int success);
 
 void mech_cyrus_sasl_init_lib(void);
 struct auth_request *mech_cyrus_sasl_new(struct login_connection *conn,

Index: passdb-pam.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/passdb-pam.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- passdb-pam.c	27 Jan 2003 01:33:40 -0000	1.1
+++ passdb-pam.c	27 Jan 2003 08:08:14 -0000	1.2
@@ -194,8 +194,9 @@
 	return PAM_SUCCESS;
 }
 
-static enum passdb_result
-pam_verify_plain(const char *user, const char *realm, const char *password)
+static void
+pam_verify_plain(const char *user, const char *realm, const char *password,
+		 verify_plain_callback_t *callback, void *context)
 {
 	pam_handle_t *pamh;
 	struct pam_userpass userpass;
@@ -217,19 +218,21 @@
 			i_info("PAM: pam_start(%s) failed: %s",
 			       user, pam_strerror(pamh, status));
 		}
-		return PASSDB_RESULT_INTERNAL_FAILURE;
+		callback(PASSDB_RESULT_INTERNAL_FAILURE, context);
+		return;
 	}
 
 	status = pam_auth(pamh, user);
 	if ((status2 = pam_end(pamh, status)) != PAM_SUCCESS) {
 		i_error("pam_end(%s) failed: %s",
 			user, pam_strerror(pamh, status2));
-		return PASSDB_RESULT_INTERNAL_FAILURE;
+		callback(PASSDB_RESULT_INTERNAL_FAILURE, context);
+		return;
 	}
 
 	/* FIXME: check for PASSDB_RESULT_UNKNOWN_USER somehow */
-	return status == PAM_SUCCESS ? PASSDB_RESULT_OK :
-		PASSDB_RESULT_PASSWORD_MISMATCH;
+	callback(status == PAM_SUCCESS ? PASSDB_RESULT_OK :
+		 PASSDB_RESULT_PASSWORD_MISMATCH, context);
 }
 
 static void pam_init(const char *args)

Index: passdb-passwd-file.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/passdb-passwd-file.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- passdb-passwd-file.c	27 Jan 2003 01:33:40 -0000	1.1
+++ passdb-passwd-file.c	27 Jan 2003 08:08:14 -0000	1.2
@@ -15,44 +15,55 @@
 
 struct passwd_file *passdb_pwf = NULL;
 
-static enum passdb_result
+static void
 passwd_file_verify_plain(const char *user, const char *realm,
-			 const char *password)
+			 const char *password,
+			 verify_plain_callback_t *callback, void *context)
 {
 	struct passwd_user *pu;
 	unsigned char digest[16];
 	const char *str;
 
 	pu = passwd_file_lookup_user(passdb_pwf, user, realm);
-	if (pu == NULL)
-		return PASSDB_RESULT_USER_UNKNOWN;
+	if (pu == NULL) {
+		callback(PASSDB_RESULT_USER_UNKNOWN, context);
+		return;
+	}
 
 	switch (pu->password_type) {
 	case PASSWORD_NONE:
-		return PASSDB_RESULT_PASSWORD_MISMATCH;
+		callback(PASSDB_RESULT_PASSWORD_MISMATCH, context);
+		return;
 
 	case PASSWORD_DES:
-		if (strcmp(mycrypt(password, pu->password), pu->password) == 0)
-			return PASSDB_RESULT_OK;
+		if (strcmp(mycrypt(password, pu->password),
+			   pu->password) == 0) {
+			callback(PASSDB_RESULT_OK, context);
+			return;
+		}
 
 		if (verbose) {
 			i_info("passwd-file(%s): DES password mismatch",
 			       pu->user_realm);
 		}
-		return PASSDB_RESULT_PASSWORD_MISMATCH;
+		callback(PASSDB_RESULT_PASSWORD_MISMATCH, context);
+		return;
 
 	case PASSWORD_MD5:
 		md5_get_digest(password, strlen(password), digest);
 		str = binary_to_hex(digest, sizeof(digest));
 
-		if (strcmp(str, pu->password) == 0)
-			return PASSDB_RESULT_OK;
+		if (strcmp(str, pu->password) == 0) {
+			callback(PASSDB_RESULT_OK, context);
+			return;
+		}
 
 		if (verbose) {
 			i_info("passwd-file(%s): MD5 password mismatch",
 			       pu->user_realm);
 		}
-		return PASSDB_RESULT_PASSWORD_MISMATCH;
+		callback(PASSDB_RESULT_PASSWORD_MISMATCH, context);
+		return;
 
 	case PASSWORD_DIGEST_MD5:
 		/* user:realm:passwd */
@@ -63,51 +74,64 @@
 		md5_get_digest(str, strlen(str), digest);
 		str = binary_to_hex(digest, sizeof(digest));
 
-		if (strcmp(str, pu->password) == 0)
-			return PASSDB_RESULT_OK;
+		if (strcmp(str, pu->password) == 0) {
+			callback(PASSDB_RESULT_OK, context);
+			return;
+		}
 
 		if (verbose) {
 			i_info("passwd-file(%s): DIGEST-MD5 password mismatch",
 			       pu->user_realm);
 		}
-		return PASSDB_RESULT_PASSWORD_MISMATCH;
+
+		callback(PASSDB_RESULT_PASSWORD_MISMATCH, context);
+		return;
 	}
 
 	i_unreached();
 }
 
-static const char *
+static void
 passwd_file_lookup_credentials(const char *user, const char *realm,
-			       enum passdb_credentials credentials)
+			       enum passdb_credentials credentials,
+			       lookup_credentials_callback_t *callback,
+			       void *context)
 {
 	struct passwd_user *pu;
 
 	pu = passwd_file_lookup_user(passdb_pwf, user, realm);
-	if (pu == NULL)
-		return NULL;
+	if (pu == NULL) {
+		callback(NULL, context);
+		return;
+	}
 
 	if (pu->password_type == PASSWORD_NONE) {
 		if (verbose)
 			i_info("passwd-file(%s): No password", pu->user_realm);
-		return NULL;
+		callback(NULL, context);
+		return;
 	}
 
 	switch (credentials) {
 	case PASSDB_CREDENTIALS_DIGEST_MD5:
-		if (pu->password_type == PASSWORD_DIGEST_MD5)
-			return pu->password;
+		if (pu->password_type == PASSWORD_DIGEST_MD5) {
+			callback(pu->password, context);
+			return;
+		}
 
 		if (verbose) {
 			i_info("passwd-file(%s): No DIGEST-MD5 password",
 			       pu->user_realm);
 		}
-		return NULL;
+		callback(NULL, context);
+		return;
 	default:
 		if (verbose) {
 			i_info("passwd-file(%s): Unsupported credentials %u",
 			       pu->user_realm, (unsigned int)credentials);
 		}
-		return NULL;
+		callback(NULL, context);
+		return;
 	}
 }
 

Index: passdb-passwd.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/passdb-passwd.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- passdb-passwd.c	27 Jan 2003 01:33:40 -0000	1.1
+++ passdb-passwd.c	27 Jan 2003 08:08:14 -0000	1.2
@@ -12,8 +12,9 @@
 
 #include <pwd.h>
 
-static enum passdb_result
-passwd_verify_plain(const char *user, const char *realm, const char *password)
+static void
+passwd_verify_plain(const char *user, const char *realm, const char *password,
+		    verify_plain_callback_t *callback, void *context)
 {
 	struct passwd *pw;
 	int result;
@@ -26,7 +27,8 @@
 			i_error("getpwnam(%s) failed: %m", user);
 		else if (verbose)
 			i_info("passwd(%s): unknown user", user);
-		return PASSDB_RESULT_USER_UNKNOWN;
+		callback(PASSDB_RESULT_USER_UNKNOWN, context);
+		return;
 	}
 
 	if (!IS_VALID_PASSWD(pw->pw_passwd)) {
@@ -34,7 +36,8 @@
 			i_info("passwd(%s): invalid password field '%s'",
 			       user, pw->pw_passwd);
 		}
-		return PASSDB_RESULT_USER_DISABLED;
+		callback(PASSDB_RESULT_USER_DISABLED, context);
+		return;
 	}
 
 	/* check if the password is valid */
@@ -46,10 +49,11 @@
 	if (!result) {
 		if (verbose)
 			i_info("passwd(%s): password mismatch", user);
-		return PASSDB_RESULT_PASSWORD_MISMATCH;
+		callback(PASSDB_RESULT_PASSWORD_MISMATCH, context);
+		return;
 	}
 
-	return PASSDB_RESULT_OK;
+	callback(PASSDB_RESULT_OK, context);
 }
 
 static void passwd_deinit(void)

Index: passdb-shadow.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/passdb-shadow.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- passdb-shadow.c	27 Jan 2003 01:33:40 -0000	1.1
+++ passdb-shadow.c	27 Jan 2003 08:08:14 -0000	1.2
@@ -12,8 +12,9 @@
 
 #include <shadow.h>
 
-static enum passdb_result
-shadow_verify_plain(const char *user, const char *realm, const char *password)
+static void
+shadow_verify_plain(const char *user, const char *realm, const char *password,
+		    verify_plain_callback_t *callback, void *context)
 {
 	struct spwd *spw;
 	int result;
@@ -26,7 +27,8 @@
 			i_error("getspnam(%s) failed: %m", user);
 		else if (verbose)
 			i_info("shadow(%s): unknown user", user);
-		return PASSDB_RESULT_USER_UNKNOWN;
+		callback(PASSDB_RESULT_USER_UNKNOWN, context);
+		return;
 	}
 
 	if (!IS_VALID_PASSWD(spw->sp_pwdp)) {
@@ -34,7 +36,8 @@
 			i_info("shadow(%s): invalid password field '%s'",
 			       user, spw->sp_pwdp);
 		}
-		return PASSDB_RESULT_USER_DISABLED;
+		callback(PASSDB_RESULT_USER_DISABLED, context);
+		return;
 	}
 
 	/* check if the password is valid */
@@ -46,10 +49,11 @@
 	if (!result) {
 		if (verbose)
 			i_info("shadow(%s): password mismatch", user);
-		return PASSDB_RESULT_PASSWORD_MISMATCH;
+		callback(PASSDB_RESULT_PASSWORD_MISMATCH, context);
+		return;
 	}
 
-	return PASSDB_RESULT_OK;
+	callback(PASSDB_RESULT_OK, context);
 }
 
 static void shadow_deinit(void)

Index: passdb-vpopmail.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/passdb-vpopmail.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- passdb-vpopmail.c	27 Jan 2003 01:33:40 -0000	1.1
+++ passdb-vpopmail.c	27 Jan 2003 08:08:14 -0000	1.2
@@ -14,21 +14,25 @@
 
 #include "userdb-vpopmail.h"
 
-static enum passdb_result
-vpopmail_verify_plain(const char *user, const char *realm, const char *password)
+static void
+vpopmail_verify_plain(const char *user, const char *realm, const char *password,
+		      verify_plain_callback_t *callback, void *context)
 {
 	char vpop_user[VPOPMAIL_LIMIT], vpop_domain[VPOPMAIL_LIMIT];
 	struct vqpasswd *vpw;
 	int result;
 
 	vpw = vpopmail_lookup_vqp(user, realm, vpop_user, vpop_domain);
-	if (vpw == NULL)
-		return PASSDB_RESULT_USER_UNKNOWN;
+	if (vpw == NULL) {
+		callback(PASSDB_RESULT_USER_UNKNOWN, context);
+		return;
+	}
 
 	if ((vpw->pw_gid & NO_IMAP) != 0) {
 		if (verbose)
 			i_info("vpopmail(%s): IMAP disabled", user);
-		return PASSDB_RESULT_USER_DISABLED;
+		callback(PASSDB_RESULT_USER_DISABLED, context);
+		return;
 	}
 
 	/* verify password */
@@ -38,10 +42,11 @@
 	if (!result) {
 		if (verbose)
 			i_info("vpopmail(%s): password mismatch", user);
-		return PASSDB_RESULT_PASSWORD_MISMATCH;
+		callback(PASSDB_RESULT_PASSWORD_MISMATCH, context);
+		return;
 	}
 
-	return PASSDB_RESULT_OK;
+	callback(PASSDB_RESULT_OK, context);
 }
 
 static void vpopmail_deinit(void)

Index: passdb.h
===================================================================
RCS file: /home/cvs/dovecot/src/auth/passdb.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- passdb.h	27 Jan 2003 01:33:40 -0000	1.1
+++ passdb.h	27 Jan 2003 08:08:14 -0000	1.2
@@ -18,18 +18,24 @@
 	PASSDB_RESULT_OK = 1,
 };
 
+typedef void verify_plain_callback_t(enum passdb_result result, void *context);
+typedef void lookup_credentials_callback_t(const char *result, void *context);
+
 struct passdb_module {
 	void (*init)(const char *args);
 	void (*deinit)(void);
 
 	/* Check if plaintext password matches */
-	enum passdb_result (*verify_plain)(const char *user, const char *realm,
-					   const char *password);
+	void (*verify_plain)(const char *user, const char *realm,
+			     const char *password,
+			     verify_plain_callback_t *callback, void *context);
 
 	/* Return authentication credentials. Type is authentication mechanism
 	   specific value that is requested. */
-	const char *(*lookup_credentials)(const char *user, const char *realm,
-					  enum passdb_credentials credentials);
+	void (*lookup_credentials)(const char *user, const char *realm,
+				   enum passdb_credentials credentials,
+				   lookup_credentials_callback_t *callback,
+				   void *context);
 };
 
 const char *passdb_credentials_to_str(enum passdb_credentials credentials);

Index: userdb-passwd-file.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/userdb-passwd-file.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- userdb-passwd-file.c	27 Jan 2003 01:33:40 -0000	1.1
+++ userdb-passwd-file.c	27 Jan 2003 08:08:14 -0000	1.2
@@ -11,15 +11,18 @@
 
 struct passwd_file *userdb_pwf = NULL;
 
-static struct user_data *passwd_file_lookup(const char *user, const char *realm)
+static void passwd_file_lookup(const char *user, const char *realm,
+			       userdb_callback_t *callback, void *context)
 {
 	struct user_data *data;
 	struct passwd_user *pu;
 	pool_t pool;
 
 	pu = passwd_file_lookup_user(userdb_pwf, user, realm);
-	if (pu == NULL)
-		return NULL;
+	if (pu == NULL) {
+		callback(NULL, context);
+		return;
+	}
 
 	pool = pool_alloconly_create("user_data", 512);
 	data = p_new(pool, struct user_data, 1);
@@ -34,7 +37,8 @@
 	data->mail = p_strdup(data->pool, pu->mail);
 
 	data->chroot = pu->chroot;
-	return data;
+
+	callback(data, context);
 }
 
 static void passwd_file_init(const char *args)

Index: userdb-passwd.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/userdb-passwd.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- userdb-passwd.c	27 Jan 2003 01:33:40 -0000	1.1
+++ userdb-passwd.c	27 Jan 2003 08:08:14 -0000	1.2
@@ -10,7 +10,8 @@
 
 #include <pwd.h>
 
-static struct user_data *passwd_lookup(const char *user, const char *realm)
+static void passwd_lookup(const char *user, const char *realm,
+			  userdb_callback_t *callback, void *context)
 {
 	struct user_data *data;
 	struct passwd *pw;
@@ -24,7 +25,8 @@
 			i_error("getpwnam(%s) failed: %m", user);
 		else if (verbose)
 			i_info("passwd(%s): unknown user", user);
-		return NULL;
+		callback(NULL, context);
+		return;
 	}
 
 	pool = pool_alloconly_create("user_data", 512);
@@ -38,7 +40,7 @@
 	data->virtual_user = data->system_user;
 	data->home = p_strdup(data->pool, pw->pw_dir);
 
-	return data;
+	callback(data, context);
 }
 
 struct userdb_module userdb_passwd = {

Index: userdb-static.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/userdb-static.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- userdb-static.c	27 Jan 2003 01:33:40 -0000	1.1
+++ userdb-static.c	27 Jan 2003 08:08:14 -0000	1.2
@@ -16,7 +16,8 @@
 static gid_t static_gid;
 static char *static_home_template;
 
-static struct user_data *static_lookup(const char *user, const char *realm)
+static void static_lookup(const char *user, const char *realm,
+			  userdb_callback_t *callback, void *context)
 {
 	struct user_data *data;
 	pool_t pool;
@@ -39,7 +40,7 @@
 	var_expand(str, static_home_template, user, NULL);
 	data->home = p_strdup(data->pool, str_c(str));
 
-	return data;
+	callback(data, context);
 }
 
 static void static_init(const char *args)

Index: userdb-vpopmail.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/userdb-vpopmail.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- userdb-vpopmail.c	27 Jan 2003 01:33:40 -0000	1.1
+++ userdb-vpopmail.c	27 Jan 2003 08:08:14 -0000	1.2
@@ -50,7 +50,8 @@
 
 #ifdef USERDB_VPOPMAIL
 
-static struct user_data *vpopmail_lookup(const char *user, const char *realm)
+static void vpopmail_lookup(const char *user, const char *realm,
+			    userdb_callback_t *callback, void *context)
 {
 	char vpop_user[VPOPMAIL_LIMIT], vpop_domain[VPOPMAIL_LIMIT];
 	struct vqpasswd *vpw;
@@ -63,8 +64,10 @@
 		user = t_strconcat(user, "@", realm, NULL);
 
 	vpw = vpopmail_lookup_vqp(user, realm, vpop_user, vpop_domain);
-	if (vpw == NULL)
-		return NULL;
+	if (vpw == NULL) {
+		callback(NULL, context);
+		return;
+	}
 
 	/* we have to get uid/gid separately, because the gid field in
 	   struct vqpasswd isn't really gid at all but just some flags... */
@@ -73,7 +76,8 @@
 			i_info("vpopmail(%s): vget_assign(%s) failed",
 			       user, vpop_domain);
 		}
-		return NULL;
+		callback(NULL, context);
+		return;
 	}
 
 	if (vpw->pw_dir == NULL || vpw->pw_dir[0] == '\0') {
@@ -86,13 +90,16 @@
 		if (make_user_dir(vpop_user, vpop_domain, uid, gid) == NULL) {
 			i_error("vpopmail(%s): make_user_dir(%s, %s) failed",
 				user, vpop_user, vpop_domain);
-			return NULL;
+			callback(NULL, context);
+			return;
 		}
 
 		/* get the user again so pw_dir is visible */
 		vpw = vauth_getpw(vpop_user, vpop_domain);
-		if (vpw == NULL)
-			return NULL;
+		if (vpw == NULL) {
+			callback(NULL, context);
+			return;
+		}
 	}
 
 	pool = pool_alloconly_create("user_data", 1024);
@@ -105,7 +112,7 @@
 	data->virtual_user = p_strdup(data->pool, vpw->pw_name);
 	data->home = p_strdup(data->pool, vpw->pw_dir);
 
-	return data;
+	callback(data, context);
 }
 
 struct userdb_module userdb_vpopmail = {

Index: userdb.h
===================================================================
RCS file: /home/cvs/dovecot/src/auth/userdb.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- userdb.h	27 Jan 2003 01:33:40 -0000	1.1
+++ userdb.h	27 Jan 2003 08:08:14 -0000	1.2
@@ -15,11 +15,14 @@
 	int chroot; /* chroot to home directory */
 };
 
+typedef void userdb_callback_t(struct user_data *user, void *context);
+
 struct userdb_module {
 	void (*init)(const char *args);
 	void (*deinit)(void);
 
-	struct user_data *(*lookup)(const char *user, const char *realm);
+	void (*lookup)(const char *user, const char *realm,
+		       userdb_callback_t *callback, void *context);
 };
 
 extern struct userdb_module *userdb;




More information about the dovecot-cvs mailing list