userdb-passwd.c revision 82f71aaa55eba909aa180716483b4f2f9d5f7619
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2002-2013 Dovecot authors, see the included COPYING file */
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainen#define PASSDB_SLOW_MASTER_WARN_COUNT_INTERVAL 100
ef50336eefcb9ba99f73c6af37420eaf8857a39bTimo Sirainen#define PASSDB_SLOW_MASTER_WARN_MIN_PERCENTAGE 5
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct passwd_userdb_iterate_context *next_waiting;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic struct passwd_userdb_iterate_context *cur_userdb_iter = NULL;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic struct timeout *cur_userdb_iter_to = NULL;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenpasswd_check_warnings(struct auth_request *auth_request,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen msecs = timeval_diff_msecs(&end_tv, start_tv);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_warning("passwd: Lookup for %s took %u secs",
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (percentage < PASSDB_SLOW_MASTER_WARN_MIN_PERCENTAGE) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* start from beginning */
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,
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainenstatic void passwd_lookup(struct auth_request *auth_request,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct userdb_module *_module = auth_request->userdb->userdb;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen auth_request_log_debug(auth_request, "passwd", "lookup");
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen passwd_check_warnings(auth_request, module, &start_tv);
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 auth_request_log_info(auth_request, "passwd", "unknown user");
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen callback(USERDB_RESULT_USER_UNKNOWN, auth_request);
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen auth_request_set_field(auth_request, "user", pw.pw_name, NULL);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen auth_request_set_userdb_field(auth_request, "system_groups_user",
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 userdb_template_export(module->tmpl, auth_request);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenpasswd_iterate_init(struct auth_request *auth_request,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen userdb_iter_callback_t *callback, void *context)
1701e3f91107051b1704721bf1dc1e32491faaf9Timo Sirainen ctx = i_new(struct passwd_userdb_iterate_context, 1);
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainenpasswd_iterate_want_pw(struct passwd *pw, const struct auth_settings *set)
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen /* skip entries not in valid UID range.
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen they're users for daemons and such. */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (pw->pw_uid > (uid_t)set->last_valid_uid && set->last_valid_uid != 0)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstatic void passwd_iterate_next(struct userdb_iterate_context *_ctx)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen const struct auth_settings *set = _ctx->auth_request->set;
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;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenpasswd_iterate_next_timeout(void *context ATTR_UNUSED)
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volkstatic int passwd_iterate_deinit(struct userdb_iterate_context *_ctx)
5666a3d6a7ea89362b8d9e8b39b15424cd9d6388Timo Sirainen cur_userdb_iter_to = timeout_add(0, passwd_iterate_next_timeout,
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainenpasswd_passwd_preinit(pool_t pool, const char *args)
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen module = p_new(pool, struct passwd_userdb_module, 1);
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen module->tmpl = userdb_template_build(pool, "passwd", args);
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen if (userdb_template_remove(module->tmpl, "blocking", &value))
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen module->module.blocking = strcasecmp(value, "yes") == 0;
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen /* FIXME: backwards compatibility */
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen i_warning("userdb passwd: Move templates args to override_fields setting");
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainenstruct userdb_module_interface userdb_passwd = {