Mercurial > dovecot > original-hg > dovecot-1.2
view src/auth/db-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 source
/* Copyright (C) 2003 Alex Howansky, Timo Sirainen */ #include "config.h" #undef HAVE_CONFIG_H #if defined(PASSDB_PGSQL) || defined(USERDB_PGSQL) #include "common.h" #include "network.h" #include "str.h" #include "settings.h" #include "db-pgsql.h" #include <stddef.h> #define DEF(type, name) { type, #name, offsetof(struct pgsql_settings, name) } static struct setting_def setting_defs[] = { DEF(SET_STR, connect), DEF(SET_STR, password_query), DEF(SET_STR, user_query), DEF(SET_STR, allowed_chars), DEF(SET_STR, default_pass_scheme) }; struct pgsql_settings default_pgsql_settings = { MEMBER(connect) "dbname=virtual user=virtual", MEMBER(password_query) "SELECT password FROM users WHERE userid = '%u'", MEMBER(user_query) "SELECT home, uid, gid FROM users WHERE userid = '%u'", MEMBER(allowed_chars) "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-@", MEMBER(default_pass_scheme) "PLAIN-MD5" }; static struct pgsql_connection *pgsql_connections = NULL; static int pgsql_conn_open(struct pgsql_connection *conn); static void pgsql_conn_close(struct pgsql_connection *conn); int db_pgsql_is_valid_username(struct pgsql_connection *conn, const char *username) { const char *p; for (p = username; *p != '\0'; p++) { if (strchr(conn->set.allowed_chars, *p) == NULL) return FALSE; } return TRUE; } void db_pgsql_query(struct pgsql_connection *conn, const char *query, struct pgsql_request *request) { PGresult *res; int failed; if (!conn->connected) { if (!pgsql_conn_open(conn)) { request->callback(conn, request, NULL); return; } } if (verbose_debug) i_info("PGSQL: Performing query: %s", query); res = PQexec(conn->pg, query); if (PQresultStatus(res) != PGRES_TUPLES_OK) { i_error("PGSQL: Query \"%s\" failed: %s", query, PQresultErrorMessage(res)); failed = TRUE; } else if (PQntuples(res) != 1) { i_error("PGSQL: Query \"%s\" returned %d rows", query, PQntuples(res)); failed = TRUE; } else { failed = FALSE; } request->callback(conn, request, failed ? NULL : res); PQclear(res); } static int pgsql_conn_open(struct pgsql_connection *conn) { if (conn->connected) return TRUE; if (conn->pg == NULL) { conn->pg = PQconnectdb(conn->set.connect); if (PQstatus(conn->pg) != CONNECTION_OK) { i_error("PGSQL: Can't connect to database %s", conn->set.connect); return FALSE; } } conn->connected = TRUE; return TRUE; } static void pgsql_conn_close(struct pgsql_connection *conn) { conn->connected = FALSE; if (conn->pg != NULL) { PQfinish(conn->pg); conn->pg = NULL; } } static struct pgsql_connection *pgsql_conn_find(const char *config_path) { struct pgsql_connection *conn; for (conn = pgsql_connections; conn != NULL; conn = conn->next) { if (strcmp(conn->config_path, config_path) == 0) return conn; } return NULL; } static const char *parse_setting(const char *key, const char *value, void *context) { struct pgsql_connection *conn = context; return parse_setting_from_defs(conn->pool, setting_defs, &conn->set, key, value); } struct pgsql_connection *db_pgsql_init(const char *config_path) { struct pgsql_connection *conn; pool_t pool; conn = pgsql_conn_find(config_path); if (conn != NULL) { conn->refcount++; return conn; } pool = pool_alloconly_create("pgsql_connection", 1024); conn = p_new(pool, struct pgsql_connection, 1); conn->pool = pool; conn->refcount = 1; conn->config_path = p_strdup(pool, config_path); conn->set = default_pgsql_settings; settings_read(config_path, parse_setting, conn); (void)pgsql_conn_open(conn); conn->next = pgsql_connections; pgsql_connections = conn; return conn; } void db_pgsql_unref(struct pgsql_connection *conn) { if (--conn->refcount > 0) return; pgsql_conn_close(conn); pool_unref(conn->pool); } #endif