Example #1
0
struct auth_settings *
auth_settings_read(const char *service, pool_t pool,
		   struct master_service_settings_output *output_r)
{
	static const struct setting_parser_info *set_roots[] = {
		&auth_setting_parser_info,
		NULL
	};
 	struct master_service_settings_input input;
	struct setting_parser_context *set_parser;
	const char *error;

	memset(&input, 0, sizeof(input));
	input.roots = set_roots;
	input.module = "auth";
	input.service = service;
	if (master_service_settings_read(master_service, &input,
					 output_r, &error) < 0)
		i_fatal("Error reading configuration: %s", error);

	set_parser = settings_parser_dup(master_service->set_parser, pool);
	if (!settings_parser_check(set_parser, pool, &error))
		i_unreached();

	return settings_parser_get_list(set_parser)[1];
}
const struct master_service_ssl_settings *
master_service_ssl_settings_get(struct master_service *service)
{
	void **sets;

	sets = settings_parser_get_list(service->set_parser);
	return sets[1];
}
Example #3
0
void lmtp_settings_dup(const struct setting_parser_context *set_parser,
		       pool_t pool,
		       const struct lmtp_settings **lmtp_set_r,
		       const struct lda_settings **lda_set_r)
{
	void **sets;

	sets = settings_parser_get_list(set_parser) + 1;
	*lda_set_r = settings_dup(&lda_setting_parser_info, sets[1], pool);
	*lmtp_set_r = settings_dup(&lmtp_setting_parser_info, sets[2], pool);
}
int master_service_settings_read(struct master_service *service,
				 const struct master_service_settings_input *input,
				 struct master_service_settings_output *output_r,
				 const char **error_r)
{
	ARRAY(const struct setting_parser_info *) all_roots;
	const struct setting_parser_info *tmp_root;
	struct setting_parser_context *parser;
	struct istream *istream;
	const char *path = NULL, *error;
	void **sets;
	unsigned int i;
	int ret, fd = -1;
	time_t now, timeout;
	bool use_environment, retry;

	memset(output_r, 0, sizeof(*output_r));

	if (getenv("DOVECONF_ENV") == NULL &&
	    (service->flags & MASTER_SERVICE_FLAG_NO_CONFIG_SETTINGS) == 0) {
		retry = service->config_fd != -1;
		for (;;) {
			fd = master_service_open_config(service, input,
							&path, error_r);
			if (fd == -1) {
				if (errno == EACCES)
					output_r->permission_denied = TRUE;
				return -1;
			}

			if (config_send_request(service, input, fd,
						path, error_r) == 0)
				break;
			i_close_fd(&fd);
			if (!retry) {
				config_exec_fallback(service, input);
				return -1;
			}
			/* config process died, retry connecting */
			retry = FALSE;
		}
	}

	if (service->set_pool != NULL) {
		if (service->set_parser != NULL)
			settings_parser_deinit(&service->set_parser);
		p_clear(service->set_pool);
	} else {
		service->set_pool =
			pool_alloconly_create("master service settings", 16384);
	}

	p_array_init(&all_roots, service->set_pool, 8);
	tmp_root = &master_service_setting_parser_info;
	array_append(&all_roots, &tmp_root, 1);
	if (service->want_ssl_settings) {
		tmp_root = &master_service_ssl_setting_parser_info;
		array_append(&all_roots, &tmp_root, 1);
	}
	if (input->roots != NULL) {
		for (i = 0; input->roots[i] != NULL; i++)
			array_append(&all_roots, &input->roots[i], 1);
	}

	parser = settings_parser_init_list(service->set_pool,
			array_idx(&all_roots, 0), array_count(&all_roots),
			SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS);

	if (fd != -1) {
		istream = i_stream_create_fd(fd, (size_t)-1);
		now = time(NULL);
		timeout = now + CONFIG_READ_TIMEOUT_SECS;
		do {
			alarm(timeout - now);
			ret = config_read_reply_header(istream, path,
						       service->set_pool, input,
						       output_r, error_r);
			if (ret == 0) {
				ret = settings_parse_stream_read(parser,
								 istream);
				if (ret < 0)
					*error_r = settings_parser_get_error(parser);
			}
			alarm(0);
			if (ret <= 0)
				break;

			/* most likely timed out, but just in case some other
			   signal was delivered early check if we need to
			   continue */
			now = time(NULL);
		} while (now < timeout);
		i_stream_unref(&istream);

		if (ret != 0) {
			if (ret > 0) {
				*error_r = t_strdup_printf(
					"Timeout reading config from %s", path);
			}
			i_close_fd(&fd);
			config_exec_fallback(service, input);
			settings_parser_deinit(&parser);
			return -1;
		}

		if ((service->flags & MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN) != 0 &&
		    service->config_fd == -1 && input->config_path == NULL)
			service->config_fd = fd;
		else
			i_close_fd(&fd);
		use_environment = FALSE;
	} else {
		use_environment = TRUE;
	}

	if (use_environment || service->keep_environment) {
		if (settings_parse_environ(parser) < 0) {
			*error_r = t_strdup(settings_parser_get_error(parser));
			settings_parser_deinit(&parser);
			return -1;
		}
	}

	if (array_is_created(&service->config_overrides)) {
		if (master_service_apply_config_overrides(service, parser,
							  error_r) < 0) {
			settings_parser_deinit(&parser);
			return -1;
		}
	}

	if (!settings_parser_check(parser, service->set_pool, &error)) {
		*error_r = t_strdup_printf("Invalid settings: %s", error);
		settings_parser_deinit(&parser);
		return -1;
	}

	sets = settings_parser_get_list(parser);
	service->set = sets[0];
	service->set_parser = parser;

	if (service->set->version_ignore &&
	    (service->flags & MASTER_SERVICE_FLAG_STANDALONE) != 0) {
		/* running standalone. we want to ignore plugin versions. */
		service->version_string = NULL;
	}

	if (service->set->shutdown_clients)
		master_service_set_die_with_master(master_service, TRUE);

	/* if we change any settings afterwards, they're in expanded form.
	   especially all settings from userdb are already expanded. */
	settings_parse_set_expanded(service->set_parser, TRUE);
	return 0;
}