Mercurial > dovecot > original-hg > dovecot-1.2
changeset 1046:561da07883b6 HEAD
Async userdb and passdb interface.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 27 Jan 2003 10:08:14 +0200 |
parents | be7710b9a819 |
children | c8adf40c8f42 |
files | src/auth/login-connection.c src/auth/master-connection.c src/auth/mech-digest-md5.c src/auth/mech-plain.c src/auth/mech.c src/auth/mech.h src/auth/passdb-pam.c src/auth/passdb-passwd-file.c src/auth/passdb-passwd.c src/auth/passdb-shadow.c src/auth/passdb-vpopmail.c src/auth/passdb.h src/auth/userdb-passwd-file.c src/auth/userdb-passwd.c src/auth/userdb-static.c src/auth/userdb-vpopmail.c src/auth/userdb.h |
diffstat | 17 files changed, 235 insertions(+), 141 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/login-connection.c Mon Jan 27 09:01:20 2003 +0200 +++ b/src/auth/login-connection.c Mon Jan 27 10:08:14 2003 +0200 @@ -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);
--- a/src/auth/master-connection.c Mon Jan 27 09:01:20 2003 +0200 +++ b/src/auth/master-connection.c Mon Jan 27 10:08:14 2003 +0200 @@ -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) { @@ -110,6 +87,40 @@ } } +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); + } +} + static void master_input(void *context __attr_unused__) { int ret;
--- a/src/auth/mech-digest-md5.c Mon Jan 27 09:01:20 2003 +0200 +++ b/src/auth/mech-digest-md5.c Mon Jan 27 10:08:14 2003 +0200 @@ -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)
--- a/src/auth/mech-plain.c Mon Jan 27 09:01:20 2003 +0200 +++ b/src/auth/mech-plain.c Mon Jan 27 10:08:14 2003 +0200 @@ -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; - } + passdb->verify_plain(auth_request->user, auth_request->realm, + pass, verify_callback, auth_request); - /* make sure it's cleared */ - safe_memset(pass, 0, strlen(pass)); - } - - 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
--- a/src/auth/mech.c Mon Jan 27 09:01:20 2003 +0200 +++ b/src/auth/mech.c Mon Jan 27 10:08:14 2003 +0200 @@ -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;
--- a/src/auth/mech.h Mon Jan 27 09:01:20 2003 +0200 +++ b/src/auth/mech.h Mon Jan 27 10:08:14 2003 +0200 @@ -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,
--- a/src/auth/passdb-pam.c Mon Jan 27 09:01:20 2003 +0200 +++ b/src/auth/passdb-pam.c Mon Jan 27 10:08:14 2003 +0200 @@ -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)
--- a/src/auth/passdb-passwd-file.c Mon Jan 27 09:01:20 2003 +0200 +++ b/src/auth/passdb-passwd-file.c Mon Jan 27 10:08:14 2003 +0200 @@ -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; } }
--- a/src/auth/passdb-passwd.c Mon Jan 27 09:01:20 2003 +0200 +++ b/src/auth/passdb-passwd.c Mon Jan 27 10:08:14 2003 +0200 @@ -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)
--- a/src/auth/passdb-shadow.c Mon Jan 27 09:01:20 2003 +0200 +++ b/src/auth/passdb-shadow.c Mon Jan 27 10:08:14 2003 +0200 @@ -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)
--- a/src/auth/passdb-vpopmail.c Mon Jan 27 09:01:20 2003 +0200 +++ b/src/auth/passdb-vpopmail.c Mon Jan 27 10:08:14 2003 +0200 @@ -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)
--- a/src/auth/passdb.h Mon Jan 27 09:01:20 2003 +0200 +++ b/src/auth/passdb.h Mon Jan 27 10:08:14 2003 +0200 @@ -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);
--- a/src/auth/userdb-passwd-file.c Mon Jan 27 09:01:20 2003 +0200 +++ b/src/auth/userdb-passwd-file.c Mon Jan 27 10:08:14 2003 +0200 @@ -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)
--- a/src/auth/userdb-passwd.c Mon Jan 27 09:01:20 2003 +0200 +++ b/src/auth/userdb-passwd.c Mon Jan 27 10:08:14 2003 +0200 @@ -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 = {
--- a/src/auth/userdb-static.c Mon Jan 27 09:01:20 2003 +0200 +++ b/src/auth/userdb-static.c Mon Jan 27 10:08:14 2003 +0200 @@ -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)
--- a/src/auth/userdb-vpopmail.c Mon Jan 27 09:01:20 2003 +0200 +++ b/src/auth/userdb-vpopmail.c Mon Jan 27 10:08:14 2003 +0200 @@ -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 = {
--- a/src/auth/userdb.h Mon Jan 27 09:01:20 2003 +0200 +++ b/src/auth/userdb.h Mon Jan 27 10:08:14 2003 +0200 @@ -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;