dovecot-2.0-pigeonhole: ManageSieve: enabled dynamic capability ...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Sat Jul 3 15:21:47 EEST 2010


details:   http://hg.rename-it.nl/dovecot-2.0-pigeonhole/rev/44ec09203ab4
changeset: 1304:44ec09203ab4
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Sat Jul 03 14:21:38 2010 +0200
description:
ManageSieve: enabled dynamic capability inference.

diffstat:

 m4/dovecot.m4                                             |    2 +-
 src/managesieve-login/Makefile.am                         |    6 +-
 src/managesieve-login/managesieve-login-settings-plugin.c |  204 ++++++++++++++++++
 src/managesieve-login/managesieve-login-settings-plugin.h |   12 +
 src/managesieve-login/managesieve-login-settings.c        |  192 -----------------
 src/managesieve-login/managesieve-login-settings.h        |    1 +
 6 files changed, 222 insertions(+), 195 deletions(-)

diffs (truncated from 481 to 300 lines):

diff -r 37b0ecfb4de7 -r 44ec09203ab4 m4/dovecot.m4
--- a/m4/dovecot.m4	Thu Jul 01 11:16:45 2010 +0200
+++ b/m4/dovecot.m4	Sat Jul 03 14:21:38 2010 +0200
@@ -56,7 +56,7 @@
 	AX_SUBST_L([DOVECOT_CFLAGS], [DOVECOT_LIBS], [DOVECOT_SSL_LIBS])
 	AX_SUBST_L([LIBDOVECOT], [LIBDOVECOT_LOGIN], [LIBDOVECOT_SQL], [LIBDOVECOT_LDA], [LIBDOVECOT_STORAGE])
 	AX_SUBST_L([LIBDOVECOT_DEPS], [LIBDOVECOT_LOGIN_DEPS], [LIBDOVECOT_SQL_DEPS], [LIBDOVECOT_LDA_DEPS], [LIBDOVECOT_STORAGE_DEPS])
-	AX_SUBST_L([LIBDOVECOT_INCLUDE], [LIBDOVECOT_LDA_INCLUDE], [LIBDOVECOT_SERVICE_INCLUDE], [LIBDOVECOT_STORAGE_INCLUDE], [LIBDOVECOT_LOGIN_INCLUDE])
+	AX_SUBST_L([LIBDOVECOT_INCLUDE], [LIBDOVECOT_LDA_INCLUDE], [LIBDOVECOT_SERVICE_INCLUDE], [LIBDOVECOT_STORAGE_INCLUDE], [LIBDOVECOT_LOGIN_INCLUDE], [LIBDOVECOT_CONFIG_INCLUDE])
 
 	DC_PLUGIN_DEPS
 ])
diff -r 37b0ecfb4de7 -r 44ec09203ab4 src/managesieve-login/Makefile.am
--- a/src/managesieve-login/Makefile.am	Thu Jul 01 11:16:45 2010 +0200
+++ b/src/managesieve-login/Makefile.am	Sat Jul 03 14:21:38 2010 +0200
@@ -15,8 +15,9 @@
 	libmanagesieve_login_settings.la
 
 libmanagesieve_login_settings_la_SOURCES = \
-	managesieve-login-settings.c
-libmanagesieve_login_settings_la_CFLAGS = $(AM_CFLAGS) -D_CONFIG_PLUGIN -DPKG_LIBEXECDIR=\""$(dovecot_pkglibexecdir)"\"
+	managesieve-login-settings-plugin.c
+libmanagesieve_login_settings_la_CFLAGS = \
+	$(AM_CFLAGS) $(LIBDOVECOT_CONFIG_INCLUDE) -DPKG_LIBEXECDIR=\""$(dovecot_pkglibexecdir)"\"
 
 libs = \
 	$(top_srcdir)/src/lib-managesieve/libmanagesieve.a
@@ -34,4 +35,5 @@
 	client.h \
 	client-authenticate.h \
 	managesieve-login-settings.h \
+	managesieve-login-settings-plugin.h \
 	managesieve-proxy.h
diff -r 37b0ecfb4de7 -r 44ec09203ab4 src/managesieve-login/managesieve-login-settings-plugin.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/managesieve-login/managesieve-login-settings-plugin.c	Sat Jul 03 14:21:38 2010 +0200
@@ -0,0 +1,204 @@
+/* Copyright (c) 2002-2010 Dovecot Sieve authors, see the included COPYING file
+ */
+
+#include "lib.h"
+#include "str.h"
+#include "buffer.h"
+#include "env-util.h"
+#include "fd-close-on-exec.h"
+#include "execv-const.h"
+#include "settings-parser.h"
+#include "config-parser-private.h"
+#include "managesieve-login-settings-plugin.h"
+
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <sysexits.h>
+
+typedef enum { CAP_SIEVE, CAP_NOTIFY } capability_type_t;
+
+static char *capability_sieve = NULL;
+static char *capability_notify = NULL;
+
+static void (*next_hook_config_parser_begin)(struct config_parser_context *ctx) = NULL;
+
+static void managesieve_login_config_parser_begin(struct config_parser_context *ctx);
+
+void managesieve_login_settings_init(struct module *module ATTR_UNUSED)
+{
+	next_hook_config_parser_begin = hook_config_parser_begin;
+	hook_config_parser_begin = managesieve_login_config_parser_begin;
+}
+
+void managesieve_login_settings_deinit(void)
+{
+	hook_config_parser_begin = next_hook_config_parser_begin;
+
+	if ( capability_sieve != NULL )
+		i_free(capability_sieve);
+
+	if ( capability_notify != NULL )
+		i_free(capability_notify);
+}
+
+static void capability_store(capability_type_t cap_type, const char *value)
+{
+	switch ( cap_type ) {
+	case CAP_SIEVE:
+		capability_sieve = i_strdup(value);
+		break;
+	case CAP_NOTIFY:
+		capability_notify = i_strdup(value);
+		break;
+	}
+}
+
+static void capability_parse(const char *cap_string)
+{
+	capability_type_t cap_type = CAP_SIEVE;
+	const char *p = cap_string;
+	string_t *part = t_str_new(256);
+
+	if ( cap_string == NULL || *cap_string == '\0' ) {
+		i_warning("managesieve-login: capability string is empty.");
+		return;
+	}
+	
+	while ( *p != '\0' ) {
+		if ( *p == '\\' ) {
+			p++;
+			if ( *p != '\0' ) {
+				str_append_c(part, *p);
+				p++;
+			} else break;
+		} else if ( *p == ':' ) {
+			if ( strcasecmp(str_c(part), "SIEVE") == 0 )
+				cap_type = CAP_SIEVE;
+			else if ( strcasecmp(str_c(part), "NOTIFY") == 0 )
+				cap_type = CAP_NOTIFY;
+			else
+				i_warning("managesieve-login: unknown capability '%s' listed in "
+					"capability string (ignored).", str_c(part));
+			str_truncate(part, 0); 
+		} else if ( *p == ',' ) {
+			capability_store(cap_type, str_c(part));
+			str_truncate(part, 0);
+		} else {
+			/* Append character, but omit leading spaces */
+			if ( str_len(part) > 0 || *p != ' ' )
+				str_append_c(part, *p);
+		}
+		p++;
+	}
+	
+	if ( str_len(part) > 0 ) {
+		capability_store(cap_type, str_c(part));
+	}
+}
+
+static bool capability_dump(void)
+{
+	char buf[4096];
+	int fd[2], status;
+	ssize_t ret;
+	unsigned int pos;
+	pid_t pid;
+
+	if ( pipe(fd) < 0 ) {
+		i_error("managesieve-login: dump-capability pipe() failed: %m");
+		return FALSE;
+	}
+	fd_close_on_exec(fd[0], TRUE);
+	fd_close_on_exec(fd[1], TRUE);
+
+	if ( (pid = fork()) == (pid_t)-1 ) {
+		(void)close(fd[0]); (void)close(fd[1]);
+		i_error("managesieve-login: dump-capability fork() failed: %m");
+		return FALSE;
+	}
+
+	if ( pid == 0 ) {
+		const char *argv[2];
+
+		/* Child */
+		(void)close(fd[0]);		
+	
+		if (dup2(fd[1], STDOUT_FILENO) < 0)
+			i_fatal("managesieve-login: dump-capability dup2() failed: %m");
+
+		env_put("DUMP_CAPABILITY=1");
+
+		argv[0] = PKG_LIBEXECDIR"/managesieve"; /* BAD */
+		argv[1] = NULL;
+		execv_const(argv[0], argv);
+
+		i_fatal("managesieve-login: dump-capability execv(%s) failed: %m", argv[0]);
+	}
+
+	(void)close(fd[1]);
+
+	alarm(5);
+	if (wait(&status) == -1) {
+		i_error("managesieve-login: dump-capability failed: process %d got stuck", 
+			(int)pid);
+		return FALSE;
+	}
+	alarm(0);
+
+	if (status != 0) {
+		(void)close(fd[0]);
+		if (WIFSIGNALED(status)) {
+			i_error("managesieve-login: dump-capability process "
+				"killed with signal %d", WTERMSIG(status));
+		} else {
+			i_error("managesieve-login: dump-capability process returned %d",
+				WIFEXITED(status) ? WEXITSTATUS(status) : status);
+		}
+		return FALSE;
+	}
+
+	pos = 0;
+	while ((ret = read(fd[0], buf + pos, sizeof(buf) - pos)) > 0)
+		pos += ret;
+
+	if (ret < 0) {
+		i_error("managesieve-login: read(dump-capability process) failed: %m");
+		(void)close(fd[0]);
+		return FALSE;
+	}
+	(void)close(fd[0]);
+
+	if (pos == 0 || buf[pos-1] != '\n') {
+		i_error("managesieve-login: dump-capability: Couldn't read capability "
+			"(got %u bytes)", pos);
+		return FALSE;
+	}
+	buf[pos-1] = '\0';
+
+	capability_parse(buf);
+
+	return TRUE;
+}
+
+static void managesieve_login_config_set
+(struct config_parser_context *ctx, const char *key, const char *value)
+{
+	config_apply_line(ctx, key, 
+		t_strdup_printf("service/managesieve-login/%s=%s", key, value), NULL);
+}
+
+static void managesieve_login_config_parser_begin(struct config_parser_context *ctx)
+{
+	if ( capability_sieve == NULL ) {
+		if ( !capability_dump() ) {
+			capability_sieve = "";
+		}
+	}
+
+	if ( capability_sieve != NULL )
+		managesieve_login_config_set(ctx, "managesieve_sieve_capability", capability_sieve);
+
+	if ( capability_notify != NULL )
+		managesieve_login_config_set(ctx, "managesieve_notify_capability", capability_notify);
+}
diff -r 37b0ecfb4de7 -r 44ec09203ab4 src/managesieve-login/managesieve-login-settings-plugin.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/managesieve-login/managesieve-login-settings-plugin.h	Sat Jul 03 14:21:38 2010 +0200
@@ -0,0 +1,12 @@
+/* Copyright (c) 2002-2010 Dovecot Sieve authors, see the included COPYING file
+ */
+
+#ifndef __MANAGESIEVE_LOGIN_SETTINGS_PLUGIN_H
+#define __MANAGESIEVE_LOGIN_SETTINGS_PLUGIN_H
+
+#include "lib.h"
+
+void managesieve_login_settings_init(struct module *module);
+void managesieve_login_settings_deinit(void);
+
+#endif /* __MANAGESIEVE_LOGIN_SETTINGS_PLUGIN_H */
diff -r 37b0ecfb4de7 -r 44ec09203ab4 src/managesieve-login/managesieve-login-settings.c
--- a/src/managesieve-login/managesieve-login-settings.c	Thu Jul 01 11:16:45 2010 +0200
+++ b/src/managesieve-login/managesieve-login-settings.c	Sat Jul 03 14:21:38 2010 +0200
@@ -18,10 +18,6 @@
 #include <sysexits.h>
 
 /* <settings checks> */
-#ifdef _CONFIG_PLUGIN
-static bool managesieve_login_settings_verify
-	(void *_set, pool_t pool, const char **error_r);
-#endif
 
 static struct inet_listener_settings managesieve_login_inet_listeners_array[] = {
     { "sieve", "", 4190, FALSE },
@@ -94,11 +90,6 @@
 	.parent_offset = (size_t)-1,
 	.parent = NULL,
 
-	/* Only compiled in the doveconf plugin */
-#ifdef _CONFIG_PLUGIN
-//	.check_func = managesieve_login_settings_verify,
-#endif
-
 	.dependencies = managesieve_login_setting_dependencies
 };
 
@@ -108,186 +99,3 @@
 	NULL
 };
 
-/* 
- * Dynamic ManageSieve capability determination
- *   Only compiled in the doveconf plugin 
- */
-
-#ifdef _CONFIG_PLUGIN
-
-typedef enum { CAP_SIEVE, CAP_NOTIFY } capability_type_t;
-
-static char *capability_sieve = NULL;
-static char *capability_notify = NULL;
-
-void managesieve_login_settings_deinit(void)


More information about the dovecot-cvs mailing list