passdb-passwd.c revision dd93aba1901a457346990f49c54a738947dc7128
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn#include "common.h"
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn#include "passdb.h"
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn#ifdef PASSDB_PASSWD
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn
9afe19d634946d50eab30e3b90cb5cebcde39eeaDaniel Lezcano#include "safe-memset.h"
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn#include <pwd.h>
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn#define PASSWD_CACHE_KEY "%u"
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn#define PASSWD_PASS_SCHEME "CRYPT"
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallynstatic void
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallynpasswd_verify_plain(struct auth_request *request, const char *password,
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn verify_plain_callback_t *callback)
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn{
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn struct passwd *pw;
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn int ret;
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn auth_request_log_debug(request, "passwd", "lookup");
250b1eec71b074acdff1c5f6b5a1f0d7d2c20b77Stéphane Graber
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn pw = getpwnam(request->user);
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn if (pw == NULL) {
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn auth_request_log_info(request, "passwd", "unknown user");
7f95145833bb24f54e037f73ecc37444d6635697Dwight Engen callback(PASSDB_RESULT_USER_UNKNOWN, request);
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn return;
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn }
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn if (!IS_VALID_PASSWD(pw->pw_passwd)) {
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn auth_request_log_info(request, "passwd",
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn "invalid password field '%s'", pw->pw_passwd);
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn callback(PASSDB_RESULT_USER_DISABLED, request);
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn return;
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn }
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn /* save the password so cache can use it */
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn auth_request_set_field(request, "password", pw->pw_passwd,
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn PASSWD_PASS_SCHEME);
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn /* check if the password is valid */
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn ret = auth_request_password_verify(request, password, pw->pw_passwd,
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn PASSWD_PASS_SCHEME, "passwd");
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn /* clear the passwords from memory */
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn safe_memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn if (ret <= 0) {
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn return;
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn }
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn /* make sure we're using the username exactly as it's in the database */
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn auth_request_set_field(request, "user", pw->pw_name, NULL);
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn callback(PASSDB_RESULT_OK, request);
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn}
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallynstatic void passwd_init(struct passdb_module *module, const char *args)
585f3c6b6942e82a25af1d68672fd4744ecfa09dKATOH Yasufumi{
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn if (strcmp(args, "blocking=yes") == 0)
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn module->blocking = TRUE;
dc92f6c7eec81dc104b3f7873ffd74ec56a1dae1Serge Hallyn else
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn i_fatal("passdb passwd: Unknown setting: %s", args);
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn module->cache_key = PASSWD_CACHE_KEY;
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn module->default_pass_scheme = PASSWD_PASS_SCHEME;
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn}
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallynstatic void passwd_deinit(struct passdb_module *module ATTR_UNUSED)
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn{
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn endpwent();
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn}
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn
585f3c6b6942e82a25af1d68672fd4744ecfa09dKATOH Yasufumistruct passdb_module_interface passdb_passwd = {
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn "passwd",
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn
dc92f6c7eec81dc104b3f7873ffd74ec56a1dae1Serge Hallyn NULL,
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn passwd_init,
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn passwd_deinit,
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn passwd_verify_plain,
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn NULL,
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn NULL
11cddd70eb8c285287b73562ba4208d74e1b9fdeSerge Hallyn};
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn#else
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallynstruct passdb_module_interface passdb_passwd = {
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn MEMBER(name) "passwd"
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn};
9be53773792fc9e8bd173edc3b7ac7e144875387Serge Hallyn#endif
1f92162dc0432b6f7f8156d22348f22934cbea3fStéphane Graber