示例#1
0
static int write_from_line(struct mbox_save_context *ctx, time_t received_date,
			   const char *from_envelope)
{
	int ret;

	T_BEGIN {
		const char *line;

		if (from_envelope == NULL) {
			struct mail_storage *storage =
				&ctx->mbox->storage->storage;

			from_envelope =
				strchr(storage->user->username, '@') != NULL ?
				storage->user->username :
				t_strconcat(storage->user->username,
					    "@", my_hostdomain(), NULL);
		} else if (*from_envelope == '\0') {
			/* can't write empty envelope */
			from_envelope = "MAILER-DAEMON";
		}

		/* save in local timezone, no matter what it was given with */
		line = mbox_from_create(from_envelope, received_date);

		if ((ret = o_stream_send_str(ctx->output, line)) < 0)
			write_error(ctx);
	} T_END;
	return ret;
}
示例#2
0
static void
service_process_setup_environment(struct service *service, unsigned int uid)
{
	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_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", my_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");
}
示例#3
0
static bool lda_settings_check(void *_set, pool_t pool, const char **error_r)
{
	struct lda_settings *set = _set;

	if (*set->hostname == '\0')
		set->hostname = p_strdup(pool, my_hostdomain());
	if (*set->postmaster_address == '\0') {
		/* check for valid looking fqdn in hostname */
		if (strchr(set->hostname, '.') == NULL) {
			*error_r = "postmaster_address setting not given";
			return FALSE;
		}
		set->postmaster_address = p_strconcat(pool, "postmaster@",
						      set->hostname, NULL);
	}
	return TRUE;
}
示例#4
0
static bool
submission_settings_verify(void *_set, pool_t pool ATTR_UNUSED, const char **error_r)
{
	struct submission_settings *set = _set;

	if (submission_settings_parse_workarounds(set, error_r) < 0)
		return FALSE;

#ifndef CONFIG_BINARY
	if (set->submission_relay_max_idle_time == 0) {
		*error_r = "submission_relay_max_idle_time must not be 0";
		return FALSE;
	}
	if (*set->hostname == '\0')
		set->hostname = p_strdup(pool, my_hostdomain());
#endif
	return TRUE;
}
示例#5
0
struct service_process *service_process_create(struct service *service)
{
	static unsigned int uid_counter = 0;
	struct service_process *process;
	unsigned int uid = ++uid_counter;
	const char *hostdomain;
	pid_t pid;
	bool process_forked;

	i_assert(service->status_fd[0] != -1);

	if (service->to_throttle != NULL) {
		/* throttling service, don't create new processes */
		return NULL;
	}
	if (service->list->destroying) {
		/* these services are being destroyed, no point in creating
		   new processes now */
		return NULL;
	}
	/* look this up before fork()ing so that it gets cached for all the
	   future lookups. */
	hostdomain = my_hostdomain();

	if (service->type == SERVICE_TYPE_ANVIL &&
	    service_anvil_global->pid != 0) {
		pid = service_anvil_global->pid;
		uid = service_anvil_global->uid;
		process_forked = FALSE;
	} else {
		pid = fork();
		process_forked = TRUE;
		service->list->fork_counter++;
	}

	if (pid < 0) {
		service_error(service, "fork() failed: %m");
		return NULL;
	}
	if (pid == 0) {
		/* child */
		service_process_setup_environment(service, uid, hostdomain);
		service_reopen_inet_listeners(service);
		service_dup_fds(service);
		drop_privileges(service);
		process_exec(service->executable, NULL);
	}
	i_assert(hash_table_lookup(service_pids, POINTER_CAST(pid)) == NULL);

	process = i_new(struct service_process, 1);
	process->service = service;
	process->refcount = 1;
	process->pid = pid;
	process->uid = uid;
	if (process_forked) {
		process->to_status =
			timeout_add(SERVICE_FIRST_STATUS_TIMEOUT_SECS * 1000,
				    service_process_status_timeout, process);
	}

	process->available_count = service->client_limit;
	service->process_count++;
	service->process_avail++;
	DLLIST_PREPEND(&service->processes, process);

	service_list_ref(service->list);
	hash_table_insert(service_pids, POINTER_CAST(process->pid), process);

	if (service->type == SERVICE_TYPE_ANVIL && process_forked)
		service_anvil_process_created(process);
	return process;
}
示例#6
0
struct sieve_instance *sieve_tool_init_finish
(struct sieve_tool *tool, bool init_mailstore, bool preserve_root)
{
	enum mail_storage_service_flags storage_service_flags =
		MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR |
		MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT |
		MAIL_STORAGE_SERVICE_FLAG_USE_SYSEXITS;
	struct mail_storage_service_input service_input;
	struct sieve_environment svenv;
	const char *username = tool->username;
	const char *homedir = tool->homedir;
	const char *errstr;

	master_service_init_finish(master_service);

	if ( username == NULL ) {
		sieve_tool_get_user_data(&username, &homedir);

		username = tool->username = i_strdup(username);

		if ( tool->homedir != NULL )
			i_free(tool->homedir);
		tool->homedir = i_strdup(homedir);

		if ( preserve_root ) {
			storage_service_flags |=
				MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS;
		}
	} else {
		storage_service_flags |=
			MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
	}

	if ( !init_mailstore )
		storage_service_flags |=
			MAIL_STORAGE_SERVICE_FLAG_NO_NAMESPACES;

	memset(&service_input, 0, sizeof(service_input));
	service_input.module = "mail";
	service_input.service = tool->name;
	service_input.username = username;

	tool->storage_service = mail_storage_service_init
		(master_service, NULL, storage_service_flags);
	if (mail_storage_service_lookup_next
		(tool->storage_service, &service_input, &tool->service_user,
			&tool->mail_user_dovecot, &errstr) <= 0)
		i_fatal("%s", errstr);

	if ( master_service_set
		(master_service, "mail_full_filesystem_access=yes") < 0 )
		i_unreached();

	memset((void *)&svenv, 0, sizeof(svenv));
	svenv.username = username;
	(void)mail_user_get_home(tool->mail_user_dovecot, &svenv.home_dir);
	svenv.hostname = my_hostdomain();
	svenv.base_dir = tool->mail_user_dovecot->set->base_dir;
	svenv.temp_dir = tool->mail_user_dovecot->set->mail_temp_dir;
	svenv.location = SIEVE_ENV_LOCATION_MS;
	svenv.delivery_phase = SIEVE_DELIVERY_PHASE_POST;

	/* Initialize Sieve Engine */
	if ( (tool->svinst=sieve_init
		(&svenv, &sieve_tool_callbacks, tool, tool->debug)) == NULL )
		i_fatal("failed to initialize sieve implementation");

	/* Load Sieve plugins */
	if ( array_count(&tool->sieve_plugins) > 0 ) {
		sieve_tool_load_plugins(tool);
	}

	/* Set active Sieve extensions */
	if ( tool->sieve_extensions != NULL ) {
		sieve_set_extensions(tool->svinst, tool->sieve_extensions);
	} else if ( tool->no_config ) {
		sieve_set_extensions(tool->svinst, NULL);
	}

	return tool->svinst;
}