From: Timo Sirainen Date: Fri, 21 Mar 2025 14:09:45 +0000 (+0200) Subject: lib-master: Add API changes to allow anvil_callback_t to return error string X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ea0e4612df4ba1ba477efe426acad5a2327631ce;p=thirdparty%2Fdovecot%2Fcore.git lib-master: Add API changes to allow anvil_callback_t to return error string --- diff --git a/src/auth/auth-penalty.c b/src/auth/auth-penalty.c index 77b49f3b7d..78b5e0a116 100644 --- a/src/auth/auth-penalty.c +++ b/src/auth/auth-penalty.c @@ -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? */ diff --git a/src/doveadm/doveadm-kick.c b/src/doveadm/doveadm-kick.c index 07fab3be93..ac927f76b5 100644 --- a/src/doveadm/doveadm-kick.c +++ b/src/doveadm/doveadm-kick.c @@ -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; } diff --git a/src/lib-master/anvil-client.c b/src/lib-master/anvil-client.c index d38c343939..b1020a93f9 100644 --- a/src/lib-master/anvil-client.c +++ b/src/lib-master/anvil-client.c @@ -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); } diff --git a/src/lib-master/anvil-client.h b/src/lib-master/anvil-client.h index b2652f8160..a9fc62d6c0 100644 --- a/src/lib-master/anvil-client.h +++ b/src/lib-master/anvil-client.h @@ -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. */ diff --git a/src/lmtp/lmtp-local.c b/src/lmtp/lmtp-local.c index 9fe04559ed..74904e3ef3 100644 --- a/src/lmtp/lmtp-local.c +++ b/src/lmtp/lmtp-local.c @@ -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, ¶llel_count) < 0) { - e_error(rcpt->event, "Invalid reply from anvil: %s", reply); + } else if (str_to_uint(reply->reply, ¶llel_count) < 0) { + e_error(rcpt->event, "Invalid reply from anvil: %s", + reply->reply); } if (parallel_count >= client->lmtp_set->lmtp_user_concurrency_limit) { diff --git a/src/login-common/sasl-server.c b/src/login-common/sasl-server.c index f02262c00f..9c8cc192fd 100644 --- a/src/login-common/sasl-server.c +++ b/src/login-common/sasl-server.c @@ -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 */