From: Timo Sirainen Date: Fri, 22 Aug 2003 04:57:49 +0000 (+0300) Subject: Fixed crash if login process connection died while there were some auth X-Git-Tag: 1.1.alpha1~4398 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=68d76bc6de2d923d03955e49d563d6e4629b86bf;p=thirdparty%2Fdovecot%2Fcore.git Fixed crash if login process connection died while there were some auth requests. --HG-- branch : HEAD --- diff --git a/src/auth/auth-client-connection.c b/src/auth/auth-client-connection.c index 1d01046193..d81f022f50 100644 --- a/src/auth/auth-client-connection.c +++ b/src/auth/auth-client-connection.c @@ -212,7 +212,8 @@ static void auth_request_hash_destroy(void *key __attr_unused__, void *value, { struct auth_request *auth_request = value; - auth_request->auth_free(auth_request); + auth_request->conn = NULL; + auth_request_unref(auth_request); } void auth_client_connection_destroy(struct auth_client_connection *conn) diff --git a/src/auth/mech-anonymous.c b/src/auth/mech-anonymous.c index 272ab23fac..b9e5b3f503 100644 --- a/src/auth/mech-anonymous.c +++ b/src/auth/mech-anonymous.c @@ -38,6 +38,7 @@ mech_anonymous_auth_new(struct auth_client_connection *conn, unsigned int id, pool = pool_alloconly_create("anonymous_auth_request", 256); auth_request = p_new(pool, struct auth_request, 1); + auth_request->refcount = 1; auth_request->pool = pool; auth_request->auth_continue = mech_anonymous_auth_continue; auth_request->auth_free = mech_anonymous_auth_free; diff --git a/src/auth/mech-cyrus-sasl2.c b/src/auth/mech-cyrus-sasl2.c index 06b4a28361..0d200ef1a1 100644 --- a/src/auth/mech-cyrus-sasl2.c +++ b/src/auth/mech-cyrus-sasl2.c @@ -195,6 +195,7 @@ struct auth_request *mech_cyrus_sasl_new(struct login_connection *conn, pool = pool_alloconly_create("cyrus_sasl_auth_request", 256); cyrus_request = p_new(pool, struct cyrus_auth_request, 1); + cyrus_request->auth_request.refcount = 1; cyrus_request->auth_request.pool = pool; cyrus_request->auth_request.auth_continue = cyrus_sasl_auth_continue; diff --git a/src/auth/mech-digest-md5.c b/src/auth/mech-digest-md5.c index a5bd4faf9a..f48b01e7ee 100644 --- a/src/auth/mech-digest-md5.c +++ b/src/auth/mech-digest-md5.c @@ -620,6 +620,7 @@ mech_digest_md5_auth_new(struct auth_client_connection *conn, auth = p_new(pool, struct digest_auth_request, 1); auth->pool = pool; + auth->auth_request.refcount = 1; auth->auth_request.pool = pool; auth->auth_request.auth_continue = mech_digest_md5_auth_continue; auth->auth_request.auth_free = mech_digest_md5_auth_free; diff --git a/src/auth/mech-plain.c b/src/auth/mech-plain.c index d82c022043..1daf49fe25 100644 --- a/src/auth/mech-plain.c +++ b/src/auth/mech-plain.c @@ -91,6 +91,7 @@ mech_plain_auth_new(struct auth_client_connection *conn, unsigned int id, pool = pool_alloconly_create("plain_auth_request", 256); auth_request = p_new(pool, struct auth_request, 1); + auth_request->refcount = 1; auth_request->pool = pool; auth_request->auth_continue = mech_plain_auth_continue; auth_request->auth_free = mech_plain_auth_free; diff --git a/src/auth/mech.c b/src/auth/mech.c index 1d67309de0..25fb2407cd 100644 --- a/src/auth/mech.c +++ b/src/auth/mech.c @@ -127,7 +127,7 @@ void mech_request_continue(struct auth_client_connection *conn, void mech_request_free(struct auth_client_connection *conn, struct auth_request *auth_request, unsigned int id) { - auth_request->auth_free(auth_request); + auth_request_unref(auth_request); hash_remove(conn->auth_requests, POINTER_CAST(id)); } @@ -200,6 +200,20 @@ int mech_is_valid_username(const char *username) return TRUE; } +void auth_request_ref(struct auth_request *request) +{ + request->refcount++; +} + +int auth_request_unref(struct auth_request *request) +{ + if (--request->refcount > 0) + return TRUE; + + request->auth_free(request); + return FALSE; +} + extern struct mech_module mech_plain; extern struct mech_module mech_digest_md5; extern struct mech_module mech_anonymous; diff --git a/src/auth/mech.h b/src/auth/mech.h index 13cbfaa343..2322e29d6d 100644 --- a/src/auth/mech.h +++ b/src/auth/mech.h @@ -10,6 +10,8 @@ typedef void mech_callback_t(struct auth_client_request_reply *reply, struct auth_client_connection *conn); struct auth_request { + int refcount; + pool_t pool; char *user; @@ -70,6 +72,9 @@ mech_cyrus_sasl_new(struct auth_client_connection *conn, struct auth_client_request_new *request, mech_callback_t *callback); +void auth_request_ref(struct auth_request *request); +int auth_request_unref(struct auth_request *request); + void mech_init(void); void mech_deinit(void); diff --git a/src/auth/passdb-ldap.c b/src/auth/passdb-ldap.c index a4ef437319..fafc0a466c 100644 --- a/src/auth/passdb-ldap.c +++ b/src/auth/passdb-ldap.c @@ -98,6 +98,11 @@ static void handle_request(struct ldap_connection *conn, } } + /* LDAP result is free'd now. we can check if auth_request is + even needed anymore */ + if (!auth_request_unref(auth_request)) + return; + scheme = password_get_scheme(&password); if (scheme == NULL) { scheme = conn->set.default_pass_scheme; @@ -149,6 +154,7 @@ static void ldap_lookup_pass(struct auth_request *auth_request, filter = str_c(str); } + auth_request_ref(auth_request); ldap_request->callback = handle_request; ldap_request->context = auth_request; diff --git a/src/auth/passdb-pam.c b/src/auth/passdb-pam.c index 383e63062b..9def058d3f 100644 --- a/src/auth/passdb-pam.c +++ b/src/auth/passdb-pam.c @@ -288,7 +288,8 @@ static void pam_child_input(void *context) } } - request->callback(result, request->request); + if (auth_request_unref(request->request)) + request->callback(result, request->request); if (close(request->fd) < 0) i_error("PAM: close(child input) failed: %m"); @@ -360,6 +361,7 @@ pam_verify_plain(struct auth_request *request, const char *password, if (close(fd[1]) < 0) i_error("PAM: close(fd[1]) failed: %m"); + auth_request_ref(request); pam_auth_request = i_new(struct pam_auth_request, 1); pam_auth_request->fd = fd[0]; pam_auth_request->request = request;