From: Timo Sirainen Date: Wed, 12 May 2010 14:40:22 +0000 (+0200) Subject: auth: Separate auth and login connections. Non-login requests are freed immediately... X-Git-Tag: 2.0.beta6~245 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=daa7e7459749ae8f82cd3eed9c44522d81c609a3;p=thirdparty%2Fdovecot%2Fcore.git auth: Separate auth and login connections. Non-login requests are freed immediately after auth finished. The login connections are used by Dovecot internally, while the auth connections are for SMTP AUTH etc. --HG-- branch : HEAD --- diff --git a/src/auth/auth-client-connection.c b/src/auth/auth-client-connection.c index 3be14942a0..3790cfff7b 100644 --- a/src/auth/auth-client-connection.c +++ b/src/auth/auth-client-connection.c @@ -115,6 +115,7 @@ auth_client_input_cpid(struct auth_client_connection *conn, const char *args) conn->refcount++; conn->request_handler = auth_request_handler_create(auth_callback, conn, + !conn->login_requests ? NULL : auth_master_request_callback); auth_request_handler_set(conn->request_handler, conn->connect_uid, pid); @@ -263,7 +264,7 @@ static void auth_client_input(struct auth_client_connection *conn) } struct auth_client_connection * -auth_client_connection_create(struct auth *auth, int fd) +auth_client_connection_create(struct auth *auth, int fd, bool login_requests) { static unsigned int connect_uid_counter = 0; struct auth_client_connection *conn; @@ -273,6 +274,7 @@ auth_client_connection_create(struct auth *auth, int fd) conn->auth = auth; conn->refcount = 1; conn->connect_uid = ++connect_uid_counter; + conn->login_requests = login_requests; random_fill(conn->cookie, sizeof(conn->cookie)); conn->fd = fd; diff --git a/src/auth/auth-client-connection.h b/src/auth/auth-client-connection.h index 3c035642e0..314dbc0470 100644 --- a/src/auth/auth-client-connection.h +++ b/src/auth/auth-client-connection.h @@ -17,11 +17,12 @@ struct auth_client_connection { uint8_t cookie[MASTER_AUTH_COOKIE_SIZE]; struct auth_request_handler *request_handler; + unsigned int login_requests:1; unsigned int version_received:1; }; struct auth_client_connection * -auth_client_connection_create(struct auth *auth, int fd); +auth_client_connection_create(struct auth *auth, int fd, bool login_requests); void auth_client_connection_destroy(struct auth_client_connection **conn); struct auth_client_connection * diff --git a/src/auth/auth-master-connection.c b/src/auth/auth-master-connection.c index fb4ec380f0..33245ff07c 100644 --- a/src/auth/auth-master-connection.c +++ b/src/auth/auth-master-connection.c @@ -100,9 +100,12 @@ master_input_request(struct auth_master_connection *conn, const char *args) client_pid); (void)o_stream_send_str(conn->output, t_strdup_printf("FAIL\t%u\n", id)); - } else { - auth_request_handler_master_request( - client_conn->request_handler, conn, id, client_id); + } else if (!auth_request_handler_master_request( + client_conn->request_handler, conn, id, client_id)) { + i_error("Master requested auth for non-login client %u", + client_pid); + (void)o_stream_send_str(conn->output, + t_strdup_printf("FAIL\t%u\n", id)); } return TRUE; } diff --git a/src/auth/auth-request-handler.c b/src/auth/auth-request-handler.c index 73a384e31d..09266e516b 100644 --- a/src/auth/auth-request-handler.c +++ b/src/auth/auth-request-handler.c @@ -536,7 +536,7 @@ static void userdb_callback(enum userdb_result result, auth_request_handler_unref(&handler); } -void auth_request_handler_master_request(struct auth_request_handler *handler, +bool auth_request_handler_master_request(struct auth_request_handler *handler, struct auth_master_connection *master, unsigned int id, unsigned int client_id) @@ -552,8 +552,10 @@ void auth_request_handler_master_request(struct auth_request_handler *handler, handler->client_pid, client_id); auth_stream_reply_add(reply, "FAIL", NULL); auth_stream_reply_add(reply, NULL, dec2str(id)); + if (handler->master_callback == NULL) + return FALSE; handler->master_callback(reply, master); - return; + return TRUE; } auth_request_ref(request); @@ -582,6 +584,7 @@ void auth_request_handler_master_request(struct auth_request_handler *handler, handler->refcount++; auth_request_lookup_user(request, userdb_callback); } + return TRUE; } void auth_request_handler_flush_failures(bool flush_all) diff --git a/src/auth/auth-request-handler.h b/src/auth/auth-request-handler.h index b7d3c12791..4bea9a5b89 100644 --- a/src/auth/auth-request-handler.h +++ b/src/auth/auth-request-handler.h @@ -33,7 +33,7 @@ bool auth_request_handler_auth_begin(struct auth_request_handler *handler, const char *args); bool auth_request_handler_auth_continue(struct auth_request_handler *handler, const char *args); -void auth_request_handler_master_request(struct auth_request_handler *handler, +bool auth_request_handler_master_request(struct auth_request_handler *handler, struct auth_master_connection *master, unsigned int id, unsigned int client_id); diff --git a/src/auth/auth-settings.c b/src/auth/auth-settings.c index 5dc8da36fa..67192b916a 100644 --- a/src/auth/auth-settings.c +++ b/src/auth/auth-settings.c @@ -16,7 +16,7 @@ static bool auth_userdb_settings_check(void *_set, pool_t pool, const char **err /* */ static struct file_listener_settings auth_unix_listeners_array[] = { - { "login/auth", 0666, "", "" }, + { "login/login", 0666, "", "" }, { "auth-client", 0600, "", "" }, { "auth-userdb", 0600, "", "" }, { "auth-master", 0600, "", "" } diff --git a/src/auth/main.c b/src/auth/main.c index d3627d6820..57228e80c9 100644 --- a/src/auth/main.c +++ b/src/auth/main.c @@ -33,6 +33,7 @@ enum auth_socket_type { AUTH_SOCKET_UNKNOWN = 0, AUTH_SOCKET_CLIENT, + AUTH_SOCKET_LOGIN_CLIENT, AUTH_SOCKET_MASTER, AUTH_SOCKET_USERDB }; @@ -195,20 +196,29 @@ static void worker_connected(const struct master_service_connection *conn) static void client_connected(const struct master_service_connection *conn) { enum auth_socket_type *type; - const char *name, *suffix; + const char *path, *name, *suffix; struct auth *auth; type = array_idx_modifiable(&listen_fd_types, conn->listen_fd); if (*type == AUTH_SOCKET_UNKNOWN) { /* figure out if this is a server or network socket by checking the socket path name. */ - if (net_getunixname(conn->listen_fd, &name) < 0) + if (net_getunixname(conn->listen_fd, &path) < 0) i_fatal("getsockname(%d) failed: %m", conn->listen_fd); + name = strrchr(path, '/'); + if (name == NULL) + name = path; + else + name++; + suffix = strrchr(name, '-'); - if (suffix == NULL) - *type = AUTH_SOCKET_CLIENT; - else { + if (suffix == NULL) { + if (strcmp(name, "login") == 0) + *type = AUTH_SOCKET_LOGIN_CLIENT; + else + *type = AUTH_SOCKET_CLIENT; + } else { suffix++; if (strcmp(suffix, "master") == 0) *type = AUTH_SOCKET_MASTER; @@ -227,8 +237,11 @@ static void client_connected(const struct master_service_connection *conn) case AUTH_SOCKET_USERDB: (void)auth_master_connection_create(auth, conn->fd, TRUE); break; + case AUTH_SOCKET_LOGIN_CLIENT: + (void)auth_client_connection_create(auth, conn->fd, TRUE); + break; case AUTH_SOCKET_CLIENT: - (void)auth_client_connection_create(auth, conn->fd); + (void)auth_client_connection_create(auth, conn->fd, FALSE); break; default: i_unreached(); diff --git a/src/login-common/main.c b/src/login-common/main.c index e93cea09af..a5dbd9b94e 100644 --- a/src/login-common/main.c +++ b/src/login-common/main.c @@ -297,7 +297,7 @@ static void main_init(void) client_destroy_oldest); master_service_set_die_callback(master_service, login_die); - auth_client = auth_client_init("auth", (unsigned int)getpid(), FALSE); + auth_client = auth_client_init("login", (unsigned int)getpid(), FALSE); auth_client_set_connect_notify(auth_client, auth_connect_notify, NULL); master_auth = master_auth_init(master_service, login_binary.protocol);