dovecot-2.0: auth: Added PASS command for auth-master socket to ...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Aug 17 19:55:36 EEST 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/620183ce36f9
changeset: 9804:620183ce36f9
user: Timo Sirainen <tss at iki.fi>
date: Mon Aug 17 12:55:29 2009 -0400
description:
auth: Added PASS command for auth-master socket to do passdb lookups.
diffstat:
1 file changed, 133 insertions(+), 49 deletions(-)
src/auth/auth-master-connection.c | 182 +++++++++++++++++++++++++++----------
diffs (220 lines):
diff -r 7f9fcd00a819 -r 620183ce36f9 src/auth/auth-master-connection.c
--- a/src/auth/auth-master-connection.c Mon Aug 17 12:54:54 2009 -0400
+++ b/src/auth/auth-master-connection.c Mon Aug 17 12:55:29 2009 -0400
@@ -94,51 +94,19 @@ master_input_request(struct auth_master_
return TRUE;
}
-static void
-user_callback(enum userdb_result result,
- struct auth_request *auth_request)
-{
- struct auth_master_connection *conn = auth_request->context;
- struct auth_stream_reply *reply = auth_request->userdb_reply;
- string_t *str;
-
- if (auth_request->userdb_lookup_failed)
- result = USERDB_RESULT_INTERNAL_FAILURE;
-
- str = t_str_new(128);
- switch (result) {
- case USERDB_RESULT_INTERNAL_FAILURE:
- str_printfa(str, "FAIL\t%u", auth_request->id);
- break;
- case USERDB_RESULT_USER_UNKNOWN:
- str_printfa(str, "NOTFOUND\t%u", auth_request->id);
- break;
- case USERDB_RESULT_OK:
- str_printfa(str, "USER\t%u\t", auth_request->id);
- str_append(str, auth_stream_reply_export(reply));
- break;
- }
-
- if (conn->auth->set->debug)
- i_info("master out: %s", str_c(str));
-
- str_append_c(str, '\n');
- (void)o_stream_send(conn->output, str_data(str), str_len(str));
- auth_request_unref(&auth_request);
- auth_master_connection_unref(&conn);
-}
-
-static bool
-master_input_user(struct auth_master_connection *conn, const char *args)
+static int
+master_input_auth_request(struct auth_master_connection *conn, const char *args,
+ const char *cmd, struct auth_request **request_r,
+ const char **error_r)
{
struct auth_request *auth_request;
- const char *const *list, *name, *arg, *error;
+ const char *const *list, *name, *arg;
/* <id> <userid> [<parameters>] */
list = t_strsplit(args, "\t");
if (list[0] == NULL || list[1] == NULL) {
- i_error("BUG: Master sent broken USER");
- return FALSE;
+ i_error("BUG: Master sent broken %s", cmd);
+ return -1;
}
auth_request = auth_request_new_dummy(conn->auth);
@@ -146,10 +114,9 @@ master_input_user(struct auth_master_con
auth_request->context = conn;
auth_master_connection_ref(conn);
- if (!auth_request_set_username(auth_request, list[1], &error)) {
- auth_request_log_info(auth_request, "userdb", "%s", error);
- user_callback(USERDB_RESULT_USER_UNKNOWN, auth_request);
- return TRUE;
+ if (!auth_request_set_username(auth_request, list[1], error_r)) {
+ *request_r = auth_request;
+ return 0;
}
for (list += 2; *list != NULL; list++) {
@@ -166,13 +133,128 @@ master_input_user(struct auth_master_con
}
if (auth_request->service == NULL) {
- i_error("BUG: Master sent USER request without service");
+ i_error("BUG: Master sent %s request without service", cmd);
+ auth_master_connection_unref(&conn);
auth_request_unref(&auth_request);
- return FALSE;
- }
-
- auth_request->state = AUTH_REQUEST_STATE_USERDB;
- auth_request_lookup_user(auth_request, user_callback);
+ return -1;
+ }
+ *request_r = auth_request;
+ return 1;
+}
+
+static void
+user_callback(enum userdb_result result,
+ struct auth_request *auth_request)
+{
+ struct auth_master_connection *conn = auth_request->context;
+ struct auth_stream_reply *reply = auth_request->userdb_reply;
+ string_t *str;
+
+ if (auth_request->userdb_lookup_failed)
+ result = USERDB_RESULT_INTERNAL_FAILURE;
+
+ str = t_str_new(128);
+ switch (result) {
+ case USERDB_RESULT_INTERNAL_FAILURE:
+ str_printfa(str, "FAIL\t%u", auth_request->id);
+ break;
+ case USERDB_RESULT_USER_UNKNOWN:
+ str_printfa(str, "NOTFOUND\t%u", auth_request->id);
+ break;
+ case USERDB_RESULT_OK:
+ str_printfa(str, "USER\t%u\t", auth_request->id);
+ str_append(str, auth_stream_reply_export(reply));
+ break;
+ }
+
+ if (conn->auth->set->debug)
+ i_info("master out: %s", str_c(str));
+
+ str_append_c(str, '\n');
+ (void)o_stream_send(conn->output, str_data(str), str_len(str));
+ auth_request_unref(&auth_request);
+ auth_master_connection_unref(&conn);
+}
+
+static bool
+master_input_user(struct auth_master_connection *conn, const char *args)
+{
+ struct auth_request *auth_request;
+ const char *error;
+ int ret;
+
+ ret = master_input_auth_request(conn, args, "USER",
+ &auth_request, &error);
+ if (ret <= 0) {
+ if (ret < 0)
+ return FALSE;
+ auth_request_log_info(auth_request, "userdb", "%s", error);
+ user_callback(USERDB_RESULT_USER_UNKNOWN, auth_request);
+ } else {
+ auth_request->state = AUTH_REQUEST_STATE_USERDB;
+ auth_request_lookup_user(auth_request, user_callback);
+ }
+ return TRUE;
+}
+
+static void
+pass_callback(enum passdb_result result,
+ const unsigned char *credentials ATTR_UNUSED,
+ size_t size ATTR_UNUSED,
+ struct auth_request *auth_request)
+{
+ struct auth_master_connection *conn = auth_request->context;
+ struct auth_stream_reply *reply = auth_request->extra_fields;
+ string_t *str;
+
+ str = t_str_new(128);
+ switch (result) {
+ case PASSDB_RESULT_OK:
+ str_printfa(str, "PASS\t%u\t", auth_request->id);
+ if (reply != NULL)
+ str_append(str, auth_stream_reply_export(reply));
+ break;
+ case PASSDB_RESULT_USER_UNKNOWN:
+ case PASSDB_RESULT_USER_DISABLED:
+ case PASSDB_RESULT_PASS_EXPIRED:
+ str_printfa(str, "NOTFOUND\t%u", auth_request->id);
+ break;
+ case PASSDB_RESULT_PASSWORD_MISMATCH:
+ case PASSDB_RESULT_INTERNAL_FAILURE:
+ case PASSDB_RESULT_SCHEME_NOT_AVAILABLE:
+ str_printfa(str, "FAIL\t%u", auth_request->id);
+ break;
+ }
+
+ if (conn->auth->set->debug)
+ i_info("master out: %s", str_c(str));
+
+ str_append_c(str, '\n');
+ (void)o_stream_send(conn->output, str_data(str), str_len(str));
+ auth_request_unref(&auth_request);
+ auth_master_connection_unref(&conn);
+}
+
+static bool
+master_input_pass(struct auth_master_connection *conn, const char *args)
+{
+ struct auth_request *auth_request;
+ const char *error;
+ int ret;
+
+ ret = master_input_auth_request(conn, args, "PASS",
+ &auth_request, &error);
+ if (ret <= 0) {
+ if (ret < 0)
+ return FALSE;
+ auth_request_log_info(auth_request, "passdb", "%s", error);
+ pass_callback(PASSDB_RESULT_USER_UNKNOWN,
+ NULL, 0, auth_request);
+ } else {
+ auth_request->state = AUTH_REQUEST_STATE_MECH_CONTINUE;
+ auth_request_lookup_credentials(auth_request, "",
+ pass_callback);
+ }
return TRUE;
}
@@ -296,6 +378,8 @@ auth_master_input_line(struct auth_maste
if (!conn->userdb_only) {
if (strncmp(line, "REQUEST\t", 8) == 0)
return master_input_request(conn, line + 8);
+ if (strncmp(line, "PASS\t", 5) == 0)
+ return master_input_pass(conn, line + 5);
if (strncmp(line, "CPID\t", 5) == 0) {
i_error("Authentication client trying to connect to "
"master socket");
More information about the dovecot-cvs
mailing list