diff options
Diffstat (limited to 'pigeonhole/src/plugins/doveadm-sieve/doveadm-sieve-cmd.c')
-rw-r--r-- | pigeonhole/src/plugins/doveadm-sieve/doveadm-sieve-cmd.c | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/pigeonhole/src/plugins/doveadm-sieve/doveadm-sieve-cmd.c b/pigeonhole/src/plugins/doveadm-sieve/doveadm-sieve-cmd.c new file mode 100644 index 0000000..eb9318c --- /dev/null +++ b/pigeonhole/src/plugins/doveadm-sieve/doveadm-sieve-cmd.c @@ -0,0 +1,179 @@ +/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file + */ + +#include "lib.h" +#include "unichar.h" +#include "mail-storage.h" +#include "doveadm-mail.h" + +#include "sieve.h" +#include "sieve-script.h" +#include "sieve-storage.h" + +#include "doveadm-sieve-cmd.h" + +void doveadm_sieve_cmd_failed_error +(struct doveadm_sieve_cmd_context *ctx, enum sieve_error error) +{ + struct doveadm_mail_cmd_context *mctx = &ctx->ctx; + int exit_code = 0; + + switch ( error ) { + case SIEVE_ERROR_NONE: + i_unreached(); + return; + case SIEVE_ERROR_TEMP_FAILURE: + exit_code = EX_TEMPFAIL; + break; + case SIEVE_ERROR_NOT_POSSIBLE: + case SIEVE_ERROR_EXISTS: + case SIEVE_ERROR_NOT_VALID: + case SIEVE_ERROR_ACTIVE: + exit_code = DOVEADM_EX_NOTPOSSIBLE; + break; + case SIEVE_ERROR_BAD_PARAMS: + exit_code = EX_USAGE; + break; + case SIEVE_ERROR_NO_PERMISSION: + exit_code = EX_NOPERM; + break; + case SIEVE_ERROR_NO_QUOTA: + exit_code = EX_CANTCREAT; + break; + case SIEVE_ERROR_NOT_FOUND: + exit_code = DOVEADM_EX_NOTFOUND; + break; + default: + i_unreached(); + } + /* tempfail overrides all other exit codes, otherwise use whatever + error happened first */ + if ( mctx->exit_code == 0 || exit_code == EX_TEMPFAIL ) + mctx->exit_code = exit_code; +} + +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); +} + +static const char *doveadm_sieve_cmd_get_setting +(void *context, const char *identifier) +{ + struct doveadm_sieve_cmd_context *ctx = + (struct doveadm_sieve_cmd_context *) context; + + return mail_user_plugin_getenv(ctx->ctx.cur_mail_user, identifier); +} + +static const struct sieve_callbacks sieve_callbacks = { + NULL, + doveadm_sieve_cmd_get_setting +}; + +static bool doveadm_sieve_cmd_parse_arg +(struct doveadm_mail_cmd_context *_ctx ATTR_UNUSED, + int c ATTR_UNUSED) +{ + return FALSE; +} + +void doveadm_sieve_cmd_scriptnames_check(const char *const args[]) +{ + unsigned int i; + + for (i = 0; args[i] != NULL; i++) { + if (!uni_utf8_str_is_valid(args[i])) { + i_fatal_status(EX_DATAERR, + "Sieve script name not valid UTF-8: %s", args[i]); + } + if ( !sieve_script_name_is_valid(args[i]) ) { + i_fatal_status(EX_DATAERR, + "Sieve script name not valid: %s", args[i]); + } + } +} + +static int +doveadm_sieve_cmd_run +(struct doveadm_mail_cmd_context *_ctx, + struct mail_user *user) +{ + struct doveadm_sieve_cmd_context *ctx = + (struct doveadm_sieve_cmd_context *)_ctx; + struct sieve_environment svenv; + enum sieve_error error; + int ret; + + memset((void*)&svenv, 0, sizeof(svenv)); + svenv.username = user->username; + (void)mail_user_get_home(user, &svenv.home_dir); + svenv.base_dir = user->set->base_dir; + svenv.flags = SIEVE_FLAG_HOME_RELATIVE; + + ctx->svinst = sieve_init + (&svenv, &sieve_callbacks, (void *)ctx, user->mail_debug); + + ctx->storage = sieve_storage_create_main + (ctx->svinst, user, SIEVE_STORAGE_FLAG_READWRITE, &error); + if ( ctx->storage == NULL ) { + switch ( error ) { + case SIEVE_ERROR_NOT_POSSIBLE: + error = SIEVE_ERROR_NOT_FOUND; + i_error("Failed to open Sieve storage: " + "Sieve is disabled for this user"); + break; + case SIEVE_ERROR_NOT_FOUND: + i_error("Failed to open Sieve storage: " + "User cannot manage personal Sieve scripts."); + break; + default: + i_error("Failed to open Sieve storage."); + } + doveadm_sieve_cmd_failed_error(ctx, error); + ret = -1; + + } else { + i_assert( ctx->v.run != NULL ); + ret = ctx->v.run(ctx); + sieve_storage_unref(&ctx->storage); + } + + sieve_deinit(&ctx->svinst); + return ret; +} + +struct doveadm_sieve_cmd_context * +doveadm_sieve_cmd_alloc_size(size_t size) +{ + struct doveadm_sieve_cmd_context *ctx; + + ctx = (struct doveadm_sieve_cmd_context *) + doveadm_mail_cmd_alloc_size(size); + ctx->ctx.getopt_args = "s"; + ctx->ctx.v.parse_arg = doveadm_sieve_cmd_parse_arg; + ctx->ctx.v.run = doveadm_sieve_cmd_run; + return ctx; +} + +static struct doveadm_cmd_ver2 *doveadm_sieve_commands[] = { + &doveadm_sieve_cmd_list, + &doveadm_sieve_cmd_get, + &doveadm_sieve_cmd_put, + &doveadm_sieve_cmd_delete, + &doveadm_sieve_cmd_activate, + &doveadm_sieve_cmd_deactivate, + &doveadm_sieve_cmd_rename +}; + +void doveadm_sieve_cmds_init(void) +{ + unsigned int i; + + for (i = 0; i < N_ELEMENTS(doveadm_sieve_commands); i++) + doveadm_cmd_register_ver2(doveadm_sieve_commands[i]); +} |