Mercurial > dovecot > core-2.2
diff src/auth/passdb-pgsql.c @ 1296:a9ac5865daf8 HEAD
Whops, forgot to add.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 14 Mar 2003 21:28:59 +0200 |
parents | |
children | 7cde19dbe754 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/auth/passdb-pgsql.c Fri Mar 14 21:28:59 2003 +0200 @@ -0,0 +1,173 @@ +/* Copyright (C) 2003 Alex Howansky, Timo Sirainen */ + +#include "config.h" +#undef HAVE_CONFIG_H + +#ifdef PASSDB_PGSQL + +#include "common.h" +#include "str.h" +#include "var-expand.h" +#include "password-scheme.h" +#include "db-pgsql.h" +#include "passdb.h" + +#include <libpq-fe.h> +#include <stdlib.h> +#include <string.h> + +struct passdb_pgsql_connection { + struct pgsql_connection *conn; +}; + +struct passdb_pgsql_request { + struct pgsql_request request; + + enum passdb_credentials credentials; + union { + verify_plain_callback_t *verify_plain; + lookup_credentials_callback_t *lookup_credentials; + } callback; + + char password[1]; +}; + +static struct passdb_pgsql_connection *passdb_pgsql_conn; + +static void pgsql_handle_request(struct pgsql_connection *conn, + struct pgsql_request *request, PGresult *res) +{ + struct passdb_pgsql_request *pgsql_request = + (struct passdb_pgsql_request *) request; + struct auth_request *auth_request = request->context; + const char *user, *password, *scheme; + int ret = 0; + + user = auth_request->user; + password = NULL; + + if (res != NULL) { + if (PQntuples(res) == 0) { + if (verbose) + i_info("pgsql(%s): Unknown user", user); + } else if (PQntuples(res) > 1) { + i_error("pgsql(%s): Multiple matches for user", user); + } else if (PQnfields(res) != 1) { + i_error("pgsql(%s): Password query returned " + "more than one field", user); + } else { + password = t_strdup(PQgetvalue(res, 0, 0)); + } + } + + scheme = password_get_scheme(&password); + if (scheme == NULL) { + scheme = conn->set.default_pass_scheme; + i_assert(scheme != NULL); + } + + if (pgsql_request->credentials != -1) { + passdb_handle_credentials(pgsql_request->credentials, + user, password, scheme, + pgsql_request->callback.lookup_credentials, + auth_request); + return; + } + + /* verify plain */ + if (password == NULL) { + pgsql_request->callback.verify_plain(PASSDB_RESULT_USER_UNKNOWN, + auth_request); + return; + } + + ret = password_verify(pgsql_request->password, password, + scheme, user); + if (ret < 0) + i_error("pgsql(%s): Unknown password scheme %s", user, scheme); + else if (ret == 0) { + if (verbose) + i_info("pgsql(%s): Password mismatch", user); + } + + pgsql_request->callback.verify_plain(ret > 0 ? PASSDB_RESULT_OK : + PASSDB_RESULT_PASSWORD_MISMATCH, + auth_request); +} + +static void pgsql_lookup_pass(struct auth_request *auth_request, + struct pgsql_request *pgsql_request) +{ + struct pgsql_connection *conn = passdb_pgsql_conn->conn; + const char *query; + string_t *str; + + str = t_str_new(512); + var_expand(str, conn->set.password_query, auth_request->user, NULL); + query = str_c(str); + + pgsql_request->callback = pgsql_handle_request; + pgsql_request->context = auth_request; + + if (db_pgsql_is_valid_username(conn, auth_request->user)) + db_pgsql_query(conn, query, pgsql_request); + else { + if (verbose) { + i_error("pgsql(%s): Invalid username", + auth_request->user); + } + pgsql_handle_request(conn, pgsql_request, NULL); + } +} + +static void +pgsql_verify_plain(struct auth_request *request, const char *password, + verify_plain_callback_t *callback) +{ + struct passdb_pgsql_request *pgsql_request; + + pgsql_request = i_malloc(sizeof(struct passdb_pgsql_request) + + strlen(password)); + pgsql_request->credentials = -1; + pgsql_request->callback.verify_plain = callback; + strcpy(pgsql_request->password, password); + + pgsql_lookup_pass(request, &pgsql_request->request); +} + +static void pgsql_lookup_credentials(struct auth_request *request, + enum passdb_credentials credentials, + lookup_credentials_callback_t *callback) +{ + struct passdb_pgsql_request *pgsql_request; + + pgsql_request = i_new(struct passdb_pgsql_request, 1); + pgsql_request->credentials = credentials; + pgsql_request->callback.lookup_credentials = callback; + + pgsql_lookup_pass(request, &pgsql_request->request); +} + +static void passdb_pgsql_init(const char *args) +{ + struct pgsql_connection *conn; + + passdb_pgsql_conn = i_new(struct passdb_pgsql_connection, 1); + passdb_pgsql_conn->conn = conn = db_pgsql_init(args); +} + +static void passdb_pgsql_deinit(void) +{ + db_pgsql_unref(passdb_pgsql_conn->conn); + i_free(passdb_pgsql_conn); +} + +struct passdb_module passdb_pgsql = { + passdb_pgsql_init, + passdb_pgsql_deinit, + + pgsql_verify_plain, + pgsql_lookup_credentials +}; + +#endif