Mercurial > dovecot > original-hg > dovecot-1.2
changeset 3657:0c10475d9968 HEAD
Separated passdb_module's interface and the actual data struct. Now it's
possible to have multiple passdbs of same type but with different settings.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 16 Oct 2005 17:06:59 +0300 |
parents | fda241fa5d77 |
children | fc4622b1c1ef |
files | src/auth/auth-cache.c src/auth/auth-cache.h src/auth/auth-request.c src/auth/auth-worker-client.c src/auth/auth.c src/auth/db-ldap.c src/auth/db-passwd-file.c src/auth/db-passwd-file.h src/auth/passdb-bsdauth.c src/auth/passdb-checkpassword.c src/auth/passdb-ldap.c src/auth/passdb-pam.c src/auth/passdb-passwd-file.c src/auth/passdb-passwd.c src/auth/passdb-shadow.c src/auth/passdb-sql.c src/auth/passdb-vpopmail.c src/auth/passdb.c src/auth/passdb.h src/auth/userdb-passwd-file.c |
diffstat | 20 files changed, 376 insertions(+), 247 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/auth-cache.c Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/auth-cache.c Sun Oct 16 17:06:59 2005 +0300 @@ -28,7 +28,7 @@ unsigned int hit_count, miss_count; }; -char *auth_cache_parse_key(const char *query) +const char *auth_cache_parse_key(const char *query) { string_t *str; char key_seen[256]; @@ -36,7 +36,7 @@ memset(key_seen, 0, sizeof(key_seen)); - str = str_new(default_pool, 32); + str = t_str_new(32); for (; *query != '\0'; query++) { if (*query == '%' && query[1] != '\0') { query++; @@ -52,7 +52,7 @@ } } } - return str_free_without_data(str); + return str_c(str); } static void
--- a/src/auth/auth-cache.h Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/auth-cache.h Sun Oct 16 17:06:59 2005 +0300 @@ -6,7 +6,7 @@ /* Parses all %x variables from query and compresses them into tab-separated list, so it can be used as a cache key. */ -char *auth_cache_parse_key(const char *query); +const char *auth_cache_parse_key(const char *query); /* Create a new cache. max_size specifies the maximum amount of memory in bytes to use for cache (it's not fully exact). ttl_secs specifies time to
--- a/src/auth/auth-request.c Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/auth-request.c Sun Oct 16 17:06:59 2005 +0300 @@ -347,8 +347,8 @@ if (passdb->blocking) passdb_blocking_verify_plain(request); else { - passdb->verify_plain(request, password, - auth_request_verify_plain_callback); + passdb->iface->verify_plain(request, password, + auth_request_verify_plain_callback); } } @@ -421,8 +421,8 @@ if (passdb->blocking) passdb_blocking_lookup_credentials(request); - else if (passdb->lookup_credentials != NULL) { - passdb->lookup_credentials(request, + else if (passdb->iface->lookup_credentials != NULL) { + passdb->iface->lookup_credentials(request, auth_request_lookup_credentials_callback); } else { /* this passdb doesn't support credentials */
--- a/src/auth/auth-worker-client.c Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/auth-worker-client.c Sun Oct 16 17:06:59 2005 +0300 @@ -144,8 +144,8 @@ } } - auth_request->passdb->passdb->verify_plain(auth_request, password, - verify_plain_callback); + auth_request->passdb->passdb->iface-> + verify_plain(auth_request, password, verify_plain_callback); } static void @@ -220,7 +220,7 @@ } } - auth_request->passdb->passdb-> + auth_request->passdb->passdb->iface-> lookup_credentials(auth_request, lookup_credentials_callback); }
--- a/src/auth/auth.c Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/auth.c Sun Oct 16 17:06:59 2005 +0300 @@ -108,7 +108,7 @@ struct auth_passdb *passdb; for (passdb = auth->passdbs; passdb != NULL; passdb = passdb->next) { - if (passdb->passdb->verify_plain != NULL) + if (passdb->passdb->iface->verify_plain != NULL) return TRUE; } return FALSE; @@ -119,7 +119,7 @@ struct auth_passdb *passdb; for (passdb = auth->passdbs; passdb != NULL; passdb = passdb->next) { - if (passdb->passdb->lookup_credentials != NULL) + if (passdb->passdb->iface->lookup_credentials != NULL) return TRUE; } return FALSE;
--- a/src/auth/db-ldap.c Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/db-ldap.c Sun Oct 16 17:06:59 2005 +0300 @@ -413,9 +413,18 @@ void db_ldap_unref(struct ldap_connection *conn) { + struct ldap_connection **p; + + i_assert(conn->refcount >= 0); if (--conn->refcount > 0) return; - i_assert(conn->refcount == 0); + + for (p = &ldap_connections; *p != NULL; p = &(*p)->next) { + if (*p == conn) { + *p = conn->next; + break; + } + } ldap_conn_close(conn);
--- a/src/auth/db-passwd-file.c Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/db-passwd-file.c Sun Oct 16 17:06:59 2005 +0300 @@ -18,6 +18,8 @@ #include <fcntl.h> #include <sys/stat.h> +static struct db_passwd_file *passwd_files; + static void passwd_file_add(struct passwd_file *pw, const char *username, const char *pass, const char *const *args) { @@ -232,12 +234,37 @@ return TRUE; } +static struct db_passwd_file *db_passwd_file_find(const char *path) +{ + struct db_passwd_file *f; + + for (f = passwd_files; f != NULL; f = f->next) { + if (strcmp(f->path, path) == 0) + return f; + } + + return NULL; +} + struct db_passwd_file *db_passwd_file_parse(const char *path, int userdb) { struct db_passwd_file *db; const char *p; int percents = FALSE; + db = db_passwd_file_find(path); + if (db != NULL) { + db->refcount++; + if (userdb && !db->userdb) { + db->userdb = TRUE; + if (db->default_file != NULL) { + /* resync */ + db->default_file->stamp = 0; + } + } + return db; + } + db = i_new(struct db_passwd_file, 1); db->refcount = 1; db->userdb = userdb; @@ -279,24 +306,37 @@ if (!passwd_file_open(db->default_file)) exit(FATAL_DEFAULT); } + + db->next = passwd_files; + passwd_files = db; return db; } void db_passwd_file_unref(struct db_passwd_file *db) { + struct db_passwd_file **p; struct hash_iterate_context *iter; void *key, *value; - if (--db->refcount == 0) { - iter = hash_iterate_init(db->files); - while (hash_iterate(iter, &key, &value)) - passwd_file_free(value); - hash_iterate_deinit(iter); + i_assert(db->refcount >= 0); + if (--db->refcount > 0) + return; - hash_destroy(db->files); - i_free(db->path); - i_free(db); + for (p = &passwd_files; *p != NULL; p = &(*p)->next) { + if (*p == db) { + *p = db->next; + break; + } } + + iter = hash_iterate_init(db->files); + while (hash_iterate(iter, &key, &value)) + passwd_file_free(value); + hash_iterate_deinit(iter); + + hash_destroy(db->files); + i_free(db->path); + i_free(db); } static const char *path_fix(const char *path)
--- a/src/auth/db-passwd-file.h Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/db-passwd-file.h Sun Oct 16 17:06:59 2005 +0300 @@ -26,6 +26,8 @@ }; struct db_passwd_file { + struct db_passwd_file *next; + int refcount; char *path; @@ -37,9 +39,6 @@ unsigned int userdb:1; }; -extern struct db_passwd_file *userdb_pwf; -extern struct db_passwd_file *passdb_pwf; - struct passwd_user * db_passwd_file_lookup(struct db_passwd_file *db, struct auth_request *request);
--- a/src/auth/passdb-bsdauth.c Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/passdb-bsdauth.c Sun Oct 16 17:06:59 2005 +0300 @@ -12,9 +12,6 @@ #include <bsd_auth.h> #include <pwd.h> -extern struct passdb_module passdb_bsdauth; -static char *bsdauth_cache_key; - static void bsdauth_verify_plain(struct auth_request *request, const char *password, verify_plain_callback_t *callback) @@ -55,28 +52,30 @@ callback(PASSDB_RESULT_OK, request); } -static void bsdauth_init(const char *args) +static struct passdb_module * +bsdauth_preinit(struct auth_passdb *auth_passdb, const char *args) { - bsdauth_cache_key = NULL; + struct passdb_module *module; - if (strncmp(args, "cache_key=", 10) == 0) - bsdauth_cache_key = i_strdup(args + 10); + module = p_new(auth_passdb->auth->pool, struct passdb_module, 1); - passdb_bsdauth.cache_key = bsdauth_cache_key; + if (strncmp(args, "cache_key=", 10) == 0) { + module->cache_key = + p_strdup(auth_passdb->auth->pool, args + 10); + } + return module; } -static void bsdauth_deinit(void) +static void bsdauth_deinit(struct passdb_module *module __attr_unused__) { endpwent(); - i_free(bsdauth_cache_key); } -struct passdb_module passdb_bsdauth = { +struct passdb_module_interface passdb_bsdauth = { "bsdauth", - NULL, NULL, FALSE, + bsdauth_preinit, NULL, - bsdauth_init, bsdauth_deinit, bsdauth_verify_plain,
--- a/src/auth/passdb-checkpassword.c Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/passdb-checkpassword.c Sun Oct 16 17:06:59 2005 +0300 @@ -15,6 +15,14 @@ #include <unistd.h> #include <sys/wait.h> +struct checkpassword_passdb_module { + struct passdb_module module; + + const char *checkpassword_path, *checkpassword_reply_path; + struct hash_table *clients; + struct timeout *to_wait; +}; + struct chkpw_auth_request { int fd_out, fd_in; struct io *io_out, *io_in; @@ -31,10 +39,6 @@ unsigned int exited:1; }; -static char *checkpassword_path, *checkpassword_reply_path; -struct hash_table *clients; -static struct timeout *to_wait; - static void checkpassword_request_close(struct chkpw_auth_request *request) { if (request->fd_in != -1) { @@ -58,7 +62,11 @@ static void checkpassword_request_finish(struct chkpw_auth_request *request, enum passdb_result result) { - hash_remove(clients, POINTER_CAST(request->pid)); + struct passdb_module *_module = request->request->passdb->passdb; + struct checkpassword_passdb_module *module = + (struct checkpassword_passdb_module *)_module; + + hash_remove(module->clients, POINTER_CAST(request->pid)); if (result == PASSDB_RESULT_OK) { request->request->extra_fields = @@ -115,8 +123,9 @@ } } -static void wait_timeout(void *context __attr_unused__) +static void wait_timeout(void *context) { + struct checkpassword_passdb_module *module = context; struct chkpw_auth_request *request; int status; pid_t pid; @@ -125,14 +134,14 @@ while ((pid = waitpid(-1, &status, WNOHANG)) != 0) { if (pid == -1) { if (errno == ECHILD) { - timeout_remove(to_wait); - to_wait = NULL; + timeout_remove(module->to_wait); + module->to_wait = NULL; } else if (errno != EINTR) i_error("waitpid() failed: %m"); return; } - request = hash_lookup(clients, POINTER_CAST(pid)); + request = hash_lookup(module->clients, POINTER_CAST(pid)); if (WIFSIGNALED(status)) { i_error("checkpassword: Child %s died with signal %d", @@ -151,22 +160,24 @@ } } -static void checkpassword_verify_plain_child(int fd_in, int fd_out) +static void +checkpassword_verify_plain_child(struct checkpassword_passdb_module *module, + int fd_in, int fd_out) { - char *args[3]; + const char *args[3]; if (dup2(fd_out, 3) < 0) i_error("checkpassword: dup2() failed: %m"); else if (dup2(fd_in, 4) < 0) i_error("checkpassword: dup2() failed: %m"); else { - args[0] = checkpassword_path; - args[1] = checkpassword_reply_path; + args[0] = module->checkpassword_path; + args[1] = module->checkpassword_reply_path; args[2] = NULL; - execv(checkpassword_path, args); + execv(module->checkpassword_path, (char **)args); i_error("checkpassword: execv(%s) failed: %m", - checkpassword_path); + module->checkpassword_path); } exit(2); } @@ -243,6 +254,9 @@ checkpassword_verify_plain(struct auth_request *request, const char *password, verify_plain_callback_t *callback) { + struct passdb_module *_module = request->passdb->passdb; + struct checkpassword_passdb_module *module = + (struct checkpassword_passdb_module *)_module; struct chkpw_auth_request *chkpw_auth_request; int fd_in[2], fd_out[2]; pid_t pid; @@ -274,7 +288,7 @@ if (pid == 0) { (void)close(fd_in[0]); (void)close(fd_out[1]); - checkpassword_verify_plain_child(fd_in[1], fd_out[0]); + checkpassword_verify_plain_child(module, fd_in[1], fd_out[0]); } if (close(fd_in[1]) < 0) { @@ -302,50 +316,54 @@ io_add(fd_out[1], IO_WRITE, checkpassword_child_output, chkpw_auth_request); - hash_insert(clients, POINTER_CAST(pid), chkpw_auth_request); + hash_insert(module->clients, POINTER_CAST(pid), chkpw_auth_request); - if (to_wait == NULL) { + if (module->to_wait == NULL) { /* FIXME: we could use SIGCHLD */ - to_wait = timeout_add(100, wait_timeout, NULL); + module->to_wait = timeout_add(100, wait_timeout, module); } } -static void checkpassword_init(const char *args) +static struct passdb_module * +checkpassword_preinit(struct auth_passdb *auth_passdb, const char *args) { - checkpassword_path = i_strdup(args); - checkpassword_reply_path = - i_strdup(PKG_LIBEXECDIR"/checkpassword-reply"); + struct checkpassword_passdb_module *module; - to_wait = NULL; - clients = hash_create(default_pool, default_pool, 0, NULL, NULL); + module = p_new(auth_passdb->auth->pool, + struct checkpassword_passdb_module, 1); + module->checkpassword_path = p_strdup(auth_passdb->auth->pool, args); + module->checkpassword_reply_path = + PKG_LIBEXECDIR"/checkpassword-reply"; + + module->clients = + hash_create(default_pool, default_pool, 0, NULL, NULL); + return &module->module; } -static void checkpassword_deinit(void) +static void checkpassword_deinit(struct passdb_module *_module) { + struct checkpassword_passdb_module *module = + (struct checkpassword_passdb_module *)_module; struct hash_iterate_context *iter; void *key, *value; - iter = hash_iterate_init(clients); + iter = hash_iterate_init(module->clients); while (hash_iterate(iter, &key, &value)) { checkpassword_request_finish(value, PASSDB_RESULT_INTERNAL_FAILURE); } hash_iterate_deinit(iter); - hash_destroy(clients); + hash_destroy(module->clients); - if (to_wait != NULL) - timeout_remove(to_wait); - - i_free(checkpassword_path); - i_free(checkpassword_reply_path); + if (module->to_wait != NULL) + timeout_remove(module->to_wait); } -struct passdb_module passdb_checkpassword = { +struct passdb_module_interface passdb_checkpassword = { "checkpassword", - NULL, NULL, FALSE, + checkpassword_preinit, NULL, - checkpassword_init, checkpassword_deinit, checkpassword_verify_plain,
--- a/src/auth/passdb-ldap.c Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/passdb-ldap.c Sun Oct 16 17:06:59 2005 +0300 @@ -15,12 +15,16 @@ #include <ldap.h> #include <stdlib.h> -extern struct passdb_module passdb_ldap; - static const char *default_attr_map[] = { "user", "password", NULL }; +struct ldap_passdb_module { + struct passdb_module module; + + struct ldap_connection *conn; +}; + struct passdb_ldap_request { struct ldap_request request; @@ -30,9 +34,6 @@ } callback; }; -static struct ldap_connection *passdb_ldap_conn; -static char *passdb_ldap_cache_key; - static void ldap_query_save_result(struct ldap_connection *conn, LDAPMessage *entry, struct auth_request *auth_request) @@ -45,7 +46,7 @@ attr = ldap_first_attribute(conn->ld, entry, &ber); while (attr != NULL) { - name = hash_lookup(passdb_ldap_conn->pass_attr_map, attr); + name = hash_lookup(conn->pass_attr_map, attr); vals = ldap_get_values(conn->ld, entry, attr); if (auth_request->auth->verbose_debug) { @@ -170,7 +171,10 @@ static void ldap_lookup_pass(struct auth_request *auth_request, struct ldap_request *ldap_request) { - struct ldap_connection *conn = passdb_ldap_conn; + struct passdb_module *_module = auth_request->passdb->passdb; + struct ldap_passdb_module *module = + (struct ldap_passdb_module *)_module; + struct ldap_connection *conn = module->conn; const struct var_expand_table *vars; const char **attr_names = (const char **)conn->pass_attr_names; const char *filter, *base; @@ -195,9 +199,8 @@ base, conn->set.scope, filter, t_strarray_join(attr_names, ",")); - db_ldap_search(conn, base, conn->set.ldap_scope, - filter, passdb_ldap_conn->pass_attr_names, - ldap_request); + db_ldap_search(conn, base, conn->set.ldap_scope, filter, + conn->pass_attr_names, ldap_request); } static void @@ -224,37 +227,44 @@ ldap_lookup_pass(request, &ldap_request->request); } -static void passdb_ldap_preinit(const char *args) +static struct passdb_module * +passdb_ldap_preinit(struct auth_passdb *auth_passdb, const char *args) { - passdb_ldap_conn = db_ldap_init(args); - passdb_ldap_conn->pass_attr_map = - hash_create(default_pool, passdb_ldap_conn->pool, 0, str_hash, + struct ldap_passdb_module *module; + struct ldap_connection *conn; + + module = p_new(auth_passdb->auth->pool, struct ldap_passdb_module, 1); + module->conn = conn = db_ldap_init(args); + conn->pass_attr_map = + hash_create(default_pool, conn->pool, 0, str_hash, (hash_cmp_callback_t *)strcmp); - db_ldap_set_attrs(passdb_ldap_conn, passdb_ldap_conn->set.pass_attrs, - &passdb_ldap_conn->pass_attr_names, - passdb_ldap_conn->pass_attr_map, - default_attr_map); - passdb_ldap.cache_key = passdb_ldap_cache_key = - auth_cache_parse_key(passdb_ldap_conn->set.pass_filter); - passdb_ldap.default_pass_scheme = - passdb_ldap_conn->set.default_pass_scheme; + db_ldap_set_attrs(conn, conn->set.pass_attrs, &conn->pass_attr_names, + conn->pass_attr_map, default_attr_map); + module->module.cache_key = auth_cache_parse_key(conn->set.pass_filter); + module->module.default_pass_scheme = conn->set.default_pass_scheme; + return &module->module; } -static void passdb_ldap_init(const char *args __attr_unused__) +static void passdb_ldap_init(struct passdb_module *_module, + const char *args __attr_unused__) { - (void)db_ldap_connect(passdb_ldap_conn); + struct ldap_passdb_module *module = + (struct ldap_passdb_module *)_module; + + (void)db_ldap_connect(module->conn); } -static void passdb_ldap_deinit(void) +static void passdb_ldap_deinit(struct passdb_module *_module) { - db_ldap_unref(passdb_ldap_conn); - i_free(passdb_ldap_cache_key); + struct ldap_passdb_module *module = + (struct ldap_passdb_module *)_module; + + db_ldap_unref(module->conn); } -struct passdb_module passdb_ldap = { +struct passdb_module_interface passdb_ldap = { "ldap", - NULL, NULL, FALSE, passdb_ldap_preinit, passdb_ldap_init,
--- a/src/auth/passdb-pam.c Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/passdb-pam.c Sun Oct 16 17:06:59 2005 +0300 @@ -58,6 +58,14 @@ # define USERPASS_USER_FIXED 3 #endif +struct pam_passdb_module { + struct passdb_module module; + + int pam_session; + const char *service_name, *pam_cache_key; + struct timeout *to_wait; +}; + struct pam_auth_request { int fd; struct io *io; @@ -71,12 +79,6 @@ const char *pass; }; -extern struct passdb_module passdb_pam; - -static int pam_session; -static char *service_name, *pam_cache_key; -static struct timeout *to_wait; - static int pam_userpass_conv(int num_msg, linux_const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { @@ -171,6 +173,8 @@ static int pam_auth(struct auth_request *request, pam_handle_t *pamh, const char **error) { + struct passdb_module *_module = request->passdb->passdb; + struct pam_passdb_module *module = (struct pam_passdb_module *)_module; void *item; int status; @@ -196,7 +200,7 @@ return status; } - if (pam_session) { + if (module->pam_session) { if ((status = pam_open_session(pamh, 0)) != PAM_SUCCESS) { *error = t_strdup_printf( "pam_open_session() failed: %s", @@ -332,8 +336,9 @@ i_free(request); } -static void wait_timeout(void *context __attr_unused__) +static void wait_timeout(void *context) { + struct pam_passdb_module *module = context; int status; pid_t pid; @@ -341,8 +346,8 @@ while ((pid = waitpid(-1, &status, WNOHANG)) != 0) { if (pid == -1) { if (errno == ECHILD) { - timeout_remove(to_wait); - to_wait = NULL; + timeout_remove(module->to_wait); + module->to_wait = NULL; } else if (errno != EINTR) i_error("waitpid() failed: %m"); return; @@ -359,12 +364,15 @@ pam_verify_plain(struct auth_request *request, const char *password, verify_plain_callback_t *callback) { + struct passdb_module *_module = request->passdb->passdb; + struct pam_passdb_module *module = (struct pam_passdb_module *)_module; struct pam_auth_request *pam_auth_request; const char *service; int fd[2]; pid_t pid; - service = service_name != NULL ? service_name : request->service; + service = module->service_name != NULL ? + module->service_name : request->service; if (pipe(fd) < 0) { auth_request_log_error(request, "pam", "pipe() failed: %m"); callback(PASSDB_RESULT_INTERNAL_FAILURE, request); @@ -400,57 +408,57 @@ pam_auth_request->io = io_add(fd[0], IO_READ, pam_child_input, pam_auth_request); - if (to_wait == NULL) - to_wait = timeout_add(1000, wait_timeout, NULL); + if (module->to_wait == NULL) + module->to_wait = timeout_add(1000, wait_timeout, module); } -static void pam_init(const char *args) +static struct passdb_module * +pam_preinit(struct auth_passdb *auth_passdb, const char *args) { + struct pam_passdb_module *module; const char *const *t_args; int i; - pam_session = FALSE; - service_name = i_strdup("dovecot"); - pam_cache_key = NULL; + module = p_new(auth_passdb->auth->pool, struct pam_passdb_module, 1); + module->service_name = "dovecot"; t_push(); t_args = t_strsplit(args, " "); for(i = 0; t_args[i] != NULL; i++) { if (strcmp(t_args[i], "-session") == 0) - pam_session = TRUE; + module->pam_session = TRUE; else if (strncmp(t_args[i], "cache_key=", 10) == 0) { - i_free(pam_cache_key); - pam_cache_key = i_strdup(t_args[i] + 10); + module->module.cache_key = + p_strdup(auth_passdb->auth->pool, + t_args[i] + 10); } else if (strcmp(t_args[i], "*") == 0) { - i_free(service_name); - service_name = NULL; + module->service_name = NULL; } else { if (*t_args[i] != '\0') { - i_free(service_name); - service_name = i_strdup(t_args[i]); + module->service_name = + p_strdup(auth_passdb->auth->pool, + t_args[i]); } } } t_pop(); - to_wait = NULL; - passdb_pam.cache_key = pam_cache_key; + return &module->module; } -static void pam_deinit(void) +static void pam_deinit(struct passdb_module *_module) { - if (to_wait != NULL) - timeout_remove(to_wait); - i_free(service_name); - i_free(pam_cache_key); + struct pam_passdb_module *module = (struct pam_passdb_module *)_module; + + if (module->to_wait != NULL) + timeout_remove(module->to_wait); } -struct passdb_module passdb_pam = { +struct passdb_module_interface passdb_pam = { "pam", - NULL, NULL, FALSE, + pam_preinit, NULL, - pam_init, pam_deinit, pam_verify_plain,
--- a/src/auth/passdb-passwd-file.c Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/passdb-passwd-file.c Sun Oct 16 17:06:59 2005 +0300 @@ -11,17 +11,24 @@ #define PASSWD_FILE_CACHE_KEY "%u" #define PASSWD_FILE_DEFAULT_SCHEME "CRYPT" -struct db_passwd_file *passdb_pwf = NULL; +struct passwd_file_passdb_module { + struct passdb_module module; + + struct db_passwd_file *pwf; +}; static void passwd_file_verify_plain(struct auth_request *request, const char *password, verify_plain_callback_t *callback) { + struct passdb_module *_module = request->passdb->passdb; + struct passwd_file_passdb_module *module = + (struct passwd_file_passdb_module *)_module; struct passwd_user *pu; const char *scheme, *crypted_pass; int ret; - pu = db_passwd_file_lookup(passdb_pwf, request); + pu = db_passwd_file_lookup(module->pwf, request); if (pu == NULL) { callback(PASSDB_RESULT_USER_UNKNOWN, request); return; @@ -29,7 +36,7 @@ crypted_pass = pu->password; scheme = password_get_scheme(&crypted_pass); - if (scheme == NULL) scheme = PASSWD_FILE_DEFAULT_SCHEME; + if (scheme == NULL) scheme = _module->default_pass_scheme; /* save the password so cache can use it */ auth_request_set_field(request, "password", crypted_pass, scheme); @@ -54,10 +61,13 @@ passwd_file_lookup_credentials(struct auth_request *request, lookup_credentials_callback_t *callback) { + struct passdb_module *_module = request->passdb->passdb; + struct passwd_file_passdb_module *module = + (struct passwd_file_passdb_module *)_module; struct passwd_user *pu; const char *crypted_pass, *scheme; - pu = db_passwd_file_lookup(passdb_pwf, request); + pu = db_passwd_file_lookup(module->pwf, request); if (pu == NULL) { callback(PASSDB_RESULT_USER_UNKNOWN, NULL, request); return; @@ -70,28 +80,39 @@ callback, request); } -static void passwd_file_init(const char *args) +static struct passdb_module * +passwd_file_preinit(struct auth_passdb *auth_passdb, + const char *args __attr_unused__) { - if (userdb_pwf != NULL && strcmp(userdb_pwf->path, args) == 0) { - passdb_pwf = userdb_pwf; - passdb_pwf->refcount++; - } else { - passdb_pwf = db_passwd_file_parse(args, FALSE); - } + struct passwd_file_passdb_module *module; + + module = p_new(auth_passdb->auth->pool, + struct passwd_file_passdb_module, 1); + module->module.cache_key = PASSWD_FILE_CACHE_KEY; + module->module.default_pass_scheme = PASSWD_FILE_DEFAULT_SCHEME; + return &module->module; } -static void passwd_file_deinit(void) +static void passwd_file_init(struct passdb_module *_module, const char *args) { - db_passwd_file_unref(passdb_pwf); + struct passwd_file_passdb_module *module = + (struct passwd_file_passdb_module *)_module; + + module->pwf = db_passwd_file_parse(args, FALSE); } -struct passdb_module passdb_passwd_file = { +static void passwd_file_deinit(struct passdb_module *_module) +{ + struct passwd_file_passdb_module *module = + (struct passwd_file_passdb_module *)_module; + + db_passwd_file_unref(module->pwf); +} + +struct passdb_module_interface passdb_passwd_file = { "passwd-file", - PASSWD_FILE_CACHE_KEY, - NULL, - FALSE, - NULL, + passwd_file_preinit, passwd_file_init, passwd_file_deinit,
--- a/src/auth/passdb-passwd.c Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/passdb-passwd.c Sun Oct 16 17:06:59 2005 +0300 @@ -56,18 +56,23 @@ callback(PASSDB_RESULT_OK, request); } -static void passwd_deinit(void) +static void passwd_init(struct passdb_module *module, + const char *args __attr_unused__) +{ + module->cache_key = PASSWD_CACHE_KEY; + module->default_pass_scheme = PASSWD_PASS_SCHEME; +} + +static void passwd_deinit(struct passdb_module *module __attr_unused__) { endpwent(); } -struct passdb_module passdb_passwd = { +struct passdb_module_interface passdb_passwd = { "passwd", - PASSWD_CACHE_KEY, - PASSWD_PASS_SCHEME, - FALSE, - NULL, NULL, + NULL, + passwd_init, passwd_deinit, passwd_verify_plain,
--- a/src/auth/passdb-shadow.c Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/passdb-shadow.c Sun Oct 16 17:06:59 2005 +0300 @@ -56,18 +56,23 @@ callback(PASSDB_RESULT_OK, request); } -static void shadow_deinit(void) +static void shadow_init(struct passdb_module *module, + const char *args __attr_unused__) +{ + module->cache_key = SHADOW_CACHE_KEY; + module->default_pass_scheme = SHADOW_PASS_SCHEME; +} + +static void shadow_deinit(struct passdb_module *module __attr_unused__) { endspent(); } -struct passdb_module passdb_shadow = { +struct passdb_module_interface passdb_shadow = { "shadow", - SHADOW_CACHE_KEY, - SHADOW_PASS_SCHEME, - FALSE, - NULL, NULL, + NULL, + shadow_init, shadow_deinit, shadow_verify_plain,
--- a/src/auth/passdb-sql.c Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/passdb-sql.c Sun Oct 16 17:06:59 2005 +0300 @@ -15,7 +15,11 @@ #include <stdlib.h> #include <string.h> -extern struct passdb_module passdb_sql; +struct sql_passdb_module { + struct passdb_module module; + + struct sql_connection *conn; +}; struct passdb_sql_request { struct auth_request *auth_request; @@ -25,13 +29,12 @@ } callback; }; -static struct sql_connection *passdb_sql_conn; -static char *passdb_sql_cache_key; - static void sql_query_save_results(struct sql_result *result, struct passdb_sql_request *sql_request) { struct auth_request *auth_request = sql_request->auth_request; + struct passdb_module *_module = auth_request->passdb->passdb; + struct sql_passdb_module *module = (struct sql_passdb_module *)_module; unsigned int i, fields_count; const char *name, *value; @@ -42,7 +45,7 @@ if (value != NULL) { auth_request_set_field(auth_request, name, value, - passdb_sql_conn->set.default_pass_scheme); + module->conn->set.default_pass_scheme); } } } @@ -120,17 +123,20 @@ static void sql_lookup_pass(struct passdb_sql_request *sql_request) { + struct passdb_module *_module = + sql_request->auth_request->passdb->passdb; + struct sql_passdb_module *module = (struct sql_passdb_module *)_module; string_t *query; query = t_str_new(512); - var_expand(query, passdb_sql_conn->set.password_query, + var_expand(query, module->conn->set.password_query, auth_request_get_var_expand_table(sql_request->auth_request, str_escape)); auth_request_log_debug(sql_request->auth_request, "sql", "query: %s", str_c(query)); - sql_query(passdb_sql_conn->db, str_c(query), + sql_query(module->conn->db, str_c(query), sql_query_callback, sql_request); } @@ -159,36 +165,45 @@ sql_lookup_pass(sql_request); } -static void passdb_sql_preinit(const char *args) +static struct passdb_module * +passdb_sql_preinit(struct auth_passdb *auth_passdb, const char *args) { - passdb_sql_conn = db_sql_init(args); + struct sql_passdb_module *module; + struct sql_connection *conn; - passdb_sql.cache_key = passdb_sql_cache_key = - auth_cache_parse_key(passdb_sql_conn->set.password_query); - passdb_sql.default_pass_scheme = - passdb_sql_conn->set.default_pass_scheme; + module = p_new(auth_passdb->auth->pool, struct sql_passdb_module, 1); + module->conn = conn = db_sql_init(args); + + module->module.cache_key = + auth_cache_parse_key(conn->set.password_query); + module->module.default_pass_scheme = conn->set.default_pass_scheme; + return &module->module; } -static void passdb_sql_init(const char *args __attr_unused__) +static void passdb_sql_init(struct passdb_module *_module, + const char *args __attr_unused__) { + struct sql_passdb_module *module = + (struct sql_passdb_module *)_module; enum sql_db_flags flags; - flags = sql_get_flags(passdb_sql_conn->db); - passdb_sql.blocking = (flags & SQL_DB_FLAG_BLOCKING) != 0; + flags = sql_get_flags(module->conn->db); + module->module.blocking = (flags & SQL_DB_FLAG_BLOCKING) != 0; - if (!passdb_sql.blocking || worker) - sql_connect(passdb_sql_conn->db); + if (!module->module.blocking || worker) + sql_connect(module->conn->db); } -static void passdb_sql_deinit(void) +static void passdb_sql_deinit(struct passdb_module *_module) { - db_sql_unref(passdb_sql_conn); - i_free(passdb_sql_cache_key); + struct sql_passdb_module *module = + (struct sql_passdb_module *)_module; + + db_sql_unref(module->conn); } -struct passdb_module passdb_sql = { +struct passdb_module_interface passdb_sql = { "sql", - NULL, NULL, FALSE, passdb_sql_preinit, passdb_sql_init,
--- a/src/auth/passdb-vpopmail.c Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/passdb-vpopmail.c Sun Oct 16 17:06:59 2005 +0300 @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2003 Timo Sirainen */ +/* Copyright (C) 2002-2005 Timo Sirainen */ /* Thanks to Courier-IMAP for showing how the vpopmail API should be used */ @@ -16,9 +16,6 @@ #define VPOPMAIL_DEFAULT_PASS_SCHEME "CRYPT" -extern struct passdb_module passdb_vpopmail; -static char *vpopmail_cache_key; - static void vpopmail_verify_plain(struct auth_request *request, const char *password, verify_plain_callback_t *callback) @@ -50,7 +47,8 @@ crypted_pass = vpw->pw_passwd; scheme = password_get_scheme(&crypted_pass); - if (scheme == NULL) scheme = passdb_vpopmail.default_pass_scheme; + if (scheme == NULL) + scheme = request->passdb->passdb->default_pass_scheme; ret = password_verify(password, crypted_pass, scheme, request->user); @@ -94,30 +92,31 @@ callback(PASSDB_RESULT_OK, request); } -static void vpopmail_init(const char *args) +static struct passdb_module * +vpopmail_preinit(struct auth_passdb *auth_passdb, const char *args) { - vpopmail_cache_key = NULL; + struct passdb_module *module; - if (strncmp(args, "cache_key=", 10) == 0) - vpopmail_cache_key = i_strdup(args + 10); + module = p_new(auth_passdb->auth->pool, struct passdb_module, 1); + module->default_pass_scheme = VPOPMAIL_DEFAULT_PASS_SCHEME; - passdb_vpopmail.cache_key = vpopmail_cache_key; + if (strncmp(args, "cache_key=", 10) == 0) { + module->cache_key = + p_strdup(auth_passdb->auth->pool, args + 10); + } + return module; } -static void vpopmail_deinit(void) +static void vpopmail_deinit(struct passdb_module *module __attr_unused__) { vclose(); - i_free(vpopmail_cache_key); } -struct passdb_module passdb_vpopmail = { +struct passdb_module_interface passdb_vpopmail = { "vpopmail", + + vpopmail_preinit, NULL, - VPOPMAIL_DEFAULT_PASS_SCHEME, - FALSE, - - NULL, - vpopmail_init, vpopmail_deinit, vpopmail_verify_plain,
--- a/src/auth/passdb.c Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/passdb.c Sun Oct 16 17:06:59 2005 +0300 @@ -8,17 +8,17 @@ #include <stdlib.h> -extern struct passdb_module passdb_passwd; -extern struct passdb_module passdb_bsdauth; -extern struct passdb_module passdb_shadow; -extern struct passdb_module passdb_passwd_file; -extern struct passdb_module passdb_pam; -extern struct passdb_module passdb_checkpassword; -extern struct passdb_module passdb_vpopmail; -extern struct passdb_module passdb_ldap; -extern struct passdb_module passdb_sql; +extern struct passdb_module_interface passdb_passwd; +extern struct passdb_module_interface passdb_bsdauth; +extern struct passdb_module_interface passdb_shadow; +extern struct passdb_module_interface passdb_passwd_file; +extern struct passdb_module_interface passdb_pam; +extern struct passdb_module_interface passdb_checkpassword; +extern struct passdb_module_interface passdb_vpopmail; +extern struct passdb_module_interface passdb_ldap; +extern struct passdb_module_interface passdb_sql; -struct passdb_module *passdbs[] = { +struct passdb_module_interface *passdb_interfaces[] = { #ifdef PASSDB_PASSWD &passdb_passwd, #endif @@ -124,7 +124,7 @@ struct auth_passdb *passdb_preinit(struct auth *auth, const char *driver, const char *args) { - struct passdb_module **p; + struct passdb_module_interface **p, *iface; struct auth_passdb *auth_passdb, **dest; if (args == NULL) args = ""; @@ -137,35 +137,41 @@ auth_passdb->num++; *dest = auth_passdb; - for (p = passdbs; *p != NULL; p++) { + iface = NULL; + for (p = passdb_interfaces; *p != NULL; p++) { if (strcmp((*p)->name, driver) == 0) { - auth_passdb->passdb = *p; + iface = *p; break; } } #ifdef HAVE_MODULES - if (auth_passdb->passdb == NULL) + if (iface == NULL) auth_passdb->module = auth_module_open(driver); if (auth_passdb->module != NULL) { - auth_passdb->passdb = - auth_module_sym(auth_passdb->module, + iface = auth_module_sym(auth_passdb->module, t_strconcat("passdb_", driver, NULL)); } #endif - if (auth_passdb->passdb == NULL) + if (iface == NULL) i_fatal("Unknown passdb driver '%s'", driver); - if (auth_passdb->passdb->preinit != NULL) - auth_passdb->passdb->preinit(auth_passdb->args); + if (iface->preinit == NULL) { + auth_passdb->passdb = + p_new(auth->pool, struct passdb_module, 1); + } else { + auth_passdb->passdb = + iface->preinit(auth_passdb, auth_passdb->args); + } + auth_passdb->passdb->iface = iface; return auth_passdb; } void passdb_init(struct auth_passdb *passdb) { - if (passdb->passdb->init != NULL) - passdb->passdb->init(passdb->args); + if (passdb->passdb->iface->init != NULL) + passdb->passdb->iface->init(passdb->passdb, passdb->args); i_assert(passdb->passdb->default_pass_scheme != NULL || passdb->passdb->cache_key == NULL); @@ -178,8 +184,8 @@ void passdb_deinit(struct auth_passdb *passdb) { - if (passdb->passdb->deinit != NULL) - passdb->passdb->deinit(); + if (passdb->passdb->iface->deinit != NULL) + passdb->passdb->iface->deinit(passdb->passdb); #ifdef HAVE_MODULES if (passdb->module != NULL) auth_module_close(passdb->module);
--- a/src/auth/passdb.h Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/passdb.h Sun Oct 16 17:06:59 2005 +0300 @@ -35,8 +35,6 @@ struct auth_request *request); struct passdb_module { - const char *name; - /* The caching key for this module, or NULL if caching isn't wanted. */ const char *cache_key; /* Default password scheme for this module. @@ -46,9 +44,16 @@ this passdb. */ int blocking; - void (*preinit)(const char *args); - void (*init)(const char *args); - void (*deinit)(void); + const struct passdb_module_interface *iface; +}; + +struct passdb_module_interface { + const char *name; + + struct passdb_module * + (*preinit)(struct auth_passdb *auth_passdb, const char *args); + void (*init)(struct passdb_module *module, const char *args); + void (*deinit)(struct passdb_module *module); /* Check if plaintext password matches */ void (*verify_plain)(struct auth_request *request, const char *password,
--- a/src/auth/userdb-passwd-file.c Sun Oct 16 15:49:14 2005 +0300 +++ b/src/auth/userdb-passwd-file.c Sun Oct 16 17:06:59 2005 +0300 @@ -37,17 +37,7 @@ static void passwd_file_init(const char *args) { - if (passdb_pwf != NULL && strcmp(passdb_pwf->path, args) == 0) { - userdb_pwf = passdb_pwf; - userdb_pwf->refcount++; - - /* resync */ - userdb_pwf->userdb = TRUE; - if (userdb_pwf->default_file != NULL) - userdb_pwf->default_file->stamp = 0; - } else { - userdb_pwf = db_passwd_file_parse(args, TRUE); - } + userdb_pwf = db_passwd_file_parse(args, TRUE); } static void passwd_file_deinit(void)