db-sql.c revision e665999b757e60bfb98e5a84a78b05f061453140
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2003-2011 Dovecot authors, see the included COPYING file */
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger#include "auth-common.h"
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
c96eb61168670cfdd7596baba18856d3f086a093Timo Sirainen#if defined(PASSDB_SQL) || defined(USERDB_SQL)
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen#include "settings.h"
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen#include "auth-request.h"
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen#include "db-sql.h"
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen#include <stddef.h>
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen#include <stdlib.h>
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen#define DEF_STR(name) DEF_STRUCT_STR(name, sql_settings)
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen#define DEF_INT(name) DEF_STRUCT_INT(name, sql_settings)
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen#define DEF_BOOL(name) DEF_STRUCT_BOOL(name, sql_settings)
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainenstatic struct setting_def setting_defs[] = {
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen DEF_STR(driver),
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen DEF_STR(connect),
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen DEF_STR(password_query),
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen DEF_STR(user_query),
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen DEF_STR(update_query),
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen DEF_STR(iterate_query),
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen DEF_STR(default_pass_scheme),
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen DEF_BOOL(userdb_warning_disable),
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
39e6fcc3e8b1ccb13087c232cb6bdea04d1a20a4Timo Sirainen { 0, NULL, 0 }
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen};
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainenstatic struct sql_settings default_sql_settings = {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen .driver = NULL,
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen .connect = NULL,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen .password_query = "SELECT username, domain, password FROM users WHERE username = '%n' AND domain = '%d'",
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen .user_query = "SELECT home, uid, gid FROM users WHERE username = '%n' AND domain = '%d'",
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen .update_query = "UPDATE users SET password = '%w' WHERE username = '%n' AND domain = '%d'",
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen .iterate_query = "SELECT username, domain FROM users",
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen .default_pass_scheme = "MD5",
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen .userdb_warning_disable = FALSE
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen};
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainenstatic struct sql_connection *connections = NULL;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainenstatic struct sql_connection *sql_conn_find(const char *config_path)
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen{
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen struct sql_connection *conn;
150e64c376365becf1ec5c9d45912ecb840eea96Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen for (conn = connections; conn != NULL; conn = conn->next) {
150e64c376365becf1ec5c9d45912ecb840eea96Timo Sirainen if (strcmp(conn->config_path, config_path) == 0)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return conn;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen }
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen return NULL;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen}
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainenstatic const char *parse_setting(const char *key, const char *value,
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen struct sql_connection *conn)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen{
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen return parse_setting_from_defs(conn->pool, setting_defs,
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen &conn->set, key, value);
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen}
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainenstruct sql_connection *db_sql_init(const char *config_path, bool userdb)
5afa8e2edf4f313cd56e5909f92f39c3b5b7b4d3Timo Sirainen{
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen struct sql_connection *conn;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen pool_t pool;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen conn = sql_conn_find(config_path);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen if (conn != NULL) {
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen if (userdb)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen conn->userdb_used = TRUE;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen conn->refcount++;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen return conn;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen }
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen if (*config_path == '\0')
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen i_fatal("sql: Configuration file path not given");
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen pool = pool_alloconly_create("sql_connection", 1024);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen conn = p_new(pool, struct sql_connection, 1);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen conn->pool = pool;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen conn->userdb_used = userdb;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen conn->refcount = 1;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen conn->config_path = p_strdup(pool, config_path);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen conn->set = default_sql_settings;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (!settings_read(config_path, NULL, parse_setting,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen null_settings_section_callback, conn))
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen exit(FATAL_DEFAULT);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (conn->set.password_query == default_sql_settings.password_query)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen conn->default_password_query = TRUE;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (conn->set.user_query == default_sql_settings.user_query)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen conn->default_user_query = TRUE;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (conn->set.update_query == default_sql_settings.update_query)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen conn->default_update_query = TRUE;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (conn->set.iterate_query == default_sql_settings.iterate_query)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen conn->default_iterate_query = TRUE;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (conn->set.driver == NULL) {
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen i_fatal("sql: driver not set in configuration file %s",
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen config_path);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen }
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (conn->set.connect == NULL) {
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen i_fatal("sql: connect string not set in configuration file %s",
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen config_path);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen }
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen conn->db = sql_init(conn->set.driver, conn->set.connect);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen conn->next = connections;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen connections = conn;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return conn;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen}
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenvoid db_sql_unref(struct sql_connection **_conn)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen{
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen struct sql_connection *conn = *_conn;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen /* abort all pending auth requests before setting conn to NULL,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen so that callbacks can still access it */
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen sql_disconnect(conn->db);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen *_conn = NULL;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (--conn->refcount > 0)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen sql_deinit(&conn->db);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen pool_unref(&conn->pool);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen}
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenvoid db_sql_check_userdb_warning(struct sql_connection *conn)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen{
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (worker || conn->userdb_used || conn->set.userdb_warning_disable)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (strcmp(conn->set.user_query,
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen default_sql_settings.user_query) != 0) {
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen i_warning("sql: Ignoring changed user_query in %s, "
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen "because userdb sql not used. "
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen "(If this is intentional, set userdb_warning_disable=yes)",
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen conn->config_path);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen } else if (strcmp(conn->set.iterate_query,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen default_sql_settings.iterate_query) != 0) {
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen i_warning("sql: Ignoring changed iterate_query in %s, "
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen "because userdb sql not used. "
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen "(If this is intentional, set userdb_warning_disable=yes)",
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen conn->config_path);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen }
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen}
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen#endif
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen