[dovecot-cvs] dovecot/src/auth auth-request.c, 1.31,
1.32 auth-worker-client.c, 1.14, 1.15 passdb-blocking.c, 1.7,
1.8 passdb-cache.c, 1.12, 1.13 passdb-cache.h, 1.4,
1.5 passdb-ldap.c, 1.32, 1.33 passdb-passwd-file.c, 1.19,
1.20 passdb-sql.c, 1.20, 1.21 passdb.c, 1.36, 1.37 passdb.h,
1.27, 1.28
cras at dovecot.org
cras at dovecot.org
Sun Oct 16 15:03:39 EEST 2005
- Previous message: [dovecot-cvs] dovecot/src/lib failures.c,1.26,1.27
- Next message: [dovecot-cvs] dovecot/src/auth auth-request.c, 1.32,
1.33 passdb-bsdauth.c, 1.11, 1.12 passdb-pam.c, 1.27,
1.28 passdb-passwd-file.c, 1.20, 1.21 passdb-passwd.c, 1.14,
1.15 passdb-shadow.c, 1.15, 1.16 passdb-vpopmail.c, 1.21, 1.22
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /var/lib/cvs/dovecot/src/auth
In directory talvi:/tmp/cvs-serv1340
Modified Files:
auth-request.c auth-worker-client.c passdb-blocking.c
passdb-cache.c passdb-cache.h passdb-ldap.c
passdb-passwd-file.c passdb-sql.c passdb.c passdb.h
Log Message:
Fixes and cleanups to credentials handling. Also fixed auth caching to work
more correctly in case of internal failures.
Index: auth-request.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-request.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -d -r1.31 -r1.32
--- auth-request.c 7 Oct 2005 10:43:12 -0000 1.31
+++ auth-request.c 16 Oct 2005 12:03:37 -0000 1.32
@@ -29,6 +29,7 @@
request->refcount = 1;
request->created = ioloop_time;
+ request->credentials = -1;
request->auth = auth;
request->mech = mech;
@@ -51,6 +52,7 @@
auth_request->auth = auth;
auth_request->passdb = auth->passdbs;
auth_request->userdb = auth->userdbs;
+ auth_request->credentials = -1;
return auth_request;
}
@@ -163,6 +165,21 @@
const char *extra_fields;
string_t *str;
+ switch (result) {
+ case PASSDB_RESULT_USER_UNKNOWN:
+ case PASSDB_RESULT_PASSWORD_MISMATCH:
+ case PASSDB_RESULT_OK:
+ case PASSDB_RESULT_SCHEME_NOT_AVAILABLE:
+ /* can be cached */
+ break;
+ case PASSDB_RESULT_USER_DISABLED:
+ /* FIXME: we can't cache this now, or cache lookup would
+ return success. */
+ return;
+ case PASSDB_RESULT_INTERNAL_FAILURE:
+ i_unreached();
+ }
+
extra_fields = request->extra_fields == NULL ? NULL :
auth_stream_reply_export(request->extra_fields);
i_assert(extra_fields == NULL ||
@@ -214,69 +231,84 @@
auth_cache_insert(passdb_cache, request, passdb->cache_key, str_c(str));
}
+static int
+auth_request_handle_passdb_callback(enum passdb_result *result,
+ struct auth_request *request)
+{
+ if (request->passdb_password != NULL) {
+ safe_memset(request->passdb_password, 0,
+ strlen(request->passdb_password));
+ }
+
+ if (request->passdb->deny && *result != PASSDB_RESULT_USER_UNKNOWN) {
+ /* deny passdb. we can get through this step only if the
+ lookup returned that user doesn't exist in it. internal
+ errors are fatal here. */
+ if (*result != PASSDB_RESULT_INTERNAL_FAILURE) {
+ auth_request_log_info(request, "passdb",
+ "User found from deny passdb");
+ *result = PASSDB_RESULT_USER_DISABLED;
+ }
+ } else if (*result != PASSDB_RESULT_OK &&
+ *result != PASSDB_RESULT_USER_DISABLED &&
+ request->passdb->next != NULL) {
+ /* try next passdb. */
+ if (*result == PASSDB_RESULT_INTERNAL_FAILURE) {
+ /* remember that we have had an internal failure. at
+ the end return internal failure if we couldn't
+ successfully login. */
+ request->passdb_internal_failure = TRUE;
+ }
+ if (request->extra_fields != NULL)
+ auth_stream_reply_reset(request->extra_fields);
+
+ return FALSE;
+ } else if (request->passdb_internal_failure &&
+ *result != PASSDB_RESULT_OK) {
+ /* one of the passdb lookups returned internal failure.
+ it may have had the correct password, so return internal
+ failure instead of plain failure. */
+ *result = PASSDB_RESULT_INTERNAL_FAILURE;
+ }
+
+ return TRUE;
+}
+
void auth_request_verify_plain_callback(enum passdb_result result,
struct auth_request *request)
{
- const char *cache_key;
-
i_assert(request->state == AUTH_REQUEST_STATE_PASSDB);
request->state = AUTH_REQUEST_STATE_MECH_CONTINUE;
- auth_request_save_cache(request, result);
-
- cache_key = passdb_cache == NULL ? NULL :
- request->passdb->passdb->cache_key;
- if (result == PASSDB_RESULT_INTERNAL_FAILURE && cache_key != NULL) {
+ if (result != PASSDB_RESULT_INTERNAL_FAILURE)
+ auth_request_save_cache(request, result);
+ else {
/* lookup failed. if we're looking here only because the
request was expired in cache, fallback to using cached
expired record. */
+ const char *cache_key = request->passdb->passdb->cache_key;
+
if (passdb_cache_verify_plain(request, cache_key,
request->mech_password,
&result, TRUE)) {
- request->private_callback.verify_plain(result, request);
- safe_memset(request->mech_password, 0,
- strlen(request->mech_password));
- return;
+ auth_request_log_info(request, "passdb",
+ "Fallbacking to expired data from cache");
}
}
- if (request->passdb_password != NULL) {
- safe_memset(request->passdb_password, 0,
- strlen(request->passdb_password));
- }
-
- if (result != PASSDB_RESULT_USER_UNKNOWN && request->passdb->deny) {
- /* user found from deny passdb. deny this authentication. */
- auth_request_log_info(request, "passdb",
- "User found from deny passdb");
- result = PASSDB_RESULT_USER_DISABLED;
- } else if (result != PASSDB_RESULT_OK &&
- result != PASSDB_RESULT_USER_DISABLED &&
- request->passdb->next != NULL) {
- /* try next passdb. */
- if (result == PASSDB_RESULT_INTERNAL_FAILURE)
- request->passdb_internal_failure = TRUE;
- if (request->extra_fields != NULL)
- auth_stream_reply_reset(request->extra_fields);
-
- request->state = AUTH_REQUEST_STATE_MECH_CONTINUE;
+ if (!auth_request_handle_passdb_callback(&result, request)) {
+ /* try next passdb */
request->passdb = request->passdb->next;
auth_request_verify_plain(request, request->mech_password,
request->private_callback.verify_plain);
- return;
- } else if (request->passdb_internal_failure &&
- result != PASSDB_RESULT_OK) {
- /* one of the passdb lookups returned internal failure.
- it may have had the correct password, so return internal
- failure instead of plain failure. */
- result = PASSDB_RESULT_INTERNAL_FAILURE;
+ } else {
+ auth_request_ref(request);
+ request->private_callback.verify_plain(result, request);
+ safe_memset(request->mech_password, 0,
+ strlen(request->mech_password));
+ auth_request_unref(request);
}
-
- auth_request_ref(request);
- request->private_callback.verify_plain(result, request);
- safe_memset(request->mech_password, 0, strlen(request->mech_password));
- auth_request_unref(request);
}
void auth_request_verify_plain(struct auth_request *request,
@@ -303,6 +335,7 @@
}
request->state = AUTH_REQUEST_STATE_PASSDB;
+ request->credentials = -1;
if (passdb->blocking)
passdb_blocking_verify_plain(request);
@@ -313,41 +346,45 @@
}
void auth_request_lookup_credentials_callback(enum passdb_result result,
- const char *credentials,
+ const char *password,
struct auth_request *request)
{
- const char *cache_key, *scheme;
+ const char *scheme;
i_assert(request->state == AUTH_REQUEST_STATE_PASSDB);
request->state = AUTH_REQUEST_STATE_MECH_CONTINUE;
- auth_request_save_cache(request, result);
- if (request->passdb_password != NULL) {
- safe_memset(request->passdb_password, 0,
- strlen(request->passdb_password));
- }
-
- cache_key = passdb_cache == NULL ? NULL :
- request->passdb->passdb->cache_key;
- if (result == PASSDB_RESULT_INTERNAL_FAILURE && cache_key != NULL) {
+ if (result != PASSDB_RESULT_INTERNAL_FAILURE)
+ auth_request_save_cache(request, result);
+ else {
/* lookup failed. if we're looking here only because the
request was expired in cache, fallback to using cached
expired record. */
+ const char *cache_key = request->passdb->passdb->cache_key;
+
if (passdb_cache_lookup_credentials(request, cache_key,
- &credentials, &scheme,
- TRUE)) {
- passdb_handle_credentials(credentials != NULL ?
- PASSDB_RESULT_OK : PASSDB_RESULT_USER_UNKNOWN,
- request->credentials, credentials, scheme,
- request->private_callback.lookup_credentials,
- request);
- return;
+ &password, &scheme,
+ &result, TRUE)) {
+ auth_request_log_info(request, "passdb",
+ "Fallbacking to expired data from cache");
+ password = result != PASSDB_RESULT_OK ? NULL :
+ passdb_get_credentials(request, password,
+ scheme);
+ if (password == NULL && result == PASSDB_RESULT_OK)
+ result = PASSDB_RESULT_SCHEME_NOT_AVAILABLE;
}
}
- request->private_callback.lookup_credentials(result, credentials,
- request);
+ if (!auth_request_handle_passdb_callback(&result, request)) {
+ /* try next passdb */
+ request->passdb = request->passdb->next;
+ auth_request_lookup_credentials(request, request->credentials,
+ request->private_callback.lookup_credentials);
+ } else {
+ request->private_callback.
+ lookup_credentials(result, password, request);
+ }
}
void auth_request_lookup_credentials(struct auth_request *request,
@@ -355,18 +392,17 @@
lookup_credentials_callback_t *callback)
{
struct passdb_module *passdb = request->passdb->passdb;
- const char *cache_key, *result, *scheme;
+ const char *cache_key, *password, *scheme;
+ enum passdb_result result;
i_assert(request->state == AUTH_REQUEST_STATE_MECH_CONTINUE);
cache_key = passdb_cache == NULL ? NULL : passdb->cache_key;
if (cache_key != NULL) {
if (passdb_cache_lookup_credentials(request, cache_key,
- &result, &scheme, FALSE)) {
- passdb_handle_credentials(result != NULL ?
- PASSDB_RESULT_OK :
- PASSDB_RESULT_USER_UNKNOWN,
- credentials, result, scheme,
+ &password, &scheme,
+ &result, FALSE)) {
+ passdb_handle_credentials(result, password, scheme,
callback, request);
return;
}
@@ -378,9 +414,13 @@
if (passdb->blocking)
passdb_blocking_lookup_credentials(request);
- else {
- passdb->lookup_credentials(request, credentials,
+ else if (passdb->lookup_credentials != NULL) {
+ passdb->lookup_credentials(request,
auth_request_lookup_credentials_callback);
+ } else {
+ /* this passdb doesn't support credentials */
+ auth_request_lookup_credentials_callback(
+ PASSDB_RESULT_SCHEME_NOT_AVAILABLE, NULL, request);
}
}
Index: auth-worker-client.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-worker-client.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- auth-worker-client.c 7 Aug 2005 11:41:19 -0000 1.14
+++ auth-worker-client.c 16 Oct 2005 12:03:37 -0000 1.15
@@ -221,8 +221,7 @@
}
auth_request->passdb->passdb->
- lookup_credentials(auth_request, credentials,
- lookup_credentials_callback);
+ lookup_credentials(auth_request, lookup_credentials_callback);
}
static void
Index: passdb-blocking.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-blocking.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- passdb-blocking.c 1 Oct 2005 10:52:14 -0000 1.7
+++ passdb-blocking.c 16 Oct 2005 12:03:37 -0000 1.8
@@ -135,8 +135,7 @@
result = PASSDB_RESULT_INTERNAL_FAILURE;
}
- passdb_handle_credentials(result, request->credentials,
- password, scheme,
+ passdb_handle_credentials(result, password, scheme,
auth_request_lookup_credentials_callback,
request);
}
Index: passdb-cache.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-cache.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- passdb-cache.c 7 Oct 2005 10:43:28 -0000 1.12
+++ passdb-cache.c 16 Oct 2005 12:03:37 -0000 1.13
@@ -82,8 +82,10 @@
}
int passdb_cache_lookup_credentials(struct auth_request *request,
- const char *key, const char **result_r,
- const char **scheme_r, int use_expired)
+ const char *key, const char **password_r,
+ const char **scheme_r,
+ enum passdb_result *result_r,
+ int use_expired)
{
const char *value, *const *list;
int expired;
@@ -97,7 +99,8 @@
if (*value == '\0') {
/* negative cache entry */
- *result_r = NULL;
+ *result_r = PASSDB_RESULT_USER_UNKNOWN;
+ *password_r = NULL;
*scheme_r = NULL;
return TRUE;
}
@@ -105,8 +108,9 @@
list = t_strsplit(value, "\t");
list_save(request, list + 1);
- *result_r = list[0];
- *scheme_r = password_get_scheme(result_r);
+ *result_r = PASSDB_RESULT_OK;
+ *password_r = list[0];
+ *scheme_r = password_get_scheme(password_r);
i_assert(*scheme_r != NULL);
return TRUE;
}
Index: passdb-cache.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-cache.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- passdb-cache.h 5 Mar 2005 11:48:13 -0000 1.4
+++ passdb-cache.h 16 Oct 2005 12:03:37 -0000 1.5
@@ -10,8 +10,10 @@
const char *password,
enum passdb_result *result_r, int use_expired);
int passdb_cache_lookup_credentials(struct auth_request *request,
- const char *key, const char **result_r,
- const char **scheme_r, int use_expired);
+ const char *key, const char **password_r,
+ const char **scheme_r,
+ enum passdb_result *result_r,
+ int use_expired);
void passdb_cache_init(void);
void passdb_cache_deinit(void);
Index: passdb-ldap.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-ldap.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- passdb-ldap.c 12 Jul 2005 12:58:47 -0000 1.32
+++ passdb-ldap.c 16 Oct 2005 12:03:37 -0000 1.33
@@ -24,7 +24,6 @@
struct passdb_ldap_request {
struct ldap_request request;
- enum passdb_credentials credentials;
union {
verify_plain_callback_t *verify_plain;
lookup_credentials_callback_t *lookup_credentials;
@@ -139,9 +138,8 @@
/* auth_request_set_field() sets scheme */
i_assert(password == NULL || scheme != NULL);
- if (ldap_request->credentials != -1) {
- passdb_handle_credentials(passdb_result,
- ldap_request->credentials, password, scheme,
+ if (auth_request->credentials != -1) {
+ passdb_handle_credentials(passdb_result, password, scheme,
ldap_request->callback.lookup_credentials,
auth_request);
return;
@@ -210,20 +208,17 @@
struct passdb_ldap_request *ldap_request;
ldap_request = p_new(request->pool, struct passdb_ldap_request, 1);
- ldap_request->credentials = -1;
ldap_request->callback.verify_plain = callback;
ldap_lookup_pass(request, &ldap_request->request);
}
static void ldap_lookup_credentials(struct auth_request *request,
- enum passdb_credentials credentials,
lookup_credentials_callback_t *callback)
{
struct passdb_ldap_request *ldap_request;
ldap_request = p_new(request->pool, struct passdb_ldap_request, 1);
- ldap_request->credentials = credentials;
ldap_request->callback.lookup_credentials = callback;
ldap_lookup_pass(request, &ldap_request->request);
Index: passdb-passwd-file.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-passwd-file.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- passdb-passwd-file.c 22 Jul 2005 12:42:57 -0000 1.19
+++ passdb-passwd-file.c 16 Oct 2005 12:03:37 -0000 1.20
@@ -46,7 +46,6 @@
static void
passwd_file_lookup_credentials(struct auth_request *request,
- enum passdb_credentials credentials,
lookup_credentials_callback_t *callback)
{
struct passwd_user *pu;
@@ -61,8 +60,8 @@
crypted_pass = pu->password;
scheme = password_get_scheme(&crypted_pass);
- passdb_handle_credentials(PASSDB_RESULT_OK, credentials, crypted_pass,
- scheme, callback, request);
+ passdb_handle_credentials(PASSDB_RESULT_OK, crypted_pass, scheme,
+ callback, request);
}
static void passwd_file_init(const char *args)
Index: passdb-sql.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-sql.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- passdb-sql.c 12 Jul 2005 12:58:47 -0000 1.20
+++ passdb-sql.c 16 Oct 2005 12:03:37 -0000 1.21
@@ -19,7 +19,6 @@
struct passdb_sql_request {
struct auth_request *auth_request;
- enum passdb_credentials credentials;
union {
verify_plain_callback_t *verify_plain;
lookup_credentials_callback_t *lookup_credentials;
@@ -92,9 +91,8 @@
/* auth_request_set_field() sets scheme */
i_assert(password == NULL || scheme != NULL);
- if (sql_request->credentials != -1) {
- passdb_handle_credentials(passdb_result,
- sql_request->credentials, password, scheme,
+ if (auth_request->credentials != -1) {
+ passdb_handle_credentials(passdb_result, password, scheme,
sql_request->callback.lookup_credentials,
auth_request);
return;
@@ -144,21 +142,18 @@
sql_request = p_new(request->pool, struct passdb_sql_request, 1);
sql_request->auth_request = request;
- sql_request->credentials = -1;
sql_request->callback.verify_plain = callback;
sql_lookup_pass(sql_request);
}
static void sql_lookup_credentials(struct auth_request *request,
- enum passdb_credentials credentials,
lookup_credentials_callback_t *callback)
{
struct passdb_sql_request *sql_request;
sql_request = p_new(request->pool, struct passdb_sql_request, 1);
sql_request->auth_request = request;
- sql_request->credentials = credentials;
sql_request->callback.lookup_credentials = callback;
sql_lookup_pass(sql_request);
Index: passdb.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- passdb.c 24 Sep 2005 12:55:23 -0000 1.36
+++ passdb.c 16 Oct 2005 12:03:37 -0000 1.37
@@ -74,37 +74,25 @@
return "??";
}
-void passdb_handle_credentials(enum passdb_result result,
- enum passdb_credentials credentials,
- const char *password, const char *scheme,
- lookup_credentials_callback_t *callback,
- struct auth_request *auth_request)
+const char *
+passdb_get_credentials(struct auth_request *auth_request,
+ const char *password, const char *scheme)
{
const char *wanted_scheme;
- if (result != PASSDB_RESULT_OK) {
- callback(result, NULL, auth_request);
- return;
- }
- i_assert(password != NULL);
-
- if (credentials == PASSDB_CREDENTIALS_CRYPT) {
+ if (auth_request->credentials == PASSDB_CREDENTIALS_CRYPT) {
/* anything goes */
- password = t_strdup_printf("{%s}%s", scheme, password);
- callback(result, password, auth_request);
- return;
+ return t_strdup_printf("{%s}%s", scheme, password);
}
- wanted_scheme = passdb_credentials_to_str(credentials);
+ wanted_scheme = passdb_credentials_to_str(auth_request->credentials);
if (strcasecmp(scheme, wanted_scheme) != 0) {
if (strcasecmp(scheme, "PLAIN") != 0 &&
strcasecmp(scheme, "CLEARTEXT") != 0) {
auth_request_log_info(auth_request, "password",
"Requested %s scheme, but we have only %s",
wanted_scheme, scheme);
- callback(PASSDB_RESULT_SCHEME_NOT_AVAILABLE,
- NULL, auth_request);
- return;
+ return NULL;
}
/* we can generate anything out of plaintext passwords */
@@ -113,7 +101,24 @@
i_assert(password != NULL);
}
- callback(PASSDB_RESULT_OK, password, auth_request);
+ return password;
+}
+
+void passdb_handle_credentials(enum passdb_result result,
+ const char *password, const char *scheme,
+ lookup_credentials_callback_t *callback,
+ struct auth_request *auth_request)
+{
+ if (result != PASSDB_RESULT_OK) {
+ callback(result, NULL, auth_request);
+ return;
+ }
+ i_assert(password != NULL);
+
+ password = passdb_get_credentials(auth_request, password, scheme);
+ if (password == NULL)
+ result = PASSDB_RESULT_SCHEME_NOT_AVAILABLE;
+ callback(result, password, auth_request);
}
struct auth_passdb *passdb_preinit(struct auth *auth, const char *driver,
Index: passdb.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb.h,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- passdb.h 24 Sep 2005 12:55:23 -0000 1.27
+++ passdb.h 16 Oct 2005 12:03:37 -0000 1.28
@@ -31,7 +31,7 @@
typedef void verify_plain_callback_t(enum passdb_result result,
struct auth_request *request);
typedef void lookup_credentials_callback_t(enum passdb_result result,
- const char *credentials,
+ const char *password,
struct auth_request *request);
struct passdb_module {
@@ -54,15 +54,17 @@
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. */
+ /* Return authentication credentials, set in
+ auth_request->credentials. */
void (*lookup_credentials)(struct auth_request *request,
- enum passdb_credentials credentials,
lookup_credentials_callback_t *callback);
};
+const char *
+passdb_get_credentials(struct auth_request *auth_request,
+ const char *password, const char *scheme);
+
void passdb_handle_credentials(enum passdb_result result,
- enum passdb_credentials credentials,
const char *password, const char *scheme,
lookup_credentials_callback_t *callback,
struct auth_request *auth_request);
- Previous message: [dovecot-cvs] dovecot/src/lib failures.c,1.26,1.27
- Next message: [dovecot-cvs] dovecot/src/auth auth-request.c, 1.32,
1.33 passdb-bsdauth.c, 1.11, 1.12 passdb-pam.c, 1.27,
1.28 passdb-passwd-file.c, 1.20, 1.21 passdb-passwd.c, 1.14,
1.15 passdb-shadow.c, 1.15, 1.16 passdb-vpopmail.c, 1.21, 1.22
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list