db-sql.c revision 48010d123abfac8cb19f33f1fe12f33a7090089e
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (c) 2003-2010 Dovecot authors, see the included COPYING file */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "auth-common.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#if defined(PASSDB_SQL) || defined(USERDB_SQL)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
bdd36cfdba3ff66d25570a9ff568d69e1eb543cfTimo Sirainen#include "settings.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "auth-request.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "db-sql.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
e98e8ba55a01427844b2d24becd791dde8b0178bTimo Sirainen#include <stddef.h>
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include <stdlib.h>
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#define DEF_STR(name) DEF_STRUCT_STR(name, sql_settings)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#define DEF_INT(name) DEF_STRUCT_INT(name, sql_settings)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#define DEF_BOOL(name) DEF_STRUCT_BOOL(name, sql_settings)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschstatic struct setting_def setting_defs[] = {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch DEF_STR(driver),
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen DEF_STR(connect),
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch DEF_STR(password_query),
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch DEF_STR(user_query),
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch DEF_STR(update_query),
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch DEF_STR(iterate_query),
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch DEF_STR(default_pass_scheme),
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch { 0, NULL, 0 }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch};
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschstatic struct sql_settings default_sql_settings = {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch .driver = NULL,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch .connect = NULL,
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen .password_query = "SELECT username, domain, password FROM users WHERE username = '%n' AND domain = '%d'",
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch .user_query = "SELECT home, uid, gid FROM users WHERE username = '%n' AND domain = '%d'",
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch .update_query = "UPDATE users SET password = '%w' WHERE username = '%n' AND domain = '%d'",
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch .iterate_query = "SELECT username, domain FROM users",
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch .default_pass_scheme = "MD5"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch};
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschstatic struct sql_connection *connections = NULL;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
7b6cc2bca3b2fb58bbbea5293ed8f63d352dc305Timo Sirainenstatic struct sql_connection *sql_conn_find(const char *config_path)
7b6cc2bca3b2fb58bbbea5293ed8f63d352dc305Timo Sirainen{
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch struct sql_connection *conn;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch for (conn = connections; conn != NULL; conn = conn->next) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (strcmp(conn->config_path, config_path) == 0)
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainen return conn;
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainen }
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainen
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainen return NULL;
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainen}
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainen
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainenstatic const char *parse_setting(const char *key, const char *value,
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainen struct sql_connection *conn)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch{
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch return parse_setting_from_defs(conn->pool, setting_defs,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch &conn->set, key, value);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch}
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschstruct sql_connection *db_sql_init(const char *config_path)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch{
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch struct sql_connection *conn;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch pool_t pool;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch conn = sql_conn_find(config_path);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (conn != NULL) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch conn->refcount++;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch return conn;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (*config_path == '\0')
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch i_fatal("sql: Configuration file path not given");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch pool = pool_alloconly_create("sql_connection", 1024);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch conn = p_new(pool, struct sql_connection, 1);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch conn->pool = pool;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch conn->refcount = 1;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch conn->config_path = p_strdup(pool, config_path);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch conn->set = default_sql_settings;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (!settings_read(config_path, NULL, parse_setting,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch null_settings_section_callback, conn))
c1b9c4531186c6a7cd92d2c353273a834f8ee66fTimo Sirainen exit(FATAL_DEFAULT);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (conn->set.password_query == default_sql_settings.password_query)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch conn->default_password_query = TRUE;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (conn->set.user_query == default_sql_settings.user_query)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch conn->default_user_query = TRUE;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (conn->set.update_query == default_sql_settings.update_query)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch conn->default_update_query = TRUE;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (conn->set.iterate_query == default_sql_settings.iterate_query)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch conn->default_iterate_query = TRUE;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (conn->set.driver == NULL) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch i_fatal("sql: driver not set in configuration file %s",
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch config_path);
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen }
c1b9c4531186c6a7cd92d2c353273a834f8ee66fTimo Sirainen if (conn->set.connect == NULL) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch i_fatal("sql: connect string not set in configuration file %s",
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch config_path);
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen }
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen conn->db = sql_init(conn->set.driver, conn->set.connect);
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen conn->next = connections;
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen connections = conn;
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen return conn;
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen}
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschvoid db_sql_unref(struct sql_connection **_conn)
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen{
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen struct sql_connection *conn = *_conn;
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen *_conn = NULL;
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen if (--conn->refcount > 0)
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen return;
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen
5c8a42e2860a0db7b8911c5479910a4f918436b9Timo Sirainen sql_deinit(&conn->db);
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen pool_unref(&conn->pool);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch}
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#endif
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen