1
/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
3
#include "auth-common.h"
7
#include "var-expand.h"
9
#include "password-scheme.h"
10
#include "auth-cache.h"
16
struct dict_passdb_module {
17
struct passdb_module module;
19
struct dict_connection *conn;
22
struct passdb_dict_request {
23
struct auth_request *auth_request;
25
verify_plain_callback_t *verify_plain;
26
lookup_credentials_callback_t *lookup_credentials;
31
dict_query_save_results(struct auth_request *auth_request,
32
struct dict_connection *conn, const char *result)
34
struct db_dict_value_iter *iter;
35
const char *key, *value, *error;
37
iter = db_dict_value_iter_init(conn, result);
38
while (db_dict_value_iter_next(iter, &key, &value)) {
40
auth_request_set_field(auth_request, key, value,
41
conn->set.default_pass_scheme);
44
if (db_dict_value_iter_deinit(&iter, &error) < 0) {
45
auth_request_log_error(auth_request, "dict",
46
"Value '%s' not in valid %s format: %s",
47
result, conn->set.value_format, error);
53
static enum passdb_result
54
passdb_dict_lookup_key(struct auth_request *auth_request,
55
struct dict_passdb_module *module, const char *key)
60
auth_request_log_debug(auth_request, "dict", "lookup %s", key);
61
ret = dict_lookup(module->conn->dict, pool_datastack_create(),
64
auth_request_log_error(auth_request, "dict", "Lookup failed");
65
return PASSDB_RESULT_INTERNAL_FAILURE;
66
} else if (ret == 0) {
67
auth_request_log_unknown_user(auth_request, "dict");
68
return PASSDB_RESULT_USER_UNKNOWN;
70
auth_request_log_debug(auth_request, "dict",
72
if (dict_query_save_results(auth_request, module->conn, value) < 0)
73
return PASSDB_RESULT_INTERNAL_FAILURE;
75
if (auth_request->passdb_password == NULL &&
76
!auth_fields_exists(auth_request->extra_fields, "nopassword")) {
77
auth_request_log_info(auth_request, "dict",
78
"No password returned (and no nopassword)");
79
return PASSDB_RESULT_PASSWORD_MISMATCH;
81
return PASSDB_RESULT_OK;
86
static void passdb_dict_lookup_pass(struct passdb_dict_request *dict_request)
88
struct auth_request *auth_request = dict_request->auth_request;
89
struct passdb_module *_module = auth_request->passdb->passdb;
90
struct dict_passdb_module *module =
91
(struct dict_passdb_module *)_module;
93
const char *password = NULL, *scheme = NULL;
94
enum passdb_result passdb_result;
98
str_append(key, DICT_PATH_SHARED);
99
var_expand(key, module->conn->set.password_key,
100
auth_request_get_var_expand_table(auth_request, NULL));
102
if (*module->conn->set.password_key == '\0') {
103
auth_request_log_error(auth_request, "dict",
104
"password_key not specified");
105
passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
107
passdb_result = passdb_dict_lookup_key(auth_request, module,
111
if (passdb_result == PASSDB_RESULT_OK) {
112
/* passdb_password may change on the way,
113
so we'll need to strdup. */
114
password = t_strdup(auth_request->passdb_password);
115
scheme = password_get_scheme(&password);
116
/* auth_request_set_field() sets scheme */
117
i_assert(password == NULL || scheme != NULL);
120
if (auth_request->credentials_scheme != NULL) {
121
passdb_handle_credentials(passdb_result, password, scheme,
122
dict_request->callback.lookup_credentials,
125
if (password != NULL) {
126
ret = auth_request_password_verify(auth_request,
127
auth_request->mech_password,
128
password, scheme, "dict");
129
passdb_result = ret > 0 ? PASSDB_RESULT_OK :
130
PASSDB_RESULT_PASSWORD_MISMATCH;
133
dict_request->callback.verify_plain(passdb_result,
138
static void dict_verify_plain(struct auth_request *request,
139
const char *password ATTR_UNUSED,
140
verify_plain_callback_t *callback)
142
struct passdb_dict_request *dict_request;
144
dict_request = p_new(request->pool, struct passdb_dict_request, 1);
145
dict_request->auth_request = request;
146
dict_request->callback.verify_plain = callback;
148
passdb_dict_lookup_pass(dict_request);
151
static void dict_lookup_credentials(struct auth_request *request,
152
lookup_credentials_callback_t *callback)
154
struct passdb_dict_request *dict_request;
156
dict_request = p_new(request->pool, struct passdb_dict_request, 1);
157
dict_request->auth_request = request;
158
dict_request->callback.lookup_credentials = callback;
160
passdb_dict_lookup_pass(dict_request);
163
static struct passdb_module *
164
passdb_dict_preinit(pool_t pool, const char *args)
166
struct dict_passdb_module *module;
167
struct dict_connection *conn;
169
module = p_new(pool, struct dict_passdb_module, 1);
170
module->conn = conn = db_dict_init(args);
172
module->module.blocking = TRUE;
173
module->module.cache_key =
174
auth_cache_parse_key(pool, conn->set.password_key);
175
module->module.default_pass_scheme = conn->set.default_pass_scheme;
176
return &module->module;
179
static void passdb_dict_deinit(struct passdb_module *_module)
181
struct dict_passdb_module *module =
182
(struct dict_passdb_module *)_module;
184
db_dict_unref(&module->conn);
187
struct passdb_module_interface passdb_dict = {
195
dict_lookup_credentials,