passdb-sql.c revision f3d506e525a720f214020ca0f989a1966b30edae
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2004-2010 Dovecot authors, see the included COPYING file */
2dd39e478269d6fb0bb26d12b394aa30ee965e38Timo Sirainen lookup_credentials_callback_t *lookup_credentials;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstatic void sql_query_save_results(struct sql_result *result,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct auth_request *auth_request = sql_request->auth_request;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct passdb_module *_module = auth_request->passdb->passdb;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen struct sql_passdb_module *module = (struct sql_passdb_module *)_module;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen unsigned int i, fields_count;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen fields_count = sql_result_get_fields_count(result);
3e564425db51f3921ce4de11859777135fdedd15Timo Sirainen for (i = 0; i < fields_count; i++) {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen value = sql_result_get_field_value(result, i);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen auth_request_set_field(auth_request, name, value,
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainenstatic void sql_query_callback(struct sql_result *result,
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen struct auth_request *auth_request = sql_request->auth_request;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen "Password query failed: %s",
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen } else if (ret == 0) {
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen auth_request_log_info(auth_request, "sql", "unknown user");
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen /* Note that we really want to check if the password field is
8d630c15a8ed6f85553467c3a231a273defca5f6Timo Sirainen found. Just checking if password is set isn't enough,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen because with proxies we might want to return NULL as
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen if (sql_result_find_field(result, "password") < 0) {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen "Password query must return a field named "
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen "'password'");
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen "Password query returned multiple matches");
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen } else if (auth_request->passdb_password == NULL &&
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen "Empty password returned without nopassword");
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen passdb_result = PASSDB_RESULT_PASSWORD_MISMATCH;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* passdb_password may change on the way,
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen so we'll need to strdup. */
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen password = t_strdup(auth_request->passdb_password);
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen /* auth_request_set_field() sets scheme */
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen if (auth_request->credentials_scheme != NULL) {
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen passdb_handle_credentials(passdb_result, password, scheme,
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen /* verify plain */
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen sql_request->callback.verify_plain(passdb_result, auth_request);
4b41116563110d00330896a568eff1078c382827Timo Sirainen ret = auth_request_password_verify(auth_request,
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen sql_request->callback.verify_plain(ret > 0 ? PASSDB_RESULT_OK :
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstatic const char *
b2c1349cf07410aefab0f5b17153af9e5cfcf48fTimo Sirainenpassdb_sql_escape(const char *str, const struct auth_request *auth_request)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct passdb_module *_module = auth_request->passdb->passdb;
48270badadd82279bfe50ae3d187aea8b0b2b30eTimo Sirainen struct sql_passdb_module *module = (struct sql_passdb_module *)_module;
48270badadd82279bfe50ae3d187aea8b0b2b30eTimo Sirainen return sql_escape_string(module->conn->db, str);
cb05ecbd96ddb5e53c1850d27434541138a3f284Timo Sirainenstatic void sql_lookup_pass(struct passdb_sql_request *sql_request)
14ab4610b6038da6c5d0814fecabc6b74bc81a6bTimo Sirainen struct sql_passdb_module *module = (struct sql_passdb_module *)_module;
e3796bfd2bc0fd5ba664893d346df9334a5b3af0Timo Sirainen var_expand(query, module->conn->set.password_query,
e3796bfd2bc0fd5ba664893d346df9334a5b3af0Timo Sirainen auth_request_get_var_expand_table(sql_request->auth_request,
5afa8e2edf4f313cd56e5909f92f39c3b5b7b4d3Timo Sirainen auth_request_log_debug(sql_request->auth_request, "sql",
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainenstatic void sql_verify_plain(struct auth_request *request,
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen sql_request = p_new(request->pool, struct passdb_sql_request, 1);
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen sql_request->callback.verify_plain = callback;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstatic void sql_lookup_credentials(struct auth_request *request,
de58be41126e5d68008d2ea706d62ccdc1f29337Timo Sirainen sql_request = p_new(request->pool, struct passdb_sql_request, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sql_request->callback.lookup_credentials = callback;
f3bb2fbe87425dc89a839908985af496f7f65702Timo Sirainenstatic void sql_set_credentials_callback(const char *error,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen auth_request_log_error(sql_request->auth_request, "sql",
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen "Set credentials query failed: %s",
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen set_credentials(error == NULL, sql_request->auth_request);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int sql_set_credentials(struct auth_request *request,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen (struct sql_passdb_module *) request->passdb->passdb;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen request->mech_password = p_strdup(request->pool, new_credentials);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen var_expand(query, module->conn->set.update_query,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen sql_request = i_new(struct passdb_sql_request, 1);
64b5dcc136d6eb7ad90463e6cba9e16880ab52adTimo Sirainen sql_request->callback.set_credentials = callback;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen transaction = sql_transaction_begin(module->conn->db);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainenpassdb_sql_preinit(pool_t pool, const char *args)
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen module = p_new(pool, struct sql_passdb_module, 1);
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen auth_cache_parse_key(pool, conn->set.password_query);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen module->module.default_pass_scheme = conn->set.default_pass_scheme;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstatic void passdb_sql_init(struct passdb_module *_module)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen module->module.blocking = (flags & SQL_DB_FLAG_BLOCKING) != 0;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenstatic void passdb_sql_deinit(struct passdb_module *_module)