userdb-passwd.c revision 82f71aaa55eba909aa180716483b4f2f9d5f7619
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2002-2013 Dovecot authors, see the included COPYING file */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include "auth-common.h"
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include "userdb.h"
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
472369cba85d9f7c995dda60e7cd01d78b4a960aTimo Sirainen#ifdef USERDB_PASSWD
e28fa207d1a097fa6e4a867f74ee0761472ef1ceTimo Sirainen
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainen#include "ioloop.h"
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen#include "ipwd.h"
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainen#include "time-util.h"
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainen#include "userdb-template.h"
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainen
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainen#define USER_CACHE_KEY "%u"
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainen#define PASSWD_SLOW_WARN_MSECS (10*1000)
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen#define PASSWD_SLOW_MASTER_WARN_MSECS 50
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainen#define PASSDB_SLOW_MASTER_WARN_COUNT_INTERVAL 100
ef50336eefcb9ba99f73c6af37420eaf8857a39bTimo Sirainen#define PASSDB_SLOW_MASTER_WARN_MIN_PERCENTAGE 5
e28fa207d1a097fa6e4a867f74ee0761472ef1ceTimo Sirainen
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainenstruct passwd_userdb_module {
ef50336eefcb9ba99f73c6af37420eaf8857a39bTimo Sirainen struct userdb_module module;
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen struct userdb_template *tmpl;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen unsigned int fast_count, slow_count;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen unsigned int slow_warned:1;
5694eeb99b69dea8033ca77ad69743c6b4871370Timo Sirainen};
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
5694eeb99b69dea8033ca77ad69743c6b4871370Timo Sirainenstruct passwd_userdb_iterate_context {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct userdb_iterate_context ctx;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct passwd_userdb_iterate_context *next_waiting;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen};
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic struct passwd_userdb_iterate_context *cur_userdb_iter = NULL;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic struct timeout *cur_userdb_iter_to = NULL;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic void
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenpasswd_check_warnings(struct auth_request *auth_request,
de486b59018016977015ef42e6071155b60e82e1Timo Sirainen struct passwd_userdb_module *module,
de486b59018016977015ef42e6071155b60e82e1Timo Sirainen const struct timeval *start_tv)
de486b59018016977015ef42e6071155b60e82e1Timo Sirainen{
de486b59018016977015ef42e6071155b60e82e1Timo Sirainen struct timeval end_tv;
de486b59018016977015ef42e6071155b60e82e1Timo Sirainen unsigned int msecs, percentage;
de4d9f77d6378a416c9963963eac5ac18b75ec0bTimo Sirainen
de4d9f77d6378a416c9963963eac5ac18b75ec0bTimo Sirainen if (gettimeofday(&end_tv, NULL) < 0)
de486b59018016977015ef42e6071155b60e82e1Timo Sirainen return;
de486b59018016977015ef42e6071155b60e82e1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen msecs = timeval_diff_msecs(&end_tv, start_tv);
220e21750948941dc6e33b8f11b552fa21d7f81eTimo Sirainen if (msecs >= PASSWD_SLOW_WARN_MSECS) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_warning("passwd: Lookup for %s took %u secs",
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen auth_request->user, msecs/1000);
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen return;
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen }
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen if (worker || module->slow_warned)
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen return;
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen if (msecs < PASSWD_SLOW_MASTER_WARN_MSECS) {
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen module->fast_count++;
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen return;
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen }
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen module->slow_count++;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (module->fast_count + module->slow_count <
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen PASSDB_SLOW_MASTER_WARN_COUNT_INTERVAL)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen percentage = module->slow_count * 100 /
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen (module->slow_count + module->fast_count);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (percentage < PASSDB_SLOW_MASTER_WARN_MIN_PERCENTAGE) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* start from beginning */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen module->slow_count = module->fast_count = 0;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen } else {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_warning("passwd: %u%% of last %u lookups took over "
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen "%u milliseconds, "
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen "you may want to set blocking=yes for userdb",
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen percentage, PASSDB_SLOW_MASTER_WARN_COUNT_INTERVAL,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen PASSWD_SLOW_MASTER_WARN_MSECS);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen module->slow_warned = TRUE;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen}
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainenstatic void passwd_lookup(struct auth_request *auth_request,
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen userdb_callback_t *callback)
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct userdb_module *_module = auth_request->userdb->userdb;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct passwd_userdb_module *module =
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen (struct passwd_userdb_module *)_module;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct passwd pw;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct timeval start_tv;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen int ret;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen auth_request_log_debug(auth_request, "passwd", "lookup");
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (gettimeofday(&start_tv, NULL) < 0)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen start_tv.tv_sec = 0;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen ret = i_getpwnam(auth_request->user, &pw);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (start_tv.tv_sec != 0)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen passwd_check_warnings(auth_request, module, &start_tv);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen switch (ret) {
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen case -1:
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen auth_request_log_error(auth_request, "passwd",
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen "getpwnam() failed: %m");
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request);
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen return;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen case 0:
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen auth_request_log_info(auth_request, "passwd", "unknown user");
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen callback(USERDB_RESULT_USER_UNKNOWN, auth_request);
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen return;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen }
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen auth_request_set_field(auth_request, "user", pw.pw_name, NULL);
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen auth_request_init_userdb_reply(auth_request);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen auth_request_set_userdb_field(auth_request, "system_groups_user",
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen pw.pw_name);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen auth_request_set_userdb_field(auth_request, "uid", dec2str(pw.pw_uid));
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen auth_request_set_userdb_field(auth_request, "gid", dec2str(pw.pw_gid));
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen auth_request_set_userdb_field(auth_request, "home", pw.pw_dir);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen userdb_template_export(module->tmpl, auth_request);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen callback(USERDB_RESULT_OK, auth_request);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen}
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstatic struct userdb_iterate_context *
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenpasswd_iterate_init(struct auth_request *auth_request,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen userdb_iter_callback_t *callback, void *context)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct passwd_userdb_iterate_context *ctx;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
1701e3f91107051b1704721bf1dc1e32491faaf9Timo Sirainen ctx = i_new(struct passwd_userdb_iterate_context, 1);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen ctx->ctx.auth_request = auth_request;
6600c05e2ab38e9f662582b63c56b0c980a03748Timo Sirainen ctx->ctx.callback = callback;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen ctx->ctx.context = context;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen setpwent();
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen if (cur_userdb_iter == NULL)
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen cur_userdb_iter = ctx;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen return &ctx->ctx;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen}
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainenstatic bool
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainenpasswd_iterate_want_pw(struct passwd *pw, const struct auth_settings *set)
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen{
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen /* skip entries not in valid UID range.
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen they're users for daemons and such. */
1701e3f91107051b1704721bf1dc1e32491faaf9Timo Sirainen if (pw->pw_uid < (uid_t)set->first_valid_uid)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen return FALSE;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (pw->pw_uid > (uid_t)set->last_valid_uid && set->last_valid_uid != 0)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen return FALSE;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen return TRUE;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen}
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstatic void passwd_iterate_next(struct userdb_iterate_context *_ctx)
3fe67ec75ccae1230bb9eb9f16affc48377f6441Timo Sirainen{
b13f738e8eb3f24dc2abf2c804f954b4d864ac6fTimo Sirainen struct passwd_userdb_iterate_context *ctx =
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen (struct passwd_userdb_iterate_context *)_ctx;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen const struct auth_settings *set = _ctx->auth_request->set;
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen struct passwd *pw;
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen if (cur_userdb_iter != NULL && cur_userdb_iter != ctx) {
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen /* we can't support concurrent userdb iteration.
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen wait until the previous one is done */
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen ctx->next_waiting = cur_userdb_iter->next_waiting;
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen cur_userdb_iter->next_waiting = ctx;
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen return;
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen }
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen errno = 0;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen while ((pw = getpwent()) != NULL) {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (passwd_iterate_want_pw(pw, set)) {
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen _ctx->callback(pw->pw_name, _ctx->context);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen return;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen }
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen }
27586e4785d56aeb76e1fd96af8db799688dc64aTimo Sirainen if (errno != 0) {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen i_error("getpwent() failed: %m");
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen _ctx->failed = TRUE;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen }
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen _ctx->callback(NULL, _ctx->context);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen}
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstatic void ATTR_NULL(1)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenpasswd_iterate_next_timeout(void *context ATTR_UNUSED)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen{
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen timeout_remove(&cur_userdb_iter_to);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen passwd_iterate_next(&cur_userdb_iter->ctx);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen}
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volkstatic int passwd_iterate_deinit(struct userdb_iterate_context *_ctx)
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk{
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk struct passwd_userdb_iterate_context *ctx =
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk (struct passwd_userdb_iterate_context *)_ctx;
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk int ret = _ctx->failed ? -1 : 0;
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk cur_userdb_iter = ctx->next_waiting;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen i_free(ctx);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (cur_userdb_iter != NULL) {
5666a3d6a7ea89362b8d9e8b39b15424cd9d6388Timo Sirainen cur_userdb_iter_to = timeout_add(0, passwd_iterate_next_timeout,
1701e3f91107051b1704721bf1dc1e32491faaf9Timo Sirainen (void *)NULL);
1701e3f91107051b1704721bf1dc1e32491faaf9Timo Sirainen }
1701e3f91107051b1704721bf1dc1e32491faaf9Timo Sirainen return ret;
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen}
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainenstatic struct userdb_module *
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainenpasswd_passwd_preinit(pool_t pool, const char *args)
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen{
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen struct passwd_userdb_module *module;
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen const char *value;
9abf5be0962538e1f6f5c73c838ff677341da0c9Timo Sirainen
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen module = p_new(pool, struct passwd_userdb_module, 1);
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen module->module.cache_key = USER_CACHE_KEY;
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen module->tmpl = userdb_template_build(pool, "passwd", args);
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen module->module.blocking = TRUE;
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen if (userdb_template_remove(module->tmpl, "blocking", &value))
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen module->module.blocking = strcasecmp(value, "yes") == 0;
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen /* FIXME: backwards compatibility */
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen if (!userdb_template_is_empty(module->tmpl))
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen i_warning("userdb passwd: Move templates args to override_fields setting");
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen return &module->module;
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen}
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainenstruct userdb_module_interface userdb_passwd = {
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen "passwd",
02e61e13a8360a9d3ec92c5fa5ae60c0f0181b71Timo Sirainen
02e61e13a8360a9d3ec92c5fa5ae60c0f0181b71Timo Sirainen passwd_passwd_preinit,
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen NULL,
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen NULL,
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen passwd_lookup,
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen passwd_iterate_init,
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen passwd_iterate_next,
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen passwd_iterate_deinit
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen};
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen#else
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainenstruct userdb_module_interface userdb_passwd = {
5c597df6aa8d81de4053c6986fab7739f3b44b20Timo Sirainen .name = "passwd"
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen};
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen#endif
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen