userdb-passwd.c revision fd7a5919cfd68a347d6eb1b3e6e8627e1b656c75
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (c) 2002-2012 Dovecot authors, see the included COPYING file */
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "auth-common.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "userdb.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#ifdef USERDB_PASSWD
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "ioloop.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "ipwd.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "time-util.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "userdb-template.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#define USER_CACHE_KEY "%u"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#define PASSWD_SLOW_WARN_MSECS (10*1000)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#define PASSWD_SLOW_MASTER_WARN_MSECS 50
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#define PASSDB_SLOW_MASTER_WARN_COUNT_INTERVAL 100
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#define PASSDB_SLOW_MASTER_WARN_MIN_PERCENTAGE 5
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstruct passwd_userdb_module {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct userdb_module module;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct userdb_template *tmpl;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen unsigned int fast_count, slow_count;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen unsigned int slow_warned:1;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen};
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstruct passwd_userdb_iterate_context {
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct userdb_iterate_context ctx;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct passwd_userdb_iterate_context *next_waiting;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen};
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainenstatic struct passwd_userdb_iterate_context *cur_userdb_iter = NULL;
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainenstatic struct timeout *cur_userdb_iter_to = NULL;
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainenstatic void
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainenpasswd_check_warnings(struct auth_request *auth_request,
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen struct passwd_userdb_module *module,
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen const struct timeval *start_tv)
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen{
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen struct timeval end_tv;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen unsigned int msecs, percentage;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (gettimeofday(&end_tv, NULL) < 0)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen return;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen msecs = timeval_diff_msecs(&end_tv, start_tv);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (msecs >= PASSWD_SLOW_WARN_MSECS) {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen i_warning("passwd: Lookup for %s took %u secs",
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen auth_request->user, msecs/1000);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen return;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen }
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (worker || module->slow_warned)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen return;
fea7b8b3fc182e415b1875d79587c0aa1adb09d7Timo Sirainen
fea7b8b3fc182e415b1875d79587c0aa1adb09d7Timo Sirainen if (msecs < PASSWD_SLOW_MASTER_WARN_MSECS) {
fea7b8b3fc182e415b1875d79587c0aa1adb09d7Timo Sirainen module->fast_count++;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen return;
fea7b8b3fc182e415b1875d79587c0aa1adb09d7Timo Sirainen }
fea7b8b3fc182e415b1875d79587c0aa1adb09d7Timo Sirainen module->slow_count++;
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen if (module->fast_count + module->slow_count <
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen PASSDB_SLOW_MASTER_WARN_COUNT_INTERVAL)
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen return;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen percentage = module->slow_count * 100 /
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen (module->slow_count + module->fast_count);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (percentage < PASSDB_SLOW_MASTER_WARN_MIN_PERCENTAGE) {
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen /* start from beginning */
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen module->slow_count = module->fast_count = 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen } else {
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen i_warning("passwd: %u%% of last %u lookups took over "
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen "%u milliseconds, "
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen "you may want to set blocking=yes for userdb",
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen percentage, PASSDB_SLOW_MASTER_WARN_COUNT_INTERVAL,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen PASSWD_SLOW_MASTER_WARN_MSECS);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen module->slow_warned = TRUE;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen}
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstatic void passwd_lookup(struct auth_request *auth_request,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen userdb_callback_t *callback)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct userdb_module *_module = auth_request->userdb->userdb;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct passwd_userdb_module *module =
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen (struct passwd_userdb_module *)_module;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen struct passwd pw;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct timeval start_tv;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen int ret;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen auth_request_log_debug(auth_request, "passwd", "lookup");
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen if (gettimeofday(&start_tv, NULL) < 0)
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen start_tv.tv_sec = 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen ret = i_getpwnam(auth_request->user, &pw);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen if (start_tv.tv_sec != 0)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen passwd_check_warnings(auth_request, module, &start_tv);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen switch (ret) {
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen case -1:
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen auth_request_log_error(auth_request, "passwd",
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen "getpwnam() failed: %m");
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen return;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen case 0:
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen auth_request_log_info(auth_request, "passwd", "unknown user");
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen callback(USERDB_RESULT_USER_UNKNOWN, auth_request);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen return;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen auth_request_set_field(auth_request, "user", pw.pw_name, NULL);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen auth_request_init_userdb_reply(auth_request);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen auth_request_set_userdb_field(auth_request, "system_groups_user",
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen pw.pw_name);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen auth_request_set_userdb_field(auth_request, "uid", dec2str(pw.pw_uid));
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen auth_request_set_userdb_field(auth_request, "gid", dec2str(pw.pw_gid));
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen auth_request_set_userdb_field(auth_request, "home", pw.pw_dir);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
b42697a5749b85659a24316d97f1c208d469e4e8Timo Sirainen userdb_template_export(module->tmpl, auth_request);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen callback(USERDB_RESULT_OK, auth_request);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenstatic struct userdb_iterate_context *
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenpasswd_iterate_init(struct auth_request *auth_request,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen userdb_iter_callback_t *callback, void *context)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen struct passwd_userdb_iterate_context *ctx;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen ctx = i_new(struct passwd_userdb_iterate_context, 1);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen ctx->ctx.auth_request = auth_request;
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen ctx->ctx.callback = callback;
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen ctx->ctx.context = context;
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen setpwent();
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen if (cur_userdb_iter == NULL)
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen cur_userdb_iter = ctx;
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen return &ctx->ctx;
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen}
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainenstatic bool
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainenpasswd_iterate_want_pw(struct passwd *pw, const struct auth_settings *set)
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen{
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen /* skip entries not in valid UID range.
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen they're users for daemons and such. */
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen if (pw->pw_uid < (uid_t)set->first_valid_uid)
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen return FALSE;
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen if (pw->pw_uid > (uid_t)set->last_valid_uid && set->last_valid_uid != 0)
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen return FALSE;
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen /* skip entries that don't have a valid shell.
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen they're again probably not real users. */
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen if (strcmp(pw->pw_shell, "/bin/false") == 0 ||
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen strcmp(pw->pw_shell, "/sbin/nologin") == 0 ||
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen strcmp(pw->pw_shell, "/usr/sbin/nologin") == 0)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen return FALSE;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen return TRUE;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstatic void passwd_iterate_next(struct userdb_iterate_context *_ctx)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen struct passwd_userdb_iterate_context *ctx =
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen (struct passwd_userdb_iterate_context *)_ctx;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen const struct auth_settings *set = _ctx->auth_request->set;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct passwd *pw;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen if (cur_userdb_iter != NULL && cur_userdb_iter != ctx) {
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen /* we can't support concurrent userdb iteration.
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen wait until the previous one is done */
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen ctx->next_waiting = cur_userdb_iter->next_waiting;
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen cur_userdb_iter->next_waiting = ctx;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen return;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen errno = 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen while ((pw = getpwent()) != NULL) {
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (passwd_iterate_want_pw(pw, set)) {
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen _ctx->callback(pw->pw_name, _ctx->context);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen return;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (errno != 0) {
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen i_error("getpwent() failed: %m");
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen _ctx->failed = TRUE;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen _ctx->callback(NULL, _ctx->context);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstatic void passwd_iterate_next_timeout(void *context ATTR_UNUSED)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen timeout_remove(&cur_userdb_iter_to);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen passwd_iterate_next(&cur_userdb_iter->ctx);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstatic int passwd_iterate_deinit(struct userdb_iterate_context *_ctx)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct passwd_userdb_iterate_context *ctx =
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen (struct passwd_userdb_iterate_context *)_ctx;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen int ret = _ctx->failed ? -1 : 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cur_userdb_iter = ctx->next_waiting;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen i_free(ctx);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (cur_userdb_iter != NULL) {
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cur_userdb_iter_to =
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen timeout_add(0, passwd_iterate_next_timeout, NULL);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen return ret;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstatic struct userdb_module *
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenpasswd_passwd_preinit(pool_t pool, const char *args)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct passwd_userdb_module *module;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen const char *value;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
71c4ac143fefd57aeec6298489c4559b6f13c67bTimo Sirainen module = p_new(pool, struct passwd_userdb_module, 1);
71c4ac143fefd57aeec6298489c4559b6f13c67bTimo Sirainen module->module.cache_key = USER_CACHE_KEY;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen module->tmpl = userdb_template_build(pool, "passwd", args);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen module->module.blocking = TRUE;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (userdb_template_remove(module->tmpl, "blocking", &value))
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen module->module.blocking = strcasecmp(value, "yes") == 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen /* FIXME: backwards compatibility */
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (!userdb_template_is_empty(module->tmpl))
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen i_warning("userdb passwd: Move templates args to override_fields setting");
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen return &module->module;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstruct userdb_module_interface userdb_passwd = {
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen "passwd",
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen passwd_passwd_preinit,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen NULL,
4321f6c969e7b8f6b243ff5bb6b8d297921676f6Timo Sirainen NULL,
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen passwd_lookup,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen passwd_iterate_init,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen passwd_iterate_next,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen passwd_iterate_deinit
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen};
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#else
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstruct userdb_module_interface userdb_passwd = {
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen .name = "passwd"
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen};
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#endif
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen