Example #1
0
//void do_sender(const char *s)
void do_sender(char *s)
{
  char *x;
  int n;
  int a;
  int i;

  env_unset("QMAILNAME");
  env_unset("MAILNAME");
  env_unset("NAME");
  env_unset("QMAILHOST");
  env_unset("MAILHOST");

  n = str_len(s);
  a = str_rchr(s, '@');
  if (a == n)
  {
    env_put("QMAILUSER", s);
    return;
  }
  env_put("QMAILHOST",s + a + 1);

  x = (char *) alloc((a + 1) * sizeof(char));
  if (!x) nomem();
  for (i = 0; i < a; i++)
    x[i] = s[i];
  x[i] = 0;
  env_put("QMAILUSER", x);
  alloc_free(x);
}
Example #2
0
static void service_process_setup_config_environment(struct service *service)
{
	const struct master_service_settings *set = service->list->service_set;

	switch (service->type) {
	case SERVICE_TYPE_CONFIG:
		env_put(t_strconcat(MASTER_CONFIG_FILE_ENV"=",
				    service->config_file_path, NULL));
		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));
		if (set->verbose_proctitle)
			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));
		break;
	}
}
static void ATTR_NORETURN
master_service_exec_config(struct master_service *service,
			   const struct master_service_settings_input *input)
{
	const char **conf_argv, *binary_path = service->argv[0];
	const char *home = NULL, *user = NULL, *timestamp = NULL;
	unsigned int i, argv_max_count;

	(void)t_binary_abspath(&binary_path);

	if (!service->keep_environment && !input->preserve_environment) {
		if (input->preserve_home)
			home = getenv("HOME");
		if (input->preserve_user)
			user = getenv("USER");
		if ((service->flags & MASTER_SERVICE_FLAG_STANDALONE) != 0)
			timestamp = getenv("LOG_STDERR_TIMESTAMP");
		master_service_env_clean();
		if (home != NULL)
			env_put(t_strconcat("HOME=", home, NULL));
		if (user != NULL)
			env_put(t_strconcat("USER="******"LOG_STDERR_TIMESTAMP=", timestamp, NULL));
	}
	if (input->use_sysexits)
		env_put("USE_SYSEXITS=1");

	/* @UNSAFE */
	i = 0;
	argv_max_count = 11 + (service->argc + 1) + 1;
	conf_argv = t_new(const char *, argv_max_count);
	conf_argv[i++] = DOVECOT_CONFIG_BIN_PATH;
	if (input->service != NULL) {
		conf_argv[i++] = "-f";
		conf_argv[i++] = t_strconcat("service=", input->service, NULL);
	}
	conf_argv[i++] = "-c";
	conf_argv[i++] = service->config_path;
	if (input->module != NULL) {
		conf_argv[i++] = "-m";
		conf_argv[i++] = input->module;
		if (service->want_ssl_settings) {
			conf_argv[i++] = "-m";
			conf_argv[i++] = "ssl";
		}
	}
	if (input->parse_full_config)
		conf_argv[i++] = "-p";

	conf_argv[i++] = "-e";
	conf_argv[i++] = binary_path;
	memcpy(conf_argv+i, service->argv + 1,
	       (service->argc) * sizeof(conf_argv[0]));
	i += service->argc;

	i_assert(i < argv_max_count);
	execv_const(conf_argv[0], conf_argv);
}
Example #4
0
static void env_put_extra_fields(const char *extra_fields)
{
	const char *const *tmp;
	const char *key, *p;

	for (tmp = t_strsplit(extra_fields, "\t"); *tmp != NULL; tmp++) {
		key = t_str_ucase(t_strcut(*tmp, '='));
		p = strchr(*tmp, '=');
		if (p == NULL)
			env_put(t_strconcat(key, "=1", NULL));
		else
			env_put(t_strconcat(key, p, NULL));
	}
}
Example #5
0
static void env_clean_except_real(const char *const preserve_envs[])
{
	ARRAY_TYPE(const_string) copy;
	const char *value, *const *envp;
	unsigned int i;

	t_array_init(&copy, 16);
	for (i = 0; preserve_envs[i] != NULL; i++) {
		const char *key = preserve_envs[i];

		value = getenv(key);
		if (value != NULL) {
			value = t_strconcat(key, "=", value, NULL);
			array_append(&copy, &value, 1);
		}
	}

	/* 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. */
	env_clean();

	array_foreach(&copy, envp)
		env_put(*envp);
}
Example #6
0
static void main_init(void)
{
	struct module_dir_load_settings mod_set;
	void **sets;

	sets = master_service_settings_get_others(master_service);
	dict_settings = sets[0];

	if (*dict_settings->dict_db_config != '\0') {
		/* for berkeley db library */
		env_put(t_strconcat("DB_CONFIG=", dict_settings->dict_db_config,
				    NULL));
	}

	memset(&mod_set, 0, sizeof(mod_set));
	mod_set.version = master_service_get_version_string(master_service);
	mod_set.require_init_funcs = TRUE;

	modules = module_dir_load(DICT_MODULE_DIR, NULL, &mod_set);
	module_dir_init(modules);

	/* Register only after loading modules. They may contain SQL drivers,
	   which we'll need to register. */
	dict_drivers_register_all();
}
Example #7
0
static void test_var_expand_builtin(void)
{
	static struct var_expand_test tests[] = {
		{ "%{hostname}", NULL },
		{ "%{pid}", NULL },
		{ "a%{env:FOO}b", "abaRb" }
	};
	static struct var_expand_table table[] = {
		{ '\0', NULL, NULL }
	};
	string_t *str = t_str_new(128);
	unsigned int i;

	tests[0].out = my_hostname;
	tests[1].out = my_pid;
	env_put("FOO=baR");

	test_begin("var_expand");
	for (i = 0; i < N_ELEMENTS(tests); i++) {
		str_truncate(str, 0);
		var_expand(str, tests[i].in, table);
		test_assert(strcmp(tests[i].out, str_c(str)) == 0);
	}
	test_end();
}
Example #8
0
static void test_var_expand_builtin(void)
{
	static struct var_expand_test tests[] = {
		{ "%{hostname}", NULL, 1 },
		{ "%{pid}", NULL, 1 },
		{ "a%{env:FOO}b", "abaRb", 1 },
		{ "%50Hv", "1f", 1 },
		{ "%50Hw", "2e", 1 },
		{ "%50Nv", "25", 1 },
		{ "%50Nw", "e", 1 },

		{ "%{nonexistent}", "UNSUPPORTED_VARIABLE_nonexistent", 0 },
		{ "%{nonexistent:default}", "UNSUPPORTED_VARIABLE_nonexistent", 0 },
	};
	static const struct var_expand_table table[] = {
		{ 'v', "value", NULL },
		{ 'w', "value2", NULL },
		{ '\0', NULL, NULL }
	};
	string_t *str = t_str_new(128);
	const char *error;
	unsigned int i;

	tests[0].out = my_hostname;
	tests[1].out = my_pid;
	env_put("FOO=baR");

	test_begin("var_expand - builtin");
	for (i = 0; i < N_ELEMENTS(tests); i++) {
		str_truncate(str, 0);
		test_assert_idx(var_expand(str, tests[i].in, table, &error) == tests[i].ret, i);
		test_assert_idx(strcmp(tests[i].out, str_c(str)) == 0, i);
	}
	test_end();
}
static void ATTR_NORETURN
checkpassword_lookup_child(struct auth_request *request,
			   struct checkpassword_userdb_module *module,
			   int fd_in, int fd_out)
{
	const char *cmd, *const *args;

	if (dup2(fd_out, 3) < 0 || dup2(fd_in, 4) < 0) {
		auth_request_log_error(request, "userdb-checkpassword",
				       "dup2() failed: %m");
	} else {
		/* We want to retrieve user data and don't do
		   authorization, so we need to signalize the
		   checkpassword program that the password shall be
		   ignored by setting AUTHORIZED.  This needs a
		   special checkpassword program which knows how to
		   handle this. */
		env_put("AUTHORIZED=1");
		checkpassword_setup_env(request);
		cmd = checkpassword_get_cmd(request, module->checkpassword_path,
					    module->checkpassword_reply_path);
		auth_request_log_debug(request, "userdb-checkpassword",
				       "execute: %s", cmd);

		/* very simple argument splitting. */
		args = t_strsplit(cmd, " ");
		execv_const(args[0], args);
	}
	exit(2);
}
struct pop3c_client *
pop3c_client_init(const struct pop3c_client_settings *set)
{
	struct pop3c_client *client;
	struct ssl_iostream_settings ssl_set;
	const char *error;
	pool_t pool;

	// CLEANUP: Remove Warning
	i_warning("pop3c_client_init called");

	pool = pool_alloconly_create("pop3c client", 1024);
	client = p_new(pool, struct pop3c_client, 1);
	client->pool = pool;
	client->fd = -1;

	client->set.debug = set->debug;
	client->set.host = p_strdup(pool, set->host);
	client->set.port = set->port;
	client->set.master_user = p_strdup_empty(pool, set->master_user);
	client->set.username = p_strdup(pool, set->username);

	// CLEANUP: remove warning
	i_warning("pop3c_client_init: username %s", client->set.username);
	env_put(t_strconcat("POP3C_USERNAME="******"pop3c(%s:%u): Couldn't initialize SSL context: %s",
				set->host, set->port, error);
		}
	}
	return client;
}
Example #11
0
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_strconcat("SERVICE=", request->service, NULL));
	if (request->local_ip.family != 0) {
		env_put(t_strconcat("TCPLOCALIP=",
				    net_ip2addr(&request->local_ip), NULL));
		/* FIXME: for backwards compatibility only,
		   remove some day */
		env_put(t_strconcat("LOCAL_IP=",
				    net_ip2addr(&request->local_ip), NULL));
	}
	if (request->remote_ip.family != 0) {
		env_put(t_strconcat("TCPREMOTEIP=",
				    net_ip2addr(&request->remote_ip), NULL));
		/* FIXME: for backwards compatibility only,
		   remove some day */
		env_put(t_strconcat("REMOTE_IP=",
				    net_ip2addr(&request->remote_ip), NULL));
	}
	if (request->local_port != 0) {
		env_put(t_strdup_printf("TCPLOCALPORT=%u",
					request->local_port));
	}
	if (request->remote_port != 0) {
		env_put(t_strdup_printf("TCPREMOTEPORT=%u",
					request->remote_port));
	}
	if (request->master_user != NULL) {
		env_put(t_strconcat("MASTER_USER=",
				    request->master_user, NULL));
	}
	if (request->extra_fields != NULL) {
		const char *fields =
			auth_stream_reply_export(request->extra_fields);

		/* extra fields could come from master db */
		env_put_extra_fields(fields);
	}
}
Example #12
0
void smtpd()
{
  if (!env_get("PROTO")) {
    if (!env_put("RELAYCLIENT=")) nomem();
    if (!env_put("DATABYTES=0")) nomem();
    if (!env_put("PROTO=TCP")) nomem();
    if (!env_put("TCPLOCALIP=127.0.0.1")) nomem();
    if (!env_put("TCPLOCALHOST=localhost")) nomem();
    if (!env_put("TCPREMOTEIP=127.0.0.1")) nomem();
    if (!env_put("TCPREMOTEHOST=localhost")) nomem();
    if (!env_put("TCPREMOTEINFO=sendmail-bs")) nomem();
  }
  execv(*smtpdarg,(char **)smtpdarg);
  substdio_putsflush(subfderr,"sendmail: fatal: unable to run qmail-smtpd\n");
  _exit(111);
}
Example #13
0
static void
exec_child(struct master_service_connection *conn,
	const char *const *args, const char *const *envs)
{
	unsigned int i, socket_count;

	if (dup2(conn->fd, STDIN_FILENO) < 0)
		i_fatal("dup2() failed: %m");
	if (dup2(conn->fd, STDOUT_FILENO) < 0)
		i_fatal("dup2() failed: %m");

	/* close all fds */
	socket_count = master_service_get_socket_count(master_service);
	for (i = 0; i < socket_count; i++) {
		if (close(MASTER_LISTEN_FD_FIRST + i) < 0)
			i_error("close(listener) failed: %m");
	}
	if (close(MASTER_STATUS_FD) < 0)
		i_error("close(status) failed: %m");
	if (close(conn->fd) < 0)
		i_error("close(conn->fd) failed: %m");

	for (; *args != NULL; args++) {
		const char *arg = t_str_tabunescape(*args);
		array_append(&exec_args, &arg, 1);
	}
	array_append_zero(&exec_args);

	env_clean();
	if (envs != NULL) {
		for(; *envs != NULL; envs++)
			env_put(*envs);
        }

	args = array_idx(&exec_args, 0);
	execvp_const(args[0], args);
}
Example #14
0
static void
service_dup_fds(struct service *service)
{
	struct service_listener *const *listeners;
	ARRAY_TYPE(dup2) dups;
	string_t *listener_settings;
	int fd = MASTER_LISTEN_FD_FIRST;
	unsigned int i, count, socket_listener_count;

	/* stdin/stdout is already redirected to /dev/null. Other master fds
	   should have been opened with fd_close_on_exec() so we don't have to
	   worry about them.

	   because the destination fd might be another one's source fd we have
	   to be careful not to overwrite anything. dup() the fd when needed */

        socket_listener_count = 0;
	listeners = array_get(&service->listeners, &count);
	t_array_init(&dups, count + 10);

	switch (service->type) {
	case SERVICE_TYPE_LOG:
		i_assert(fd == MASTER_LISTEN_FD_FIRST);
		services_log_dup2(&dups, service->list, fd,
				  &socket_listener_count);
		fd += socket_listener_count;
		break;
	case SERVICE_TYPE_ANVIL:
		dup2_append(&dups, service_anvil_global->log_fdpass_fd[0],
			    MASTER_ANVIL_LOG_FDPASS_FD);
		/* nonblocking anvil fd must be the first one. anvil treats it
		   as the master's fd */
		dup2_append(&dups, service_anvil_global->nonblocking_fd[0], fd++);
		dup2_append(&dups, service_anvil_global->blocking_fd[0], fd++);
		socket_listener_count += 2;
		break;
	default:
		break;
	}

	/* add listeners */
	listener_settings = t_str_new(256);
	for (i = 0; i < count; i++) {
		if (listeners[i]->fd != -1) {
			str_truncate(listener_settings, 0);
			str_append_tabescaped(listener_settings, listeners[i]->name);

			if (listeners[i]->type == SERVICE_LISTENER_INET) {
				if (listeners[i]->set.inetset.set->ssl)
					str_append(listener_settings, "\tssl");
				if (listeners[i]->set.inetset.set->haproxy)
					str_append(listener_settings, "\thaproxy");
			}
			
			dup2_append(&dups, listeners[i]->fd, fd++);

			env_put(t_strdup_printf("SOCKET%d_SETTINGS=%s",
				socket_listener_count, str_c(listener_settings)));
			socket_listener_count++;
		}
	}

	if (service->login_notify_fd != -1) {
		dup2_append(&dups, service->login_notify_fd,
			    MASTER_LOGIN_NOTIFY_FD);
	}
	switch (service->type) {
	case SERVICE_TYPE_LOG:
	case SERVICE_TYPE_ANVIL:
	case SERVICE_TYPE_CONFIG:
		dup2_append(&dups, null_fd, MASTER_ANVIL_FD);
		break;
	case SERVICE_TYPE_UNKNOWN:
	case SERVICE_TYPE_LOGIN:
	case SERVICE_TYPE_STARTUP:
		dup2_append(&dups, service_anvil_global->blocking_fd[1],
			    MASTER_ANVIL_FD);
		break;
	}
	dup2_append(&dups, service->status_fd[1], MASTER_STATUS_FD);
	if (service->type != SERVICE_TYPE_ANVIL) {
		dup2_append(&dups, service->list->master_dead_pipe_fd[1],
			    MASTER_DEAD_FD);
	} else {
		dup2_append(&dups, global_master_dead_pipe_fd[1],
			    MASTER_DEAD_FD);
	}

	if (service->type == SERVICE_TYPE_LOG) {
		/* keep stderr as-is. this is especially important when
		   log_path=/dev/stderr, but might be helpful even in other
		   situations for logging startup errors */
	} else {
		/* set log file to stderr. dup2() here immediately so that
		   we can set up logging to it without causing any log messages
		   to be lost. */
		i_assert(service->log_fd[1] != -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();
	}

	/* make sure we don't leak syslog fd. try to do it as late as possible,
	   but also before dup2()s in case syslog fd is one of them. */
	closelog();

	if (dup2_array(&dups) < 0)
		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));
}
Example #15
0
static void
service_process_setup_environment(struct service *service, unsigned int uid,
				  const char *hostdomain)
{
	master_service_env_clean();

	env_put(MASTER_IS_PARENT_ENV"=1");
	service_process_setup_config_environment(service);
	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));
	if (service->set->service_count != 0) {
		env_put(t_strdup_printf(MASTER_SERVICE_COUNT_ENV"=%u",
					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));

	if (!service->set->master_set->version_ignore)
		env_put(MASTER_DOVECOT_VERSION_ENV"="PACKAGE_VERSION);

	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));
	}
	if (service->type == SERVICE_TYPE_ANVIL &&
	    service_anvil_global->restarted)
		env_put("ANVIL_RESTARTED=1");
}
Example #16
0
static void client_connected(struct master_service_connection *conn)
{
	enum mail_storage_service_flags flags =
		MAIL_STORAGE_SERVICE_FLAG_NO_PLUGINS;
	string_t *instr, *keys;
	const char **args, *key, *value, *error, *version_line, *data_line;
	struct mail_storage_service_ctx *service_ctx;
	struct mail_storage_service_input input;
	struct mail_storage_service_user *user;
	char buf[1024];
	unsigned int i, socket_count;
	int fd = -1;
	ssize_t ret;

	alarm(SCRIPT_LOGIN_READ_TIMEOUT_SECS);

	net_set_nonblock(conn->fd, FALSE);
	instr = t_str_new(1024);
	ret = fd_read(conn->fd, buf, sizeof(buf), &fd);
	while (ret > 0) {
		str_append_n(instr, buf, ret);
		if (buf[ret-1] == '\n' &&
		    strchr(str_c(instr), '\n')[1] != '\0') {
			str_truncate(instr, str_len(instr)-1);
			break;
		}

		ret = read(conn->fd, buf, sizeof(buf));
	}

	version_line = str_c(instr);
	data_line = strchr(version_line, '\n');
	if (data_line != NULL)
		version_line = t_strdup_until(version_line, data_line++);
	else
		version_line = NULL;

	if (ret > 0 || version_line != NULL) {
		if (version_line == NULL ||
		    !version_string_verify(version_line, "script-login",
				SCRIPT_LOGIN_PROTOCOL_VERSION_MAJOR)) {
			i_fatal("Client not compatible with this binary "
				"(connecting to wrong socket?)");
		}
	}

	if (ret <= 0) {
		if (ret < 0)
			i_fatal("read() failed: %m");
		else
			i_fatal("read() failed: disconnected");
	}
	if (fd == -1)
		i_fatal("client fd not received");

	alarm(0);

	/* put everything to environment */
	env_clean();
	keys = t_str_new(256);
	args = t_strsplit_tab(data_line);

	if (str_array_length(args) < 3)
		i_fatal("Missing input fields");

	i = 0;
	memset(&input, 0, sizeof(input));
	input.module = "mail"; /* need to get mail_uid, mail_gid */
	input.service = "script-login";
	(void)net_addr2ip(args[i++], &input.local_ip);
	(void)net_addr2ip(args[i++], &input.remote_ip);
	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="******"%s ", key);
		}
	}
	env_put(t_strconcat(ENV_USERDB_KEYS"=", str_c(keys), NULL));

	master_service_init_log(master_service,
		t_strdup_printf("script-login(%s): ", input.username));

	if (drop_to_userdb_privileges) {
		service_ctx = mail_storage_service_init(master_service, NULL, flags);
		if (mail_storage_service_lookup(service_ctx, &input, &user, &error) <= 0)
			i_fatal("%s", error);
		mail_storage_service_restrict_setenv(service_ctx, user);
		/* we can't exec anything in a chroot */
		env_remove("RESTRICT_CHROOT");
		restrict_access_by_env(getenv("HOME"), TRUE);
	}

	if (dup2(fd, STDIN_FILENO) < 0)
		i_fatal("dup2() failed: %m");
	if (dup2(fd, STDOUT_FILENO) < 0)
		i_fatal("dup2() failed: %m");
	if (close(fd) < 0)
		i_fatal("close() failed: %m");
	if (conn->fd != SCRIPT_COMM_FD) {
		if (dup2(conn->fd, SCRIPT_COMM_FD) < 0)
			i_fatal("dup2() failed: %m");
		if (close(conn->fd) < 0)
			i_fatal("close() failed: %m");
	}

	/* close all listener sockets */
	socket_count = master_service_get_socket_count(master_service);
	for (i = 0; i < socket_count; i++) {
		if (close(MASTER_LISTEN_FD_FIRST + i) < 0)
			i_error("close(listener) failed: %m");
	}
	if (close(MASTER_STATUS_FD) < 0)
		i_error("close(status) failed: %m");

	execvp_const(exec_args[0], exec_args);
}
Example #17
0
	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));
	}
int sieve_ldap_storage_read_settings
(struct sieve_ldap_storage *lstorage, const char *config_path)
{
    struct sieve_storage *storage = &lstorage->storage;
    const char *str, *error;
    struct stat st;

    if ( stat(config_path, &st) < 0 ) {
        sieve_storage_sys_error(storage,
                                "Failed to read LDAP storage config: "
                                "stat(%s) failed: %m", config_path);
        return -1;
    }

    lstorage->set = default_settings;
    lstorage->set_mtime = st.st_mtime;

    if (!settings_read_nosection
            (config_path, parse_setting, lstorage, &error)) {
        sieve_storage_set_critical(storage,
                                   "Failed to read LDAP storage config `%s': %s",
                                   config_path, error);
        return -1;
    }

    if (lstorage->set.base == NULL) {
        sieve_storage_set_critical(storage,
                                   "Invalid LDAP storage config `%s': "
                                   "No search base given", config_path);
        return -1;
    }

    if (lstorage->set.uris == NULL && lstorage->set.hosts == NULL) {
        sieve_storage_set_critical(storage,
                                   "Invalid LDAP storage config `%s': "
                                   "No uris or hosts set", config_path);
        return -1;
    }

    if (*lstorage->set.ldaprc_path != '\0') {
        str = getenv("LDAPRC");
        if (str != NULL && strcmp(str, lstorage->set.ldaprc_path) != 0) {
            sieve_storage_set_critical(storage,
                                       "Invalid LDAP storage config `%s': "
                                       "Multiple different ldaprc_path settings not allowed "
                                       "(%s and %s)", config_path, str, lstorage->set.ldaprc_path);
            return -1;
        }
        env_put(t_strconcat("LDAPRC=", lstorage->set.ldaprc_path, NULL));
    }

    if ( ldap_deref_from_str
            (lstorage->set.deref, &lstorage->set.ldap_deref) < 0 ) {
        sieve_storage_set_critical(storage,
                                   "Invalid LDAP storage config `%s': "
                                   "Invalid deref option `%s'",
                                   config_path, lstorage->set.deref);;
    }

    if ( ldap_scope_from_str
            (lstorage->set.scope, &lstorage->set.ldap_scope) < 0 ) {
        sieve_storage_set_critical(storage,
                                   "Invalid LDAP storage config `%s': "
                                   "Invalid scope option `%s'",
                                   config_path, lstorage->set.scope);;
    }

#ifdef OPENLDAP_TLS_OPTIONS
    if ( lstorage->set.tls_require_cert != NULL &&
            ldap_tls_require_cert_from_str(lstorage->set.tls_require_cert,
                                           &lstorage->set.ldap_tls_require_cert) < 0) {
        sieve_storage_set_critical(storage,
                                   "Invalid LDAP storage config `%s': "
                                   "Invalid tls_require_cert option `%s'",
                                   config_path, lstorage->set.tls_require_cert);
    }
#endif
    return 0;
}
static void exec_child
(const char *bin_path, const char *const *args, const char *const *envs,
	int in_fd, int out_fd, int *extra_fds, bool drop_stderr)
{
	ARRAY_TYPE(const_string) exec_args;

	/* Setup stdin/stdout */

	if ( in_fd < 0 ) {
		in_fd = open("/dev/null", O_RDONLY);

		if ( in_fd == -1 )
			i_fatal("open(/dev/null) failed: %m");
	}
	if ( out_fd < 0 ) {
		out_fd = open("/dev/null", O_WRONLY);

		if ( out_fd == -1 )
			i_fatal("open(/dev/null) failed: %m");
	}

	if ( dup2(in_fd, STDIN_FILENO) < 0 )
		i_fatal("dup2(stdin) failed: %m");
	if ( dup2(out_fd, STDOUT_FILENO) < 0 )
		i_fatal("dup2(stdout) failed: %m");

	if ( close(in_fd) < 0 )
		i_error("close(in_fd) failed: %m");
	if ( (out_fd != in_fd) && close(out_fd) < 0 )
		i_error("close(out_fd) failed: %m");

	/* Drop stderr if requested */
	if ( drop_stderr ) {
		int err_fd = open("/dev/null", O_WRONLY);
		if ( err_fd == -1 )
			i_fatal("open(/dev/null) failed: %m");
		if ( dup2(err_fd, STDERR_FILENO) < 0 )
			i_fatal("dup2(stderr) failed: %m");
		if ( close(err_fd) < 0 )
			i_error("close(err_fd) failed: %m");
	}

	/* Setup extra fds */
	if ( extra_fds != NULL ) {
		for (; *extra_fds != -1; extra_fds += 2 ) {
			if ( dup2(extra_fds[0], extra_fds[1]) < 0 )
				i_fatal("dup2(extra_fd=%d) failed: %m", extra_fds[1]);
			if ( close(extra_fds[0]) < 0 )
				i_error("close(extra_fd=%d) failed: %m", extra_fds[1]);
		}
	}

	/* Compose argv */

	t_array_init(&exec_args, 16);
	array_append(&exec_args, &bin_path, 1);
	if ( args != NULL ) {
		for (; *args != NULL; args++)
			array_append(&exec_args, args, 1);
	}
	(void)array_append_space(&exec_args);

	/* Setup environment */

	env_clean();
	if ( envs != NULL ) {
		for (; *envs != NULL; envs++)
			env_put(*envs);
	}

	/* Execute */

	args = array_idx(&exec_args, 0);
	execvp_const(args[0], args);
}
Example #20
0
int main(int argc,char *argv[])
//int argc;
//char *argv[];
{
  int dummy;
  char *proto;
  int opt;
  int flagremoteinfo;
  unsigned long timeout;
// struct sockaddr_in *v4;

  sig_pipeignore();

  flagremoteinfo = 1;
  timeout = 30;
  while ((opt = getopt(argc,argv,"rRt:")) != opteof)
    switch(opt)
    {
     case 'r': flagremoteinfo = 1; break;
     case 'R': flagremoteinfo = 0; break;
     case 't': scan_ulong(subgetoptarg,&timeout); break;
    }

  argv += subgetoptind;
  argc -= subgetoptind;

  if (argc < 1) die();
  if (!env_init()) die();

  proto = env_get("PROTO");
  if (!proto || str_diff(proto,"TCP"))
  {
    if (!env_puts("PROTO=TCP")) die();

    dummy = sizeof(salocal);
    if (getsockname(0,(struct sockaddr *) &salocal, (socklen_t *) &dummy) == -1) die();
    mappedtov4(&salocal);
    switch(salocal.sa.sa_family) {
    case AF_INET:
      localport = ntohs(salocal.sa4.sin_port);
      temp[fmt_ulong(temp,localport)] = 0;
    if (!env_put("TCPLOCALPORT",temp)) die();
      temp[ip4_fmt(temp,(char *) &salocal.sa4.sin_addr)] = 0;
    if (!env_put("TCPLOCALIP",temp)) die();

    switch(dns_ptr(&localname,&salocal.sa4.sin_addr)) {
      case DNS_MEM: die();
      case DNS_SOFT:
        if (!stralloc_copys(&localname,"softdnserror")) die();
      case 0:
        if (!stralloc_0(&localname)) die();
        case_lowers(localname.s);
        if (!env_put("TCPLOCALHOST",localname.s)) die();
        break;
      default:
        if (!env_unset("TCPLOCALHOST")) die();
    }
    break;
#ifdef INET6
    case AF_INET6:
      localport = ntohs(salocal.sa6.sin6_port);
      temp[fmt_ulong(temp,localport)] = 0;
      if (!env_put("TCPLOCALPORT",temp)) die();
      temp[ip6_fmt(temp,(char *) &salocal.sa6.sin6_addr)] = 0;
      if (!env_put("TCPLOCALIP",temp)) die();
      switch(dns_ptr6(&localname,&salocal.sa6.sin6_addr)) {
        case DNS_MEM: die();
        case DNS_SOFT:
             if (!stralloc_copys(&localname,"softdnserror")) die();
        case 0:
             if (!stralloc_0(&localname)) die();
          case_lowers(localname.s);
          if (!env_put("TCPLOCALHOST",localname.s)) die();
          break;
        default:
             if (!env_unset("TCPLOCALHOST")) die();
      }
      break;
#endif
    default:
      die();
    }

    dummy = sizeof(saremote);
    if (getpeername(0,(struct sockaddr *) &saremote, (socklen_t *) &dummy) == -1) die();
      mappedtov4(&saremote);

    switch(saremote.sa.sa_family) {
    case AF_INET:
      remoteport = ntohs(saremote.sa4.sin_port);
      temp[fmt_ulong(temp,remoteport)] = 0;
    if (!env_put("TCPREMOTEPORT",temp)) die();

    temp[ip4_fmt(temp,(char *)&saremote.sa4.sin_addr)] = 0;
    if (!env_put("TCPREMOTEIP",temp)) die();

    switch(dns_ptr(&remotename,&saremote.sa4.sin_addr)) {
    case DNS_MEM: die();
    case DNS_SOFT:
      if (!stralloc_copys(&remotename,"softdnserror")) die();
    case 0:
      if (!stralloc_0(&remotename)) die();
      case_lowers(remotename.s);
      if (!env_put("TCPREMOTEHOST",remotename.s)) die();
      break;
    default:
      if (!env_unset("TCPREMOTEHOST")) die();
    }
    break;
#ifdef INET6
    case AF_INET6:
    remoteport = ntohs(saremote.sa6.sin6_port);
      temp[fmt_ulong(temp,remoteport)] = 0;
    if (!env_put("TCPREMOTEPORT",temp)) die();
    temp[ip6_fmt(temp,(char *) &saremote.sa6.sin6_addr)] = 0;
    if (!env_put("TCPREMOTEIP",temp)) die();
    switch(dns_ptr6(&remotename,&saremote.sa6.sin6_addr)) {
     case DNS_MEM: die();
     case DNS_SOFT:
       if (!stralloc_copys(&remotename,"softdnserror")) die();
     case 0:
       if (!stralloc_0(&remotename)) die();
       case_lowers(remotename.s);
       if (!env_put("TCPREMOTEHOST",remotename.s)) die();
       break;
     default:
       if (!env_unset("TCPREMOTEHOST")) die();
    }
    break;
#endif
    default:
      die();
    }

    if (!env_unset("TCPREMOTEINFO")) die();

    if (flagremoteinfo)
    {
      char *rinfo;
      rinfo = remoteinfo_get(&saremote, &salocal,(int) timeout);
      if (rinfo)
        if (!env_put("TCPREMOTEINFO",rinfo)) die();
    }
  }

  sig_pipedefault();
  execvp(*argv,argv);
  die();
  return(0);  /* never reached */
}
Example #21
0
int main(int argc,char **argv)
{
  int opt;
  char **qiargv;
  char **arg;
  int i;

  if (chdir(auto_qmail) == -1) {
    buffer_putsflush(buffer_2,"sendmail: fatal: unable to switch to qmail home directory\n");
    _exit(111);
  }

  flagh = 0;
  sender = 0;
  while ((opt = getopt(argc,argv,"vimte:f:p:o:B:F:EJxb:")) != opteof)
    switch(opt) {
      case 'B': break;
      case 't': flagh = 1; break;
      case 'f': sender = optarg; break;
      case 'F': if (!env_put("MAILNAME",optarg)) nomem(); break;
      case 'p': break; /* could generate a Received line from optarg */
      case 'v': break;
      case 'i': break; /* what an absurd concept */
      case 'x': break; /* SVR4 stupidity */
      case 'm': break; /* twisted-paper-path blindness, incompetent design */
      case 'e': break; /* qmail has only one error mode */
      case 'o':
        switch(optarg[0]) {
      case 'd': break; /* qmail has only one delivery mode */
      case 'e': break; /* see 'e' above */
      case 'i': break; /* see 'i' above */
      case 'm': break; /* see 'm' above */
    }
        break;
      case 'E': case 'J': /* Sony NEWS-OS */
        while (argv[optind][optpos]) ++optpos; /* skip optional argument */
        break;
      case 'b':
    switch(optarg[0]) {
      case 'm': break;
      case 'p': mailq();
      case 's': smtpd();
      default: die_usage();
    }
    break;
      default:
    die_usage();
    }
  argc -= optind;
  argv += optind;

  if (str_equal(optprogname,"mailq"))
    mailq();

  if (str_equal(optprogname,"newaliases")) {
    buffer_putsflush(buffer_2,"sendmail: fatal: please use fastforward/newaliases instead\n");
    _exit(100);
  }

  qiargv = (char **) alloc((argc + 10) * sizeof(char *));
  if (!qiargv) nomem();

  arg = qiargv;
  *arg++ = "bin/qmail-inject";
  *arg++ = (flagh ? "-H" : "-a");
  if (sender) {
    *arg++ = "-f";
    *arg++ = sender;
    do_sender(sender);
  }
  *arg++ = "--";
  for (i = 0;i < argc;++i) *arg++ = argv[i];
  *arg = 0;

  execv(*qiargv,qiargv);
  buffer_putsflush(buffer_2,"sendmail: fatal: unable to run qmail-inject\n");
  _exit(111);
//  return(0);  /* never reached */
}