userdb-sql.c revision 48010d123abfac8cb19f33f1fe12f33a7090089e
bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2004-2010 Dovecot authors, see the included COPYING file */
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "auth-common.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "userdb.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#ifdef USERDB_SQL
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen#include "str.h"
022412398e56a8f31ef111cfd7271498d64af9a9Timo Sirainen#include "strescape.h"
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen#include "var-expand.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "auth-cache.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "db-sql.h"
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen#include <stdlib.h>
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen#include <string.h>
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainenstruct sql_userdb_module {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct userdb_module module;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct sql_connection *conn;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct userdb_sql_request {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct auth_request *auth_request;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen userdb_callback_t *callback;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenstruct sql_userdb_iterate_context {
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen struct userdb_iterate_context ctx;
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen struct sql_result *result;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen unsigned int freed:1;
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen unsigned int call_iter:1;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen};
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
2d3aac5be07b96f72cf0551fac35ac74a4f07770Timo Sirainenstatic void userdb_sql_iterate_next(struct userdb_iterate_context *_ctx);
2d3aac5be07b96f72cf0551fac35ac74a4f07770Timo Sirainenstatic int userdb_sql_iterate_deinit(struct userdb_iterate_context *_ctx);
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainenstatic void
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainensql_query_get_result(struct sql_result *result,
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen struct auth_request *auth_request)
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen{
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen const char *name, *value;
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen unsigned int i, fields_count;
a205d315b0978985ba77d871f44e4a98273612e6Timo Sirainen
a205d315b0978985ba77d871f44e4a98273612e6Timo Sirainen auth_request_init_userdb_reply(auth_request);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen fields_count = sql_result_get_fields_count(result);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen for (i = 0; i < fields_count; i++) {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen name = sql_result_get_field_name(result, i);
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen value = sql_result_get_field_value(result, i);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen if (*name != '\0' && value != NULL) {
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainen auth_request_set_userdb_field(auth_request,
a6a2b38d806f3ab3198160e39240a8200775e525Timo Sirainen name, value);
a6a2b38d806f3ab3198160e39240a8200775e525Timo Sirainen }
a6a2b38d806f3ab3198160e39240a8200775e525Timo Sirainen }
fb2e0bbb7737f3223b16aa41e4b40fb0cd5f288fTimo Sirainen}
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainen
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainenstatic void sql_query_callback(struct sql_result *sql_result,
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainen struct userdb_sql_request *sql_request)
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainen{
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainen struct auth_request *auth_request = sql_request->auth_request;
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen struct userdb_module *_module = auth_request->userdb->userdb;
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen struct sql_userdb_module *module =
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen (struct sql_userdb_module *)_module;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen enum userdb_result result = USERDB_RESULT_INTERNAL_FAILURE;
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen int ret;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen ret = sql_result_next_row(sql_result);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen if (ret < 0) {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen if (!module->conn->default_user_query) {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen auth_request_log_error(auth_request, "sql",
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen "User query failed: %s",
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen sql_result_get_error(sql_result));
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen } else {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen auth_request_log_error(auth_request, "sql",
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen "User query failed: %s "
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen "(using built-in default user_query: %s)",
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen sql_result_get_error(sql_result),
821984ecb6c90696f35c32a8dc4c8a60f9e98f99Timo Sirainen module->conn->set.user_query);
821984ecb6c90696f35c32a8dc4c8a60f9e98f99Timo Sirainen }
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen } else if (ret == 0) {
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen result = USERDB_RESULT_USER_UNKNOWN;
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen auth_request_log_info(auth_request, "sql", "Unknown user");
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen } else {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen sql_query_get_result(sql_result, auth_request);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen result = USERDB_RESULT_OK;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen }
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen sql_request->callback(result, auth_request);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen auth_request_unref(&auth_request);
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen i_free(sql_request);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen}
e5759add4dc24b96606dccc4a989838e260f2a12Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenstatic const char *
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenuserdb_sql_escape(const char *str, const struct auth_request *auth_request)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen{
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct userdb_module *_module = auth_request->userdb->userdb;
4efba37e4f27b93832f6147c3a353d6d22c855c7Timo Sirainen struct sql_userdb_module *module =
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen (struct sql_userdb_module *)_module;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen return sql_escape_string(module->conn->db, str);
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen}
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenstatic void userdb_sql_lookup(struct auth_request *auth_request,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen userdb_callback_t *callback)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen{
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct userdb_module *_module = auth_request->userdb->userdb;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct sql_userdb_module *module =
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen (struct sql_userdb_module *)_module;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen struct userdb_sql_request *sql_request;
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen string_t *query;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen query = t_str_new(512);
8bb360f9e5de1c25e4f875205bb06e8bf15dae14Timo Sirainen var_expand(query, module->conn->set.user_query,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen auth_request_get_var_expand_table(auth_request,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen userdb_sql_escape));
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
821984ecb6c90696f35c32a8dc4c8a60f9e98f99Timo Sirainen auth_request_ref(auth_request);
821984ecb6c90696f35c32a8dc4c8a60f9e98f99Timo Sirainen sql_request = i_new(struct userdb_sql_request, 1);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen sql_request->callback = callback;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen sql_request->auth_request = auth_request;
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen auth_request_log_debug(auth_request, "sql", "%s", str_c(query));
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen sql_query(module->conn->db, str_c(query),
d22301419109ed4a38351715e6760011421dadecTimo Sirainen sql_query_callback, sql_request);
d22301419109ed4a38351715e6760011421dadecTimo Sirainen}
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenstatic void sql_iter_query_callback(struct sql_result *sql_result,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen struct sql_userdb_iterate_context *ctx)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen{
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen ctx->result = sql_result;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen sql_result_ref(sql_result);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (ctx->freed)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen userdb_sql_iterate_deinit(&ctx->ctx);
197ad81605dc0f6d2ebc9ad99994db5ca6d76699Timo Sirainen else if (ctx->call_iter)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen userdb_sql_iterate_next(&ctx->ctx);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen}
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainenstatic struct userdb_iterate_context *
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenuserdb_sql_iterate_init(struct userdb_module *userdb,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen userdb_iter_callback_t *callback, void *context)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen{
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen struct sql_userdb_module *module =
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen (struct sql_userdb_module *)userdb;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen struct sql_userdb_iterate_context *ctx;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen ctx = i_new(struct sql_userdb_iterate_context, 1);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen ctx->ctx.userdb = userdb;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen ctx->ctx.callback = callback;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen ctx->ctx.context = context;
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen sql_query(module->conn->db, module->conn->set.iterate_query,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen sql_iter_query_callback, ctx);
d22301419109ed4a38351715e6760011421dadecTimo Sirainen return &ctx->ctx;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen}
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenstatic int userdb_sql_iterate_get_user(struct sql_userdb_iterate_context *ctx,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen const char **user_r)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen{
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen const char *domain;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen int idx;
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen /* try user first */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen idx = sql_result_find_field(ctx->result, "user");
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (idx == 0) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen *user_r = sql_result_get_field_value(ctx->result, idx);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return 0;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen /* username [+ domain]? */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen idx = sql_result_find_field(ctx->result, "username");
d22301419109ed4a38351715e6760011421dadecTimo Sirainen if (idx < 0) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen /* no user or username, fail */
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen return -1;
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen *user_r = sql_result_get_field_value(ctx->result, idx);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (*user_r == NULL)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return 0;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen domain = sql_result_find_field_value(ctx->result, "domain");
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (domain != NULL)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen *user_r = t_strconcat(*user_r, "@", domain, NULL);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8bb360f9e5de1c25e4f875205bb06e8bf15dae14Timo Sirainenstatic void userdb_sql_iterate_next(struct userdb_iterate_context *_ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen struct sql_userdb_iterate_context *ctx =
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen (struct sql_userdb_iterate_context *)_ctx;
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen struct userdb_module *_module = _ctx->userdb;
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen struct sql_userdb_module *module = (struct sql_userdb_module *)_module;
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen const char *user;
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen int ret;
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen if (ctx->result == NULL) {
33ae95df45c9b5ec51332a6b39eb5322038686b9Timo Sirainen /* query not finished yet */
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen ctx->call_iter = TRUE;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen return;
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen ret = sql_result_next_row(ctx->result);
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen if (ret > 0) {
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen if (userdb_sql_iterate_get_user(ctx, &user) < 0)
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen i_error("sql: Iterate query didn't return 'user' field");
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen else if (user == NULL)
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen i_error("sql: Iterate query returned NULL user");
bf301a34ffbfd049be583094019b2644884b6d0bTimo Sirainen else {
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen _ctx->callback(user, _ctx->context);
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen return;
58eb2cb24dbeadd94500670acad7ceb1c8b0d9b4Timo Sirainen }
bf301a34ffbfd049be583094019b2644884b6d0bTimo Sirainen _ctx->failed = TRUE;
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen } else if (ret < 0) {
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen if (!module->conn->default_iterate_query) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_error("sql: Iterate query failed: %s",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sql_result_get_error(ctx->result));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else {
1e76a5b92f9d82d557f81f080f3dfad1c9d8f200Timo Sirainen i_error("sql: Iterate query failed: %s "
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen "(using built-in default iterate_query: %s)",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sql_result_get_error(ctx->result),
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen module->conn->set.iterate_query);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen _ctx->failed = TRUE;
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen }
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen _ctx->callback(NULL, _ctx->context);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int userdb_sql_iterate_deinit(struct userdb_iterate_context *_ctx)
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct sql_userdb_iterate_context *ctx =
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (struct sql_userdb_iterate_context *)_ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret = _ctx->failed ? -1 : 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ctx->result == NULL) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* sql query hasn't finished yet */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->freed = TRUE;
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen } else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ctx->result != NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sql_result_unref(ctx->result);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_free(ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen return ret;
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen}
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenstatic struct userdb_module *
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenuserdb_sql_preinit(pool_t pool, const char *args)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen struct sql_userdb_module *module;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen module = p_new(pool, struct sql_userdb_module, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen module->conn = db_sql_init(args);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen module->module.cache_key =
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen auth_cache_parse_key(pool, module->conn->set.user_query);
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen return &module->module;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void userdb_sql_init(struct userdb_module *_module)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct sql_userdb_module *module =
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (struct sql_userdb_module *)_module;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen enum sql_db_flags flags;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen flags = sql_get_flags(module->conn->db);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen _module->blocking = (flags & SQL_DB_FLAG_BLOCKING) != 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!_module->blocking || worker)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sql_connect(module->conn->db);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void userdb_sql_deinit(struct userdb_module *_module)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen{
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct sql_userdb_module *module =
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen (struct sql_userdb_module *)_module;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen db_sql_unref(&module->conn);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct userdb_module_interface userdb_sql = {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen "sql",
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen userdb_sql_preinit,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen userdb_sql_init,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen userdb_sql_deinit,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen userdb_sql_lookup,
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen userdb_sql_iterate_init,
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen userdb_sql_iterate_next,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen userdb_sql_iterate_deinit
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen};
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen#else
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainenstruct userdb_module_interface userdb_sql = {
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen .name = "sql"
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainen};
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainen#endif
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainen