Mercurial > dovecot > core-2.2
changeset 1075:f1401fa7ab03 HEAD
auth process fixes, LDAP seems to be working (with the kludge define or
fixed libldap)
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 02 Feb 2003 02:08:28 +0200 |
parents | 85e2b65cc780 |
children | e22f21b9ec49 |
files | src/auth/auth-login-interface.h src/auth/db-ldap.c src/auth/db-ldap.h src/auth/mech-digest-md5.c src/auth/mech-plain.c src/auth/mech.c src/auth/mech.h 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.h src/auth/userdb-ldap.c src/auth/userdb.c src/auth/userdb.h |
diffstat | 16 files changed, 146 insertions(+), 99 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/auth-login-interface.h Sat Feb 01 13:54:42 2003 +0200 +++ b/src/auth/auth-login-interface.h Sun Feb 02 02:08:28 2003 +0200 @@ -11,6 +11,11 @@ AUTH_MECH_COUNT }; +enum auth_protocol { + AUTH_PROTOCOL_IMAP = 0x01, + AUTH_PROTOCOL_POP3 = 0x02 +}; + enum auth_login_request_type { AUTH_LOGIN_REQUEST_NEW = 1, AUTH_LOGIN_REQUEST_CONTINUE @@ -38,7 +43,8 @@ enum auth_login_request_type type; /* AUTH_LOGIN_REQUEST_NEW */ unsigned int id; /* unique ID for the request */ - enum auth_mech mech; + enum auth_mech mech; + enum auth_protocol protocol; }; /* Continue authentication request */
--- a/src/auth/db-ldap.c Sat Feb 01 13:54:42 2003 +0200 +++ b/src/auth/db-ldap.c Sun Feb 02 02:08:28 2003 +0200 @@ -6,6 +6,7 @@ #if defined(PASSDB_LDAP) || defined(USERDB_LDAP) #include "common.h" +#include "network.h" #include "ioloop.h" #include "hash.h" #include "settings.h" @@ -18,8 +19,8 @@ static struct setting_def setting_defs[] = { DEF(SET_STR, hosts), - DEF(SET_STR, user), - DEF(SET_STR, pass), + DEF(SET_STR, dn), + DEF(SET_STR, dnpass), DEF(SET_STR, deref), DEF(SET_STR, base), DEF(SET_STR, attrs), @@ -28,8 +29,8 @@ struct ldap_settings default_ldap_settings = { MEMBER(hosts) "localhost", - MEMBER(user) NULL, - MEMBER(pass) NULL, + MEMBER(dn) NULL, + MEMBER(dnpass) NULL, MEMBER(deref) "never", MEMBER(base) NULL, MEMBER(attrs) NULL, @@ -100,6 +101,11 @@ for (;;) { memset(&timeout, 0, sizeof(timeout)); +#ifdef OPENLDAP_ASYNC_WORKAROUND + /* we may block, but at least we work */ + timeout.tv_sec = 2; +#endif + ret = ldap_result(conn->ld, LDAP_RES_ANY, 1, &timeout, &res); if (ret <= 0) { if (ret < 0) { @@ -156,7 +162,7 @@ /* NOTE: we use blocking connect, we couldn't do anything anyway until it's done. */ - ret = ldap_simple_bind_s(conn->ld, conn->set.user, conn->set.pass); + ret = ldap_simple_bind_s(conn->ld, conn->set.dn, conn->set.dnpass); if (ret != LDAP_SUCCESS) { i_error("LDAP: ldap_simple_bind_s() failed: %s", ldap_err2string(ret)); @@ -172,6 +178,7 @@ ldap_err2string(ret)); } + net_set_nonblock(fd, TRUE); conn->io = io_add(fd, IO_READ, ldap_input, conn); return TRUE; } @@ -239,10 +246,10 @@ conn->set = default_ldap_settings; settings_read(config_path, parse_setting, conn); - if (conn->set.user == NULL) + /*if (conn->set.dnuser == NULL) i_fatal("LDAP: No user given"); - if (conn->set.pass == NULL) - i_fatal("LDAP: No password given"); + if (conn->set.dnpass == NULL) + i_fatal("LDAP: No password given");*/ if (conn->set.base == NULL) i_fatal("LDAP: No base given");
--- a/src/auth/db-ldap.h Sat Feb 01 13:54:42 2003 +0200 +++ b/src/auth/db-ldap.h Sun Feb 02 02:08:28 2003 +0200 @@ -12,8 +12,8 @@ struct ldap_settings { const char *hosts; - const char *user; - const char *pass; + const char *dn; + const char *dnpass; const char *deref; const char *base; const char *attrs;
--- a/src/auth/mech-digest-md5.c Sat Feb 01 13:54:42 2003 +0200 +++ b/src/auth/mech-digest-md5.c Sun Feb 02 02:08:28 2003 +0200 @@ -520,11 +520,13 @@ return !failed; } -static void credentials_callback(const char *result, void *context) +static void credentials_callback(const char *result, + struct auth_request *request) { - struct digest_auth_request *auth = context; + struct digest_auth_request *auth = + (struct digest_auth_request *) request; - mech_auth_finish(&auth->auth_request, verify_credentials(auth, result)); + mech_auth_finish(request, verify_credentials(auth, result)); } static int @@ -559,9 +561,14 @@ auth_request->id = request->id; auth_request->callback = callback; - passdb->lookup_credentials(auth->username, auth->realm, + passdb->lookup_credentials(&auth->auth_request, PASSDB_CREDENTIALS_DIGEST_MD5, - credentials_callback, auth); + credentials_callback); + + reply.data_size = strlen(auth->rspauth); + callback(&reply, auth->rspauth, conn); + auth->authenticated = TRUE; + return TRUE; } if (error == NULL)
--- a/src/auth/mech-plain.c Sat Feb 01 13:54:42 2003 +0200 +++ b/src/auth/mech-plain.c Sun Feb 02 02:08:28 2003 +0200 @@ -6,11 +6,10 @@ #include "mech.h" #include "passdb.h" -static void verify_callback(enum passdb_result result, void *context) +static void verify_callback(enum passdb_result result, + struct auth_request *request) { - struct auth_request *auth_request = context; - - mech_auth_finish(auth_request, result == PASSDB_RESULT_OK); + mech_auth_finish(request, result == PASSDB_RESULT_OK); } static int @@ -52,8 +51,7 @@ if (auth_request->realm != NULL) auth_request->realm++; - passdb->verify_plain(auth_request->user, auth_request->realm, - pass, verify_callback, auth_request); + passdb->verify_plain(auth_request, pass, verify_callback); /* make sure it's cleared */ safe_memset(pass, 0, strlen(pass));
--- a/src/auth/mech.c Sat Feb 01 13:54:42 2003 +0200 +++ b/src/auth/mech.c Sun Feb 02 02:08:28 2003 +0200 @@ -90,6 +90,7 @@ } if (auth_request != NULL) { + auth_request->protocol = request->protocol; hash_insert(conn->auth_requests, POINTER_CAST(request->id), auth_request); }
--- a/src/auth/mech.h Sat Feb 01 13:54:42 2003 +0200 +++ b/src/auth/mech.h Sun Feb 02 02:08:28 2003 +0200 @@ -14,6 +14,7 @@ struct login_connection *conn; unsigned int id; + enum auth_protocol protocol; mech_callback_t *callback; int (*auth_continue)(struct login_connection *conn,
--- a/src/auth/passdb-pam.c Sat Feb 01 13:54:42 2003 +0200 +++ b/src/auth/passdb-pam.c Sun Feb 02 02:08:28 2003 +0200 @@ -195,16 +195,19 @@ } static void -pam_verify_plain(const char *user, const char *realm, const char *password, - verify_plain_callback_t *callback, void *context) +pam_verify_plain(struct auth_request *request, const char *password, + verify_plain_callback_t *callback) { pam_handle_t *pamh; + const char *user; struct pam_userpass userpass; struct pam_conv conv; int status, status2; - if (realm != NULL) - user = t_strconcat(user, "@", realm, NULL); + 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; @@ -218,7 +221,7 @@ i_info("PAM: pam_start(%s) failed: %s", user, pam_strerror(pamh, status)); } - callback(PASSDB_RESULT_INTERNAL_FAILURE, context); + callback(PASSDB_RESULT_INTERNAL_FAILURE, request); return; } @@ -226,13 +229,13 @@ if ((status2 = pam_end(pamh, status)) != PAM_SUCCESS) { i_error("pam_end(%s) failed: %s", user, pam_strerror(pamh, status2)); - callback(PASSDB_RESULT_INTERNAL_FAILURE, context); + callback(PASSDB_RESULT_INTERNAL_FAILURE, request); return; } /* FIXME: check for PASSDB_RESULT_UNKNOWN_USER somehow */ callback(status == PAM_SUCCESS ? PASSDB_RESULT_OK : - PASSDB_RESULT_PASSWORD_MISMATCH, context); + PASSDB_RESULT_PASSWORD_MISMATCH, request); } static void pam_init(const char *args)
--- a/src/auth/passdb-passwd-file.c Sat Feb 01 13:54:42 2003 +0200 +++ b/src/auth/passdb-passwd-file.c Sun Feb 02 02:08:28 2003 +0200 @@ -16,29 +16,28 @@ struct passwd_file *passdb_pwf = NULL; static void -passwd_file_verify_plain(const char *user, const char *realm, - const char *password, - verify_plain_callback_t *callback, void *context) +passwd_file_verify_plain(struct auth_request *request, const char *password, + verify_plain_callback_t *callback) { struct passwd_user *pu; unsigned char digest[16]; const char *str; - pu = db_passwd_file_lookup(passdb_pwf, user, realm); + pu = db_passwd_file_lookup(passdb_pwf, request->user, request->realm); if (pu == NULL) { - callback(PASSDB_RESULT_USER_UNKNOWN, context); + callback(PASSDB_RESULT_USER_UNKNOWN, request); return; } switch (pu->password_type) { case PASSWORD_NONE: - callback(PASSDB_RESULT_PASSWORD_MISMATCH, context); + callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); return; case PASSWORD_DES: if (strcmp(mycrypt(password, pu->password), pu->password) == 0) { - callback(PASSDB_RESULT_OK, context); + callback(PASSDB_RESULT_OK, request); return; } @@ -46,7 +45,7 @@ i_info("passwd-file(%s): DES password mismatch", pu->user_realm); } - callback(PASSDB_RESULT_PASSWORD_MISMATCH, context); + callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); return; case PASSWORD_MD5: @@ -54,7 +53,7 @@ str = binary_to_hex(digest, sizeof(digest)); if (strcmp(str, pu->password) == 0) { - callback(PASSDB_RESULT_OK, context); + callback(PASSDB_RESULT_OK, request); return; } @@ -62,7 +61,7 @@ i_info("passwd-file(%s): MD5 password mismatch", pu->user_realm); } - callback(PASSDB_RESULT_PASSWORD_MISMATCH, context); + callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); return; case PASSWORD_DIGEST_MD5: @@ -75,7 +74,7 @@ str = binary_to_hex(digest, sizeof(digest)); if (strcmp(str, pu->password) == 0) { - callback(PASSDB_RESULT_OK, context); + callback(PASSDB_RESULT_OK, request); return; } @@ -84,7 +83,7 @@ pu->user_realm); } - callback(PASSDB_RESULT_PASSWORD_MISMATCH, context); + callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); return; } @@ -92,30 +91,29 @@ } static void -passwd_file_lookup_credentials(const char *user, const char *realm, +passwd_file_lookup_credentials(struct auth_request *request, enum passdb_credentials credentials, - lookup_credentials_callback_t *callback, - void *context) + lookup_credentials_callback_t *callback) { struct passwd_user *pu; - pu = db_passwd_file_lookup(passdb_pwf, user, realm); + pu = db_passwd_file_lookup(passdb_pwf, request->user, request->realm); if (pu == NULL) { - callback(NULL, context); + callback(NULL, request); return; } if (pu->password_type == PASSWORD_NONE) { if (verbose) i_info("passwd-file(%s): No password", pu->user_realm); - callback(NULL, context); + callback(NULL, request); return; } switch (credentials) { case PASSDB_CREDENTIALS_DIGEST_MD5: if (pu->password_type == PASSWORD_DIGEST_MD5) { - callback(pu->password, context); + callback(pu->password, request); return; } @@ -123,14 +121,14 @@ i_info("passwd-file(%s): No DIGEST-MD5 password", pu->user_realm); } - callback(NULL, context); + callback(NULL, request); return; default: if (verbose) { i_info("passwd-file(%s): Unsupported credentials %u", pu->user_realm, (unsigned int)credentials); } - callback(NULL, context); + callback(NULL, request); return; } }
--- a/src/auth/passdb-passwd.c Sat Feb 01 13:54:42 2003 +0200 +++ b/src/auth/passdb-passwd.c Sun Feb 02 02:08:28 2003 +0200 @@ -13,21 +13,25 @@ #include <pwd.h> static void -passwd_verify_plain(const char *user, const char *realm, const char *password, - verify_plain_callback_t *callback, void *context) +passwd_verify_plain(struct auth_request *request, const char *password, + verify_plain_callback_t *callback) { + const char *user; struct passwd *pw; int result; - if (realm != NULL) - user = t_strconcat(user, "@", realm, NULL); + if (request->realm == NULL) + user = request->user; + else + user = t_strconcat(request->user, "@", request->realm, NULL); + pw = getpwnam(user); if (pw == NULL) { if (errno != 0) i_error("getpwnam(%s) failed: %m", user); else if (verbose) i_info("passwd(%s): unknown user", user); - callback(PASSDB_RESULT_USER_UNKNOWN, context); + callback(PASSDB_RESULT_USER_UNKNOWN, request); return; } @@ -36,7 +40,7 @@ i_info("passwd(%s): invalid password field '%s'", user, pw->pw_passwd); } - callback(PASSDB_RESULT_USER_DISABLED, context); + callback(PASSDB_RESULT_USER_DISABLED, request); return; } @@ -49,11 +53,11 @@ if (!result) { if (verbose) i_info("passwd(%s): password mismatch", user); - callback(PASSDB_RESULT_PASSWORD_MISMATCH, context); + callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); return; } - callback(PASSDB_RESULT_OK, context); + callback(PASSDB_RESULT_OK, request); } static void passwd_deinit(void)
--- a/src/auth/passdb-shadow.c Sat Feb 01 13:54:42 2003 +0200 +++ b/src/auth/passdb-shadow.c Sun Feb 02 02:08:28 2003 +0200 @@ -13,21 +13,25 @@ #include <shadow.h> static void -shadow_verify_plain(const char *user, const char *realm, const char *password, - verify_plain_callback_t *callback, void *context) +shadow_verify_plain(struct auth_request *request, const char *password, + verify_plain_callback_t *callback) { + const char *user; struct spwd *spw; int result; - if (realm != NULL) - user = t_strconcat(user, "@", realm, NULL); + if (request->realm == NULL) + user = request->user; + else + user = t_strconcat(request->user, "@", request->realm, NULL); + spw = getspnam(user); if (spw == NULL) { if (errno != 0) i_error("getspnam(%s) failed: %m", user); else if (verbose) i_info("shadow(%s): unknown user", user); - callback(PASSDB_RESULT_USER_UNKNOWN, context); + callback(PASSDB_RESULT_USER_UNKNOWN, request); return; } @@ -36,7 +40,7 @@ i_info("shadow(%s): invalid password field '%s'", user, spw->sp_pwdp); } - callback(PASSDB_RESULT_USER_DISABLED, context); + callback(PASSDB_RESULT_USER_DISABLED, request); return; } @@ -49,11 +53,11 @@ if (!result) { if (verbose) i_info("shadow(%s): password mismatch", user); - callback(PASSDB_RESULT_PASSWORD_MISMATCH, context); + callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); return; } - callback(PASSDB_RESULT_OK, context); + callback(PASSDB_RESULT_OK, request); } static void shadow_deinit(void)
--- a/src/auth/passdb-vpopmail.c Sat Feb 01 13:54:42 2003 +0200 +++ b/src/auth/passdb-vpopmail.c Sun Feb 02 02:08:28 2003 +0200 @@ -15,23 +15,31 @@ #include "userdb-vpopmail.h" static void -vpopmail_verify_plain(const char *user, const char *realm, const char *password, - verify_plain_callback_t *callback, void *context) +vpopmail_verify_plain(struct auth_request *request, const char *password, + verify_plain_callback_t *callback) { char vpop_user[VPOPMAIL_LIMIT], vpop_domain[VPOPMAIL_LIMIT]; struct vqpasswd *vpw; int result; - vpw = vpopmail_lookup_vqp(user, realm, vpop_user, vpop_domain); + vpw = vpopmail_lookup_vqp(request->user, request->realm, + vpop_user, vpop_domain); if (vpw == NULL) { - callback(PASSDB_RESULT_USER_UNKNOWN, context); + callback(PASSDB_RESULT_USER_UNKNOWN, request); return; } - if ((vpw->pw_gid & NO_IMAP) != 0) { - if (verbose) - i_info("vpopmail(%s): IMAP disabled", user); - callback(PASSDB_RESULT_USER_DISABLED, context); + if (((vpw->pw_gid & NO_IMAP) != 0 && + request->protocol == AUTH_PROTOCOL_IMAP) || + ((vpw->pw_gid & NO_POP) != 0 && + request->protocol == AUTH_PROTOCOL_POP3)) { + if (verbose) { + i_info("vpopmail(%s@%s): %s disabled", + vpop_user, vpop_domain, + request->protocol == AUTH_PROTOCOL_IMAP ? + "IMAP" : "POP3"); + } + callback(PASSDB_RESULT_USER_DISABLED, request); return; } @@ -40,13 +48,16 @@ safe_memset(vpw->pw_passwd, 0, strlen(vpw->pw_passwd)); if (!result) { - if (verbose) - i_info("vpopmail(%s): password mismatch", user); - callback(PASSDB_RESULT_PASSWORD_MISMATCH, context); + if (verbose) { + i_info("vpopmail(%s@%s): password mismatch", + vpop_user, vpop_domain); + } + + callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); return; } - callback(PASSDB_RESULT_OK, context); + callback(PASSDB_RESULT_OK, request); } static void vpopmail_deinit(void)
--- a/src/auth/passdb.h Sat Feb 01 13:54:42 2003 +0200 +++ b/src/auth/passdb.h Sun Feb 02 02:08:28 2003 +0200 @@ -1,6 +1,8 @@ #ifndef __PASSDB_H #define __PASSDB_H +#include "mech.h" + #define IS_VALID_PASSWD(pass) \ ((pass)[0] != '\0' && (pass)[0] != '*' && (pass)[0] != '!') @@ -18,24 +20,24 @@ PASSDB_RESULT_OK = 1, }; -typedef void verify_plain_callback_t(enum passdb_result result, void *context); -typedef void lookup_credentials_callback_t(const char *result, void *context); +typedef void verify_plain_callback_t(enum passdb_result result, + struct auth_request *request); +typedef void lookup_credentials_callback_t(const char *result, + struct auth_request *request); struct passdb_module { void (*init)(const char *args); void (*deinit)(void); /* Check if plaintext password matches */ - void (*verify_plain)(const char *user, const char *realm, - const char *password, - verify_plain_callback_t *callback, void *context); + void (*verify_plain)(struct auth_request *request, const char *password, + verify_plain_callback_t *callback); /* Return authentication credentials. Type is authentication mechanism specific value that is requested. */ - void (*lookup_credentials)(const char *user, const char *realm, + void (*lookup_credentials)(struct auth_request *request, enum passdb_credentials credentials, - lookup_credentials_callback_t *callback, - void *context); + lookup_credentials_callback_t *callback); }; const char *passdb_credentials_to_str(enum passdb_credentials credentials);
--- a/src/auth/userdb-ldap.c Sat Feb 01 13:54:42 2003 +0200 +++ b/src/auth/userdb-ldap.c Sun Feb 02 02:08:28 2003 +0200 @@ -60,7 +60,7 @@ return; } - switch (i) { + switch (conn->attrs[i]) { case ATTR_VIRTUAL_USER: user->virtual_user = t_strdup(value); break; @@ -110,11 +110,10 @@ attr = ldap_first_attribute(conn->ld, entry, &ber); while (attr != NULL) { vals = ldap_get_values(conn->ld, entry, attr); - if (vals != NULL && vals[0] != NULL && vals[1] == NULL) { + if (vals != NULL && vals[0] != NULL && vals[1] == NULL) parse_attr(userdb_ldap_conn, &user, attr, vals[0]); - ldap_value_free(vals); - ldap_memfree(attr); - } + ldap_value_free(vals); + ldap_memfree(attr); attr = ldap_next_attribute(conn->ld, entry, ber); } @@ -144,7 +143,7 @@ user = t_strconcat(user, "@", realm, NULL); if (conn->set.filter == NULL) { - filter = t_strdup_printf("(%s=%s)", + filter = t_strdup_printf("(&(objectClass=posixAccount)(%s=%s))", userdb_ldap_conn->attr_names[ATTR_VIRTUAL_USER], user); } else { filter = t_strdup_printf("(&%s(%s=%s))", conn->set.filter, @@ -163,14 +162,15 @@ static void userdb_ldap_init(const char *args) { - struct userdb_ldap_connection *conn; + struct ldap_connection *conn; + + userdb_ldap_conn = i_new(struct userdb_ldap_connection, 1); + userdb_ldap_conn->conn = conn = db_ldap_init(args); - conn = i_new(struct userdb_ldap_connection, 1); - conn->conn = db_ldap_init(args); - - db_ldap_set_attrs(conn->conn, conn->conn->set.attrs ? - conn->conn->set.attrs : DEFAULT_ATTRIBUTES, - &conn->attrs, &conn->attr_names); + db_ldap_set_attrs(conn, conn->set.attrs ? + conn->set.attrs : DEFAULT_ATTRIBUTES, + &userdb_ldap_conn->attrs, + &userdb_ldap_conn->attr_names); } static void userdb_ldap_deinit(void)
--- a/src/auth/userdb.c Sat Feb 01 13:54:42 2003 +0200 +++ b/src/auth/userdb.c Sun Feb 02 02:08:28 2003 +0200 @@ -36,6 +36,10 @@ if (strcasecmp(name, "vpopmail") == 0) userdb = &userdb_vpopmail; #endif +#ifdef USERDB_LDAP + if (strcasecmp(name, "ldap") == 0) + userdb = &userdb_ldap; +#endif if (userdb == NULL) i_fatal("Unknown userdb type '%s'", name);
--- a/src/auth/userdb.h Sat Feb 01 13:54:42 2003 +0200 +++ b/src/auth/userdb.h Sun Feb 02 02:08:28 2003 +0200 @@ -29,6 +29,7 @@ extern struct userdb_module userdb_passwd; extern struct userdb_module userdb_passwd_file; extern struct userdb_module userdb_vpopmail; +extern struct userdb_module userdb_ldap; void userdb_init(void); void userdb_deinit(void);