bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger#include "auth-common.h"
d5abbb932a0a598f002da39a8b3326643b1b5efcTimo Sirainen#include "userdb.h"
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#ifdef USERDB_PASSWD
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen#include "ioloop.h"
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen#include "ipwd.h"
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen#include "time-util.h"
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen#include "userdb-template.h"
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
c5383a0ed56a188a7d5efaaa4c6f8243af432d65Timo Sirainen#define USER_CACHE_KEY "%u"
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen#define PASSWD_SLOW_WARN_MSECS (10*1000)
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen#define PASSWD_SLOW_MASTER_WARN_MSECS 50
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen#define PASSDB_SLOW_MASTER_WARN_COUNT_INTERVAL 100
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen#define PASSDB_SLOW_MASTER_WARN_MIN_PERCENTAGE 5
c5383a0ed56a188a7d5efaaa4c6f8243af432d65Timo Sirainen
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainenstruct passwd_userdb_module {
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen struct userdb_module module;
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen struct userdb_template *tmpl;
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen unsigned int fast_count, slow_count;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool slow_warned:1;
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen};
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenstruct passwd_userdb_iterate_context {
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen struct userdb_iterate_context ctx;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen struct passwd_userdb_iterate_context *next_waiting;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen};
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenstatic struct passwd_userdb_iterate_context *cur_userdb_iter = NULL;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenstatic struct timeout *cur_userdb_iter_to = NULL;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainenstatic void
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainenpasswd_check_warnings(struct auth_request *auth_request,
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen struct passwd_userdb_module *module,
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen const struct timeval *start_tv)
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen{
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen struct timeval end_tv;
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen unsigned int msecs, percentage;
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen if (gettimeofday(&end_tv, NULL) < 0)
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen return;
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen msecs = timeval_diff_msecs(&end_tv, start_tv);
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen if (msecs >= PASSWD_SLOW_WARN_MSECS) {
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen i_warning("passwd: Lookup for %s took %u secs",
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen auth_request->user, msecs/1000);
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen return;
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen }
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen if (worker || module->slow_warned)
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen return;
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen if (msecs < PASSWD_SLOW_MASTER_WARN_MSECS) {
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen module->fast_count++;
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen return;
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen }
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen module->slow_count++;
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen if (module->fast_count + module->slow_count <
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen PASSDB_SLOW_MASTER_WARN_COUNT_INTERVAL)
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen return;
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen percentage = module->slow_count * 100 /
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen (module->slow_count + module->fast_count);
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen if (percentage < PASSDB_SLOW_MASTER_WARN_MIN_PERCENTAGE) {
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen /* start from beginning */
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen module->slow_count = module->fast_count = 0;
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen } else {
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen i_warning("passwd: %u%% of last %u lookups took over "
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen "%u milliseconds, "
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen "you may want to set blocking=yes for userdb",
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen percentage, PASSDB_SLOW_MASTER_WARN_COUNT_INTERVAL,
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen PASSWD_SLOW_MASTER_WARN_MSECS);
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen module->slow_warned = TRUE;
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen }
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen}
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen
3b94ff5951db4d4eddb7a80ed4e3f61207202635Timo Sirainenstatic void passwd_lookup(struct auth_request *auth_request,
66d2db642fe24d555d113ba463e446b038d476efTimo Sirainen userdb_callback_t *callback)
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen{
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen struct userdb_module *_module = auth_request->userdb->userdb;
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen struct passwd_userdb_module *module =
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen (struct passwd_userdb_module *)_module;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen struct passwd pw;
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen struct timeval start_tv;
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const char *error;
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen int ret;
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_debug(auth_request, AUTH_SUBSYS_DB, "lookup");
00bde9ae9eab9e720462bf6ec9a4dd85e88c3bbfTimo Sirainen
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen if (gettimeofday(&start_tv, NULL) < 0)
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen start_tv.tv_sec = 0;
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen ret = i_getpwnam(auth_request->user, &pw);
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen if (start_tv.tv_sec != 0)
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen passwd_check_warnings(auth_request, module, &start_tv);
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen
b71b9e5cd06b1dc13aad122a0729d6eeda5393e7Timo Sirainen switch (ret) {
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen case -1:
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_error(auth_request, AUTH_SUBSYS_DB,
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen "getpwnam() failed: %m");
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request);
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen return;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen case 0:
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_unknown_user(auth_request, AUTH_SUBSYS_DB);
6fabfb7bbfd88d0c1de66981e52850f26067623bTimo Sirainen callback(USERDB_RESULT_USER_UNKNOWN, auth_request);
22535a9e685e29214082878e37a267157044618eTimo Sirainen return;
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen }
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen auth_request_set_field(auth_request, "user", pw.pw_name, NULL);
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen auth_request_set_userdb_field(auth_request, "system_groups_user",
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen pw.pw_name);
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen auth_request_set_userdb_field(auth_request, "uid", dec2str(pw.pw_uid));
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen auth_request_set_userdb_field(auth_request, "gid", dec2str(pw.pw_gid));
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen auth_request_set_userdb_field(auth_request, "home", pw.pw_dir);
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen if (userdb_template_export(module->tmpl, auth_request, &error) < 0) {
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen auth_request_log_error(auth_request, AUTH_SUBSYS_DB,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen "Failed to expand template: %s", error);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen }
6fabfb7bbfd88d0c1de66981e52850f26067623bTimo Sirainen
6fabfb7bbfd88d0c1de66981e52850f26067623bTimo Sirainen callback(USERDB_RESULT_OK, auth_request);
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen}
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenstatic struct userdb_iterate_context *
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainenpasswd_iterate_init(struct auth_request *auth_request,
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen userdb_iter_callback_t *callback, void *context)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen{
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen struct passwd_userdb_iterate_context *ctx;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen ctx = i_new(struct passwd_userdb_iterate_context, 1);
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen ctx->ctx.auth_request = auth_request;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen ctx->ctx.callback = callback;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen ctx->ctx.context = context;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen setpwent();
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (cur_userdb_iter == NULL)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen cur_userdb_iter = ctx;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen return &ctx->ctx;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen}
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
0caa211038e56abfdf1b8b4937a50708f997f850Timo Sirainenstatic bool
0caa211038e56abfdf1b8b4937a50708f997f850Timo Sirainenpasswd_iterate_want_pw(struct passwd *pw, const struct auth_settings *set)
0caa211038e56abfdf1b8b4937a50708f997f850Timo Sirainen{
0caa211038e56abfdf1b8b4937a50708f997f850Timo Sirainen /* skip entries not in valid UID range.
0caa211038e56abfdf1b8b4937a50708f997f850Timo Sirainen they're users for daemons and such. */
0caa211038e56abfdf1b8b4937a50708f997f850Timo Sirainen if (pw->pw_uid < (uid_t)set->first_valid_uid)
0caa211038e56abfdf1b8b4937a50708f997f850Timo Sirainen return FALSE;
0caa211038e56abfdf1b8b4937a50708f997f850Timo Sirainen if (pw->pw_uid > (uid_t)set->last_valid_uid && set->last_valid_uid != 0)
0caa211038e56abfdf1b8b4937a50708f997f850Timo Sirainen return FALSE;
ca5b3ec5331545b46ec1f1c4ecfa1302ddb10653Timo Sirainen if (pw->pw_gid < (gid_t)set->first_valid_gid)
ca5b3ec5331545b46ec1f1c4ecfa1302ddb10653Timo Sirainen return FALSE;
ca5b3ec5331545b46ec1f1c4ecfa1302ddb10653Timo Sirainen if (pw->pw_gid > (gid_t)set->last_valid_gid && set->last_valid_gid != 0)
ca5b3ec5331545b46ec1f1c4ecfa1302ddb10653Timo Sirainen return FALSE;
0caa211038e56abfdf1b8b4937a50708f997f850Timo Sirainen return TRUE;
0caa211038e56abfdf1b8b4937a50708f997f850Timo Sirainen}
0caa211038e56abfdf1b8b4937a50708f997f850Timo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenstatic void passwd_iterate_next(struct userdb_iterate_context *_ctx)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen{
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen struct passwd_userdb_iterate_context *ctx =
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen (struct passwd_userdb_iterate_context *)_ctx;
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen const struct auth_settings *set = _ctx->auth_request->set;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen struct passwd *pw;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (cur_userdb_iter != NULL && cur_userdb_iter != ctx) {
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen /* we can't support concurrent userdb iteration.
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen wait until the previous one is done */
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen ctx->next_waiting = cur_userdb_iter->next_waiting;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen cur_userdb_iter->next_waiting = ctx;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen return;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen }
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen errno = 0;
a7f5035eebbd138a5436a2eb2ce1fa5fd3d269fbTimo Sirainen while ((pw = getpwent()) != NULL) {
0caa211038e56abfdf1b8b4937a50708f997f850Timo Sirainen if (passwd_iterate_want_pw(pw, set)) {
a7f5035eebbd138a5436a2eb2ce1fa5fd3d269fbTimo Sirainen _ctx->callback(pw->pw_name, _ctx->context);
a7f5035eebbd138a5436a2eb2ce1fa5fd3d269fbTimo Sirainen return;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen }
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen }
a7f5035eebbd138a5436a2eb2ce1fa5fd3d269fbTimo Sirainen if (errno != 0) {
a7f5035eebbd138a5436a2eb2ce1fa5fd3d269fbTimo Sirainen i_error("getpwent() failed: %m");
a7f5035eebbd138a5436a2eb2ce1fa5fd3d269fbTimo Sirainen _ctx->failed = TRUE;
a7f5035eebbd138a5436a2eb2ce1fa5fd3d269fbTimo Sirainen }
a7f5035eebbd138a5436a2eb2ce1fa5fd3d269fbTimo Sirainen _ctx->callback(NULL, _ctx->context);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen}
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainenstatic void ATTR_NULL(1)
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainenpasswd_iterate_next_timeout(void *context ATTR_UNUSED)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen{
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen timeout_remove(&cur_userdb_iter_to);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen passwd_iterate_next(&cur_userdb_iter->ctx);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen}
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenstatic int passwd_iterate_deinit(struct userdb_iterate_context *_ctx)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen{
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen struct passwd_userdb_iterate_context *ctx =
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen (struct passwd_userdb_iterate_context *)_ctx;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen int ret = _ctx->failed ? -1 : 0;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen cur_userdb_iter = ctx->next_waiting;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen i_free(ctx);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (cur_userdb_iter != NULL) {
f0cd1d0022590d0a0d84f57e362774c2e96e2ea8Timo Sirainen cur_userdb_iter_to = timeout_add(0, passwd_iterate_next_timeout,
677b75f90d81eafe742896d6570a2f63ce501d05Josef 'Jeff' Sipek NULL);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen }
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen return ret;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen}
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainenstatic struct userdb_module *
849969f639a00eab26791db3cb1b66430420c0cdTimo Sirainenpasswd_passwd_preinit(pool_t pool, const char *args)
c5383a0ed56a188a7d5efaaa4c6f8243af432d65Timo Sirainen{
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen struct passwd_userdb_module *module;
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen const char *value;
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen
849969f639a00eab26791db3cb1b66430420c0cdTimo Sirainen module = p_new(pool, struct passwd_userdb_module, 1);
74674a53a72dab535c61f455b2246ef2797844eaTimo Sirainen module->module.default_cache_key = USER_CACHE_KEY;
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen module->tmpl = userdb_template_build(pool, "passwd", args);
fd7a5919cfd68a347d6eb1b3e6e8627e1b656c75Timo Sirainen module->module.blocking = TRUE;
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen
fd7a5919cfd68a347d6eb1b3e6e8627e1b656c75Timo Sirainen if (userdb_template_remove(module->tmpl, "blocking", &value))
fd7a5919cfd68a347d6eb1b3e6e8627e1b656c75Timo Sirainen module->module.blocking = strcasecmp(value, "yes") == 0;
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen /* FIXME: backwards compatibility */
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen if (!userdb_template_is_empty(module->tmpl))
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen i_warning("userdb passwd: Move templates args to override_fields setting");
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen return &module->module;
c5383a0ed56a188a7d5efaaa4c6f8243af432d65Timo Sirainen}
c5383a0ed56a188a7d5efaaa4c6f8243af432d65Timo Sirainen
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainenstruct userdb_module_interface userdb_passwd = {
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen "passwd",
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen passwd_passwd_preinit,
c5383a0ed56a188a7d5efaaa4c6f8243af432d65Timo Sirainen NULL,
c5383a0ed56a188a7d5efaaa4c6f8243af432d65Timo Sirainen NULL,
c5383a0ed56a188a7d5efaaa4c6f8243af432d65Timo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen passwd_lookup,
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen passwd_iterate_init,
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen passwd_iterate_next,
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen passwd_iterate_deinit
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen};
d5abbb932a0a598f002da39a8b3326643b1b5efcTimo Sirainen#else
d5abbb932a0a598f002da39a8b3326643b1b5efcTimo Sirainenstruct userdb_module_interface userdb_passwd = {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .name = "passwd"
d5abbb932a0a598f002da39a8b3326643b1b5efcTimo Sirainen};
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#endif