From 137551e9dcd61b2429309de86f31275d1471820d Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Wed, 5 May 2010 19:39:26 +0200 Subject: [PATCH] ManageSieve: implemented user-independent capability dumping (untested). --- src/managesieve/Makefile.am | 2 + src/managesieve/main.c | 27 ++- src/managesieve/managesieve-capabilities.c | 188 +++++++++++++++++++++ src/managesieve/managesieve-capabilities.h | 9 + src/managesieve/managesieve-client.c | 15 -- 5 files changed, 212 insertions(+), 29 deletions(-) create mode 100644 src/managesieve/managesieve-capabilities.c create mode 100644 src/managesieve/managesieve-capabilities.h diff --git a/src/managesieve/Makefile.am b/src/managesieve/Makefile.am index def5e2e58..972e544e2 100644 --- a/src/managesieve/Makefile.am +++ b/src/managesieve/Makefile.am @@ -48,11 +48,13 @@ managesieve_SOURCES = \ managesieve-quota.c \ managesieve-client.c \ managesieve-commands.c \ + managesieve-capabilities.c \ main.c noinst_HEADERS = \ managesieve-quota.h \ managesieve-client.h \ managesieve-commands.h \ + managesieve-capabilities.h \ managesieve-settings.h \ managesieve-common.h diff --git a/src/managesieve/main.c b/src/managesieve/main.c index 17d6410cd..35e109630 100644 --- a/src/managesieve/main.c +++ b/src/managesieve/main.c @@ -20,6 +20,7 @@ #include "managesieve-common.h" #include "managesieve-commands.h" +#include "managesieve-capabilities.h" #include <stdio.h> #include <stdlib.h> @@ -119,7 +120,7 @@ static void client_add_input(struct client *client, const buffer_t *buf) o_stream_unref(&output); } -static struct client * +static int client_create_from_input(const struct mail_storage_service_input *input, int fd_in, int fd_out, const buffer_t *input_buf, const char **error_r) @@ -131,7 +132,7 @@ client_create_from_input(const struct mail_storage_service_input *input, if (mail_storage_service_lookup_next(storage_service, input, &user, &mail_user, error_r) <= 0) - return NULL; + return -1; restrict_access_allow_coredumps(TRUE); set = mail_storage_service_user_get_set(user)[1]; @@ -143,14 +144,13 @@ client_create_from_input(const struct mail_storage_service_input *input, client_add_input(client, input_buf); } T_END; - return client; + return 0; } static void main_stdio_run(const char *username) { struct mail_storage_service_input input; const char *value, *error, *input_base64; - struct client *client; buffer_t *input_buf; memset(&input, 0, sizeof(input)); @@ -169,16 +169,9 @@ static void main_stdio_run(const char *username) input_buf = input_base64 == NULL ? NULL : t_base64_decode_str(input_base64); - client = client_create_from_input(&input, STDIN_FILENO, STDOUT_FILENO, - input_buf, &error); - if ( client == NULL ) + if (client_create_from_input(&input, STDIN_FILENO, STDOUT_FILENO, + input_buf, &error) < 0) i_fatal("%s", error); - - /* Dump capabilities if requested */ - if ( getenv("DUMP_CAPABILITY") != NULL ) { - client_dump_capability(client); - exit(0); - } } static void @@ -199,7 +192,7 @@ login_client_connected(const struct master_login_client *client, buffer_create_const_data(&input_buf, client->data, client->auth_req.data_size); if (client_create_from_input(&input, client->fd, client->fd, - &input_buf, &error) == NULL) { + &input_buf, &error) < 0) { i_error("%s", error); (void)close(client->fd); master_service_client_connection_destroyed(master_service); @@ -275,6 +268,12 @@ int main(int argc, char *argv[]) /* plugins may want to add commands, so this needs to be called early */ commands_init(); + /* Dump capabilities if requested */ + if ( getenv("DUMP_CAPABILITY") != NULL ) { + managesieve_capabilities_dump(); + exit(0); + } + storage_service = mail_storage_service_init(master_service, set_roots, storage_service_flags); diff --git a/src/managesieve/managesieve-capabilities.c b/src/managesieve/managesieve-capabilities.c new file mode 100644 index 000000000..3952b6013 --- /dev/null +++ b/src/managesieve/managesieve-capabilities.c @@ -0,0 +1,188 @@ +/* Copyright (c) 2002-2010 Dovecot Sieve authors, see the included COPYING file + */ + +#include "lib.h" +#include "array.h" +#include "hostpid.h" +#include "var-expand.h" +#include "settings-parser.h" +#include "master-service.h" +#include "master-service-settings.h" +#include "master-service-settings-cache.h" + +#include "sieve.h" + +#include "managesieve-capabilities.h" + +#include <stddef.h> +#include <unistd.h> + +/* + * Global plugin settings + */ + +struct plugin_settings { + ARRAY_DEFINE(plugin_envs, const char *); +}; + +static const struct setting_parser_info **plugin_set_roots; + +#undef DEF +#define DEF(type, name) \ + { type, #name, offsetof(struct login_settings, name), NULL } + +static const struct setting_define plugin_setting_defines[] = { + { SET_STRLIST, "plugin", offsetof(struct plugin_settings, plugin_envs), NULL }, + + SETTING_DEFINE_LIST_END +}; + +static const struct setting_parser_info plugin_setting_parser_info = { + .module_name = "managesieve", + .defines = plugin_setting_defines, + + .type_offset = (size_t)-1, + .struct_size = sizeof(struct plugin_settings), + + .parent_offset = (size_t)-1, +}; + +static const struct setting_parser_info *default_plugin_set_roots[] = { + &plugin_setting_parser_info, + NULL +}; + +static const struct setting_parser_info **plugin_set_roots = + default_plugin_set_roots; + +static struct master_service_settings_cache *set_cache; + +static struct plugin_settings * +plugin_settings_read(pool_t pool, void ***other_settings_r) +{ + struct master_service_settings_input input; + const char *error; + const struct setting_parser_context *parser; + void *const *cache_sets; + void **sets; + unsigned int i, count; + + memset(&input, 0, sizeof(input)); + input.roots = plugin_set_roots; + input.module = "managesieve"; + input.service = "managesieve"; + + if (set_cache == NULL) { + set_cache = master_service_settings_cache_init + (master_service, input.module, input.service); + } + + if (master_service_settings_cache_read(set_cache, &input, NULL, + &parser, &error) < 0) + i_fatal("dump-capability: Error reading configuration: %s", error); + + cache_sets = settings_parser_get_list(parser) + 1; + for (count = 0; input.roots[count] != NULL; count++) ; + i_assert(cache_sets[count] == NULL); + sets = p_new(pool, void *, count + 1); + for (i = 0; i < count; i++) { + sets[i] = settings_dup(input.roots[i], cache_sets[i], pool); + if (!settings_check(input.roots[i], pool, sets[i], &error)) { + const char *name = input.roots[i]->module_name; + i_fatal("dump-capability: settings_check(%s) failed: %s", + name != NULL ? name : "unknown", error); + } + } + + *other_settings_r = sets + 1; + return sets[0]; +} + +static const char *plugin_settings_get + (const struct plugin_settings *set, const char *identifier) +{ + const char *const *envs; + unsigned int i, count; + + if ( !array_is_created(&set->plugin_envs) ) + return NULL; + + envs = array_get(&set->plugin_envs, &count); + for ( i = 0; i < count; i += 2 ) { + if ( strcmp(envs[i], identifier) == 0 ) + return envs[i+1]; + } + + return NULL; +} + +static void plugin_settings_deinit(void) +{ + if (set_cache != NULL) + master_service_settings_cache_deinit(&set_cache); +} + +/* + * Sieve environment + */ + +static const char *sieve_get_homedir(void *context ATTR_UNUSED) +{ + return "/tmp"; +} + +static const char *sieve_get_setting +(void *context, const char *identifier) +{ + const struct plugin_settings *set = (const struct plugin_settings *) context; + + return plugin_settings_get(set, identifier); +} + +static const struct sieve_environment sieve_env = { + sieve_get_homedir, + sieve_get_setting +}; + +/* + * Capability dumping + */ + +void managesieve_capabilities_dump(void) +{ + pool_t set_pool; + const struct plugin_settings *global_plugin_settings; + void **global_other_settings; + struct sieve_instance *svinst; + const char *extensions, *notify_cap; + + /* Read plugin settings */ + + set_pool = pool_alloconly_create("global plugin settings", 4096); + + global_plugin_settings = plugin_settings_read + (set_pool, &global_other_settings); + + /* Initialize Sieve engine */ + + svinst = sieve_init(&sieve_env, (void *) global_plugin_settings); + + extensions = plugin_settings_get(global_plugin_settings, "sieve_extensions"); + if ( extensions != NULL ) { + sieve_set_extensions(svinst, extensions); + } + + /* Dump capabilities */ + + notify_cap = sieve_get_capabilities(svinst, "notify"); + + if ( notify_cap == NULL ) + printf("SIEVE: %s\n", sieve_get_capabilities(svinst, NULL)); + else + printf("SIEVE: %s, NOTIFY: %s\n", sieve_get_capabilities(svinst, NULL), + sieve_get_capabilities(svinst, "notify")); + + /* Deinitialize */ + + plugin_settings_deinit(); +} diff --git a/src/managesieve/managesieve-capabilities.h b/src/managesieve/managesieve-capabilities.h new file mode 100644 index 000000000..a00ce731e --- /dev/null +++ b/src/managesieve/managesieve-capabilities.h @@ -0,0 +1,9 @@ +/* Copyright (c) 2002-2010 Dovecot Sieve authors, see the included COPYING file + */ + +#ifndef __MANAGESIEVE_CAPABILITIES_H +#define __MANAGESIEVE_CAPABILITIES_H + +void managesieve_capabilities_dump(void); + +#endif /* __MANAGESIEVE_CAPABILITIES_H */ diff --git a/src/managesieve/managesieve-client.c b/src/managesieve/managesieve-client.c index 0e9f00288..33fab785a 100644 --- a/src/managesieve/managesieve-client.c +++ b/src/managesieve/managesieve-client.c @@ -179,21 +179,6 @@ struct client *client_create return client; } -void client_dump_capability -(struct client *client) -{ - struct sieve_instance *svinst = client->svinst; - const char *notify_cap; - - notify_cap = sieve_get_capabilities(svinst, "notify"); - - if ( notify_cap == NULL ) - printf("SIEVE: %s\n", sieve_get_capabilities(svinst, NULL)); - else - printf("SIEVE: %s, NOTIFY: %s\n", sieve_get_capabilities(svinst, NULL), - sieve_get_capabilities(svinst, "notify")); -} - static const char *client_stats(struct client *client) { static struct var_expand_table static_tab[] = { -- GitLab