]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Fixed crash if login process connection died while there were some auth
authorTimo Sirainen <tss@iki.fi>
Fri, 22 Aug 2003 04:57:49 +0000 (07:57 +0300)
committerTimo Sirainen <tss@iki.fi>
Fri, 22 Aug 2003 04:57:49 +0000 (07:57 +0300)
requests.

--HG--
branch : HEAD

src/auth/auth-client-connection.c
src/auth/mech-anonymous.c
src/auth/mech-cyrus-sasl2.c
src/auth/mech-digest-md5.c
src/auth/mech-plain.c
src/auth/mech.c
src/auth/mech.h
src/auth/passdb-ldap.c
src/auth/passdb-pam.c

index 1d01046193de562bb1e3a007c79ed13730f76691..d81f022f503605ecc9159ba1a75583016e709b05 100644 (file)
@@ -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)
index 272ab23facb66e2605db46c70daf38fde69bf391..b9e5b3f50359b87e9389597379746e809926934e 100644 (file)
@@ -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;
index 06b4a28361b6bcb3bc7d45c72ae486852e5226b8..0d200ef1a162734979e94d007a649ee95460afa7 100644 (file)
@@ -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;
index a5bd4faf9a7300ac376262d83f6f1b4e88a5d2e4..f48b01e7ee440dab5df3b7cc668924825d54ef13 100644 (file)
@@ -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;
index d82c0220431af612fce854c107b11e6ed97b0a7b..1daf49fe2529381f4e24f4e85820ee9716465a87 100644 (file)
@@ -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;
index 1d67309de0a38560b8fd0e48b3da4de95d4757e7..25fb2407cd33922256f7adb61bf0791712766a58 100644 (file)
@@ -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;
index 13cbfaa34352110b7c4ec5970100f5081025a3b1..2322e29d6d1274b3e6278ca553736f599c58064f 100644 (file)
@@ -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);
 
index a4ef4373192bf41386e5d682ff7b45861e861656..fafc0a466c0b1e561332758a5ae41b137d474ef8 100644 (file)
@@ -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;
 
index 383e63062b791b26c76be2947e98e337daf42d9f..9def058d3fd5dda8b89b79731532fe87f159dee8 100644 (file)
@@ -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;