]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: userdb-ldap - Avoid early dereferencing
authorMarco Bettini <marco.bettini@open-xchange.com>
Mon, 6 Dec 2021 10:54:16 +0000 (11:54 +0100)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Fri, 10 Dec 2021 08:07:43 +0000 (08:07 +0000)
userdb_ldap_iterate_callback() is still invoked after dereferencing
auth_request in userdb_ldap_iterate_deinit().

Normally this happens only on teardown, but it may happens also
in case of auth disconnecting from auth-worker during iteration.
(which shouldn't happen unless the auth process crashes)

src/auth/userdb-ldap.c

index 5ae085fb2cc0225952ddeb3c091d8fd7acc31b4b..ecbf09e47927467c9ce46662529da0a5dd6e12a9 100644 (file)
@@ -36,7 +36,7 @@ struct ldap_userdb_iterate_context {
        struct userdb_iter_ldap_request request;
        pool_t pool;
        struct ldap_connection *conn;
-       bool continued, in_callback;
+       bool continued, in_callback, deinitialized;
 };
 
 static void
@@ -166,10 +166,15 @@ static void userdb_ldap_iterate_callback(struct ldap_connection *conn,
        if (res == NULL || ldap_msgtype(res) == LDAP_RES_SEARCH_RESULT) {
                if (res == NULL)
                        ctx->ctx.failed = TRUE;
-               ctx->ctx.callback(NULL, ctx->ctx.context);
+               if (!ctx->deinitialized)
+                       ctx->ctx.callback(NULL, ctx->ctx.context);
+               auth_request_unref(&request->auth_request);
                return;
        }
 
+       if (ctx->deinitialized)
+               return;
+
        /* the iteration can take a while. reset the request's create time so
           it won't be aborted while it's still running */
        request->create_time = ioloop_time;
@@ -267,7 +272,7 @@ static int userdb_ldap_iterate_deinit(struct userdb_iterate_context *_ctx)
        int ret = _ctx->failed ? -1 : 0;
 
        db_ldap_enable_input(ctx->conn, TRUE);
-       auth_request_unref(&ctx->request.request.request.auth_request);
+       ctx->deinitialized = TRUE;
        return ret;
 }