userdb-sql.c revision e665999b757e60bfb98e5a84a78b05f061453140
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen/* Copyright (c) 2004-2011 Dovecot authors, see the included COPYING file */
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "auth-common.h"
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen#include "userdb.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#ifdef USERDB_SQL
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen#include "str.h"
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen#include "strescape.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "var-expand.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "auth-cache.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "db-sql.h"
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <stdlib.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <string.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct sql_userdb_module {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct userdb_module module;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct sql_connection *conn;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainenstruct userdb_sql_request {
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen struct auth_request *auth_request;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen userdb_callback_t *callback;
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen};
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainenstruct sql_userdb_iterate_context {
2d3aac5be07b96f72cf0551fac35ac74a4f07770Timo Sirainen struct userdb_iterate_context ctx;
2d3aac5be07b96f72cf0551fac35ac74a4f07770Timo Sirainen struct sql_result *result;
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen unsigned int freed:1;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen unsigned int call_iter:1;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen};
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainenstatic void userdb_sql_iterate_next(struct userdb_iterate_context *_ctx);
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainenstatic int userdb_sql_iterate_deinit(struct userdb_iterate_context *_ctx);
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen
a205d315b0978985ba77d871f44e4a98273612e6Timo Sirainenstatic void
a205d315b0978985ba77d871f44e4a98273612e6Timo Sirainensql_query_get_result(struct sql_result *result,
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen struct auth_request *auth_request)
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen{
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen const char *name, *value;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen unsigned int i, fields_count;
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen auth_request_init_userdb_reply(auth_request);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen fields_count = sql_result_get_fields_count(result);
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen for (i = 0; i < fields_count; i++) {
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen name = sql_result_get_field_name(result, i);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen value = sql_result_get_field_value(result, i);
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen if (*name != '\0' && value != NULL) {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen auth_request_set_userdb_field(auth_request,
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen name, value);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen }
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen }
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen}
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenstatic void sql_query_callback(struct sql_result *sql_result,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct userdb_sql_request *sql_request)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen{
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct auth_request *auth_request = sql_request->auth_request;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct userdb_module *_module = auth_request->userdb->userdb;
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen struct sql_userdb_module *module =
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen (struct sql_userdb_module *)_module;
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen enum userdb_result result = USERDB_RESULT_INTERNAL_FAILURE;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen int ret;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen ret = sql_result_next_row(sql_result);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (ret < 0) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (!module->conn->default_user_query) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen auth_request_log_error(auth_request, "sql",
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen "User query failed: %s",
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo 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),
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen module->conn->set.user_query);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen }
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen } else if (ret == 0) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen result = USERDB_RESULT_USER_UNKNOWN;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen auth_request_log_info(auth_request, "sql", "Unknown user");
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo 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);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen i_free(sql_request);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen}
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo 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;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo 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);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void userdb_sql_lookup(struct auth_request *auth_request,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen userdb_callback_t *callback)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen struct userdb_module *_module = auth_request->userdb->userdb;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct sql_userdb_module *module =
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen (struct sql_userdb_module *)_module;
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen struct userdb_sql_request *sql_request;
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen string_t *query;
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen query = t_str_new(512);
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen var_expand(query, module->conn->set.user_query,
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen auth_request_get_var_expand_table(auth_request,
33ae95df45c9b5ec51332a6b39eb5322038686b9Timo Sirainen userdb_sql_escape));
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen auth_request_ref(auth_request);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen sql_request = i_new(struct userdb_sql_request, 1);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen sql_request->callback = callback;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen sql_request->auth_request = auth_request;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen auth_request_log_debug(auth_request, "sql", "%s", str_c(query));
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sql_query(module->conn->db, str_c(query),
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen sql_query_callback, sql_request);
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen}
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen
d8b77aef97e89f1ccc5cbdaef77be9052279e35fTimo Sirainenstatic void sql_iter_query_callback(struct sql_result *sql_result,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct sql_userdb_iterate_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->result = sql_result;
907723f35f4d3dfc774ca42d00a8a7b8ef90dd5dTimo Sirainen sql_result_ref(sql_result);
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ctx->freed)
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen userdb_sql_iterate_deinit(&ctx->ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else if (ctx->call_iter)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen userdb_sql_iterate_next(&ctx->ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic struct userdb_iterate_context *
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainenuserdb_sql_iterate_init(struct auth_request *auth_request,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen userdb_iter_callback_t *callback, void *context)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct userdb_module *_module = auth_request->userdb->userdb;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct sql_userdb_module *module =
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (struct sql_userdb_module *)_module;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct sql_userdb_iterate_context *ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen string_t *query;
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen query = t_str_new(512);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen var_expand(query, module->conn->set.iterate_query,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen auth_request_get_var_expand_table(auth_request,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen userdb_sql_escape));
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ctx = i_new(struct sql_userdb_iterate_context, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->ctx.auth_request = auth_request;
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen ctx->ctx.callback = callback;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ctx->ctx.context = context;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen auth_request_ref(auth_request);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sql_query(module->conn->db, str_c(query),
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen sql_iter_query_callback, ctx);
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen auth_request_log_debug(auth_request, "sql", "%s", str_c(query));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return &ctx->ctx;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int userdb_sql_iterate_get_user(struct sql_userdb_iterate_context *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char **user_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *domain;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int idx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* try user first */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen idx = sql_result_find_field(ctx->result, "user");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (idx == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *user_r = sql_result_get_field_value(ctx->result, idx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* username [+ domain]? */
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen idx = sql_result_find_field(ctx->result, "username");
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (idx < 0) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* no user or username, fail */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *user_r = sql_result_get_field_value(ctx->result, idx);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (*user_r == NULL)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen return 0;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen domain = sql_result_find_field_value(ctx->result, "domain");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (domain != NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *user_r = t_strconcat(*user_r, "@", domain, NULL);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainenstatic void userdb_sql_iterate_next(struct userdb_iterate_context *_ctx)
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen{
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen struct sql_userdb_iterate_context *ctx =
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen (struct sql_userdb_iterate_context *)_ctx;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen struct userdb_module *_module = _ctx->auth_request->userdb->userdb;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen struct sql_userdb_module *module = (struct sql_userdb_module *)_module;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen const char *user;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen int ret;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen if (ctx->result == NULL) {
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen /* query not finished yet */
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen ctx->call_iter = TRUE;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen return;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen }
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen ret = sql_result_next_row(ctx->result);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen if (ret > 0) {
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen if (userdb_sql_iterate_get_user(ctx, &user) < 0)
a60c1c1fca85402e6fccbf3ae0784b7179ae186cTimo Sirainen i_error("sql: Iterate query didn't return 'user' field");
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen else if (user == NULL)
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen i_error("sql: Iterate query returned NULL user");
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen else {
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen _ctx->callback(user, _ctx->context);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen return;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen }
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen _ctx->failed = TRUE;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen } else if (ret < 0) {
325f4573edfa5b751832ac01023f3e81be992bf0Timo Sirainen if (!module->conn->default_iterate_query) {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen i_error("sql: Iterate query failed: %s",
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen sql_result_get_error(ctx->result));
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen } else {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen i_error("sql: Iterate query failed: %s "
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen "(using built-in default iterate_query: %s)",
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen sql_result_get_error(ctx->result),
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen module->conn->set.iterate_query);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen }
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen _ctx->failed = TRUE;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen }
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen _ctx->callback(NULL, _ctx->context);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen}
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainenstatic int userdb_sql_iterate_deinit(struct userdb_iterate_context *_ctx)
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen{
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen struct sql_userdb_iterate_context *ctx =
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen (struct sql_userdb_iterate_context *)_ctx;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen int ret = _ctx->failed ? -1 : 0;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen auth_request_unref(&_ctx->auth_request);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen if (ctx->result == NULL) {
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen /* sql query hasn't finished yet */
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen ctx->freed = TRUE;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen } else {
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen if (ctx->result != NULL)
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen sql_result_unref(ctx->result);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen i_free(ctx);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen }
a60c1c1fca85402e6fccbf3ae0784b7179ae186cTimo Sirainen return ret;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen}
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic struct userdb_module *
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenuserdb_sql_preinit(pool_t pool, const char *args)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct sql_userdb_module *module;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen module = p_new(pool, struct sql_userdb_module, 1);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen module->conn = db_sql_init(args, TRUE);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen module->module.cache_key =
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen auth_cache_parse_key(pool, module->conn->set.user_query);
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen return &module->module;
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen}
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenstatic void userdb_sql_init(struct userdb_module *_module)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen{
dc049c5e83d947aaf1b97c26ae819cc9577e0475Timo Sirainen struct sql_userdb_module *module =
dc049c5e83d947aaf1b97c26ae819cc9577e0475Timo Sirainen (struct sql_userdb_module *)_module;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen enum sql_db_flags flags;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen flags = sql_get_flags(module->conn->db);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen _module->blocking = (flags & SQL_DB_FLAG_BLOCKING) != 0;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (!_module->blocking || worker)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen sql_connect(module->conn->db);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen}
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenstatic void userdb_sql_deinit(struct userdb_module *_module)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen struct sql_userdb_module *module =
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen (struct sql_userdb_module *)_module;
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen db_sql_unref(&module->conn);
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenstruct userdb_module_interface userdb_sql = {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "sql",
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen userdb_sql_preinit,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen userdb_sql_init,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen userdb_sql_deinit,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
08fa343b3aace9343da3195686c65c5326eda207Timo Sirainen userdb_sql_lookup,
08fa343b3aace9343da3195686c65c5326eda207Timo Sirainen
08fa343b3aace9343da3195686c65c5326eda207Timo Sirainen userdb_sql_iterate_init,
dc049c5e83d947aaf1b97c26ae819cc9577e0475Timo Sirainen userdb_sql_iterate_next,
dc049c5e83d947aaf1b97c26ae819cc9577e0475Timo Sirainen userdb_sql_iterate_deinit
dc049c5e83d947aaf1b97c26ae819cc9577e0475Timo Sirainen};
dc049c5e83d947aaf1b97c26ae819cc9577e0475Timo Sirainen#else
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainenstruct userdb_module_interface userdb_sql = {
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen .name = "sql"
33ae95df45c9b5ec51332a6b39eb5322038686b9Timo Sirainen};
33ae95df45c9b5ec51332a6b39eb5322038686b9Timo Sirainen#endif
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen