dovecot-2.0: auth: If userdb lookup returns tempfail, return rea...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Mar 31 19:22:29 EEST 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/b40ec803421e
changeset: 11019:b40ec803421e
user: Timo Sirainen <tss at iki.fi>
date: Wed Mar 31 19:22:19 2010 +0300
description:
auth: If userdb lookup returns tempfail, return reason field (if any).
diffstat:
src/auth/auth-master-connection.c | 6 +++
src/auth/auth-request-handler.c | 7 +++
src/auth/auth-stream.c | 53 ++++++++++++++++++++++----
src/auth/auth-stream.h | 3 +
src/auth/auth-worker-client.c | 21 ++++++++++
src/auth/passdb-blocking.c | 5 ++-
src/auth/userdb-blocking.c | 18 ++++++--
7 files changed, 99 insertions(+), 14 deletions(-)
diffs (254 lines):
diff -r 2e08ce368bc0 -r b40ec803421e src/auth/auth-master-connection.c
--- a/src/auth/auth-master-connection.c Wed Mar 31 19:21:09 2010 +0300
+++ b/src/auth/auth-master-connection.c Wed Mar 31 19:22:19 2010 +0300
@@ -164,6 +164,7 @@
struct auth_master_connection *conn = auth_request->context;
struct auth_stream_reply *reply = auth_request->userdb_reply;
string_t *str;
+ const char *value;
if (auth_request->userdb_lookup_failed)
result = USERDB_RESULT_INTERNAL_FAILURE;
@@ -172,6 +173,11 @@
switch (result) {
case USERDB_RESULT_INTERNAL_FAILURE:
str_printfa(str, "FAIL\t%u", auth_request->id);
+ if (auth_request->userdb_lookup_failed) {
+ value = auth_stream_reply_find(reply, "reason");
+ if (value != NULL)
+ str_printfa(str, "\treason=%s", value);
+ }
break;
case USERDB_RESULT_USER_UNKNOWN:
str_printfa(str, "NOTFOUND\t%u", auth_request->id);
diff -r 2e08ce368bc0 -r b40ec803421e src/auth/auth-request-handler.c
--- a/src/auth/auth-request-handler.c Wed Mar 31 19:21:09 2010 +0300
+++ b/src/auth/auth-request-handler.c Wed Mar 31 19:22:19 2010 +0300
@@ -475,6 +475,7 @@
{
struct auth_request_handler *handler = request->context;
struct auth_stream_reply *reply;
+ const char *value;
i_assert(request->state == AUTH_REQUEST_STATE_USERDB);
@@ -488,6 +489,12 @@
case USERDB_RESULT_INTERNAL_FAILURE:
auth_stream_reply_add(reply, "FAIL", NULL);
auth_stream_reply_add(reply, NULL, dec2str(request->id));
+ if (request->userdb_lookup_failed) {
+ value = auth_stream_reply_find(request->userdb_reply,
+ "reason");
+ if (value != NULL)
+ auth_stream_reply_add(reply, "reason", value);
+ }
break;
case USERDB_RESULT_USER_UNKNOWN:
auth_stream_reply_add(reply, "NOTFOUND", NULL);
diff -r 2e08ce368bc0 -r b40ec803421e src/auth/auth-stream.c
--- a/src/auth/auth-stream.c Wed Mar 31 19:21:09 2010 +0300
+++ b/src/auth/auth-stream.c Wed Mar 31 19:22:19 2010 +0300
@@ -40,7 +40,9 @@
}
}
-void auth_stream_reply_remove(struct auth_stream_reply *reply, const char *key)
+static bool
+auth_stream_reply_find_area(struct auth_stream_reply *reply, const char *key,
+ unsigned int *idx_r, unsigned int *len_r)
{
const char *str = str_c(reply->str);
unsigned int i, start, key_len = strlen(key);
@@ -49,21 +51,56 @@
while (str[i] != '\0') {
start = i;
for (; str[i] != '\0'; i++) {
- if (str[i] == '\t') {
- i++;
+ if (str[i] == '\t')
break;
- }
}
if (strncmp(str+start, key, key_len) == 0 &&
(str[start+key_len] == '=' ||
str[start+key_len] == '\t' ||
str[start+key_len] == '\0')) {
- str_delete(reply->str, start, i-start);
- if (str_len(reply->str) == start && start > 0)
- str_delete(reply->str, start - 1, 1);
- break;
+ *idx_r = start;
+ *len_r = i - start;
+ return TRUE;
}
+ if (str[i] == '\t')
+ i++;
+ }
+ return FALSE;
+}
+
+void auth_stream_reply_remove(struct auth_stream_reply *reply, const char *key)
+{
+ unsigned int idx, len;
+
+ if (!auth_stream_reply_find_area(reply, key, &idx, &len))
+ return;
+
+ if (str_len(reply->str) < idx + len) {
+ /* remove also trailing tab */
+ len++;
+ } else if (str_len(reply->str) == idx + len && idx > 0) {
+ /* removing last item, remove preceding tab */
+ len++;
+ idx--;
+ }
+
+ str_delete(reply->str, idx, len);
+}
+
+const char *auth_stream_reply_find(struct auth_stream_reply *reply,
+ const char *key)
+{
+ unsigned int idx, len, keylen;
+
+ if (!auth_stream_reply_find_area(reply, key, &idx, &len))
+ return NULL;
+ else {
+ keylen = strlen(key);
+ i_assert(len > keylen);
+ idx += keylen + 1;
+ len -= keylen + 1;
+ return t_strndup(str_c(reply->str) + idx, len);
}
}
diff -r 2e08ce368bc0 -r b40ec803421e src/auth/auth-stream.h
--- a/src/auth/auth-stream.h Wed Mar 31 19:21:09 2010 +0300
+++ b/src/auth/auth-stream.h Wed Mar 31 19:22:19 2010 +0300
@@ -9,6 +9,9 @@
void auth_stream_reply_reset(struct auth_stream_reply *reply);
void auth_stream_reply_remove(struct auth_stream_reply *reply, const char *key);
+const char *auth_stream_reply_find(struct auth_stream_reply *reply,
+ const char *key);
+
void auth_stream_reply_import(struct auth_stream_reply *reply, const char *str);
const char *auth_stream_reply_export(struct auth_stream_reply *reply);
bool auth_stream_is_empty(struct auth_stream_reply *reply);
diff -r 2e08ce368bc0 -r b40ec803421e src/auth/auth-worker-client.c
--- a/src/auth/auth-worker-client.c Wed Mar 31 19:21:09 2010 +0300
+++ b/src/auth/auth-worker-client.c Wed Mar 31 19:22:19 2010 +0300
@@ -98,6 +98,7 @@
struct auth_worker_client *client = request->context;
struct auth_stream_reply *reply;
string_t *str;
+ const char *value;
if (request->passdb_failure && result == PASSDB_RESULT_OK)
result = PASSDB_RESULT_PASSWORD_MISMATCH;
@@ -127,6 +128,13 @@
auth_stream_reply_export(request->extra_cache_fields);
auth_stream_reply_import(reply, fields);
}
+ } else if (request->userdb_lookup_failed) {
+ value = auth_stream_reply_find(request->extra_fields, "reason");
+ if (value != NULL) {
+ auth_stream_reply_add(reply, NULL, "");
+ auth_stream_reply_add(reply, NULL, "");
+ auth_stream_reply_add(reply, "reason", value);
+ }
}
str = auth_stream_reply_get_str(reply);
str_append_c(str, '\n');
@@ -200,6 +208,7 @@
struct auth_worker_client *client = request->context;
struct auth_stream_reply *reply;
string_t *str;
+ const char *value;
if (request->passdb_failure && result == PASSDB_RESULT_OK)
result = PASSDB_RESULT_PASSWORD_MISMATCH;
@@ -211,6 +220,12 @@
auth_stream_reply_add(reply, "FAIL", NULL);
auth_stream_reply_add(reply, NULL,
t_strdup_printf("%d", result));
+ value = auth_stream_reply_find(request->extra_fields, "reason");
+ if (request->userdb_lookup_failed && value != NULL) {
+ auth_stream_reply_add(reply, NULL, "");
+ auth_stream_reply_add(reply, NULL, "");
+ auth_stream_reply_add(reply, "reason", value);
+ }
} else {
auth_stream_reply_add(reply, "OK", NULL);
auth_stream_reply_add(reply, NULL, request->user);
@@ -356,6 +371,7 @@
struct auth_worker_client *client = auth_request->context;
struct auth_stream_reply *reply = auth_request->userdb_reply;
string_t *str;
+ const char *value;
if (auth_request->userdb_lookup_failed)
result = USERDB_RESULT_INTERNAL_FAILURE;
@@ -365,6 +381,11 @@
switch (result) {
case USERDB_RESULT_INTERNAL_FAILURE:
str_append(str, "FAIL\t");
+ if (auth_request->userdb_lookup_failed) {
+ value = auth_stream_reply_find(reply, "reason");
+ if (value != NULL)
+ str_printfa(str, "reason=%s", value);
+ }
break;
case USERDB_RESULT_USER_UNKNOWN:
str_append(str, "NOTFOUND\t");
diff -r 2e08ce368bc0 -r b40ec803421e src/auth/passdb-blocking.c
--- a/src/auth/passdb-blocking.c Wed Mar 31 19:21:09 2010 +0300
+++ b/src/auth/passdb-blocking.c Wed Mar 31 19:22:19 2010 +0300
@@ -48,7 +48,10 @@
/* internal failure most likely */
return ret;
} else if (args[3] != NULL) {
- auth_request_set_field(request, "user", args[2], NULL);
+ if (*args[2] != '\0') {
+ auth_request_set_field(request, "user",
+ args[2], NULL);
+ }
auth_worker_reply_parse_args(request, args + 3);
return ret;
}
diff -r 2e08ce368bc0 -r b40ec803421e src/auth/userdb-blocking.c
--- a/src/auth/userdb-blocking.c Wed Mar 31 19:21:09 2010 +0300
+++ b/src/auth/userdb-blocking.c Wed Mar 31 19:22:19 2010 +0300
@@ -19,18 +19,26 @@
{
struct auth_request *request = context;
enum userdb_result result;
+ const char *args;
- if (strncmp(reply, "FAIL\t", 5) == 0)
+ if (strncmp(reply, "FAIL\t", 5) == 0) {
result = USERDB_RESULT_INTERNAL_FAILURE;
- else if (strncmp(reply, "NOTFOUND\t", 9) == 0)
+ args = reply + 5;
+ } else if (strncmp(reply, "NOTFOUND\t", 9) == 0) {
result = USERDB_RESULT_USER_UNKNOWN;
- else if (strncmp(reply, "OK\t", 3) == 0) {
+ args = reply + 9;
+ } else if (strncmp(reply, "OK\t", 3) == 0) {
result = USERDB_RESULT_OK;
- request->userdb_reply = auth_stream_reply_init(request->pool);
- auth_stream_reply_import(request->userdb_reply, reply + 3);
+ args = reply + 3;
} else {
result = USERDB_RESULT_INTERNAL_FAILURE;
i_error("BUG: auth-worker sent invalid user reply");
+ args = "";
+ }
+
+ if (*args != '\0') {
+ request->userdb_reply = auth_stream_reply_init(request->pool);
+ auth_stream_reply_import(request->userdb_reply, args);
}
auth_request_userdb_callback(result, request);
More information about the dovecot-cvs
mailing list