From: Timo Sirainen Date: Thu, 23 Jun 2022 20:25:28 +0000 (+0300) Subject: lib-auth, global: Change forward_fields to be an array of strings X-Git-Tag: 2.4.0~3773 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2f2916e4047dc25303193553ed73237ba04fc7fc;p=thirdparty%2Fdovecot%2Fcore.git lib-auth, global: Change forward_fields to be an array of strings --- diff --git a/src/doveadm/doveadm-auth.c b/src/doveadm/doveadm-auth.c index 7ca9b186ae..88e34c7465 100644 --- a/src/doveadm/doveadm-auth.c +++ b/src/doveadm/doveadm-auth.c @@ -241,7 +241,8 @@ cmd_auth_input(const char *auth_socket_path, struct authtest_input *input) } static void -auth_user_info_parse_arg(struct auth_user_info *info, const char *arg) +auth_user_info_parse_arg(struct auth_user_info *info, const char *arg, + ARRAY_TYPE(const_string) *forward_fields) { const char *key, *value; @@ -276,21 +277,7 @@ auth_user_info_parse_arg(struct auth_user_info *info, const char *arg) if (net_str2port(value, &info->real_remote_port) < 0) i_fatal("real_rport: Invalid port number"); } else if (str_begins(arg, "forward_", &key)) { - value = strchr(key, '='); - - if (value == NULL) - value = ""; - else - key = t_strdup_until(key, value++); - key = str_tabescape(key); - value = str_tabescape(value); - if (info->forward_fields == NULL) { - info->forward_fields = - t_strdup_printf("%s=%s", key, value); - } else { - info->forward_fields = - t_strdup_printf("%s\t%s=%s", info->forward_fields, key, value); - } + array_push_back(forward_fields, &key); } else { if (!array_is_created(&info->extra_fields)) t_array_init(&info->extra_fields, 4); @@ -301,8 +288,14 @@ auth_user_info_parse_arg(struct auth_user_info *info, const char *arg) static void auth_user_info_parse(struct auth_user_info *info, const char *const *args) { + ARRAY_TYPE(const_string) forward_fields; + t_array_init(&forward_fields, 8); for (unsigned int i = 0; args[i] != NULL; i++) - auth_user_info_parse_arg(info, args[i]); + auth_user_info_parse_arg(info, args[i], &forward_fields); + if (array_count(&forward_fields) > 0) { + array_append_zero(&forward_fields); + info->forward_fields = array_front(&forward_fields); + } } static void diff --git a/src/doveadm/doveadm-mail.c b/src/doveadm/doveadm-mail.c index 1fd2e69759..87a62c7898 100644 --- a/src/doveadm/doveadm-mail.c +++ b/src/doveadm/doveadm-mail.c @@ -253,22 +253,15 @@ void doveadm_mail_get_input(struct doveadm_mail_cmd_context *ctx) doveadm_mail_cmd_input_read(ctx); } -const char * +const char *const * doveadm_mail_get_forward_fields(struct doveadm_mail_cmd_context *ctx) { - const char *field; - string_t *str; - if (!array_is_created(&ctx->proxy_forward_fields)) return NULL; - str = t_str_new(128); - array_foreach_elem(&ctx->proxy_forward_fields, field) { - if (str_len(str) > 0) - str_append_c(str, '\t'); - str_append_tabescaped(str, field); - } - return str_c(str); + array_append_zero(&ctx->proxy_forward_fields); + array_pop_back(&ctx->proxy_forward_fields); + return array_front(&ctx->proxy_forward_fields); } struct mailbox * diff --git a/src/doveadm/doveadm-mail.h b/src/doveadm/doveadm-mail.h index b297668c97..c4d2ee19f7 100644 --- a/src/doveadm/doveadm-mail.h +++ b/src/doveadm/doveadm-mail.h @@ -132,7 +132,7 @@ void doveadm_mail_server_flush(void); /* Request input stream to be read (from stdin). This must be called from the command's init() function. */ void doveadm_mail_get_input(struct doveadm_mail_cmd_context *ctx); -const char * +const char *const * doveadm_mail_get_forward_fields(struct doveadm_mail_cmd_context *ctx); struct mailbox * diff --git a/src/lib-auth/auth-client-request.c b/src/lib-auth/auth-client-request.c index df68b5e4ea..41151133b6 100644 --- a/src/lib-auth/auth-client-request.c +++ b/src/lib-auth/auth-client-request.c @@ -126,10 +126,15 @@ static void auth_server_send_new_request(struct auth_client_connection *conn, str_append_tabescaped(str, info->client_id); event_add_str(request->event, "client_id", info->client_id); } - if (info->forward_fields != NULL && - *info->forward_fields != '\0') { + if (info->forward_fields != NULL && info->forward_fields[0] != NULL) { + string_t *forward = t_str_new(64); + str_append_tabescaped(forward, info->forward_fields[0]); + for (unsigned int i = 1; info->forward_fields[i] != NULL; i++) { + str_append_c(forward, '\t'); + str_append_tabescaped(forward, info->forward_fields[i]); + } str_append(str, "\tforward_fields="); - str_append_tabescaped(str, info->forward_fields); + str_append_tabescaped(str, str_c(forward)); } if (array_is_created(&info->extra_fields)) { const char *const *fieldp; diff --git a/src/lib-auth/auth-client.h b/src/lib-auth/auth-client.h index 917f9042e2..1528f40285 100644 --- a/src/lib-auth/auth-client.h +++ b/src/lib-auth/auth-client.h @@ -45,7 +45,7 @@ struct auth_request_info { const char *cert_username; const char *local_name; const char *client_id; - const char *forward_fields; + const char *const *forward_fields; ARRAY_TYPE(const_string) extra_fields; unsigned int ssl_cipher_bits; diff --git a/src/lib-auth/auth-master.c b/src/lib-auth/auth-master.c index 896bcc00ce..20ee481a4b 100644 --- a/src/lib-auth/auth-master.c +++ b/src/lib-auth/auth-master.c @@ -559,10 +559,15 @@ void auth_user_info_export(string_t *str, const struct auth_user_info *info) str_printfa(str, "\treal_rport=%d", info->real_remote_port); if (info->debug) str_append(str, "\tdebug"); - if (info->forward_fields != NULL && - *info->forward_fields != '\0') { + if (info->forward_fields != NULL && info->forward_fields[0] != NULL) { + string_t *forward = t_str_new(64); + str_append_tabescaped(forward, info->forward_fields[0]); + for (unsigned int i = 1; info->forward_fields[i] != NULL; i++) { + str_append_c(forward, '\t'); + str_append_tabescaped(forward, info->forward_fields[i]); + } str_append(str, "\tforward_fields="); - str_append_tabescaped(str, info->forward_fields); + str_append_tabescaped(str, str_c(forward)); } if (array_is_created(&info->extra_fields)) { array_foreach(&info->extra_fields, fieldp) { diff --git a/src/lib-auth/auth-master.h b/src/lib-auth/auth-master.h index f62985a9b4..b4bcd59a67 100644 --- a/src/lib-auth/auth-master.h +++ b/src/lib-auth/auth-master.h @@ -16,7 +16,7 @@ struct auth_user_info { const char *local_name; struct ip_addr local_ip, remote_ip, real_local_ip, real_remote_ip; in_port_t local_port, remote_port, real_local_port, real_remote_port; - const char *forward_fields; + const char *const *forward_fields; ARRAY_TYPE(const_string) extra_fields; bool debug; }; diff --git a/src/lib-storage/mail-storage-service.h b/src/lib-storage/mail-storage-service.h index 31508e80ed..6831080fdf 100644 --- a/src/lib-storage/mail-storage-service.h +++ b/src/lib-storage/mail-storage-service.h @@ -58,7 +58,7 @@ struct mail_storage_service_input { const char *const *userdb_fields; - const char *forward_fields; + const char *const *forward_fields; /* Override specified global flags */ enum mail_storage_service_flags flags_override_add; diff --git a/src/lmtp/lmtp-commands.c b/src/lmtp/lmtp-commands.c index 9bacf28c23..dde9eb6c62 100644 --- a/src/lmtp/lmtp-commands.c +++ b/src/lmtp/lmtp-commands.c @@ -2,6 +2,7 @@ #include "lmtp-common.h" #include "str.h" +#include "strescape.h" #include "istream.h" #include "istream-concat.h" #include "ostream.h" @@ -81,7 +82,8 @@ cmd_rcpt_handle_forward_fields(struct smtp_server_cmd_ctx *cmd, return -1; } - lrcpt->forward_fields = p_strdup(rcpt->pool, str_c(xforward)); + char **fields = p_strsplit_tabescaped(rcpt->pool, str_c(xforward)); + lrcpt->forward_fields = (const char *const *)fields; return 0; } diff --git a/src/lmtp/lmtp-recipient.h b/src/lmtp/lmtp-recipient.h index c28b4c2c9f..0d055ef19e 100644 --- a/src/lmtp/lmtp-recipient.h +++ b/src/lmtp/lmtp-recipient.h @@ -24,7 +24,7 @@ struct lmtp_recipient { void *backend_context; const char *session_id; - const char *forward_fields; + const char *const *forward_fields; /* Module-specific contexts. */ ARRAY(union lmtp_recipient_module_context *) module_contexts; diff --git a/src/login-common/client-common-auth.c b/src/login-common/client-common-auth.c index 5e6f1de255..74363411eb 100644 --- a/src/login-common/client-common-auth.c +++ b/src/login-common/client-common-auth.c @@ -487,8 +487,11 @@ proxy_redirect_reauth(struct client *client, const char *destuser, t_array_init(&info.extra_fields, N_ELEMENTS(extra_fields)); array_append(&info.extra_fields, extra_fields, N_ELEMENTS(extra_fields)); - if (client->forward_fields != NULL) - info.forward_fields = str_c(client->forward_fields); + if (array_is_created(&client->forward_fields)) { + array_append_zero(&client->forward_fields); + array_pop_back(&client->forward_fields); + info.forward_fields = array_front(&client->forward_fields); + } client->reauth_request = auth_client_request_new(auth_client, &info, proxy_redirect_reauth_callback, client); diff --git a/src/login-common/client-common.c b/src/login-common/client-common.c index a53fde3c09..0992a959cd 100644 --- a/src/login-common/client-common.c +++ b/src/login-common/client-common.c @@ -335,7 +335,7 @@ void client_destroy(struct client *client, const char *reason) client_disconnect(client, reason, !client->login_success); pool_unref(&client->preproxy_pool); - client->forward_fields = NULL; + i_zero(&client->forward_fields); client->client_id = NULL; if (client->master_tag != 0) { @@ -739,25 +739,28 @@ struct client *clients_get_first_fd_proxy(void) void client_add_forward_field(struct client *client, const char *key, const char *value) { - if (client->forward_fields == NULL) - client->forward_fields = str_new(client->preproxy_pool, 32); - else - str_append_c(client->forward_fields, '\t'); + if (!array_is_created(&client->forward_fields)) + p_array_init(&client->forward_fields, client->preproxy_pool, 8); /* prefixing is done by auth process */ - str_append_tabescaped(client->forward_fields, key); - str_append_c(client->forward_fields, '='); - str_append_tabescaped(client->forward_fields, value); + const char *entry = + p_strdup_printf(client->preproxy_pool, "%s=%s", key, value); + array_push_back(&client->forward_fields, &entry); } bool client_forward_decode_base64(struct client *client, const char *value) { size_t value_len = strlen(value); - string_t *str = str_new(client->preproxy_pool, - MAX_BASE64_DECODED_SIZE(value_len)); + string_t *str = t_str_new(MAX_BASE64_DECODED_SIZE(value_len)); if (base64_decode(value, value_len, str) < 0) return FALSE; - client->forward_fields = str; + char **_fields = p_strsplit_tabescaped(client->preproxy_pool, + str_c(str)); + const char *const *fields = (const char *const *)_fields; + unsigned int fields_count = str_array_length(fields); + p_array_init(&client->forward_fields, + client->preproxy_pool, fields_count); + array_append(&client->forward_fields, fields, fields_count); return TRUE; } diff --git a/src/login-common/client-common.h b/src/login-common/client-common.h index 0bbc07cd11..1e44cbaab7 100644 --- a/src/login-common/client-common.h +++ b/src/login-common/client-common.h @@ -172,7 +172,7 @@ struct client { const char *client_cert_common_name; string_t *client_id; - string_t *forward_fields; + ARRAY_TYPE(const_string) forward_fields; int fd; struct istream *input; diff --git a/src/login-common/sasl-server.c b/src/login-common/sasl-server.c index 0a2f1f6258..ef6730da4b 100644 --- a/src/login-common/sasl-server.c +++ b/src/login-common/sasl-server.c @@ -1,6 +1,7 @@ /* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */ #include "login-common.h" +#include "array.h" #include "str.h" #include "base64.h" #include "buffer.h" @@ -476,8 +477,11 @@ int sasl_server_auth_request_info_fill(struct client *client, info_r->real_remote_port = client->real_remote_port; if (client->client_id != NULL) info_r->client_id = str_c(client->client_id); - if (client->forward_fields != NULL) - info_r->forward_fields = str_c(client->forward_fields); + if (array_is_created(&client->forward_fields)) { + array_append_zero(&client->forward_fields); + array_pop_back(&client->forward_fields); + info_r->forward_fields = array_front(&client->forward_fields); + } return 0; }