db-sql.c revision 79450e7c1bbc2812957ccde8dcaf41ed54eb3611
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher/* Copyright (c) 2003-2008 Dovecot authors, see the included COPYING file */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
ee359fe1384507fed6c2274e7bfe81d288de4542Stephen Gallagher#include "common.h"
33396dc46ea52c18f47db1b5d590880806521005Sumit Bose
ee359fe1384507fed6c2274e7bfe81d288de4542Stephen Gallagher#if defined(PASSDB_SQL) || defined(USERDB_SQL)
33396dc46ea52c18f47db1b5d590880806521005Sumit Bose
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher#include "settings.h"
324fb26ba803a999bedc29e93c46c84f27abf5b7Sumit Bose#include "auth-request.h"
324fb26ba803a999bedc29e93c46c84f27abf5b7Sumit Bose#include "db-sql.h"
324fb26ba803a999bedc29e93c46c84f27abf5b7Sumit Bose
324fb26ba803a999bedc29e93c46c84f27abf5b7Sumit Bose#include <stddef.h>
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher#include <stdlib.h>
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
84ae5edab16ad6be5e3be956cb6fa031c1428eb5Stephen Gallagher#define DEF_STR(name) DEF_STRUCT_STR(name, sql_settings)
84ae5edab16ad6be5e3be956cb6fa031c1428eb5Stephen Gallagher#define DEF_INT(name) DEF_STRUCT_INT(name, sql_settings)
84ae5edab16ad6be5e3be956cb6fa031c1428eb5Stephen Gallagher#define DEF_BOOL(name) DEF_STRUCT_BOOL(name, sql_settings)
e65df5b966b27e13283c65f59f99ac44781e0333Simo Sorce
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic struct setting_def setting_defs[] = {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher DEF_STR(driver),
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher DEF_STR(connect),
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher DEF_STR(password_query),
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher DEF_STR(user_query),
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher DEF_STR(update_query),
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher DEF_STR(default_pass_scheme),
84ae5edab16ad6be5e3be956cb6fa031c1428eb5Stephen Gallagher
cc98edd9479d4622634a1275c98058916c14059aStephen Gallagher { 0, NULL, 0 }
ee359fe1384507fed6c2274e7bfe81d288de4542Stephen Gallagher};
cc98edd9479d4622634a1275c98058916c14059aStephen Gallagher
d3da1c165cdb4c1ec126a8f4b6b544ca415b9d20Pavel Březinastruct sql_settings default_sql_settings = {
d3da1c165cdb4c1ec126a8f4b6b544ca415b9d20Pavel Březina MEMBER(driver) NULL,
d3da1c165cdb4c1ec126a8f4b6b544ca415b9d20Pavel Březina MEMBER(connect) NULL,
1183d29d87c5c7439cf2364b7d7324d4a13b6e35Stephen Gallagher MEMBER(password_query) "SELECT username, domain, password FROM users WHERE username = '%n' AND domain = '%d'",
1183d29d87c5c7439cf2364b7d7324d4a13b6e35Stephen Gallagher MEMBER(user_query) "SELECT home, uid, gid FROM users WHERE username = '%n' AND domain = '%d'",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher MEMBER(update_query) "UPDATE users SET password = '%w' WHERE username = '%n' AND domain = '%d'",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher MEMBER(default_pass_scheme) "MD5"
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher};
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic struct sql_connection *connections = NULL;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic struct sql_connection *sql_conn_find(const char *config_path)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher struct sql_connection *conn;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher for (conn = connections; conn != NULL; conn = conn->next) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (strcmp(conn->config_path, config_path) == 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return conn;
c89589fa349f38214c9cb8d9389c0fd557e5dca2Simo Sorce }
c89589fa349f38214c9cb8d9389c0fd557e5dca2Simo Sorce
c89589fa349f38214c9cb8d9389c0fd557e5dca2Simo Sorce return NULL;
c89589fa349f38214c9cb8d9389c0fd557e5dca2Simo Sorce}
c89589fa349f38214c9cb8d9389c0fd557e5dca2Simo Sorce
c89589fa349f38214c9cb8d9389c0fd557e5dca2Simo Sorcestatic const char *parse_setting(const char *key, const char *value,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher struct sql_connection *conn)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return parse_setting_from_defs(conn->pool, setting_defs,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher &conn->set, key, value);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstruct sql_connection *db_sql_init(const char *config_path)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher struct sql_connection *conn;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher pool_t pool;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher conn = sql_conn_find(config_path);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (conn != NULL) {
d921c1eba437662437847279f251a0a5d8f70127Maxim conn->refcount++;
d921c1eba437662437847279f251a0a5d8f70127Maxim return conn;
d921c1eba437662437847279f251a0a5d8f70127Maxim }
d921c1eba437662437847279f251a0a5d8f70127Maxim
d921c1eba437662437847279f251a0a5d8f70127Maxim if (*config_path == '\0')
d921c1eba437662437847279f251a0a5d8f70127Maxim i_fatal("sql: Configuration file path not given");
d921c1eba437662437847279f251a0a5d8f70127Maxim
327127bb7fcc07f882209f029e14026de1b23c94Maxim pool = pool_alloconly_create("sql_connection", 1024);
327127bb7fcc07f882209f029e14026de1b23c94Maxim conn = p_new(pool, struct sql_connection, 1);
327127bb7fcc07f882209f029e14026de1b23c94Maxim conn->pool = pool;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
d3da1c165cdb4c1ec126a8f4b6b544ca415b9d20Pavel Březina conn->refcount = 1;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher conn->config_path = p_strdup(pool, config_path);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher conn->set = default_sql_settings;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (!settings_read(config_path, NULL, parse_setting,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher null_settings_section_callback, conn))
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher exit(FATAL_DEFAULT);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (conn->set.driver == NULL) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_fatal("sql: driver not set in configuration file %s",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher config_path);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
4b6a0d0b3d42e5fdb457f47d9adfa5e66b160256Stephen Gallagher if (conn->set.connect == NULL) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_fatal("sql: connect string not set in configuration file %s",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher config_path);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher conn->db = sql_init(conn->set.driver, conn->set.connect);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
068dbee9ca7bf5b37330eff91c94ae10f288d09fJakub Hrozek conn->next = connections;
98ce3c3e85a4bb2e1822bf8ab2a1c2ab9e3dd61dJakub Hrozek connections = conn;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return conn;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid db_sql_unref(struct sql_connection **_conn)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher struct sql_connection *conn = *_conn;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher *_conn = NULL;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (--conn->refcount > 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher sql_deinit(&conn->db);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher pool_unref(&conn->pool);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher#endif
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher