Mercurial > dovecot > original-hg > dovecot-1.2
changeset 1191:65e48854491d HEAD
Added default_pass_scheme to LDAP. Support for more password schemes. Merged
password checking code with LDAP and passwd-file, so both support the same
schemes now.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 18 Feb 2003 21:11:26 +0200 |
parents | c54c61822d27 |
children | 76321f65960d |
files | doc/dovecot-ldap.conf src/auth/Makefile.am src/auth/auth-login-interface.h src/auth/db-ldap.c src/auth/db-ldap.h src/auth/db-passwd-file.c src/auth/db-passwd-file.h src/auth/master-connection.c src/auth/mech-digest-md5.c src/auth/mech-plain.c src/auth/mech.c src/auth/mech.h src/auth/passdb-ldap.c src/auth/passdb-pam.c src/auth/passdb-passwd-file.c src/auth/passdb-passwd.c src/auth/passdb-shadow.c src/auth/passdb-vpopmail.c src/auth/passdb.c src/auth/passdb.h src/auth/password-verify.c src/auth/password-verify.h src/auth/userdb-ldap.c src/auth/userdb-passwd-file.c src/auth/userdb-passwd.c src/auth/userdb-static.c src/auth/userdb-vpopmail.c src/auth/userdb-vpopmail.h src/auth/userdb.h src/login-common/auth-common.c |
diffstat | 30 files changed, 247 insertions(+), 289 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/dovecot-ldap.conf Tue Feb 18 21:09:18 2003 +0200 +++ b/doc/dovecot-ldap.conf Tue Feb 18 21:11:26 2003 +0200 @@ -40,6 +40,10 @@ # Filter for password lookups #pass_filter = (&(objectClass=posixAccount)(uid=%u)) +# Default password scheme. "{scheme}" before password overrides this. +# Currently supported schemes include PLAIN, PLAIN-MD5, DIGEST-MD5, CRYPT +#default_pass_scheme = CRYPT + # You can use same UID and GID for all user accounts if you really want to. # If the UID/GID is still found from LDAP reply, it overrides these values. #user_global_uid =
--- a/src/auth/Makefile.am Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/Makefile.am Tue Feb 18 21:11:26 2003 +0200 @@ -38,6 +38,7 @@ passdb-pam.c \ passdb-shadow.c \ passdb-vpopmail.c \ + password-verify.c \ userdb.c \ userdb-ldap.c \ userdb-passwd.c \ @@ -58,5 +59,6 @@ mech.h \ mycrypt.h \ passdb.h \ + password-verify.h \ userdb.h \ userdb-vpopmail.h
--- a/src/auth/auth-login-interface.h Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/auth-login-interface.h Tue Feb 18 21:11:26 2003 +0200 @@ -69,7 +69,6 @@ /* variable width data, indexes into data[]. Ignore if it points outside data_size. */ size_t username_idx; /* NUL-terminated */ - size_t realm_idx; /* NUL-terminated */ size_t reply_idx; /* last, non-NUL terminated */ size_t data_size;
--- a/src/auth/db-ldap.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/db-ldap.c Tue Feb 18 21:11:26 2003 +0200 @@ -34,6 +34,7 @@ DEF(SET_STR, user_filter), DEF(SET_STR, pass_attrs), DEF(SET_STR, pass_filter), + DEF(SET_STR, default_pass_scheme), DEF(SET_STR, user_global_uid), DEF(SET_STR, user_global_gid) }; @@ -49,6 +50,7 @@ MEMBER(user_filter) NULL, MEMBER(pass_attrs) NULL, MEMBER(pass_filter) NULL, + MEMBER(default_pass_scheme) "crypt", MEMBER(user_global_uid) 0, MEMBER(user_global_gid) 0 };
--- a/src/auth/db-ldap.h Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/db-ldap.h Tue Feb 18 21:11:26 2003 +0200 @@ -22,6 +22,7 @@ const char *pass_attrs; const char *pass_filter; + const char *default_pass_scheme; unsigned int user_global_uid; unsigned int user_global_gid;
--- a/src/auth/db-passwd-file.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/db-passwd-file.c Tue Feb 18 21:11:26 2003 +0200 @@ -41,25 +41,25 @@ p = pass == NULL ? NULL : strchr(pass, '['); if (p == NULL) { pu->password = p_strdup(pw->pool, pass); - pu->password_type = pass == NULL ? PASSWORD_NONE : PASSWORD_DES; } else { /* password[type] - we're being libpam-pwdfile compatible - here. it uses 13 = DES and 34 = MD5. We add - 56 = Digest-MD5. */ - pu->password = p_strdup_until(pw->pool, pass, p); + here. it uses 13 = DES and 34 = MD5. For backwards + comaptibility with ourself, we have also 56 = Digest-MD5. */ + pass = t_strdup_until(pass, p); if (p[1] == '3' && p[2] == '4') { - pu->password_type = PASSWORD_MD5; - str_lcase(pu->password); + pu->password = p_strconcat(pw->pool, "{PLAIN-MD5}", + pass, NULL); } else if (p[1] == '5' && p[2] == '6') { - pu->password_type = PASSWORD_DIGEST_MD5; - if (strlen(pu->password) != 32) { + pu->password = p_strconcat(pw->pool, "{DIGEST-MD5}", + pass, NULL); + if (strlen(pu->password) != 32 + 12) { i_error("User %s has invalid password in " "file %s", username, pw->path); return; } - str_lcase(pu->password); } else { - pu->password_type = PASSWORD_DES; + pu->password = p_strconcat(pw->pool, "{CRYPT}", + pass, NULL); } } @@ -208,14 +208,10 @@ } struct passwd_user * -db_passwd_file_lookup(struct passwd_file *pw, - const char *user, const char *realm) +db_passwd_file_lookup(struct passwd_file *pw, const char *user) { struct passwd_user *pu; - if (realm != NULL) - user = t_strconcat(user, "@", realm, NULL); - passwd_file_sync(pw); pu = hash_lookup(pw->users, user);
--- a/src/auth/db-passwd-file.h Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/db-passwd-file.h Tue Feb 18 21:11:26 2003 +0200 @@ -1,13 +1,6 @@ #ifndef __DB_PASSWD_FILE_H #define __DB_PASSWD_FILE_H -enum password_type { - PASSWORD_NONE, - PASSWORD_DES, - PASSWORD_MD5, - PASSWORD_DIGEST_MD5 -}; - struct passwd_user { char *user_realm; /* user@realm */ const char *realm; /* NULL or points to user_realm */ @@ -18,7 +11,6 @@ char *home; char *mail; - enum password_type password_type; char *password; unsigned int chroot:1; @@ -39,8 +31,7 @@ extern struct passwd_file *passdb_pwf; struct passwd_user * -db_passwd_file_lookup(struct passwd_file *pw, - const char *user, const char *realm); +db_passwd_file_lookup(struct passwd_file *pw, const char *user); struct passwd_file *db_passwd_file_parse(const char *path); void db_passwd_file_unref(struct passwd_file *pw);
--- a/src/auth/master-connection.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/master-connection.c Tue Feb 18 21:11:26 2003 +0200 @@ -114,8 +114,8 @@ if (request == NULL) send_reply(&failure_reply, sizeof(failure_reply), request->tag); else { - userdb->lookup(auth_request->user, auth_request->realm, - userdb_callback, POINTER_CAST(request->tag)); + userdb->lookup(auth_request->user, userdb_callback, + POINTER_CAST(request->tag)); mech_request_free(login_conn, auth_request, request->id); } }
--- a/src/auth/mech-digest-md5.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/mech-digest-md5.c Tue Feb 18 21:11:26 2003 +0200 @@ -568,10 +568,14 @@ request->data_size, &error)) { auth_request->callback = callback; - auth_request->user = p_strdup(auth_request->pool, - auth->username); - auth_request->realm = - p_strdup_empty(auth_request->pool, auth->realm); + if (auth->realm == NULL) { + auth_request->user = p_strdup(auth_request->pool, + auth->username); + } else { + auth_request->user = p_strconcat(auth_request->pool, + auth->username, "@", + auth->realm, NULL); + } passdb->lookup_credentials(&auth->auth_request, PASSDB_CREDENTIALS_DIGEST_MD5,
--- a/src/auth/mech-plain.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/mech-plain.c Tue Feb 18 21:11:26 2003 +0200 @@ -44,10 +44,6 @@ /* split and save user/realm */ auth_request->user = p_strdup(auth_request->pool, authenid); - auth_request->realm = strchr(auth_request->user, '@'); - if (auth_request->realm != NULL) - *auth_request->realm++ = '\0'; - passdb->verify_plain(auth_request, pass, verify_callback); /* make sure it's cleared */
--- a/src/auth/mech.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/mech.c Tue Feb 18 21:11:26 2003 +0200 @@ -133,7 +133,6 @@ memset(reply, 0, sizeof(*reply)); reply->username_idx = (unsigned int)-1; - reply->realm_idx = (unsigned int)-1; reply->reply_idx = (unsigned int)-1; } @@ -148,14 +147,6 @@ reply->username_idx = 0; buffer_append(buf, auth_request->user, strlen(auth_request->user)+1); - if (auth_request->realm == NULL) - reply->realm_idx = (size_t)-1; - else { - reply->realm_idx = buffer_get_used_size(buf); - buffer_append(buf, auth_request->realm, - strlen(auth_request->realm)+1); - } - if (data_size == 0) reply->reply_idx = (size_t)-1; else {
--- a/src/auth/mech.h Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/mech.h Tue Feb 18 21:11:26 2003 +0200 @@ -10,7 +10,7 @@ struct auth_request { pool_t pool; - char *user, *realm; + char *user; struct login_connection *conn; unsigned int id;
--- a/src/auth/passdb-ldap.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/passdb-ldap.c Tue Feb 18 21:11:26 2003 +0200 @@ -8,7 +8,7 @@ #include "common.h" #include "str.h" #include "var-expand.h" -#include "mycrypt.h" +#include "password-verify.h" #include "db-ldap.h" #include "passdb.h" @@ -55,15 +55,10 @@ LDAPMessage *entry; BerElement *ber; char *attr, **vals; - const char *user, *password; + const char *user, *password, *scheme; + int ret; - if (auth_request->realm == NULL) - user = auth_request->user; - else { - user = t_strconcat(auth_request->user, "@", - auth_request->realm, NULL); - } - + user = auth_request->user; password = NULL; entry = res == NULL ? NULL : ldap_first_entry(conn->ld, res); @@ -73,7 +68,6 @@ } else { attr = ldap_first_attribute(conn->ld, entry, &ber); while (attr != NULL) { - i_warning("attr: %s", attr); vals = ldap_get_values(conn->ld, entry, attr); if (vals != NULL && vals[0] != NULL && vals[1] == NULL) { @@ -95,56 +89,38 @@ } } - switch (ldap_request->credentials) { - case -1: - /* verify_plain */ - if (password == NULL) { - ldap_request->callback. - verify_plain(PASSDB_RESULT_USER_UNKNOWN, - auth_request); - break; - } + scheme = password_get_scheme(&password); + if (scheme == NULL) { + scheme = conn->set.default_pass_scheme; + i_assert(scheme != NULL); + } - if (strncasecmp(password, "{crypt}", 7) == 0) - password += 7; + if (ldap_request->credentials != -1) { + passdb_handle_credentials(ldap_request->credentials, + user, password, scheme, + ldap_request->callback.lookup_credentials, + auth_request); + return; + } - if (strcmp(mycrypt(password, ldap_request->password), - ldap_request->password) != 0) { - if (verbose) - i_info("ldap(%s): password mismatch", user); - ldap_request->callback. - verify_plain(PASSDB_RESULT_PASSWORD_MISMATCH, - auth_request); - } else { - ldap_request->callback.verify_plain(PASSDB_RESULT_OK, - auth_request); - } - break; - case PASSDB_CREDENTIALS_PLAINTEXT: - if (password != NULL && - strncasecmp(password, "{plain}", 7) == 0) - password += 7; - else - password = NULL; + /* verify plain */ + if (password == NULL) { + ldap_request->callback.verify_plain(PASSDB_RESULT_USER_UNKNOWN, + auth_request); + return; + } - ldap_request->callback.lookup_credentials(password, - auth_request); - break; - case PASSDB_CREDENTIALS_CRYPT: - ldap_request->callback.lookup_credentials(password, - auth_request); - break; - case PASSDB_CREDENTIALS_DIGEST_MD5: - if (password != NULL && - strncasecmp(password, "{digest-md5}", 12) == 0) - password += 12; - else - password = NULL; + ret = password_verify(ldap_request->password, password, scheme, user); + if (ret < 0) + i_error("ldap(%s): Unknown password scheme %s", user, scheme); + else if (ret == 0) { + if (verbose) + i_info("ldap(%s): password mismatch", user); + } - ldap_request->callback.lookup_credentials(password, - auth_request); - break; - } + ldap_request->callback.verify_plain(ret > 0 ? PASSDB_RESULT_OK : + PASSDB_RESULT_PASSWORD_MISMATCH, + auth_request); } static void ldap_lookup_pass(struct auth_request *auth_request, @@ -154,14 +130,7 @@ const char *user, *filter; string_t *str; - if (auth_request->realm == NULL) - user = auth_request->user; - else { - user = t_strconcat(auth_request->user, "@", - auth_request->realm, NULL); - } - - user = ldap_escape(user); + user = ldap_escape(auth_request->user); if (conn->set.pass_filter == NULL) { filter = t_strdup_printf("(&(objectClass=posixAccount)(%s=%s))", passdb_ldap_conn->attr_names[ATTR_VIRTUAL_USER], user);
--- a/src/auth/passdb-pam.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/passdb-pam.c Tue Feb 18 21:11:26 2003 +0200 @@ -199,36 +199,30 @@ verify_plain_callback_t *callback) { pam_handle_t *pamh; - const char *user; struct pam_userpass userpass; struct pam_conv conv; int status, status2; - if (request->realm == NULL) - user = request->user; - else - user = t_strconcat(request->user, "@", request->realm, NULL); - conv.conv = pam_userpass_conv; conv.appdata_ptr = &userpass; - userpass.user = user; + userpass.user = request->user; userpass.pass = password; - status = pam_start(service_name, user, &conv, &pamh); + status = pam_start(service_name, request->user, &conv, &pamh); if (status != PAM_SUCCESS) { if (verbose) { i_info("PAM: pam_start(%s) failed: %s", - user, pam_strerror(pamh, status)); + request->user, pam_strerror(pamh, status)); } callback(PASSDB_RESULT_INTERNAL_FAILURE, request); return; } - status = pam_auth(pamh, user); + status = pam_auth(pamh, request->user); if ((status2 = pam_end(pamh, status)) != PAM_SUCCESS) { i_error("pam_end(%s) failed: %s", - user, pam_strerror(pamh, status2)); + request->user, pam_strerror(pamh, status2)); callback(PASSDB_RESULT_INTERNAL_FAILURE, request); return; }
--- a/src/auth/passdb-passwd-file.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/passdb-passwd-file.c Tue Feb 18 21:11:26 2003 +0200 @@ -7,12 +7,9 @@ #include "common.h" #include "passdb.h" +#include "password-verify.h" #include "db-passwd-file.h" -#include "hex-binary.h" -#include "md5.h" -#include "mycrypt.h" - struct passwd_file *passdb_pwf = NULL; static void @@ -20,74 +17,33 @@ verify_plain_callback_t *callback) { struct passwd_user *pu; - unsigned char digest[16]; - const char *str; + const char *scheme, *crypted_pass; + int ret; - pu = db_passwd_file_lookup(passdb_pwf, request->user, request->realm); + pu = db_passwd_file_lookup(passdb_pwf, request->user); if (pu == NULL) { callback(PASSDB_RESULT_USER_UNKNOWN, request); return; } - switch (pu->password_type) { - case PASSWORD_NONE: - callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); - return; + crypted_pass = pu->password; + scheme = password_get_scheme(&crypted_pass); + if (scheme == NULL) scheme = "DES"; - case PASSWORD_DES: - if (strcmp(mycrypt(password, pu->password), - pu->password) == 0) { - callback(PASSDB_RESULT_OK, request); - return; - } - - if (verbose) { - i_info("passwd-file(%s): DES password mismatch", - pu->user_realm); + ret = password_verify(password, crypted_pass, scheme, + request->user); + if (ret > 0) + callback(PASSDB_RESULT_OK, request); + else { + if (ret < 0) { + i_error("passwd-file(%s): Unknown password scheme %s", + pu->user_realm, scheme); + } else if (verbose) { + i_info("passwd-file(%s): %s password mismatch", + pu->user_realm, scheme); } callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); - return; - - case PASSWORD_MD5: - md5_get_digest(password, strlen(password), digest); - str = binary_to_hex(digest, sizeof(digest)); - - if (strcmp(str, pu->password) == 0) { - callback(PASSDB_RESULT_OK, request); - return; - } - - if (verbose) { - i_info("passwd-file(%s): MD5 password mismatch", - pu->user_realm); - } - callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); - return; - - case PASSWORD_DIGEST_MD5: - /* user:realm:passwd */ - str = t_strconcat(t_strcut(pu->user_realm, '@'), ":", - pu->realm == NULL ? "" : pu->realm, ":", - password, NULL); - - md5_get_digest(str, strlen(str), digest); - str = binary_to_hex(digest, sizeof(digest)); - - if (strcmp(str, pu->password) == 0) { - callback(PASSDB_RESULT_OK, request); - return; - } - - if (verbose) { - i_info("passwd-file(%s): DIGEST-MD5 password mismatch", - pu->user_realm); - } - - callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); - return; } - - i_unreached(); } static void @@ -96,41 +52,19 @@ lookup_credentials_callback_t *callback) { struct passwd_user *pu; + const char *crypted_pass, *scheme; - pu = db_passwd_file_lookup(passdb_pwf, request->user, request->realm); + pu = db_passwd_file_lookup(passdb_pwf, request->user); if (pu == NULL) { callback(NULL, request); return; } - if (pu->password_type == PASSWORD_NONE) { - if (verbose) - i_info("passwd-file(%s): No password", pu->user_realm); - callback(NULL, request); - return; - } - - switch (credentials) { - case PASSDB_CREDENTIALS_DIGEST_MD5: - if (pu->password_type == PASSWORD_DIGEST_MD5) { - callback(pu->password, request); - return; - } + crypted_pass = pu->password; + scheme = password_get_scheme(&crypted_pass); - if (verbose) { - i_info("passwd-file(%s): No DIGEST-MD5 password", - pu->user_realm); - } - callback(NULL, request); - return; - default: - if (verbose) { - i_info("passwd-file(%s): Unsupported credentials %u", - pu->user_realm, (unsigned int)credentials); - } - callback(NULL, request); - return; - } + passdb_handle_credentials(credentials, request->user, crypted_pass, + scheme, callback, request); } static void passwd_file_init(const char *args)
--- a/src/auth/passdb-passwd.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/passdb-passwd.c Tue Feb 18 21:11:26 2003 +0200 @@ -16,21 +16,15 @@ passwd_verify_plain(struct auth_request *request, const char *password, verify_plain_callback_t *callback) { - const char *user; struct passwd *pw; int result; - if (request->realm == NULL) - user = request->user; - else - user = t_strconcat(request->user, "@", request->realm, NULL); - - pw = getpwnam(user); + pw = getpwnam(request->user); if (pw == NULL) { if (errno != 0) - i_error("getpwnam(%s) failed: %m", user); + i_error("getpwnam(%s) failed: %m", request->user); else if (verbose) - i_info("passwd(%s): unknown user", user); + i_info("passwd(%s): unknown user", request->user); callback(PASSDB_RESULT_USER_UNKNOWN, request); return; } @@ -38,7 +32,7 @@ if (!IS_VALID_PASSWD(pw->pw_passwd)) { if (verbose) { i_info("passwd(%s): invalid password field '%s'", - user, pw->pw_passwd); + request->user, pw->pw_passwd); } callback(PASSDB_RESULT_USER_DISABLED, request); return; @@ -52,7 +46,7 @@ if (!result) { if (verbose) - i_info("passwd(%s): password mismatch", user); + i_info("passwd(%s): password mismatch", request->user); callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); return; }
--- a/src/auth/passdb-shadow.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/passdb-shadow.c Tue Feb 18 21:11:26 2003 +0200 @@ -16,21 +16,15 @@ shadow_verify_plain(struct auth_request *request, const char *password, verify_plain_callback_t *callback) { - const char *user; struct spwd *spw; int result; - if (request->realm == NULL) - user = request->user; - else - user = t_strconcat(request->user, "@", request->realm, NULL); - - spw = getspnam(user); + spw = getspnam(request->user); if (spw == NULL) { if (errno != 0) - i_error("getspnam(%s) failed: %m", user); + i_error("getspnam(%s) failed: %m", request->user); else if (verbose) - i_info("shadow(%s): unknown user", user); + i_info("shadow(%s): unknown user", request->user); callback(PASSDB_RESULT_USER_UNKNOWN, request); return; } @@ -38,7 +32,7 @@ if (!IS_VALID_PASSWD(spw->sp_pwdp)) { if (verbose) { i_info("shadow(%s): invalid password field '%s'", - user, spw->sp_pwdp); + request->user, spw->sp_pwdp); } callback(PASSDB_RESULT_USER_DISABLED, request); return; @@ -52,7 +46,7 @@ if (!result) { if (verbose) - i_info("shadow(%s): password mismatch", user); + i_info("shadow(%s): password mismatch", request->user); callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); return; }
--- a/src/auth/passdb-vpopmail.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/passdb-vpopmail.c Tue Feb 18 21:11:26 2003 +0200 @@ -22,7 +22,7 @@ struct vqpasswd *vpw; int result; - vpw = vpopmail_lookup_vqp(request->user, request->realm, + vpw = vpopmail_lookup_vqp(request->user, vpop_user, vpop_domain); if (vpw == NULL) { callback(PASSDB_RESULT_USER_UNKNOWN, request);
--- a/src/auth/passdb.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/passdb.c Tue Feb 18 21:11:26 2003 +0200 @@ -13,22 +13,54 @@ struct passdb_module *passdb; -const char *passdb_credentials_to_str(enum passdb_credentials credentials) +static const char * +passdb_credentials_to_str(enum passdb_credentials credentials) { switch (credentials) { case _PASSDB_CREDENTIALS_INTERNAL: break; case PASSDB_CREDENTIALS_PLAINTEXT: - return "plaintext"; + return "PLAIN"; case PASSDB_CREDENTIALS_CRYPT: - return "crypt"; + return "CRYPT"; case PASSDB_CREDENTIALS_DIGEST_MD5: - return "digest-md5"; + return "DIGEST-MD5"; } return "??"; } +void passdb_handle_credentials(enum passdb_credentials credentials, + const char *user, const char *password, + const char *scheme, + lookup_credentials_callback_t *callback, + struct auth_request *auth_request) +{ + const char *wanted_scheme; + + if (credentials == PASSDB_CREDENTIALS_CRYPT) { + /* anything goes */ + if (password != NULL) + password = t_strdup_printf("{%s}%s", scheme, password); + callback(password, auth_request); + return; + } + + if (password != NULL) { + wanted_scheme = passdb_credentials_to_str(credentials); + if (strcasecmp(scheme, wanted_scheme) != 0) { + if (verbose) { + i_info("password(%s): Requested %s scheme, " + "but we have only %s", user, + wanted_scheme, scheme); + } + password = NULL; + } + } + + callback(password, auth_request); +} + void passdb_init(void) { const char *name, *args;
--- a/src/auth/passdb.h Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/passdb.h Tue Feb 18 21:11:26 2003 +0200 @@ -43,7 +43,11 @@ lookup_credentials_callback_t *callback); }; -const char *passdb_credentials_to_str(enum passdb_credentials credentials); +void passdb_handle_credentials(enum passdb_credentials credentials, + const char *user, const char *password, + const char *scheme, + lookup_credentials_callback_t *callback, + struct auth_request *auth_request); extern struct passdb_module *passdb;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/auth/password-verify.c Tue Feb 18 21:11:26 2003 +0200 @@ -0,0 +1,60 @@ +/* Copyright (C) 2003 Timo Sirainen */ + +#include "lib.h" +#include "hex-binary.h" +#include "md5.h" +#include "mycrypt.h" +#include "password-verify.h" + +int password_verify(const char *plaintext, const char *password, + const char *scheme, const char *user) +{ + unsigned char digest[16]; + const char *realm, *str; + + if (password == NULL) + return 0; + + if (strcasecmp(scheme, "CRYPT") == 0) + return strcmp(mycrypt(password, plaintext), plaintext) == 0; + + if (strcasecmp(scheme, "PLAIN") == 0) + return strcmp(password, plaintext) == 0; + + if (strcasecmp(scheme, "DIGEST-MD5") == 0) { + /* user:realm:passwd */ + realm = strchr(user, '@'); + if (realm != NULL) realm++; else realm = ""; + + str = t_strconcat(t_strcut(user, '@'), ":", realm, ":", + plaintext, NULL); + md5_get_digest(str, strlen(str), digest); + str = binary_to_hex(digest, sizeof(digest)); + + return strcasecmp(str, password) == 0; + } + + if (strcasecmp(scheme, "PLAIN-MD5") == 0) { + md5_get_digest(plaintext, strlen(plaintext), digest); + str = binary_to_hex(digest, sizeof(digest)); + return strcasecmp(str, password) == 0; + } + + return -1; +} + +const char *password_get_scheme(const char **password) +{ + const char *p, *scheme; + + if (*password == NULL || **password != '{') + return NULL; + + p = strchr(*password, '}'); + if (p == NULL) + return NULL; + + scheme = t_strdup_until(*password + 1, p); + *password = p + 1; + return scheme; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/auth/password-verify.h Tue Feb 18 21:11:26 2003 +0200 @@ -0,0 +1,11 @@ +#ifndef __PASSWORD_VERIFY_H +#define __PASSWORD_VERIFY_H + +/* Returns 1 = matched, 0 = didn't match, -1 = unknown scheme */ +int password_verify(const char *plaintext, const char *password, + const char *scheme, const char *user); + +/* Extracts scheme from password, or returns NULL if it isn't found. */ +const char *password_get_scheme(const char **password); + +#endif
--- a/src/auth/userdb-ldap.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/userdb-ldap.c Tue Feb 18 21:11:26 2003 +0200 @@ -137,17 +137,14 @@ t_pop(); } -static void userdb_ldap_lookup(const char *user, const char *realm, - userdb_callback_t *callback, void *context) +static void userdb_ldap_lookup(const char *user, userdb_callback_t *callback, + void *context) { struct ldap_connection *conn = userdb_ldap_conn->conn; struct userdb_ldap_request *request; const char *filter; string_t *str; - if (realm != NULL) - user = t_strconcat(user, "@", realm, NULL); - user = ldap_escape(user); if (conn->set.user_filter == NULL) { filter = t_strdup_printf("(&(objectClass=posixAccount)(%s=%s))",
--- a/src/auth/userdb-passwd-file.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/userdb-passwd-file.c Tue Feb 18 21:11:26 2003 +0200 @@ -11,13 +11,13 @@ struct passwd_file *userdb_pwf = NULL; -static void passwd_file_lookup(const char *user, const char *realm, - userdb_callback_t *callback, void *context) +static void passwd_file_lookup(const char *user, userdb_callback_t *callback, + void *context) { struct user_data data; struct passwd_user *pu; - pu = db_passwd_file_lookup(userdb_pwf, user, realm); + pu = db_passwd_file_lookup(userdb_pwf, user); if (pu == NULL) { callback(NULL, context); return; @@ -27,8 +27,7 @@ data.uid = pu->uid; data.gid = pu->gid; - data.virtual_user = realm == NULL ? user : - t_strconcat(user, "@", realm, NULL); + data.virtual_user = user; data.home = pu->home; data.mail = pu->mail;
--- a/src/auth/userdb-passwd.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/userdb-passwd.c Tue Feb 18 21:11:26 2003 +0200 @@ -10,14 +10,12 @@ #include <pwd.h> -static void passwd_lookup(const char *user, const char *realm, - userdb_callback_t *callback, void *context) +static void passwd_lookup(const char *user, userdb_callback_t *callback, + void *context) { struct user_data data; struct passwd *pw; - if (realm != NULL) - user = t_strconcat(user, "@", realm, NULL); pw = getpwnam(user); if (pw == NULL) { if (errno != 0)
--- a/src/auth/userdb-static.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/userdb-static.c Tue Feb 18 21:11:26 2003 +0200 @@ -16,15 +16,12 @@ static gid_t static_gid; static char *static_home_template; -static void static_lookup(const char *user, const char *realm, - userdb_callback_t *callback, void *context) +static void static_lookup(const char *user, userdb_callback_t *callback, + void *context) { struct user_data data; string_t *str; - if (realm != NULL) - user = t_strconcat(user, "@", realm, NULL); - memset(&data, 0, sizeof(data)); data.uid = static_uid; data.gid = static_gid;
--- a/src/auth/userdb-vpopmail.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/userdb-vpopmail.c Tue Feb 18 21:11:26 2003 +0200 @@ -11,31 +11,25 @@ #include "userdb.h" #include "userdb-vpopmail.h" -struct vqpasswd *vpopmail_lookup_vqp(const char *user, const char *realm, +struct vqpasswd *vpopmail_lookup_vqp(const char *user, char vpop_user[VPOPMAIL_LIMIT], char vpop_domain[VPOPMAIL_LIMIT]) { struct vqpasswd *vpw; - if (realm != NULL) { - if (strlen(user) >= VPOPMAIL_LIMIT || - strlen(realm) >= VPOPMAIL_LIMIT) - return NULL; - } else { - /* vpop_user must be zero-filled or parse_email() leaves an - extra character after the user name. we'll fill vpop_domain - as well just to be sure... */ - memset(vpop_user, '\0', VPOPMAIL_LIMIT); - memset(vpop_domain, '\0', VPOPMAIL_LIMIT); + /* vpop_user must be zero-filled or parse_email() leaves an + extra character after the user name. we'll fill vpop_domain + as well just to be sure... */ + memset(vpop_user, '\0', VPOPMAIL_LIMIT); + memset(vpop_domain, '\0', VPOPMAIL_LIMIT); - if (parse_email(t_strdup_noconst(user), vpop_user, vpop_domain, - VPOPMAIL_LIMIT-1) < 0) { - if (verbose) { - i_info("vpopmail(%s): parse_email() failed", - user); - } - return NULL; + if (parse_email(t_strdup_noconst(user), vpop_user, vpop_domain, + VPOPMAIL_LIMIT-1) < 0) { + if (verbose) { + i_info("vpopmail(%s): parse_email() failed", + user); } + return NULL; } vpw = vauth_getpw(vpop_user, vpop_domain); @@ -50,8 +44,8 @@ #ifdef USERDB_VPOPMAIL -static void vpopmail_lookup(const char *user, const char *realm, - userdb_callback_t *callback, void *context) +static void vpopmail_lookup(const char *user, userdb_callback_t *callback, + void *context) { char vpop_user[VPOPMAIL_LIMIT], vpop_domain[VPOPMAIL_LIMIT]; struct vqpasswd *vpw; @@ -60,10 +54,7 @@ gid_t gid; pool_t pool; - if (realm != NULL) - user = t_strconcat(user, "@", realm, NULL); - - vpw = vpopmail_lookup_vqp(user, realm, vpop_user, vpop_domain); + vpw = vpopmail_lookup_vqp(user, vpop_user, vpop_domain); if (vpw == NULL) { callback(NULL, context); return;
--- a/src/auth/userdb-vpopmail.h Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/userdb-vpopmail.h Tue Feb 18 21:11:26 2003 +0200 @@ -10,7 +10,7 @@ overflows. */ #define VPOPMAIL_LIMIT 81 -struct vqpasswd *vpopmail_lookup_vqp(const char *user, const char *realm, +struct vqpasswd *vpopmail_lookup_vqp(const char *user, char vpop_user[VPOPMAIL_LIMIT], char vpop_domain[VPOPMAIL_LIMIT]);
--- a/src/auth/userdb.h Tue Feb 18 21:09:18 2003 +0200 +++ b/src/auth/userdb.h Tue Feb 18 21:11:26 2003 +0200 @@ -19,8 +19,8 @@ void (*init)(const char *args); void (*deinit)(void); - void (*lookup)(const char *user, const char *realm, - userdb_callback_t *callback, void *context); + void (*lookup)(const char *user, userdb_callback_t *callback, + void *context); }; extern struct userdb_module *userdb;
--- a/src/login-common/auth-common.c Tue Feb 18 21:09:18 2003 +0200 +++ b/src/login-common/auth-common.c Tue Feb 18 21:11:26 2003 +0200 @@ -24,7 +24,7 @@ const unsigned char *data, struct client *client, master_callback_t *master_callback, const char **error) { - const char *user, *realm; + const char *user; *error = NULL; @@ -55,11 +55,9 @@ client->auth_request = NULL; user = auth_login_get_str(reply, data, reply->username_idx); - realm = auth_login_get_str(reply, data, reply->realm_idx); i_free(client->virtual_user); - client->virtual_user = realm == NULL ? - i_strdup(user) : i_strconcat(user, "@", realm, NULL); + client->virtual_user = i_strdup(user); master_request_imap(client, master_callback, request->conn->pid, request->id);