userdb-sql.c revision e34d170f8f0e084bd94bfbc1a7085ece67e508df
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2004-2012 Dovecot authors, see the included COPYING file */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger#include "auth-common.h"
d5abbb932a0a598f002da39a8b3326643b1b5efcTimo Sirainen#include "userdb.h"
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen#ifdef USERDB_SQL
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen#include "str.h"
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen#include "strescape.h"
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen#include "var-expand.h"
c5383a0ed56a188a7d5efaaa4c6f8243af432d65Timo Sirainen#include "auth-cache.h"
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen#include "db-sql.h"
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen#include <stdlib.h>
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen#include <string.h>
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainenstruct sql_userdb_module {
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen struct userdb_module module;
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen struct sql_connection *conn;
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen};
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstruct userdb_sql_request {
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen struct auth_request *auth_request;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen userdb_callback_t *callback;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen};
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenstruct sql_userdb_iterate_context {
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen struct userdb_iterate_context ctx;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen struct sql_result *result;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen unsigned int freed:1;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen unsigned int call_iter:1;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen};
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenstatic void userdb_sql_iterate_next(struct userdb_iterate_context *_ctx);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenstatic int userdb_sql_iterate_deinit(struct userdb_iterate_context *_ctx);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
6fabfb7bbfd88d0c1de66981e52850f26067623bTimo Sirainenstatic void
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainensql_query_get_result(struct sql_result *result,
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen struct auth_request *auth_request)
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen{
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen const char *name, *value;
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen unsigned int i, fields_count;
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen
6fabfb7bbfd88d0c1de66981e52850f26067623bTimo Sirainen auth_request_init_userdb_reply(auth_request);
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen fields_count = sql_result_get_fields_count(result);
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen for (i = 0; i < fields_count; i++) {
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen name = sql_result_get_field_name(result, i);
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen value = sql_result_get_field_value(result, i);
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen
6fabfb7bbfd88d0c1de66981e52850f26067623bTimo Sirainen if (*name != '\0' && value != NULL) {
6fabfb7bbfd88d0c1de66981e52850f26067623bTimo Sirainen auth_request_set_userdb_field(auth_request,
6fabfb7bbfd88d0c1de66981e52850f26067623bTimo Sirainen name, value);
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen }
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen }
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen}
9f431ccfb6932746db56245c8a3d3415717ef545Timo Sirainen
2cfe9983ce7a6280636ee12beccc2e865111967bTimo Sirainenstatic void sql_query_callback(struct sql_result *sql_result,
2cfe9983ce7a6280636ee12beccc2e865111967bTimo Sirainen struct userdb_sql_request *sql_request)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen struct auth_request *auth_request = sql_request->auth_request;
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen struct userdb_module *_module = auth_request->userdb->userdb;
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen struct sql_userdb_module *module =
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen (struct sql_userdb_module *)_module;
0f39a57760d93cddbce3ca43096d78e0fe2f42fdTimo Sirainen enum userdb_result result = USERDB_RESULT_INTERNAL_FAILURE;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen int ret;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
0f39a57760d93cddbce3ca43096d78e0fe2f42fdTimo Sirainen ret = sql_result_next_row(sql_result);
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen if (ret >= 0)
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen db_sql_success(module->conn);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen if (ret < 0) {
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen if (!module->conn->default_user_query) {
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen auth_request_log_error(auth_request, "sql",
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen "User query failed: %s",
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen sql_result_get_error(sql_result));
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen } else {
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen auth_request_log_error(auth_request, "sql",
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen "User query failed: %s "
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen "(using built-in default user_query: %s)",
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen sql_result_get_error(sql_result),
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen module->conn->set.user_query);
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen }
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen } else if (ret == 0) {
0f39a57760d93cddbce3ca43096d78e0fe2f42fdTimo Sirainen result = USERDB_RESULT_USER_UNKNOWN;
b323e76cf555fa6031f3dbbdedeac0df2fff3778Timo Sirainen auth_request_log_info(auth_request, "sql", "Unknown user");
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen } else {
6fabfb7bbfd88d0c1de66981e52850f26067623bTimo Sirainen sql_query_get_result(sql_result, auth_request);
6fabfb7bbfd88d0c1de66981e52850f26067623bTimo Sirainen result = USERDB_RESULT_OK;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen }
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6fabfb7bbfd88d0c1de66981e52850f26067623bTimo Sirainen sql_request->callback(result, auth_request);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen auth_request_unref(&auth_request);
a30b52af112bc98b74b8624e9a5d20cb754b2ab7Timo Sirainen i_free(sql_request);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
3c9783956dea385b322cd7fa6bf8c98c17a907a0Timo Sirainenstatic const char *
3c9783956dea385b322cd7fa6bf8c98c17a907a0Timo Sirainenuserdb_sql_escape(const char *str, const struct auth_request *auth_request)
3c9783956dea385b322cd7fa6bf8c98c17a907a0Timo Sirainen{
3c9783956dea385b322cd7fa6bf8c98c17a907a0Timo Sirainen struct userdb_module *_module = auth_request->userdb->userdb;
3c9783956dea385b322cd7fa6bf8c98c17a907a0Timo Sirainen struct sql_userdb_module *module =
3c9783956dea385b322cd7fa6bf8c98c17a907a0Timo Sirainen (struct sql_userdb_module *)_module;
3c9783956dea385b322cd7fa6bf8c98c17a907a0Timo Sirainen
3c9783956dea385b322cd7fa6bf8c98c17a907a0Timo Sirainen return sql_escape_string(module->conn->db, str);
3c9783956dea385b322cd7fa6bf8c98c17a907a0Timo Sirainen}
3c9783956dea385b322cd7fa6bf8c98c17a907a0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstatic void userdb_sql_lookup(struct auth_request *auth_request,
66d2db642fe24d555d113ba463e446b038d476efTimo Sirainen userdb_callback_t *callback)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen struct userdb_module *_module = auth_request->userdb->userdb;
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen struct sql_userdb_module *module =
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen (struct sql_userdb_module *)_module;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen struct userdb_sql_request *sql_request;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen string_t *query;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen query = t_str_new(512);
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen var_expand(query, module->conn->set.user_query,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen auth_request_get_var_expand_table(auth_request,
3c9783956dea385b322cd7fa6bf8c98c17a907a0Timo Sirainen userdb_sql_escape));
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen auth_request_ref(auth_request);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen sql_request = i_new(struct userdb_sql_request, 1);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen sql_request->callback = callback;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen sql_request->auth_request = auth_request;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
49e513d090753ccbf95560b2f3a21f081a5b6c51Timo Sirainen auth_request_log_debug(auth_request, "sql", "%s", str_c(query));
a7bee3930831a9261fa6180d02af29c484d862e9Timo Sirainen
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen sql_query(module->conn->db, str_c(query),
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen sql_query_callback, sql_request);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenstatic void sql_iter_query_callback(struct sql_result *sql_result,
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen struct sql_userdb_iterate_context *ctx)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen{
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen ctx->result = sql_result;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen sql_result_ref(sql_result);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (ctx->freed)
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen (void)userdb_sql_iterate_deinit(&ctx->ctx);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen else if (ctx->call_iter)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen userdb_sql_iterate_next(&ctx->ctx);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen}
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenstatic struct userdb_iterate_context *
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainenuserdb_sql_iterate_init(struct auth_request *auth_request,
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen userdb_iter_callback_t *callback, void *context)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen{
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen struct userdb_module *_module = auth_request->userdb->userdb;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen struct sql_userdb_module *module =
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen (struct sql_userdb_module *)_module;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen struct sql_userdb_iterate_context *ctx;
7af2a19a89c1c9da8848c570190d36570afd09e6Timo Sirainen string_t *query;
7af2a19a89c1c9da8848c570190d36570afd09e6Timo Sirainen
7af2a19a89c1c9da8848c570190d36570afd09e6Timo Sirainen query = t_str_new(512);
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen var_expand(query, module->conn->set.iterate_query,
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen auth_request_get_var_expand_table(auth_request,
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen userdb_sql_escape));
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen ctx = i_new(struct sql_userdb_iterate_context, 1);
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen ctx->ctx.auth_request = auth_request;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen ctx->ctx.callback = callback;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen ctx->ctx.context = context;
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen auth_request_ref(auth_request);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
7af2a19a89c1c9da8848c570190d36570afd09e6Timo Sirainen sql_query(module->conn->db, str_c(query),
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen sql_iter_query_callback, ctx);
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen auth_request_log_debug(auth_request, "sql", "%s", str_c(query));
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen return &ctx->ctx;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen}
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenstatic int userdb_sql_iterate_get_user(struct sql_userdb_iterate_context *ctx,
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen const char **user_r)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen{
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen const char *domain;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen int idx;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen /* try user first */
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen idx = sql_result_find_field(ctx->result, "user");
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (idx == 0) {
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen *user_r = sql_result_get_field_value(ctx->result, idx);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen return 0;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen }
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen /* username [+ domain]? */
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen idx = sql_result_find_field(ctx->result, "username");
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (idx < 0) {
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen /* no user or username, fail */
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen return -1;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen }
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen *user_r = sql_result_get_field_value(ctx->result, idx);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (*user_r == NULL)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen return 0;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen domain = sql_result_find_field_value(ctx->result, "domain");
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (domain != NULL)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen *user_r = t_strconcat(*user_r, "@", domain, NULL);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen return 0;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen}
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenstatic void userdb_sql_iterate_next(struct userdb_iterate_context *_ctx)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen{
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen struct sql_userdb_iterate_context *ctx =
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen (struct sql_userdb_iterate_context *)_ctx;
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen struct userdb_module *_module = _ctx->auth_request->userdb->userdb;
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen struct sql_userdb_module *module = (struct sql_userdb_module *)_module;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen const char *user;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen int ret;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (ctx->result == NULL) {
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen /* query not finished yet */
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen ctx->call_iter = TRUE;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen return;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen }
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen ret = sql_result_next_row(ctx->result);
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen if (ret >= 0)
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen db_sql_success(module->conn);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (ret > 0) {
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (userdb_sql_iterate_get_user(ctx, &user) < 0)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen i_error("sql: Iterate query didn't return 'user' field");
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen else if (user == NULL)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen i_error("sql: Iterate query returned NULL user");
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen else {
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen _ctx->callback(user, _ctx->context);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen return;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen }
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen _ctx->failed = TRUE;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen } else if (ret < 0) {
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen if (!module->conn->default_iterate_query) {
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen i_error("sql: Iterate query failed: %s",
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen sql_result_get_error(ctx->result));
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen } else {
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen i_error("sql: Iterate query failed: %s "
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen "(using built-in default iterate_query: %s)",
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen sql_result_get_error(ctx->result),
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen module->conn->set.iterate_query);
48010d123abfac8cb19f33f1fe12f33a7090089eTimo Sirainen }
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen _ctx->failed = TRUE;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen }
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen _ctx->callback(NULL, _ctx->context);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen}
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenstatic int userdb_sql_iterate_deinit(struct userdb_iterate_context *_ctx)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen{
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen struct sql_userdb_iterate_context *ctx =
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen (struct sql_userdb_iterate_context *)_ctx;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen int ret = _ctx->failed ? -1 : 0;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen auth_request_unref(&_ctx->auth_request);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (ctx->result == NULL) {
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen /* sql query hasn't finished yet */
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen ctx->freed = TRUE;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen } else {
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (ctx->result != NULL)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen sql_result_unref(ctx->result);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen i_free(ctx);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen }
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen return ret;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen}
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainenstatic struct userdb_module *
849969f639a00eab26791db3cb1b66430420c0cdTimo Sirainenuserdb_sql_preinit(pool_t pool, const char *args)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen struct sql_userdb_module *module;
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen
849969f639a00eab26791db3cb1b66430420c0cdTimo Sirainen module = p_new(pool, struct sql_userdb_module, 1);
e665999b757e60bfb98e5a84a78b05f061453140Timo Sirainen module->conn = db_sql_init(args, TRUE);
c5383a0ed56a188a7d5efaaa4c6f8243af432d65Timo Sirainen
c5383a0ed56a188a7d5efaaa4c6f8243af432d65Timo Sirainen module->module.cache_key =
849969f639a00eab26791db3cb1b66430420c0cdTimo Sirainen auth_cache_parse_key(pool, module->conn->set.user_query);
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen return &module->module;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
f3d506e525a720f214020ca0f989a1966b30edaeTimo Sirainenstatic void userdb_sql_init(struct userdb_module *_module)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen struct sql_userdb_module *module =
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen (struct sql_userdb_module *)_module;
66d2db642fe24d555d113ba463e446b038d476efTimo Sirainen enum sql_db_flags flags;
66d2db642fe24d555d113ba463e446b038d476efTimo Sirainen
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen flags = sql_get_flags(module->conn->db);
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen _module->blocking = (flags & SQL_DB_FLAG_BLOCKING) != 0;
f8a86fdfb0048f9c87bf223373b35416ceb5856bTimo Sirainen
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen if (!_module->blocking || worker)
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen db_sql_connect(module->conn);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainenstatic void userdb_sql_deinit(struct userdb_module *_module)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen{
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen struct sql_userdb_module *module =
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen (struct sql_userdb_module *)_module;
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen db_sql_unref(&module->conn);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen}
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainenstruct userdb_module_interface userdb_sql = {
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen "sql",
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen userdb_sql_preinit,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen userdb_sql_init,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen userdb_sql_deinit,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen userdb_sql_lookup,
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen userdb_sql_iterate_init,
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen userdb_sql_iterate_next,
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen userdb_sql_iterate_deinit
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen};
d5abbb932a0a598f002da39a8b3326643b1b5efcTimo Sirainen#else
d5abbb932a0a598f002da39a8b3326643b1b5efcTimo Sirainenstruct userdb_module_interface userdb_sql = {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .name = "sql"
d5abbb932a0a598f002da39a8b3326643b1b5efcTimo Sirainen};
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen#endif