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);
}
}
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);
}
}
}
/* 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);
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);
"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)
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)
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;
}
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);
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);
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;
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]);
} 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 */
/* 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;
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)
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;
}
}
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++) {
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[])
/* 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. */
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)
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++) {
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++;
}
}
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();
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
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;
}
}
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)
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));