db-sql.c revision d37186d1462b902a9a2624c30e3512bd2b9cd197
76b43e4417bab52e913da39b5f5bc2a130d3f149Timo Sirainen/* Copyright (c) 2003-2008 Dovecot authors, see the included COPYING file */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
2fbc2a7c65d30e46803195ebb4547176b85c22c7Timo Sirainen#include "common.h"
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen#if defined(PASSDB_SQL) || defined(USERDB_SQL)
2fbc2a7c65d30e46803195ebb4547176b85c22c7Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen#include "settings.h"
3c9783956dea385b322cd7fa6bf8c98c17a907a0Timo Sirainen#include "auth-request.h"
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen#include "db-sql.h"
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen#include <stddef.h>
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen#include <stdlib.h>
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
a84eb0599fa1d796206eaed65c4e3239f0799276Timo Sirainen#define DEF_STR(name) DEF_STRUCT_STR(name, sql_settings)
a84eb0599fa1d796206eaed65c4e3239f0799276Timo Sirainen#define DEF_INT(name) DEF_STRUCT_INT(name, sql_settings)
a84eb0599fa1d796206eaed65c4e3239f0799276Timo Sirainen#define DEF_BOOL(name) DEF_STRUCT_BOOL(name, sql_settings)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstatic struct setting_def setting_defs[] = {
a84eb0599fa1d796206eaed65c4e3239f0799276Timo Sirainen DEF_STR(driver),
a84eb0599fa1d796206eaed65c4e3239f0799276Timo Sirainen DEF_STR(connect),
a84eb0599fa1d796206eaed65c4e3239f0799276Timo Sirainen DEF_STR(password_query),
a84eb0599fa1d796206eaed65c4e3239f0799276Timo Sirainen DEF_STR(user_query),
a84eb0599fa1d796206eaed65c4e3239f0799276Timo Sirainen DEF_STR(update_query),
a84eb0599fa1d796206eaed65c4e3239f0799276Timo Sirainen DEF_STR(default_pass_scheme),
e25885d4c7c4b392c66bbf26a9b892362d90f001Timo Sirainen
e25885d4c7c4b392c66bbf26a9b892362d90f001Timo Sirainen { 0, NULL, 0 }
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen};
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstruct sql_settings default_sql_settings = {
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen MEMBER(driver) NULL,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen MEMBER(connect) NULL,
d37186d1462b902a9a2624c30e3512bd2b9cd197Timo Sirainen MEMBER(password_query) "SELECT username, domain, password FROM users WHERE username = '%n' AND domain = '%d'",
d37186d1462b902a9a2624c30e3512bd2b9cd197Timo Sirainen MEMBER(user_query) "SELECT home, uid, gid FROM users WHERE username = '%n' AND domain = '%d'",
d37186d1462b902a9a2624c30e3512bd2b9cd197Timo Sirainen MEMBER(update_query) "UPDATE users SET password = '%w' WHERE username = '%n' AND domain = '%d'",
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen MEMBER(default_pass_scheme) "PLAIN-MD5"
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen};
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstatic struct sql_connection *connections = NULL;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstatic struct sql_connection *sql_conn_find(const char *config_path)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen struct sql_connection *conn;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen for (conn = connections; conn != NULL; conn = conn->next) {
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen if (strcmp(conn->config_path, config_path) == 0)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen return conn;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen }
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen return NULL;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstatic const char *parse_setting(const char *key, const char *value,
2cfe9983ce7a6280636ee12beccc2e865111967bTimo Sirainen struct sql_connection *conn)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen return parse_setting_from_defs(conn->pool, setting_defs,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen &conn->set, key, value);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstruct sql_connection *db_sql_init(const char *config_path)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen struct sql_connection *conn;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen pool_t pool;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen conn = sql_conn_find(config_path);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen if (conn != NULL) {
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen conn->refcount++;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen return conn;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen }
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
2e1e493b248dec0127b1eabeea5a8bc330378fcdTimo Sirainen if (*config_path == '\0')
b7828b34f6d81cdea62761932a1da1a444a29bcdTimo Sirainen i_fatal("sql: Configuration file path not given");
2e1e493b248dec0127b1eabeea5a8bc330378fcdTimo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen pool = pool_alloconly_create("sql_connection", 1024);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen conn = p_new(pool, struct sql_connection, 1);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen conn->pool = pool;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen conn->refcount = 1;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen conn->config_path = p_strdup(pool, config_path);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen conn->set = default_sql_settings;
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen if (!settings_read(config_path, NULL, parse_setting,
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen null_settings_section_callback, conn))
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen exit(FATAL_DEFAULT);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen if (conn->set.driver == NULL) {
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen i_fatal("sql: driver not set in configuration file %s",
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen config_path);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen }
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen if (conn->set.connect == NULL) {
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen i_fatal("sql: connect string not set in configuration file %s",
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen config_path);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen }
f8a86fdfb0048f9c87bf223373b35416ceb5856bTimo Sirainen conn->db = sql_init(conn->set.driver, conn->set.connect);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen conn->next = connections;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen connections = conn;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen return conn;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenvoid db_sql_unref(struct sql_connection **_conn)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen struct sql_connection *conn = *_conn;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen *_conn = NULL;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen if (--conn->refcount > 0)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen return;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen sql_deinit(&conn->db);
648d24583c1574441c4fa0331a90bd4d6e7996c5Timo Sirainen pool_unref(&conn->pool);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen#endif