]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-master: Add API changes to allow anvil_callback_t to return error string
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 21 Mar 2025 14:09:45 +0000 (16:09 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Fri, 28 Mar 2025 09:55:03 +0000 (09:55 +0000)
src/auth/auth-penalty.c
src/doveadm/doveadm-kick.c
src/lib-master/anvil-client.c
src/lib-master/anvil-client.h
src/lmtp/lmtp-local.c
src/login-common/sasl-server.c

index 77b49f3b7dcc90d12ddbc24c4da64fb8cff01db2..78b5e0a1162aaedf0892504bafd66caa4238da14 100644 (file)
@@ -62,23 +62,23 @@ unsigned int auth_penalty_to_secs(unsigned int penalty)
 }
 
 static void
-auth_penalty_anvil_callback(const char *reply,
+auth_penalty_anvil_callback(const struct anvil_reply *reply,
                            struct auth_penalty_request *request)
 {
        unsigned int penalty = 0;
        unsigned long last_penalty = 0;
        unsigned int secs, drop_penalty;
 
-       if (reply == NULL) {
+       if (reply->error != NULL) {
                /* internal failure. */
                if (!anvil_client_is_connected(request->client)) {
                        /* we probably didn't have permissions to reconnect
                           back to anvil. need to restart ourself. */
                        master_service_stop(master_service);
                }
-       } else if (sscanf(reply, "%u %lu", &penalty, &last_penalty) != 2) {
+       } else if (sscanf(reply->reply, "%u %lu", &penalty, &last_penalty) != 2) {
                e_error(request->auth_request->event,
-                       "Invalid PENALTY-GET reply: %s", reply);
+                       "Invalid PENALTY-GET reply: %s", reply->reply);
        } else {
                if ((time_t)last_penalty > ioloop_time) {
                        /* time moved backwards? */
index 07fab3be936d09db838d9a71df91cf73f2489c4f..ac927f76b5f7d3d759347188d5e27af67261c05b 100644 (file)
@@ -27,14 +27,15 @@ struct kick_context {
 };
 
 static void
-kick_user_anvil_callback(const char *reply, struct kick_context *ctx)
+kick_user_anvil_callback(const struct anvil_reply *reply,
+                        struct kick_context *ctx)
 {
        unsigned int count;
 
-       if (reply != NULL) {
-               if (str_to_uint(reply, &count) < 0)
+       if (reply->error == NULL) {
+               if (str_to_uint(reply->reply, &count) < 0)
                        e_error(ctx->event,
-                               "Unexpected reply from anvil: %s", reply);
+                               "Unexpected reply from anvil: %s", reply->reply);
                else
                        ctx->kicked_count += count;
        }
index d38c343939baae31dd20ec47d9c9168abcbb008a..b1020a93f99d2b1eef21e6bd0f77304f69018fb6 100644 (file)
@@ -231,7 +231,8 @@ static int anvil_client_input_line(struct connection *conn, const char *line)
        queries = array_get(&client->queries_arr, &count);
        query = queries[aqueue_idx(client->queries, 0)];
        if (query->callback != NULL) T_BEGIN {
-               query->callback(line, query->context);
+               struct anvil_reply reply = { .reply = line };
+               query->callback(&reply, query->context);
        } T_END;
        anvil_query_free(&query);
        aqueue_delete_tail(client->queries);
@@ -267,7 +268,8 @@ int anvil_client_connect(struct anvil_client *client, bool retry)
        return 0;
 }
 
-static void anvil_client_cancel_queries(struct anvil_client *client)
+static void
+anvil_client_cancel_queries(struct anvil_client *client)
 {
        struct anvil_query *const *queries, *query;
        unsigned int count;
@@ -275,8 +277,10 @@ static void anvil_client_cancel_queries(struct anvil_client *client)
        queries = array_get(&client->queries_arr, &count);
        while (aqueue_count(client->queries) > 0) {
                query = queries[aqueue_idx(client->queries, 0)];
-               if (query->callback != NULL)
-                       query->callback(NULL, query->context);
+               if (query->callback != NULL) {
+                       struct anvil_reply reply = { .error = "Failed" };
+                       query->callback(&reply, query->context);
+               }
                anvil_query_free(&query);
                aqueue_delete_tail(client->queries);
        }
index b2652f81607d2f317b7da881713de9c3e556fd94..a9fc62d6c03fd44359abab119de801ac4cc0c542 100644 (file)
@@ -22,8 +22,14 @@ struct anvil_client_callbacks {
        bool (*command)(const char *cmd, const char *const *args);
 };
 
-/* reply=NULL if query failed */
-typedef void anvil_callback_t(const char *reply, void *context);
+struct anvil_reply {
+       /* non-NULL if query failed */
+       const char *error;
+       /* non-NULL if query succeeded */
+       const char *reply;
+};
+
+typedef void anvil_callback_t(const struct anvil_reply *reply, void *context);
 
 /* If reconnect_callback is specified, it's called when connection is lost.
    If the callback returns FALSE, reconnection isn't attempted. */
@@ -48,7 +54,7 @@ anvil_client_query(struct anvil_client *client, const char *query,
        anvil_client_query(client, query, timeout_msecs, \
                (anvil_callback_t *)(callback), 1 ? (context) : \
                CALLBACK_TYPECHECK(callback, \
-                       void (*)(const char *, typeof(context))))
+                       void (*)(const struct anvil_reply *, typeof(context))))
 void anvil_client_query_abort(struct anvil_client *client,
                              struct anvil_query **query);
 /* Send a command to anvil, don't expect any replies. */
index 9fe04559ed0046310df242118cc41f0fea758dce..74904e3ef32ad3b35f6ee2563bf0b75127fa9ad9 100644 (file)
@@ -260,7 +260,8 @@ lmtp_local_rcpt_anvil_finish(struct lmtp_local_recipient *llrcpt)
 }
 
 static void
-lmtp_local_rcpt_anvil_cb(const char *reply, struct lmtp_local_recipient *llrcpt)
+lmtp_local_rcpt_anvil_cb(const struct anvil_reply *reply,
+                        struct lmtp_local_recipient *llrcpt)
 {
        struct client *client = llrcpt->rcpt->client;
        struct smtp_server_recipient *rcpt = llrcpt->rcpt->rcpt;
@@ -268,10 +269,11 @@ lmtp_local_rcpt_anvil_cb(const char *reply, struct lmtp_local_recipient *llrcpt)
        unsigned int parallel_count = 0;
 
        llrcpt->anvil_query = NULL;
-       if (reply == NULL) {
+       if (reply->error != NULL) {
                /* lookup failed */
-       } else if (str_to_uint(reply, &parallel_count) < 0) {
-               e_error(rcpt->event, "Invalid reply from anvil: %s", reply);
+       } else if (str_to_uint(reply->reply, &parallel_count) < 0) {
+               e_error(rcpt->event, "Invalid reply from anvil: %s",
+                       reply->reply);
        }
 
        if (parallel_count >= client->lmtp_set->lmtp_user_concurrency_limit) {
index f02262c00f78b95299e90c940808d42e72b206dc..9c8cc192fd5bb007d80d9e9afa862f9f63ba792c 100644 (file)
@@ -237,7 +237,8 @@ static int master_send_request(struct anvil_request *anvil_request)
 }
 
 static void ATTR_NULL(1)
-anvil_lookup_callback(const char *reply, struct anvil_request *req)
+anvil_lookup_callback(const struct anvil_reply *reply,
+                     struct anvil_request *req)
 {
        struct client *client = req->client;
        const struct login_settings *set = client->set;
@@ -249,12 +250,15 @@ anvil_lookup_callback(const char *reply, struct anvil_request *req)
        client->anvil_request = NULL;
 
        conn_count = 0;
-       if (reply != NULL && str_to_uint(reply, &conn_count) < 0)
-               i_fatal("Received invalid reply from anvil: %s", reply);
+       if (reply != NULL && reply->error == NULL &&
+           str_to_uint(reply->reply, &conn_count) < 0)
+               i_fatal("Received invalid reply from anvil: %s", reply->reply);
 
        /* reply=NULL if we didn't need to do anvil lookup,
-          or if the anvil lookup failed. allow failed anvil lookups in. */
-       if (reply == NULL || conn_count < set->mail_max_userip_connections) {
+          reply->error != NULL if the anvil lookup failed.
+          Allow failed anvil lookups in. */
+       if (reply == NULL || reply->error != NULL ||
+           conn_count < set->mail_max_userip_connections) {
                if (master_send_request(req) < 0)
                        sasl_reply = SASL_SERVER_REPLY_MASTER_FAILED;
                errmsg = NULL; /* client will see internal error */