コード例 #1
0
static int
cmd_sieve_activate_run(struct doveadm_sieve_cmd_context *_ctx)
{
	struct doveadm_sieve_activate_cmd_context *ctx =
		(struct doveadm_sieve_activate_cmd_context *)_ctx;
	struct sieve_storage *storage = _ctx->storage;
	struct sieve_script *script;
	enum sieve_error error;
	int ret = 0;

	script = sieve_storage_open_script
		(storage, ctx->scriptname, NULL);
	if ( script == NULL ) {
		i_error("Failed to activate Sieve script: %s",
			sieve_storage_get_last_error(storage, &error));
		doveadm_sieve_cmd_failed_error(_ctx, error);
		return -1;
	}

	if ( sieve_script_is_active(script) <= 0 ) {
		/* Script is first being activated; compile it again without the UPLOAD
		 * flag.
		 */
		struct sieve_error_handler *ehandler;
		enum sieve_compile_flags cpflags =
			SIEVE_COMPILE_FLAG_NOGLOBAL | SIEVE_COMPILE_FLAG_ACTIVATED;
		struct sieve_binary *sbin;
		enum sieve_error error;

		/* Compile */
		ehandler = sieve_master_ehandler_create(ctx->ctx.svinst, NULL, 0);
		if ( (sbin=sieve_compile_script
			(script, ehandler, cpflags, &error)) == NULL ) {
			doveadm_sieve_cmd_failed_error(_ctx, error);
			ret = -1;
		} else {
			sieve_close(&sbin);
		}
		sieve_error_handler_unref(&ehandler);
	}

	/* Activate only when script is valid (or already active) */
	if ( ret == 0 ) {
		/* Refresh activation no matter what; this can also resolve some erroneous
		 * situations.
		 */
		ret = sieve_script_activate(script, (time_t)-1);
		if ( ret < 0 ) {
			i_error("Failed to activate Sieve script: %s",
				sieve_storage_get_last_error(storage, &error));
			doveadm_sieve_cmd_failed_error(_ctx, error);
			ret = -1;
		}
	}

	sieve_script_unref(&script);
	return ret;
}
コード例 #2
0
static int
sieve_attribute_set_active(struct mail_storage *storage,
			   struct sieve_storage *svstorage,
			   const struct mail_attribute_value *value)
{
	const char *scriptname;
	struct sieve_script *script;
	int ret;

	if (mailbox_attribute_value_to_string(storage, value, &scriptname) < 0)
		return -1;

	if (scriptname == NULL) {
		/* don't affect non-link active script */
		if ((ret=sieve_storage_is_singular(svstorage)) != 0) {
			if (ret < 0) {
				mail_storage_set_internal_error(storage);
				return -1;
			}
			return 0;
		}

		/* deactivate current script */
		if (sieve_storage_deactivate(svstorage, value->last_change) < 0) {
			mail_storage_set_critical(storage,
				"Failed to deactivate Sieve: %s",
				sieve_storage_get_last_error(svstorage, NULL));
			return -1;
		}
		return 0;
	}
	i_assert(scriptname[0] == MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_LINK);
	scriptname++;

	/* activate specified script */
	script = sieve_storage_open_script(svstorage, scriptname, NULL);
	ret = script == NULL ? -1 :
		sieve_script_activate(script, value->last_change);
	if (ret < 0) {
		mail_storage_set_critical(storage,
			"Failed to activate Sieve script '%s': %s", scriptname,
			sieve_storage_get_last_error(svstorage, NULL));
	}
	if (script != NULL)
		sieve_script_unref(&script);
	sieve_storage_set_modified(svstorage, value->last_change);
	return ret;
}
コード例 #3
0
static int
sieve_attribute_set_active_script(struct mail_storage *storage,
			   struct sieve_storage *svstorage,
			   const struct mail_attribute_value *value)
{
	struct istream *input;

	if (value->value != NULL) {
		input = i_stream_create_from_data(value->value, strlen(value->value));
	} else if (value->value_stream != NULL) {
		input = value->value_stream;
		i_stream_ref(input);
	} else {
		return sieve_attribute_unset_active_script(storage, svstorage, value->last_change);
	}
	/* skip over the 'S' type */
	i_stream_skip(input, 1);

	if (sieve_storage_save_as_active
		(svstorage, input, value->last_change) < 0) {
		mail_storage_set_critical(storage,
			"Failed to save active sieve script: %s",
			sieve_storage_get_last_error(svstorage, NULL));
		i_stream_unref(&input);
		return -1;
	}

	sieve_storage_set_modified(svstorage, value->last_change);
	i_stream_unref(&input);
	return 0;
}
コード例 #4
0
static int sieve_attribute_unset_script(struct mail_storage *storage,
					struct sieve_storage *svstorage,
					const char *scriptname)
{
	struct sieve_script *script;
	const char *errstr;
	enum sieve_error error;
	int ret = 0;

	script = sieve_storage_open_script(svstorage, scriptname, NULL);
	if (script == NULL) { 
		ret = -1;
	} else {
		ret = sieve_script_delete(script, TRUE);
		sieve_script_unref(&script);
	}

	if (ret < 0) {
		errstr = sieve_storage_get_last_error(svstorage, &error);
		if (error == SIEVE_ERROR_NOT_FOUND) {
			/* already deleted, ignore */
			return 0;
		}
		mail_storage_set_critical(storage,
			"Failed to delete Sieve script '%s': %s", scriptname,
			errstr);
		return -1;
	}
	return 0;
}
コード例 #5
0
void doveadm_sieve_cmd_failed_storage
(struct doveadm_sieve_cmd_context *ctx,	 struct sieve_storage *storage)
{
	enum sieve_error error;

	(void)sieve_storage_get_last_error(storage, &error);
	doveadm_sieve_cmd_failed_error(ctx, error);
}
コード例 #6
0
static const char *
sieve_attribute_iter_next_script(struct sieve_mailbox_attribute_iter *siter)
{
	struct mail_user *user = siter->iter.box->storage->user;
	struct sieve_mail_user *suser = SIEVE_USER_CONTEXT(user);
	struct sieve_storage *svstorage = suser->sieve_storage;
	const char *scriptname;
	bool active;
	int ret;

	if (siter->sieve_list == NULL)
		return NULL;

	/* Iterate through all scripts in sieve_dir */
	while ((scriptname = sieve_storage_list_next(siter->sieve_list, &active))
		!= NULL) {
		if (active)
			siter->have_active = TRUE;
		str_truncate(siter->name, strlen(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES));
		str_append(siter->name, scriptname);
		return str_c(siter->name);
	}
	if (sieve_storage_list_deinit(&siter->sieve_list) < 0) {
		mail_storage_set_critical(siter->iter.box->storage,
			"Failed to iterate sieve scripts: %s",
			sieve_storage_get_last_error(svstorage, NULL));
		siter->failed = TRUE;
		return NULL;
	}

	/* Check whether active script is a proper symlink or a regular file */
	if ((ret=sieve_storage_is_singular(svstorage)) < 0) {
		mail_storage_set_critical(siter->iter.box->storage,
			"Failed to iterate sieve scripts: %s",
			sieve_storage_get_last_error(svstorage, NULL));
		return NULL;
	}

	/* Regular file */
	if (ret > 0)
		return MAILBOX_ATTRIBUTE_SIEVE_DEFAULT;

	/* Symlink or none active */
	return siter->have_active ? MAILBOX_ATTRIBUTE_SIEVE_DEFAULT : NULL;
}
コード例 #7
0
static int
sieve_attribute_retrieve_script(struct mail_storage *storage,
			   struct sieve_storage *svstorage, struct sieve_script *script,
			   bool add_type_prefix,
			   struct mail_attribute_value *value_r, const char **errorstr_r)
{
	static char type = MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_SCRIPT;
	struct istream *input, *inputs[3];
	const struct stat *st;
	enum sieve_error error;

	if (script == NULL)
		*errorstr_r = sieve_storage_get_last_error(svstorage, &error);
	else if (sieve_script_get_stream(script, &input, &error) < 0)
		sieve_script_unref(&script);
	
	if (script == NULL) {
		if (error == SIEVE_ERROR_NOT_FOUND) {
			/* already deleted, but return the last_change */
			(void)sieve_storage_get_last_change(svstorage,
							    &value_r->last_change);
			return 0;
		}
		*errorstr_r = sieve_storage_get_last_error(svstorage, &error);
		return -1;
	}
	if (i_stream_stat(input, FALSE, &st) < 0) {
		mail_storage_set_critical(storage,
			"stat(%s) failed: %m", i_stream_get_name(input));
	} else {
		value_r->last_change = st->st_mtime;
	}
	if (!add_type_prefix) {
		i_stream_ref(input);
		value_r->value_stream = input;
	} else {
		inputs[0] = i_stream_create_from_data(&type, 1);
		inputs[1] = input;
		inputs[2] = NULL;
		value_r->value_stream = i_stream_create_concat(inputs);
		i_stream_unref(&inputs[0]);
	}
	sieve_script_unref(&script);
	return 1;
}
コード例 #8
0
static int cmd_sieve_deactivate_run
(struct doveadm_sieve_cmd_context *_ctx)
{
	struct sieve_storage *storage = _ctx->storage;
	enum sieve_error error;

	if (sieve_storage_deactivate(storage, (time_t)-1) < 0) {
		i_error("Failed to deactivate Sieve script: %s",
			sieve_storage_get_last_error(storage, &error));
		doveadm_sieve_cmd_failed_error(_ctx, error);
		return -1;
	}
	return 0;
}
コード例 #9
0
static int
cmd_sieve_delete_run(struct doveadm_sieve_cmd_context *_ctx)
{
	struct doveadm_sieve_delete_cmd_context *ctx =
		(struct doveadm_sieve_delete_cmd_context *)_ctx;
	struct sieve_storage *storage = _ctx->storage;
	const ARRAY_TYPE(const_string) *scriptnames = &ctx->scriptnames;
	const char *const *namep;
	struct sieve_script *script;
	enum sieve_error error;
	int ret = 0;

	array_foreach(scriptnames, namep) {
		const char *scriptname = *namep;
		int sret = 0;

		script = sieve_storage_open_script
			(storage, scriptname, NULL);
		if (script == NULL) {
			sret =  -1;
		} else {
			if (sieve_script_delete(script, ctx->ignore_active) < 0) {
				(void)sieve_storage_get_last_error(storage, &error);
				sret = -1;
			}
			sieve_script_unref(&script);
		}
			
		if (sret < 0) {
			i_error("Failed to delete Sieve script: %s",
				sieve_storage_get_last_error(storage, &error));
			doveadm_sieve_cmd_failed_error(_ctx, error);
			ret = -1;
		}
	}
	return ret;
}
コード例 #10
0
static int
sieve_attribute_unset_active_script(struct mail_storage *storage,
			   struct sieve_storage *svstorage, time_t last_change)
{
	int ret;

	if ((ret=sieve_storage_is_singular(svstorage)) != 0) {
		if (ret < 0)
			mail_storage_set_internal_error(storage);
		return ret;
	}

	if (sieve_storage_deactivate(svstorage, last_change) < 0) {
		mail_storage_set_critical(storage,
			"Failed to deactivate sieve: %s",
			sieve_storage_get_last_error(svstorage, NULL));
		return -1;
	}
	return 0;
}
コード例 #11
0
static int
cmd_sieve_get_run(struct doveadm_sieve_cmd_context *_ctx)
{
	struct doveadm_sieve_get_cmd_context *ctx =
		(struct doveadm_sieve_get_cmd_context *)_ctx;
	struct sieve_script *script;
	struct istream *input;
	enum sieve_error error;

	script = sieve_storage_open_script
		(_ctx->storage, ctx->scriptname, &error);
	if ( script == NULL || sieve_script_get_stream
		(script, &input, &error) < 0 ) {
		i_error("Failed to open Sieve script: %s",
			sieve_storage_get_last_error(_ctx->storage, &error));
		doveadm_sieve_cmd_failed_error(_ctx, error);
		if (script != NULL)
			sieve_script_unref(&script);
		return -1;
	}

	return doveadm_print_istream(input);
}
コード例 #12
0
static int
sieve_attribute_iter_script_init(struct sieve_mailbox_attribute_iter *siter)
{
	struct mail_user *user = siter->iter.box->storage->user;
	struct sieve_storage *svstorage;
	int ret;

	if (user->mail_debug)
		i_debug("doveadm-sieve: Iterating Sieve mailbox attributes");

	if ((ret = mail_sieve_user_init(user, &svstorage)) <= 0)
		return ret;

	siter->sieve_list = sieve_storage_list_init(svstorage);
	if (siter->sieve_list == NULL) {
		mail_storage_set_critical(siter->iter.box->storage,
			"Failed to iterate sieve scripts: %s",
			sieve_storage_get_last_error(svstorage, NULL));
		return -1;
	}
	siter->name = str_new(default_pool, 128);
	str_append(siter->name, MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES);
	return 0;
}
コード例 #13
0
static int
sieve_attribute_set_sieve(struct mail_storage *storage,
			  const char *key,
			  const struct mail_attribute_value *value)
{
	struct sieve_storage *svstorage;
	struct sieve_storage_save_context *save_ctx;
	struct istream *input;
	const char *scriptname;
	int ret;

	if ((ret = mail_sieve_user_init(storage->user, &svstorage)) <= 0) {
		if (ret == 0) {
			mail_storage_set_error(storage, MAIL_ERROR_NOTFOUND,
					       "Sieve not enabled for user");
		}
		return -1;
	}

	if (strcmp(key, MAILBOX_ATTRIBUTE_SIEVE_DEFAULT) == 0)
		return sieve_attribute_set_default(storage, svstorage, value);
	if (strncmp(key, MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES,
		    strlen(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES)) != 0) {
		mail_storage_set_error(storage, MAIL_ERROR_NOTFOUND,
				       "Nonexistent sieve attribute");
		return -1;
	}
	scriptname = key + strlen(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES);

	if (value->value != NULL) {
		input = i_stream_create_from_data(value->value,
						  strlen(value->value));
		save_ctx = sieve_storage_save_init(svstorage, scriptname, input);
		i_stream_unref(&input);
	} else if (value->value_stream != NULL) {
		input = value->value_stream;
		save_ctx = sieve_storage_save_init(svstorage, scriptname, input);
	} else {
		return sieve_attribute_unset_script(storage, svstorage, scriptname);
	}

	if (save_ctx == NULL) {
		/* save initialization failed */
		mail_storage_set_critical(storage,
			"Failed to save sieve script '%s': %s", scriptname,
			sieve_storage_get_last_error(svstorage, NULL));
		return -1;
	}

	sieve_storage_save_set_mtime(save_ctx, value->last_change);

	ret = 0;
	while (i_stream_read(input) > 0) {
		if (sieve_storage_save_continue(save_ctx) < 0) {
			mail_storage_set_critical(storage,
				"Failed to save sieve script '%s': %s", scriptname,
				sieve_storage_get_last_error(svstorage, NULL));
			ret = -1;
			break;
		}
	}
	i_assert(input->eof || ret < 0);
	if (input->stream_errno != 0) {
		errno = input->stream_errno;
		mail_storage_set_critical(storage,
			"Saving sieve script: read(%s) failed: %m",
			i_stream_get_name(input));
		ret = -1;
	}
	if (ret == 0 && sieve_storage_save_finish(save_ctx) < 0) {
		mail_storage_set_critical(storage,
			"Failed to save sieve script '%s': %s", scriptname,
			sieve_storage_get_last_error(svstorage, NULL));
		ret = -1;
	}
	if (ret < 0)
		sieve_storage_save_cancel(&save_ctx);
	else if (sieve_storage_save_commit(&save_ctx) < 0) {
		mail_storage_set_critical(storage,
			"Failed to save sieve script '%s': %s", scriptname,
			sieve_storage_get_last_error(svstorage, NULL));
		ret = -1;
	}
	return ret;
}