From: Timo Sirainen Date: Wed, 20 Jan 2021 18:46:27 +0000 (+0200) Subject: lib, global: Change env_put() API to take name,value pair X-Git-Tag: 2.3.16~176 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9f1b0a7fa536b470ad511ecaaacb5500997b7d98;p=thirdparty%2Fdovecot%2Fcore.git lib, global: Change env_put() API to take name,value pair --- diff --git a/src/auth/db-checkpassword.c b/src/auth/db-checkpassword.c index ffa2497f3b..dd7928b15f 100644 --- a/src/auth/db-checkpassword.c +++ b/src/auth/db-checkpassword.c @@ -57,7 +57,7 @@ env_put_extra_fields(const ARRAY_TYPE(auth_field) *extra_fields) array_foreach(extra_fields, field) { key = t_str_ucase(field->key); value = field->value != NULL ? field->value : "1"; - env_put(t_strconcat(key, "=", value, NULL)); + env_put(key, value); } } @@ -215,9 +215,9 @@ static void env_put_auth_vars(struct auth_request *request) checkpassword API. */ if (tab[i].long_key != NULL && tab[i].value != NULL && strcasecmp(tab[i].long_key, "password") != 0) { - env_put(t_strdup_printf("AUTH_%s=%s", - t_str_ucase(tab[i].long_key), - tab[i].value)); + env_put(t_strdup_printf("AUTH_%s", + t_str_ucase(tab[i].long_key)), + tab[i].value); } } } @@ -229,37 +229,27 @@ static void checkpassword_setup_env(struct auth_request *request) /* Besides passing the standard username and password in a pipe, also pass some other possibly interesting information via environment. Use UCSPI names for local/remote IPs. */ - env_put("PROTO=TCP"); /* UCSPI */ - env_put(t_strdup_printf("ORIG_UID=%s", dec2str(getuid()))); - env_put(t_strconcat("SERVICE=", fields->service, NULL)); + env_put("PROTO", "TCP"); /* UCSPI */ + env_put("ORIG_UID", dec2str(getuid())); + env_put("SERVICE", fields->service); if (fields->local_ip.family != 0) { - env_put(t_strconcat("TCPLOCALIP=", - net_ip2addr(&fields->local_ip), NULL)); + env_put("TCPLOCALIP", net_ip2addr(&fields->local_ip)); /* FIXME: for backwards compatibility only, remove some day */ - env_put(t_strconcat("LOCAL_IP=", - net_ip2addr(&fields->local_ip), NULL)); + env_put("LOCAL_IP", net_ip2addr(&fields->local_ip)); } if (fields->remote_ip.family != 0) { - env_put(t_strconcat("TCPREMOTEIP=", - net_ip2addr(&fields->remote_ip), NULL)); + env_put("TCPREMOTEIP", net_ip2addr(&fields->remote_ip)); /* FIXME: for backwards compatibility only, remove some day */ - env_put(t_strconcat("REMOTE_IP=", - net_ip2addr(&fields->remote_ip), NULL)); - } - if (fields->local_port != 0) { - env_put(t_strdup_printf("TCPLOCALPORT=%u", - fields->local_port)); - } - if (fields->remote_port != 0) { - env_put(t_strdup_printf("TCPREMOTEPORT=%u", - fields->remote_port)); - } - if (fields->master_user != NULL) { - env_put(t_strconcat("MASTER_USER=", - fields->master_user, NULL)); + env_put("REMOTE_IP", net_ip2addr(&fields->remote_ip)); } + if (fields->local_port != 0) + env_put("TCPLOCALPORT", dec2str(fields->local_port)); + if (fields->remote_port != 0) + env_put("TCPREMOTEPORT", dec2str(fields->remote_port)); + if (fields->master_user != NULL) + env_put("MASTER_USER", fields->master_user); if (!auth_fields_is_empty(fields->extra_fields)) { const ARRAY_TYPE(auth_field) *extra_fields = auth_fields_export(fields->extra_fields); @@ -394,12 +384,11 @@ checkpassword_exec(struct db_checkpassword *db, struct auth_request *request, ignored by setting AUTHORIZED. This needs a special checkpassword program which knows how to handle this. */ - env_put("AUTHORIZED=1"); + env_put("AUTHORIZED", "1"); if (request->wanted_credentials_scheme != NULL) { /* passdb credentials lookup */ - env_put("CREDENTIALS_LOOKUP=1"); - env_put(t_strdup_printf("SCHEME=%s", - request->wanted_credentials_scheme)); + env_put("CREDENTIALS_LOOKUP", "1"); + env_put("SCHEME", request->wanted_credentials_scheme); } } checkpassword_setup_env(request); diff --git a/src/auth/db-ldap.c b/src/auth/db-ldap.c index 899dd3875b..1b69a4911c 100644 --- a/src/auth/db-ldap.c +++ b/src/auth/db-ldap.c @@ -1937,7 +1937,7 @@ struct ldap_connection *db_ldap_init(const char *config_path, bool userdb) "settings not allowed (%s and %s)", config_path, str, conn->set.ldaprc_path); } - env_put(t_strconcat("LDAPRC=", conn->set.ldaprc_path, NULL)); + env_put("LDAPRC", conn->set.ldaprc_path); } if (deref2str(conn->set.deref, &conn->set.ldap_deref) < 0) diff --git a/src/auth/mech-gssapi.c b/src/auth/mech-gssapi.c index 33eb8d7946..e9f2af2f2b 100644 --- a/src/auth/mech-gssapi.c +++ b/src/auth/mech-gssapi.c @@ -109,7 +109,7 @@ static void mech_gssapi_initialize(const struct auth_settings *set) if (*path != '\0') { /* environment may be used by Kerberos 5 library directly */ - env_put(t_strconcat("KRB5_KTNAME=", path, NULL)); + env_put("KRB5_KTNAME", path); #ifdef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY gsskrb5_register_acceptor_identity(path); #elif defined (HAVE_KRB5_GSS_REGISTER_ACCEPTOR_IDENTITY) diff --git a/src/config/doveconf.c b/src/config/doveconf.c index a32fedf223..9f519552b8 100644 --- a/src/config/doveconf.c +++ b/src/config/doveconf.c @@ -675,7 +675,7 @@ static void config_request_putenv(const char *key, const char *value, void *context ATTR_UNUSED) { T_BEGIN { - env_put(t_strconcat(t_str_ucase(key), "=", value, NULL)); + env_put(t_str_ucase(key), value); } T_END; } @@ -1049,7 +1049,7 @@ int main(int argc, char *argv[]) master_service_env_clean(); } - env_put("DOVECONF_ENV=1"); + env_put("DOVECONF_ENV", "1"); if (config_export_finish(&ctx) < 0) i_fatal("Invalid configuration"); execvp(exec_args[0], exec_args); diff --git a/src/dict/main.c b/src/dict/main.c index 2e7ea71c26..5ab0852a0a 100644 --- a/src/dict/main.c +++ b/src/dict/main.c @@ -106,8 +106,7 @@ static void main_init(void) if (*dict_settings->dict_db_config != '\0') { /* for berkeley db library */ - env_put(t_strconcat("DB_CONFIG=", dict_settings->dict_db_config, - NULL)); + env_put("DB_CONFIG", dict_settings->dict_db_config); } i_zero(&mod_set); diff --git a/src/doveadm/doveadm.c b/src/doveadm/doveadm.c index 22245013c4..7076c38ffa 100644 --- a/src/doveadm/doveadm.c +++ b/src/doveadm/doveadm.c @@ -173,7 +173,7 @@ static void cmd_help(int argc ATTR_UNUSED, char *argv[]) if (argv[1] == NULL) usage_to(stdout, ""); - env_put("MANPATH="MANDIR); + env_put("MANPATH", MANDIR); man_argv[0] = "man"; man_argv[1] = t_strconcat("doveadm-", argv[1], NULL); man_argv[2] = NULL; @@ -186,8 +186,8 @@ static struct doveadm_cmd doveadm_cmd_help = { static void cmd_config(int argc ATTR_UNUSED, char *argv[]) { - env_put(t_strconcat(MASTER_CONFIG_FILE_ENV"=", - master_service_get_config_path(master_service), NULL)); + env_put(MASTER_CONFIG_FILE_ENV, + master_service_get_config_path(master_service)); argv[0] = BINDIR"/doveconf"; (void)execv(argv[0], argv); i_fatal("execv(%s) failed: %m", argv[0]); diff --git a/src/lda/main.c b/src/lda/main.c index 9a1064b004..5cb1d4daad 100644 --- a/src/lda/main.c +++ b/src/lda/main.c @@ -505,7 +505,7 @@ int main(int argc, char *argv[]) } else if ((ret = i_getpwuid(process_euid, &pw)) > 0) { user = t_strdup(pw.pw_name); if (home == NULL) - env_put(t_strconcat("HOME=", pw.pw_dir, NULL)); + env_put("HOME", pw.pw_dir); user_source = "passwd lookup for process euid"; } else if (ret < 0) { /* temporary failure */ diff --git a/src/lib-master/master-service-settings.c b/src/lib-master/master-service-settings.c index d16dc7bba3..1fb19d5b6e 100644 --- a/src/lib-master/master-service-settings.c +++ b/src/lib-master/master-service-settings.c @@ -191,13 +191,13 @@ master_service_exec_config(struct master_service *service, /* doveconf empties the environment before exec()ing us back if DOVECOT_PRESERVE_ENVS is set, so make sure it is. */ if (getenv(DOVECOT_PRESERVE_ENVS_ENV) == NULL) - env_put(DOVECOT_PRESERVE_ENVS_ENV"="); + env_put(DOVECOT_PRESERVE_ENVS_ENV, ""); } else { /* make sure doveconf doesn't remove any environment */ env_remove(DOVECOT_PRESERVE_ENVS_ENV); } if (input->use_sysexits) - env_put("USE_SYSEXITS=1"); + env_put("USE_SYSEXITS", "1"); /* @UNSAFE */ i = 0; diff --git a/src/lib-master/master-service.c b/src/lib-master/master-service.c index b1f01e2de2..703bf44d9b 100644 --- a/src/lib-master/master-service.c +++ b/src/lib-master/master-service.c @@ -724,15 +724,15 @@ static void master_service_import_environment_real(const char *import_environmen if (value == NULL) key = *envs; else { - key = t_strdup_until(*envs, value); - env_put(*envs); + key = t_strdup_until(*envs, value++); + env_put(key, value); } array_push_back(&keys, &key); } array_append_zero(&keys); value = t_strarray_join(array_front(&keys), " "); - env_put(t_strconcat(DOVECOT_PRESERVE_ENVS_ENV"=", value, NULL)); + env_put(DOVECOT_PRESERVE_ENVS_ENV, value); } void master_service_import_environment(const char *import_environment) diff --git a/src/lib/env-util.c b/src/lib/env-util.c index 231b1bcc0c..493b9706af 100644 --- a/src/lib/env-util.c +++ b/src/lib/env-util.c @@ -15,21 +15,27 @@ struct env_backup { static pool_t env_pool = NULL; -void env_put(const char *env) +void env_put(const char *name, const char *value) { + i_assert(strchr(name, '=') == NULL); + if (env_pool == NULL) { env_pool = pool_alloconly_create(MEMPOOL_GROWING"Environment", 2048); } - if (putenv(p_strdup(env_pool, env)) != 0) - i_fatal("putenv(%s) failed: %m", env); + if (putenv(p_strdup_printf(env_pool, "%s=%s", name, value)) != 0) + i_fatal("putenv(%s=%s) failed: %m", name, value); } void env_put_array(const char *const *envs) { for (unsigned int i = 0; envs[i] != NULL; i++) { - i_assert(strchr(envs[i], '=') != NULL); - env_put(envs[i]); + const char *value = strchr(envs[i], '='); + i_assert(value != NULL); + T_BEGIN { + const char *name = t_strdup_until(envs[i], value++); + env_put(name, value); + } T_END; } } @@ -84,8 +90,8 @@ void env_clean(void) static void env_clean_except_real(const char *const preserve_envs[]) { ARRAY_TYPE(const_string) copy; - const char *value, *env; - unsigned int i; + const char *value, *const *envp; + unsigned int i, count; t_array_init(©, 16); for (i = 0; preserve_envs[i] != NULL; i++) { @@ -93,18 +99,21 @@ static void env_clean_except_real(const char *const preserve_envs[]) value = getenv(key); if (value != NULL) { - value = t_strconcat(key, "=", value, NULL); + key = t_strdup(key); + value = t_strdup(value); + array_push_back(©, &key); array_push_back(©, &value); } } /* Note that if the original environment was set with env_put(), the environment strings will be invalid after env_clean(). That's why - we t_strconcat() them above. */ + we t_strdup() them above. */ env_clean(); - array_foreach_elem(©, env) - env_put(env); + envp = array_get(©, &count); + for (i = 0; i < count; i += 2) + env_put(envp[i], envp[i+1]); } void env_clean_except(const char *const preserve_envs[]) diff --git a/src/lib/env-util.h b/src/lib/env-util.h index d1aa516639..7d3ad5434b 100644 --- a/src/lib/env-util.h +++ b/src/lib/env-util.h @@ -3,7 +3,7 @@ /* Add new environment variable. Wrapper to putenv(). Note that calls to this function allocates memory which isn't free'd until env_clean() is called. */ -void env_put(const char *env); +void env_put(const char *name, const char *value); /* env_put() NULL-terminated array of name=value strings */ void env_put_array(const char *const *envs); /* Remove a single environment. */ diff --git a/src/lib/restrict-access.c b/src/lib/restrict-access.c index ebaa0df859..a8fc47d2fb 100644 --- a/src/lib/restrict-access.c +++ b/src/lib/restrict-access.c @@ -379,38 +379,24 @@ void restrict_access(const struct restrict_access_settings *set, void restrict_access_set_env(const struct restrict_access_settings *set) { if (set->system_groups_user != NULL && - *set->system_groups_user != '\0') { - env_put(t_strconcat("RESTRICT_USER=", - set->system_groups_user, NULL)); - } + *set->system_groups_user != '\0') + env_put("RESTRICT_USER", set->system_groups_user); if (set->chroot_dir != NULL && *set->chroot_dir != '\0') - env_put(t_strconcat("RESTRICT_CHROOT=", set->chroot_dir, NULL)); + env_put("RESTRICT_CHROOT", set->chroot_dir); - if (set->uid != (uid_t)-1) { - env_put(t_strdup_printf("RESTRICT_SETUID=%s", - dec2str(set->uid))); - } - if (set->gid != (gid_t)-1) { - env_put(t_strdup_printf("RESTRICT_SETGID=%s", - dec2str(set->gid))); - } - if (set->privileged_gid != (gid_t)-1) { - env_put(t_strdup_printf("RESTRICT_SETGID_PRIV=%s", - dec2str(set->privileged_gid))); - } - if (set->extra_groups != NULL && *set->extra_groups != '\0') { - env_put(t_strconcat("RESTRICT_SETEXTRAGROUPS=", - set->extra_groups, NULL)); - } + if (set->uid != (uid_t)-1) + env_put("RESTRICT_SETUID", dec2str(set->uid)); + if (set->gid != (gid_t)-1) + env_put("RESTRICT_SETGID", dec2str(set->gid)); + if (set->privileged_gid != (gid_t)-1) + env_put("RESTRICT_SETGID_PRIV", dec2str(set->privileged_gid)); + if (set->extra_groups != NULL && *set->extra_groups != '\0') + env_put("RESTRICT_SETEXTRAGROUPS", set->extra_groups); - if (set->first_valid_gid != 0) { - env_put(t_strdup_printf("RESTRICT_GID_FIRST=%s", - dec2str(set->first_valid_gid))); - } - if (set->last_valid_gid != 0) { - env_put(t_strdup_printf("RESTRICT_GID_LAST=%s", - dec2str(set->last_valid_gid))); - } + if (set->first_valid_gid != 0) + env_put("RESTRICT_GID_FIRST", dec2str(set->first_valid_gid)); + if (set->last_valid_gid != 0) + env_put("RESTRICT_GID_LAST", dec2str(set->last_valid_gid)); } static const char *null_if_empty(const char *str) diff --git a/src/lib/test-var-expand.c b/src/lib/test-var-expand.c index bae4277f5d..558ef76b86 100644 --- a/src/lib/test-var-expand.c +++ b/src/lib/test-var-expand.c @@ -73,7 +73,7 @@ static void test_var_expand_builtin(void) tests[0].out = my_hostname; tests[1].out = my_pid; - env_put("FOO=baR"); + env_put("FOO", "baR"); test_begin("var_expand - builtin"); for (i = 0; i < N_ELEMENTS(tests); i++) { diff --git a/src/master/service-process.c b/src/master/service-process.c index 3baa991a47..29f2f81362 100644 --- a/src/master/service-process.c +++ b/src/master/service-process.c @@ -107,8 +107,9 @@ service_dup_fds(struct service *service) dup2_append(&dups, listeners[i]->fd, fd++); - env_put(t_strdup_printf("SOCKET%d_SETTINGS=%s", - socket_listener_count, str_c(listener_settings))); + env_put(t_strdup_printf("SOCKET%d_SETTINGS", + socket_listener_count), + str_c(listener_settings)); socket_listener_count++; } } @@ -150,7 +151,7 @@ service_dup_fds(struct service *service) to be lost. */ i_assert(service->log_fd[1] != -1); - env_put("LOG_SERVICE=1"); + env_put("LOG_SERVICE", "1"); if (dup2(service->log_fd[1], STDERR_FILENO) < 0) i_fatal("dup2(log fd) failed: %m"); i_set_failure_internal(); @@ -170,7 +171,7 @@ service_dup_fds(struct service *service) i_fatal("service(%s): dup2s failed", service->set->name); i_assert(fd == MASTER_LISTEN_FD_FIRST + (int)socket_listener_count); - env_put(t_strdup_printf("SOCKET_COUNT=%d", socket_listener_count)); + env_put("SOCKET_COUNT", dec2str(socket_listener_count)); } static void @@ -212,26 +213,25 @@ static void service_process_setup_config_environment(struct service *service) switch (service->type) { case SERVICE_TYPE_CONFIG: - env_put(t_strconcat(MASTER_CONFIG_FILE_ENV"=", - service->config_file_path, NULL)); + env_put(MASTER_CONFIG_FILE_ENV, service->config_file_path); break; case SERVICE_TYPE_LOG: /* give the log's configuration directly, so it won't depend on config process */ - env_put("DOVECONF_ENV=1"); - env_put(t_strconcat("LOG_PATH=", set->log_path, NULL)); - env_put(t_strconcat("INFO_LOG_PATH=", set->info_log_path, NULL)); - env_put(t_strconcat("DEBUG_LOG_PATH=", set->debug_log_path, NULL)); - env_put(t_strconcat("LOG_TIMESTAMP=", set->log_timestamp, NULL)); - env_put(t_strconcat("SYSLOG_FACILITY=", set->syslog_facility, NULL)); - env_put(t_strconcat("INSTANCE_NAME=", set->instance_name, NULL)); + env_put("DOVECONF_ENV", "1"); + env_put("LOG_PATH", set->log_path); + env_put("INFO_LOG_PATH", set->info_log_path); + env_put("DEBUG_LOG_PATH", set->debug_log_path); + env_put("LOG_TIMESTAMP", set->log_timestamp); + env_put("SYSLOG_FACILITY", set->syslog_facility); + env_put("INSTANCE_NAME", set->instance_name); if (set->verbose_proctitle) - env_put("VERBOSE_PROCTITLE=1"); - env_put("SSL=no"); + env_put("VERBOSE_PROCTITLE", "1"); + env_put("SSL", "no"); break; default: - env_put(t_strconcat(MASTER_CONFIG_FILE_ENV"=", - services_get_config_socket_path(service->list), NULL)); + env_put(MASTER_CONFIG_FILE_ENV, + services_get_config_socket_path(service->list)); break; } } @@ -244,45 +244,39 @@ service_process_setup_environment(struct service *service, unsigned int uid, service->list->service_set; master_service_env_clean(); - env_put(MASTER_IS_PARENT_ENV"=1"); + env_put(MASTER_IS_PARENT_ENV, "1"); service_process_setup_config_environment(service); - env_put(t_strdup_printf(MASTER_SERVICE_ENV"=%s", - service->set->name)); - env_put(t_strdup_printf(MASTER_CLIENT_LIMIT_ENV"=%u", - service->client_limit)); - env_put(t_strdup_printf(MASTER_PROCESS_LIMIT_ENV"=%u", - service->process_limit)); - env_put(t_strdup_printf(MASTER_PROCESS_MIN_AVAIL_ENV"=%u", - service->set->process_min_avail)); - env_put(t_strdup_printf(MASTER_SERVICE_IDLE_KILL_ENV"=%u", - service->idle_kill)); + env_put(MASTER_SERVICE_ENV, service->set->name); + env_put(MASTER_CLIENT_LIMIT_ENV, dec2str(service->client_limit)); + env_put(MASTER_PROCESS_LIMIT_ENV, dec2str(service->process_limit)); + env_put(MASTER_PROCESS_MIN_AVAIL_ENV, + dec2str(service->set->process_min_avail)); + env_put(MASTER_SERVICE_IDLE_KILL_ENV, dec2str(service->idle_kill)); if (service->set->service_count != 0) { - env_put(t_strdup_printf(MASTER_SERVICE_COUNT_ENV"=%u", - service->set->service_count)); + env_put(MASTER_SERVICE_COUNT_ENV, + dec2str(service->set->service_count)); } - env_put(t_strdup_printf(MASTER_UID_ENV"=%u", uid)); - env_put(t_strdup_printf(MY_HOSTNAME_ENV"=%s", my_hostname)); - env_put(t_strdup_printf(MY_HOSTDOMAIN_ENV"=%s", hostdomain)); + env_put(MASTER_UID_ENV, dec2str(uid)); + env_put(MY_HOSTNAME_ENV, my_hostname); + env_put(MY_HOSTDOMAIN_ENV, hostdomain); if (!service->set->master_set->version_ignore) - env_put(MASTER_DOVECOT_VERSION_ENV"="PACKAGE_VERSION); + env_put(MASTER_DOVECOT_VERSION_ENV, PACKAGE_VERSION); if (service_set->stats_writer_socket_path[0] != '\0') { - env_put(t_strdup_printf(DOVECOT_STATS_WRITER_SOCKET_PATH"=%s/%s", - service_set->base_dir, + env_put(DOVECOT_STATS_WRITER_SOCKET_PATH, + t_strdup_printf("%s/%s", service_set->base_dir, service_set->stats_writer_socket_path)); } if (ssl_manual_key_password != NULL && service->have_inet_listeners) { /* manually given SSL password. give it only to services that have inet listeners. */ - env_put(t_strconcat(MASTER_SSL_KEY_PASSWORD_ENV"=", - ssl_manual_key_password, NULL)); + env_put(MASTER_SSL_KEY_PASSWORD_ENV, ssl_manual_key_password); } if (service->type == SERVICE_TYPE_ANVIL && service_anvil_global->restarted) - env_put("ANVIL_RESTARTED=1"); - env_put(t_strconcat(DOVECOT_LOG_DEBUG_ENV"=", - service_set->log_debug, NULL)); + env_put("ANVIL_RESTARTED", "1"); + env_put(DOVECOT_LOG_DEBUG_ENV, service_set->log_debug); } static void service_process_status_timeout(struct service_process *process) diff --git a/src/util/script-login.c b/src/util/script-login.c index e8f7b40f8b..062a1a6a08 100644 --- a/src/util/script-login.c +++ b/src/util/script-login.c @@ -98,19 +98,19 @@ static void client_connected(struct master_service_connection *conn) input.username = args[i++]; input.userdb_fields = args + i; - env_put(t_strconcat("LOCAL_IP=", net_ip2addr(&input.local_ip), NULL)); - env_put(t_strconcat("IP=", net_ip2addr(&input.remote_ip), NULL)); - env_put(t_strconcat("USER=", input.username, NULL)); + env_put("LOCAL_IP", net_ip2addr(&input.local_ip)); + env_put("IP", net_ip2addr(&input.remote_ip)); + env_put("USER", input.username); for (; args[i] != NULL; i++) { value = strchr(args[i], '='); if (value != NULL) { - key = t_str_ucase(t_strdup_until(args[i], value)); - env_put(t_strconcat(key, value, NULL)); + key = t_str_ucase(t_strdup_until(args[i], value++)); + env_put(key, value); str_printfa(keys, "%s ", key); } } - env_put(t_strconcat(ENV_USERDB_KEYS"=", str_c(keys), NULL)); + env_put(ENV_USERDB_KEYS, str_c(keys)); master_service_init_log_with_prefix(master_service, t_strdup_printf("script-login(%s): ", input.username));