diff --git a/.cvsignore b/.cvsignore
index d4d6fa3..50a3235 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -1,2 +1,2 @@
-cyrus-imapd-2.3.14.tar.gz
+cyrus-imapd-2.3.15.tar.gz
cyrus_sharedbackup-0.1.tar.gz
diff --git a/cyrus-imapd-2.3.1-authid_normalize.patch b/cyrus-imapd-2.3.1-authid_normalize.patch
index 4269446..c96e7dc 100644
--- a/cyrus-imapd-2.3.1-authid_normalize.patch
+++ b/cyrus-imapd-2.3.1-authid_normalize.patch
@@ -1,17 +1,7 @@
---- cyrus-imapd-2.3.13/lib/libcyr_cfg.h.authid_normalize 2008-07-30 18:03:39.000000000 +0200
-+++ cyrus-imapd-2.3.13/lib/libcyr_cfg.h 2009-01-13 11:41:59.000000000 +0100
-@@ -112,6 +112,8 @@ enum cyrus_opt {
- CYRUSOPT_SQL_PASSWD,
- /* Secure SQL connection (OFF) */
- CYRUSOPT_SQL_USESSL,
-+ /* Lowercase uid and strip leading and trailing blanks (OFF) */
-+ CYRUSOPT_NORMALIZEUID,
-
- CYRUSOPT_LAST
-
---- cyrus-imapd-2.3.13/lib/auth_unix.c.authid_normalize 2009-01-13 11:38:08.000000000 +0100
-+++ cyrus-imapd-2.3.13/lib/auth_unix.c 2009-01-13 11:38:08.000000000 +0100
-@@ -155,10 +155,12 @@
+diff -up cyrus-imapd-2.3.15/lib/auth_unix.c.authid_normalize cyrus-imapd-2.3.15/lib/auth_unix.c
+--- cyrus-imapd-2.3.15/lib/auth_unix.c.authid_normalize 2009-09-18 11:53:47.183115911 +0200
++++ cyrus-imapd-2.3.15/lib/auth_unix.c 2009-09-18 11:53:47.252115833 +0200
+@@ -156,10 +156,12 @@ const char *identifier;
size_t len;
{
static char retbuf[81];
@@ -24,7 +14,7 @@
if(!len) len = strlen(identifier);
if(len >= sizeof(retbuf)) return NULL;
-@@ -210,6 +212,22 @@
+@@ -211,6 +213,22 @@ size_t len;
/* now we don't */
/* if (!sawalpha) return NULL; */
@@ -47,9 +37,10 @@
return retbuf;
}
---- cyrus-imapd-2.3.13/lib/imapoptions.authid_normalize 2009-01-13 11:38:08.000000000 +0100
-+++ cyrus-imapd-2.3.13/lib/imapoptions 2009-01-13 11:38:08.000000000 +0100
-@@ -1182,6 +1182,11 @@
+diff -up cyrus-imapd-2.3.15/lib/imapoptions.authid_normalize cyrus-imapd-2.3.15/lib/imapoptions
+--- cyrus-imapd-2.3.15/lib/imapoptions.authid_normalize 2009-09-18 11:53:47.244115877 +0200
++++ cyrus-imapd-2.3.15/lib/imapoptions 2009-09-18 11:53:47.260115873 +0200
+@@ -1217,6 +1217,11 @@ product version in the capabilities */
interface, otherwise the user is assumed to be in the default
domain (if set). */
@@ -61,17 +52,29 @@
/*
.SH SEE ALSO
.PP
---- cyrus-imapd-2.3.13/lib/libcyr_cfg.c.authid_normalize 2008-07-30 18:03:38.000000000 +0200
-+++ cyrus-imapd-2.3.13/lib/libcyr_cfg.c 2009-01-13 11:38:08.000000000 +0100
-@@ -150,6 +150,11 @@
- CFGVAL(long, 0),
+diff -up cyrus-imapd-2.3.15/lib/libcyr_cfg.c.authid_normalize cyrus-imapd-2.3.15/lib/libcyr_cfg.c
+--- cyrus-imapd-2.3.15/lib/libcyr_cfg.c.authid_normalize 2009-03-31 06:43:20.000000000 +0200
++++ cyrus-imapd-2.3.15/lib/libcyr_cfg.c 2009-09-18 11:55:03.436822867 +0200
+@@ -154,6 +154,10 @@ struct cyrusopt_s cyrus_options[] = {
+ CFGVAL(long, 1),
CYRUS_OPT_SWITCH },
+ { CYRUSOPT_NORMALIZEUID,
+ CFGVAL(long, 1),
+ CYRUS_OPT_SWITCH },
+
-+
{ CYRUSOPT_LAST, { NULL }, CYRUS_OPT_NOTOPT }
};
+diff -up cyrus-imapd-2.3.15/lib/libcyr_cfg.h.authid_normalize cyrus-imapd-2.3.15/lib/libcyr_cfg.h
+--- cyrus-imapd-2.3.15/lib/libcyr_cfg.h.authid_normalize 2009-03-31 06:43:20.000000000 +0200
++++ cyrus-imapd-2.3.15/lib/libcyr_cfg.h 2009-09-18 11:55:33.267115989 +0200
+@@ -114,6 +114,8 @@ enum cyrus_opt {
+ CYRUSOPT_SQL_USESSL,
+ /* Checkpoint after every recovery (OFF) */
+ CYRUSOPT_SKIPLIST_ALWAYS_CHECKPOINT,
++ /* Lowercase uid and strip leading and trailing blanks (OFF) */
++ CYRUSOPT_NORMALIZEUID,
+
+ CYRUSOPT_LAST
+
diff --git a/cyrus-imapd-2.3.12p2-autocreate-0.10-0.diff b/cyrus-imapd-2.3.12p2-autocreate-0.10-0.diff
index d41cd28..0d9b120 100644
--- a/cyrus-imapd-2.3.12p2-autocreate-0.10-0.diff
+++ b/cyrus-imapd-2.3.12p2-autocreate-0.10-0.diff
@@ -1,435 +1,611 @@
---- cyrus-imapd-2.3.13/notifyd/notifyd.c.autocreate 2008-03-24 20:59:32.000000000 +0100
-+++ cyrus-imapd-2.3.13/notifyd/notifyd.c 2009-01-13 11:14:09.000000000 +0100
-@@ -96,7 +96,7 @@
-
- #define NOTIFY_MAXSIZE 8192
-
--int do_notify()
-+static int do_notify()
- {
- struct sockaddr_un sun_data;
- socklen_t sunlen = sizeof(sun_data);
---- cyrus-imapd-2.3.13/notifyd/Makefile.in.autocreate 2008-03-24 20:59:32.000000000 +0100
-+++ cyrus-imapd-2.3.13/notifyd/Makefile.in 2009-01-13 11:14:09.000000000 +0100
-@@ -71,10 +71,11 @@
- SERVICE=../master/service.o
-
- IMAP_LIBS = @IMAP_LIBS@ @LIB_RT@
-+SIEVE_LIBS = @SIEVE_LIBS@
- IMAP_COM_ERR_LIBS = @IMAP_COM_ERR_LIBS@
- LIB_WRAP = @LIB_WRAP@
- LIBS = @ZEPHYR_LIBS@ @LIBS@ $(IMAP_COM_ERR_LIBS)
--DEPLIBS=../imap/mutex_fake.o ../imap/libimap.a ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@
-+DEPLIBS=../imap/mutex_fake.o ../imap/libimap.a $(SIEVE_LIBS) ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@
-
- PURIFY=/usr/local/bin/purify
- PUREOPT=-best-effort
---- cyrus-imapd-2.3.13/imap/mboxlist.c.autocreate 2008-10-08 17:47:08.000000000 +0200
-+++ cyrus-imapd-2.3.13/imap/mboxlist.c 2009-01-13 11:14:09.000000000 +0100
-@@ -83,6 +83,12 @@
- #include "quota.h"
- #include "sync_log.h"
-
-+#ifdef USE_SIEVE
-+extern int autoadd_sieve(char *userid,
-+ const char *source_script);
+diff -up /dev/null cyrus-imapd-2.3.15/imap/autosieve.c
+--- /dev/null 2009-09-11 15:21:01.808252010 +0200
++++ cyrus-imapd-2.3.15/imap/autosieve.c 2009-09-18 11:11:39.778115814 +0200
+@@ -0,0 +1,590 @@
++#include
++#include
++#include
++
++#ifdef HAVE_UNISTD_H
++#include
+#endif
+
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++#include
+
- #define DB config_mboxlist_db
- #define SUBDB config_subscription_db
-
-@@ -100,11 +106,29 @@
- static int mboxlist_changequota(const char *name, int matchlen, int maycreate,
- void *rock);
-
-+static int mboxlist_autochangesub(char *name, int matchlen, int maycreate,
-+ void *rock);
++#include "global.h"
++#include "util.h"
++#include "xmalloc.h"
++#include "xstrlcpy.h"
++#include "xstrlcat.h"
++#include "mailbox.h"
++#include "imap_err.h"
++#include "sieve_interface.h"
++#include "script.h"
+
-+static int mboxlist_autosubscribe_sharedfolders(struct namespace *namespace,
-+ char *userid, char *auth_userid,
-+ struct auth_state *auth_state);
++#define TIMSIEVE_FAIL -1
++#define TIMSIEVE_OK 0
++#define MAX_FILENAME 1024
+
- struct change_rock {
- struct quota *quota;
- struct txn **tid;
- };
-
-+/*
-+ * Struct needed to be passed as void *rock to
-+ * mboxlist_autochangesub();
-+ */
-+struct changesub_rock_st {
-+ char *userid;
-+ char *auth_userid;
-+ struct auth_state *auth_state;
-+};
++static int get_script_name(char *sievename, size_t buflen, const char *filename);
++static int get_script_dir(char *sieve_script_dir, size_t buflen, char *userid, const char *sieve_dir);
++int autoadd_sieve(char *userid, const char *source_script);
+
++//static void fatal(const char *s, int code);
++static void foo(void);
++static int sieve_notify(void *ac __attribute__((unused)),
++ void *interp_context __attribute__((unused)),
++ void *script_context __attribute__((unused)),
++ void *message_context __attribute__((unused)),
++ const char **errmsg __attribute__((unused)));
++static int mysieve_error(int lineno, const char *msg,
++ void *i __attribute__((unused)), void *s);
++static int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret);
++
++
++sieve_vacation_t vacation2 = {
++ 0, /* min response */
++ 0, /* max response */
++ (sieve_callback *) &foo, /* autorespond() */
++ (sieve_callback *) &foo /* send_response() */
++};
+
- #define FNAME_SUBSSUFFIX ".sub"
-
- /*
-@@ -3383,3 +3407,349 @@
-
- return(config_delete_mode == IMAP_ENUM_DELETE_MODE_DELAYED);
- }
+
+/*
-+ * Automatically subscribe user to *ALL* shared folders,
-+ * one has permissions to be subscribed to.
-+ * INBOX subfolders are excluded.
++ * Find the name of the sieve script
++ * given the source script and compiled script names
+ */
-+static int mboxlist_autochangesub(char *name, int matchlen, int maycreate,
-+ void *rock) {
-+
-+ struct changesub_rock_st *changesub_rock = (struct changesub_rock_st *) rock;
-+ char *userid = changesub_rock->userid;
-+ char *auth_userid = changesub_rock->auth_userid;
-+ struct auth_state *auth_state = changesub_rock->auth_state;
++static int get_script_name(char *sievename, size_t buflen, const char *filename)
++{
++ char *p;
+ int r;
+
++ p = strrchr(filename, '/');
++ if (p == NULL)
++ p = (char *) filename;
++ else
++ p++;
+
-+ if((strlen(name) == 5 && !strncmp(name, "INBOX", 5)) || /* Exclude INBOX */
-+ (strlen(name) > 5 && !strncmp(name, "INBOX.",6)) || /* Exclude INBOX subfolders */
-+ (strlen(name) > 4 && !strncmp(name, "user.", 5))) /* Exclude other users' folders */
-+ return 0;
-+
-+
-+ r = mboxlist_changesub(name, userid, auth_state, 1, 0);
-+
-+ if (r) {
-+ syslog(LOG_WARNING,
-+ "autosubscribe: User %s to folder %s, subscription failed: %s",
-+ auth_userid, name, error_message(r));
-+ } else {
-+ syslog(LOG_NOTICE,
-+ "autosubscribe: User %s to folder %s, subscription succeeded",
-+ auth_userid, name);
-+ }
-+
-+ return 0;
++ r = strlcpy(sievename, p, buflen) - buflen;
++ return (r >= 0 || r == -buflen ? 1 : 0);
+}
+
-+#define SEP '|'
+
+/*
-+ * Automatically subscribe user to a shared folder.
-+ * Subscription is done successfully, if the shared
-+ * folder exists and the user has the necessary
-+ * permissions.
++ * Find the directory where the sieve scripts of the user
++ * reside
+ */
-+static int mboxlist_autosubscribe_sharedfolders(struct namespace *namespace,
-+ char *userid, char *auth_userid,
-+ struct auth_state *auth_state) {
-+
-+ const char *sub ;
-+ char *p, *q, *next_sub;
-+ char folder[MAX_MAILBOX_NAME+1], name[MAX_MAILBOX_NAME+1], mailboxname[MAX_MAILBOX_NAME+1];
-+ int len;
-+ int r = 0;
-+ int subscribe_all_sharedfolders = 0;
++static int get_script_dir(char *sieve_script_dir, size_t buflen, char *userid, const char *sieve_dir)
++{
++ char *user = NULL, *domain = NULL;
+
-+ subscribe_all_sharedfolders = config_getswitch(IMAPOPT_AUTOSUBSCRIBE_ALL_SHAREDFOLDERS);
++ /* Setup the user and the domain */
++ if(config_virtdomains && (domain = strchr(userid, '@'))) {
++ user = (char *) xmalloc((domain - userid +1) * sizeof(char));
++ strlcpy(user, userid, domain - userid + 1);
++ domain++;
++ } else
++ user = userid;
+
-+ /*
-+ * If subscribeallsharedfolders is set to yes in imapd.conf, then
-+ * subscribe user to every shared folder one has the apropriate
-+ * permissions.
-+ */
-+ if(subscribe_all_sharedfolders) {
-+ char pattern[MAX_MAILBOX_PATH+1];
-+ struct changesub_rock_st changesub_rock;
++ /* Find the dir path where the sieve scripts of the user will reside */
++ if (config_virtdomains && domain) {
++ if(snprintf(sieve_script_dir, buflen, "%s%s%c/%s/%c/%s/",
++ sieve_dir, FNAME_DOMAINDIR, dir_hash_c(domain, config_fulldirhash), domain, dir_hash_c(user,config_fulldirhash), user) >= buflen) {
++ free(user);
++ return 1;
++ }
++ } else {
++ if(snprintf(sieve_script_dir, buflen, "%s/%c/%s/",
++ sieve_dir, dir_hash_c(user,config_fulldirhash), user) >= buflen)
++ return 1;
++ }
+
-+ strcpy(pattern, "*");
-+ changesub_rock.userid = userid;
-+ changesub_rock.auth_userid = auth_userid;
-+ changesub_rock.auth_state = auth_state;
++ /* Free the xmalloced user memory, reserved above */
++ if(user != userid)
++ free(user);
+
-+ r = mboxlist_findall(namespace, pattern, 0, userid,
-+ auth_state, mboxlist_autochangesub, &changesub_rock);
++ return 0;
++}
+
-+ return r;
++int autoadd_sieve(char *userid, const char *source_script)
++{
++ sieve_script_t *s = NULL;
++ bytecode_info_t *bc = NULL;
++ char *err = NULL;
++ FILE *in_stream, *out_fp;
++ int out_fd, in_fd, r, k;
++ int do_compile = 0;
++ const char *sieve_dir = NULL;
++ const char *compiled_source_script = NULL;
++ char sievename[MAX_FILENAME];
++ char sieve_script_name[MAX_FILENAME];
++ char sieve_script_dir[MAX_FILENAME];
++ char sieve_bcscript_name[MAX_FILENAME];
++ char sieve_default[MAX_FILENAME];
++ char sieve_tmpname[MAX_FILENAME];
++ char sieve_bctmpname[MAX_FILENAME];
++ char sieve_bclink_name[MAX_FILENAME];
++ char buf[4096];
++ mode_t oldmask;
++ struct stat statbuf;
++
++ /* We don't support using the homedirectory, like timsieved */
++ if (config_getswitch(IMAPOPT_SIEVEUSEHOMEDIR)) {
++ syslog(LOG_WARNING,"autocreate_sieve: autocreate_sieve does not work with sieveusehomedir option in imapd.conf");
++ return 1;
+ }
+
-+ if ((sub=config_getstring(IMAPOPT_AUTOSUBSCRIBESHAREDFOLDERS)) == NULL)
-+ return r;
++ /* Check if sievedir is defined in imapd.conf */
++ if(!(sieve_dir = config_getstring(IMAPOPT_SIEVEDIR))) {
++ syslog(LOG_WARNING, "autocreate_sieve: sievedir option is not defined. Check imapd.conf");
++ return 1;
++ }
+
-+ next_sub = (char *) sub;
-+ while (*next_sub) {
-+ for (p = next_sub ; isspace((int) *p) || *p == SEP ; p++);
-+ for (next_sub = p ; *next_sub && *next_sub != SEP ; next_sub++);
-+ for (q = next_sub ; q > p && (isspace((int) *q) || *q == SEP || !*q) ; q--);
-+ if (!*p ) continue;
++ /* Check if autocreate_sieve_compiledscript is defined in imapd.conf */
++ if(!(compiled_source_script = config_getstring(IMAPOPT_AUTOCREATE_SIEVE_COMPILEDSCRIPT))) {
++ syslog(LOG_WARNING, "autocreate_sieve: autocreate_sieve_compiledscript option is not defined. Compiling it");
++ do_compile = 1;
++ }
+
-+ len = q - p + 1;
-+ /* Check for folder length */
-+ if (len > sizeof(folder)-1)
-+ continue;
++ if(get_script_dir(sieve_script_dir, sizeof(sieve_script_dir), userid, sieve_dir)) {
++ syslog(LOG_WARNING, "autocreate_sieve: Cannot find sieve scripts directory");
++ return 1;
++ }
+
-+ if (!r) {
-+ strncpy(folder, p, len);
-+ folder[len] = '\0';
++ if (get_script_name(sievename, sizeof(sievename), source_script)) {
++ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve script %s", source_script);
++ return 1;
++ }
+
-+ strlcpy(name, namespace->prefix[NAMESPACE_SHARED], sizeof(name));
-+ len = strlcat(name, folder, sizeof(name));
++ if(snprintf(sieve_tmpname, sizeof(sieve_tmpname), "%s%s.script.NEW",sieve_script_dir, sievename) >= sizeof(sieve_tmpname)) {
++ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
++ return 1;
++ }
++ if(snprintf(sieve_bctmpname, sizeof(sieve_bctmpname), "%s%s.bc.NEW",sieve_script_dir, sievename) >= sizeof(sieve_bctmpname)) {
++ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
++ return 1;
++ }
++ if(snprintf(sieve_script_name, sizeof(sieve_script_name), "%s%s.script",sieve_script_dir, sievename) >= sizeof(sieve_script_name)) {
++ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
++ return 1;
++ }
++ if(snprintf(sieve_bcscript_name, sizeof(sieve_bcscript_name), "%s%s.bc",sieve_script_dir, sievename) >= sizeof(sieve_bcscript_name)) {
++ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
++ return 1;
++ }
++ if(snprintf(sieve_default, sizeof(sieve_default), "%s%s",sieve_script_dir,"defaultbc") >= sizeof(sieve_default)) {
++ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
++ return 1;
++ }
++ if(snprintf(sieve_bclink_name, sizeof(sieve_bclink_name), "%s.bc", sievename) >= sizeof(sieve_bclink_name)) {
++ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
++ return 1;
++ }
+
-+ r = (namespace->mboxname_tointernal) (namespace, name, userid,
-+ mailboxname);
-+ }
-+
-+ if (!r)
-+ r = mboxlist_changesub(mailboxname, userid, auth_state, 1, 0);
++ /* Check if a default sieve filter alrady exists */
++ if(!stat(sieve_default,&statbuf)) {
++ syslog(LOG_WARNING,"autocreate_sieve: Default sieve script already exists");
++ fclose(in_stream);
++ return 1;
++ }
+
-+ if (!r) {
-+ syslog(LOG_NOTICE, "autosubscribe: User %s to %s succeeded",
-+ userid, folder);
++ /* Open the source script. if there is a problem with that exit */
++ in_stream = fopen(source_script, "r");
++ if(!in_stream) {
++ syslog(LOG_WARNING,"autocreate_sieve: Unable to open sieve script %s. Check permissions",source_script);
++ return 1;
++ }
++
++
++ /*
++ * At this point we start the modifications of the filesystem
++ */
++
++ /* Create the directory where the sieve scripts will reside */
++ r = cyrus_mkdir(sieve_script_dir, 0755);
++ if(r == -1) {
++ /* If this fails we just leave */
++ syslog(LOG_WARNING,"autocreate_sieve: Unable to create directory %s. Check permissions",sieve_script_name);
++ return 1;
++ }
++
++ /*
++ * We open the file that will be used as the bc file. If this file exists, overwrite it
++ * since something bad has happened. We open the file here so that this error checking is
++ * done before we try to open the rest of the files to start copying etc.
++ */
++ out_fd = open(sieve_bctmpname, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
++ if(out_fd < 0) {
++ if(errno == EEXIST) {
++ syslog(LOG_WARNING,"autocreate_sieve: File %s already exists. Probaly left over. Ignoring",sieve_bctmpname);
++ } else if (errno == EACCES) {
++ syslog(LOG_WARNING,"autocreate_sieve: No access to create file %s. Check permissions",sieve_bctmpname);
++ fclose(in_stream);
++ return 1;
+ } else {
-+ syslog(LOG_WARNING, "autosubscribe: User %s to %s failed: %s",
-+ userid, folder, error_message(r));
-+ r = 0;
++ syslog(LOG_WARNING,"autocreate_sieve: Unable to create %s. Unknown error",sieve_bctmpname);
++ fclose(in_stream);
++ return 1;
+ }
+ }
+
-+ return r;
-+}
++ if(!do_compile && compiled_source_script && (in_fd = open(compiled_source_script, O_RDONLY)) != -1) {
++ while((r = read(in_fd, buf, sizeof(buf))) > 0) {
++ if((k=write(out_fd, buf,r)) < 0) {
++ syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s, error: %d", sieve_bctmpname, errno);
++ close(out_fd);
++ close(in_fd);
++ fclose(in_stream);
++ unlink(sieve_bctmpname);
++ return 1;
++ }
++ }
+
++ if(r == 0) { /* EOF */
++ close(out_fd);
++ close(in_fd);
++ } else if (r < 0) {
++ syslog(LOG_WARNING, "autocreate_sieve: Error reading compiled script file: %s. Will try to compile it",
++ compiled_source_script);
++ close(in_fd);
++ do_compile = 1;
++ if(lseek(out_fd, 0, SEEK_SET)) {
++ syslog(LOG_WARNING, "autocreate_sieve: Major IO problem. Aborting");
++ return 1;
++ }
++ }
++ close(in_fd);
++ } else {
++ if(compiled_source_script)
++ syslog(LOG_WARNING,"autocreate_sieve: Problem opening compiled script file: %s. Compiling it", compiled_source_script);
++ do_compile = 1;
++ }
+
+
-+int mboxlist_autocreateinbox(struct namespace *namespace,
-+ char *userid,
-+ struct auth_state *auth_state,
-+ char *mailboxname, int autocreatequota) {
-+ char name [MAX_MAILBOX_NAME+1];
-+ char folder [MAX_MAILBOX_NAME+1];
-+ char *auth_userid = NULL;
-+ char *partition = NULL;
-+ const char *crt;
-+ const char *sub;
-+ char *p, *q, *next_crt, *next_sub;
-+ int len;
-+ int r = 0;
-+ int numcrt = 0;
-+ int numsub = 0;
-+#ifdef USE_SIEVE
-+ const char *source_script;
-+#endif
++ /* Because we failed to open a precompiled bc sieve script, we compile one */
++ if(do_compile) {
++ if(is_script_parsable(in_stream,&err, &s) == TIMSIEVE_FAIL) {
++ if(err && *err) {
++ syslog(LOG_WARNING,"autocreate_sieve: Error while parsing script %s.",err);
++ free(err);
++ } else
++ syslog(LOG_WARNING,"autocreate_sieve: Error while parsing script");
++
++ unlink(sieve_bctmpname);
++ fclose(in_stream);
++ close(out_fd);
++ return 1;
++ }
+
++ /* generate the bytecode */
++ if(sieve_generate_bytecode(&bc, s) == TIMSIEVE_FAIL) {
++ syslog(LOG_WARNING,"autocreate_sieve: problem compiling sieve script");
++ /* removing the copied script and cleaning up memory */
++ unlink(sieve_bctmpname);
++ sieve_script_free(&s);
++ fclose(in_stream);
++ close(out_fd);
++ return 1;
++ }
+
++ if(sieve_emit_bytecode(out_fd, bc) == TIMSIEVE_FAIL) {
++ syslog(LOG_WARNING,"autocreate_sieve: problem emiting sieve script");
++ /* removing the copied script and cleaning up memory */
++ unlink(sieve_bctmpname);
++ sieve_free_bytecode(&bc);
++ sieve_script_free(&s);
++ fclose(in_stream);
++ close(out_fd);
++ return 1;
++ }
+
-+ auth_userid = auth_canonuser(auth_state);
-+ if (auth_userid == NULL) {
-+ /*
-+ * Couldn't get cannon userid
-+ */
-+ syslog(LOG_ERR,
-+ "autocreateinbox: Could not get canonified userid for user %s", userid);
-+ return IMAP_PARTITION_UNKNOWN;
++ /* clean up the memory */
++ sieve_free_bytecode(&bc);
++ sieve_script_free(&s);
+ }
+
-+ /* Added this for debug information. */
-+ syslog(LOG_DEBUG, "autocreateinbox: autocreate inbox for user %s was called", auth_userid);
++ close(out_fd);
++ rewind(in_stream);
+
-+ /*
-+ * While this is not needed for admins
-+ * and imap_admins accounts, it would be
-+ * better to separate *all* admins and
-+ * proxyservers from normal accounts
-+ * (accounts that have mailboxes).
-+ * UOA Specific note(1): Even if we do not
-+ * exclude these servers-classes here,
-+ * UOA specific code, will neither return
-+ * role, nor create INBOX, because none of these
-+ * administrative accounts belong to the
-+ * mailRecipient objectclass, or have imapPartition.
-+ * UOA Specific note(2): Another good reason for doing
-+ * this, is to prevent the code, from getting into
-+ * cyrus_ldap.c because of the continues MSA logins to LMTPd.
-+ */
++ /* Copy the initial script */
++ oldmask = umask(077);
++ if((out_fp = fopen(sieve_tmpname, "w")) == NULL) {
++ syslog(LOG_WARNING,"autocreate_sieve: Unable to open %s destination sieve script", sieve_tmpname);
++ unlink(sieve_bctmpname);
++ umask(oldmask);
++ fclose(in_stream);
++ return 1;
++ }
++ umask(oldmask);
+
-+ /*
-+ * admins and the coresponding imap
-+ * service, had already been excluded.
-+ */
++ while((r = fread(buf,sizeof(char), sizeof(buf), in_stream))) {
++ if( fwrite(buf,sizeof(char), r, out_fp) != r) {
++ syslog(LOG_WARNING,"autocreate_sieve: Problem writing to sieve script file: %s",sieve_tmpname);
++ fclose(out_fp);
++ unlink(sieve_tmpname);
++ unlink(sieve_bctmpname);
++ fclose(in_stream);
++ return 1;
++ }
++ }
++
++ if(feof(in_stream)) {
++ fclose(out_fp);
++ } else { /* ferror */
++ fclose(out_fp);
++ unlink(sieve_tmpname);
++ unlink(sieve_bctmpname);
++ fclose(in_stream);
++ return 1;
++ }
+
-+ /*
-+ * Do we really need group membership
-+ * for admins or service_admins?
-+ */
-+ if (global_authisa(auth_state, IMAPOPT_ADMINS)) return 0;
++ /* Renaming the necessary stuff */
++ if(rename(sieve_tmpname, sieve_script_name)) {
++ unlink(sieve_tmpname);
++ unlink(sieve_bctmpname);
++ return 1;
++ }
+
-+ /*
-+ * Do we really need group membership
-+ * for proxyservers?
-+ */
-+ if (global_authisa(auth_state, IMAPOPT_PROXYSERVERS)) return 0;
++ if(rename(sieve_bctmpname, sieve_bcscript_name)) {
++ unlink(sieve_bctmpname);
++ unlink(sieve_bcscript_name);
++ return 1;
++ }
++
++ /* end now with the symlink */
++ if(symlink(sieve_bclink_name, sieve_default)) {
++ if(errno != EEXIST) {
++ syslog(LOG_WARNING, "autocreate_sieve: problem making the default link.");
++ /* Lets delete the files */
++ unlink(sieve_script_name);
++ unlink(sieve_bcscript_name);
++ }
++ }
+
+ /*
-+ * Check if user belongs to the autocreate_users group. This option
-+ * controls for whom the mailbox may be automatically created. Default
-+ * value for this option is 'anyone'. So, if not declared, all mailboxes
-+ * will be created.
++ * If everything has succeeded AND we have compiled the script AND we have requested
++ * to generate the global script so that it is not compiled each time then we create it.
+ */
-+ if (!global_authisa(auth_state, IMAPOPT_AUTOCREATE_USERS)) {
-+ syslog(LOG_DEBUG, "autocreateinbox: User %s does not belong to the autocreate_users. No mailbox is created",
-+ auth_userid);
-+ return IMAP_MAILBOX_NONEXISTENT;
-+ }
++ if(do_compile &&
++ config_getswitch(IMAPOPT_GENERATE_COMPILED_SIEVE_SCRIPT)) {
++
++ if(!compiled_source_script) {
++ syslog(LOG_WARNING, "autocreate_sieve: To save a compiled sieve script, autocreate_sieve_compiledscript must have been defined in imapd.conf");
++ return 0;
++ }
++
++ if(snprintf(sieve_tmpname, sizeof(sieve_tmpname), "%s.NEW", compiled_source_script) >= sizeof(sieve_tmpname))
++ return 0;
+
-+#if 0
+ /*
-+ * Get Partition info or return.
-+ * (Here you should propably use
-+ * you own "get_partition(char *userid)"
-+ * function. Otherwise all new INBOXes will be
-+ * created into whatever partition has been declared
-+ * as default in your imapd.conf)
++ * Copy everything from the newly created bc sieve sieve script.
+ */
++ if((in_fd = open(sieve_bcscript_name, O_RDONLY))<0) {
++ return 0;
++ }
+
-+ partition = get_partition(userid);
-+ if (partition == NULL) {
-+ /*
-+ * Couldn't get partition info
-+ */
-+ syslog(LOG_ERR,
-+ "Could not get imapPartition info for user %s", userid);
-+ return IMAP_PARTITION_UNKNOWN;
++ if((out_fd = open(sieve_tmpname, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
++ if(errno == EEXIST) {
++ /* Someone is already doing this so just bail out. */
++ syslog(LOG_WARNING, "autocreate_sieve: %s already exists. Some other instance processing it, or it is left over", sieve_tmpname);
++ close(in_fd);
++ return 0;
++ } else if (errno == EACCES) {
++ syslog(LOG_WARNING,"autocreate_sieve: No access to create file %s. Check permissions",sieve_tmpname);
++ close(in_fd);
++ return 0;
++ } else {
++ syslog(LOG_WARNING,"autocreate_sieve: Unable to create %s",sieve_tmpname);
++ close(in_fd);
++ return 0;
++ }
+ }
-+#endif
+
-+ r = mboxlist_createmailbox(mailboxname, MAILBOX_FORMAT_NORMAL, NULL,
-+ 1, userid, auth_state, 0, 0, 0);
++ while((r = read(in_fd, buf, sizeof(buf))) > 0) {
++ if((k = write(out_fd,buf,r)) < 0) {
++ syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s, error: %d", sieve_tmpname, errno);
++ close(out_fd);
++ close(in_fd);
++ unlink(sieve_tmpname);
++ return 0;
++ }
++ }
+
-+ if (!r && autocreatequota > 0)
-+ r = mboxlist_setquota(mailboxname, autocreatequota, 0);
++ if(r == 0 ) { /*EOF */
++ close(out_fd);
++ close(in_fd);
++ } else if (r < 0) {
++ syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s, error: %d", sieve_tmpname, errno);
++ close(out_fd);
++ close(in_fd);
++ unlink(sieve_tmpname);
++ return 0;
++ }
+
-+ if (!r)
-+ r = mboxlist_changesub(mailboxname, userid,
-+ auth_state, 1, 1);
++ /* Rename the temporary created sieve script to its final name. */
++ if(rename(sieve_tmpname, compiled_source_script)) {
++ if(errno != EEXIST) {
++ unlink(sieve_tmpname);
++ unlink(compiled_source_script);
++ }
++ return 0;
++ }
+
-+ if (!r) {
-+ syslog(LOG_NOTICE, "autocreateinbox: User %s, INBOX was successfully created in partition %s",
-+ auth_userid, partition == NULL ? "default" : partition);
-+ } else {
-+ syslog(LOG_ERR, "autocreateinbox: User %s, INBOX failed. %s",
-+ auth_userid, error_message(r));
++ syslog(LOG_NOTICE, "autocreate_sieve: Compiled sieve script was successfully saved in %s", compiled_source_script);
+ }
+
-+#if 0
-+ /* Allocated from get_partition, and not needed any more */
-+ free_partition(partition);
-+#endif
++ return 0;
++}
+
-+ if (r) return r;
++/*static void fatal(const char *s, int code)
++{
++ printf("Fatal error: %s (%d)\r\n", s, code);
++ exit(1);
++}*/
+
-+ /* INBOX's subfolders */
-+ if ((crt=config_getstring(IMAPOPT_AUTOCREATEINBOXFOLDERS)))
-+ sub=config_getstring(IMAPOPT_AUTOSUBSCRIBEINBOXFOLDERS);
++/* to make larry's stupid functions happy :) */
++static void foo(void)
++{
++ fatal("stub function called", 0);
++}
+
-+ /* Roll through crt */
-+ next_crt = (char *) crt;
-+ while (next_crt!=NULL && *next_crt) {
-+ for (p = next_crt ; isspace((int) *p) || *p == SEP ; p++);
-+ for (next_crt = p ; *next_crt && *next_crt != SEP ; next_crt++);
-+ for (q = next_crt ; q > p && (isspace((int) *q) || *q == SEP || !*q); q--);
++static int sieve_notify(void *ac __attribute__((unused)),
++ void *interp_context __attribute__((unused)),
++ void *script_context __attribute__((unused)),
++ void *message_context __attribute__((unused)),
++ const char **errmsg __attribute__((unused)))
++{
++ fatal("stub function called", 0);
++ return SIEVE_FAIL;
++}
+
-+ if (!*p) continue;
++static int mysieve_error(int lineno, const char *msg,
++ void *i __attribute__((unused)), void *s)
++{
++ char buf[1024];
++ char **errstr = (char **) s;
+
-+ len = q - p + 1;
++ snprintf(buf, 80, "line %d: %s\r\n", lineno, msg);
++ *errstr = (char *) xrealloc(*errstr, strlen(*errstr) + strlen(buf) + 30);
++ syslog(LOG_DEBUG, "%s", buf);
++ strcat(*errstr, buf);
+
-+ /* First time we check for length */
-+ if (len > sizeof(folder) - 5)
-+ r = IMAP_MAILBOX_BADNAME;
++ return SIEVE_OK;
++}
+
-+ if (!r) {
-+ strncpy(folder, p, len);
-+ folder[len] = '\0';
++/* end the boilerplate */
+
-+ strlcpy(name, namespace->prefix[NAMESPACE_INBOX], sizeof(name));
-+ len = strlcat(name, folder, sizeof(name));
-+ }
++/* returns TRUE or FALSE */
++int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret)
++{
++ sieve_interp_t *i;
++ sieve_script_t *s;
++ int res;
+
-+ if (!r)
-+ r = (namespace->mboxname_tointernal) (namespace, name, userid,
-+ mailboxname);
-+ if (!r)
-+ r = mboxlist_createmailbox(mailboxname, MAILBOX_FORMAT_NORMAL, NULL,
-+ 1, userid, auth_state, 0, 0, 0);
++ res = sieve_interp_alloc(&i, NULL);
++ if (res != SIEVE_OK) {
++ syslog(LOG_WARNING, "sieve_interp_alloc() returns %d\n", res);
++ return TIMSIEVE_FAIL;
++ }
+
-+ if (!r) {
-+ numcrt++;
-+ syslog(LOG_NOTICE, "autocreateinbox: User %s, subfolder %s creation succeeded.",
-+ auth_userid, name);
-+ } else {
-+ syslog(LOG_WARNING, "autocreateinbox: User %s, subfolder %s creation failed. %s",
-+ auth_userid, name, error_message(r));
-+ r=0;
-+ continue;
-+ }
++ res = sieve_register_redirect(i, (sieve_callback *) &foo);
++ if (res != SIEVE_OK) {
++ syslog(LOG_WARNING, "sieve_register_redirect() returns %d\n", res);
++ return TIMSIEVE_FAIL;
++ }
++ res = sieve_register_discard(i, (sieve_callback *) &foo);
++ if (res != SIEVE_OK) {
++ syslog(LOG_WARNING, "sieve_register_discard() returns %d\n", res);
++ return TIMSIEVE_FAIL;
++ }
++ res = sieve_register_reject(i, (sieve_callback *) &foo);
++ if (res != SIEVE_OK) {
++ syslog(LOG_WARNING, "sieve_register_reject() returns %d\n", res);
++ return TIMSIEVE_FAIL;
++ }
++ res = sieve_register_fileinto(i, (sieve_callback *) &foo);
++ if (res != SIEVE_OK) {
++ syslog(LOG_WARNING, "sieve_register_fileinto() returns %d\n", res);
++ return TIMSIEVE_FAIL;
++ }
++ res = sieve_register_keep(i, (sieve_callback *) &foo);
++ if (res != SIEVE_OK) {
++ syslog(LOG_WARNING, "sieve_register_keep() returns %d\n", res);
++ return TIMSIEVE_FAIL;
++ }
+
-+ /* Roll through sub */
-+ next_sub = (char *) sub;
-+ while (next_sub!=NULL && *next_sub) {
-+ for (p = next_sub ; isspace((int) *p) || *p == SEP ; p++);
-+ for (next_sub = p ; *next_sub && *next_sub != SEP ; next_sub++);
-+ for (q = next_sub ; q > p && (isspace((int) *q) || *q == SEP || !*q) ; q--);
-+ if (!*p ) continue;
++ res = sieve_register_imapflags(i, NULL);
++ if (res != SIEVE_OK) {
++ syslog(LOG_WARNING, "sieve_register_imapflags() returns %d\n", res);
++ return TIMSIEVE_FAIL;
++ }
+
-+ len = q - p + 1;
++ res = sieve_register_size(i, (sieve_get_size *) &foo);
++ if (res != SIEVE_OK) {
++ syslog(LOG_WARNING, "sieve_register_size() returns %d\n", res);
++ return TIMSIEVE_FAIL;
++ }
+
-+ if (len != strlen(folder) || strncmp(folder, p, len))
-+ continue;
++ res = sieve_register_header(i, (sieve_get_header *) &foo);
++ if (res != SIEVE_OK) {
++ syslog(LOG_WARNING, "sieve_register_header() returns %d\n", res);
++ return TIMSIEVE_FAIL;
++ }
+
-+ r = mboxlist_changesub(mailboxname, userid, auth_state, 1, 1);
++ res = sieve_register_envelope(i, (sieve_get_envelope *) &foo);
++ if (res != SIEVE_OK) {
++ syslog(LOG_WARNING, "sieve_register_envelope() returns %d\n", res);
++ return TIMSIEVE_FAIL;
++ }
+
-+ if (!r) {
-+ numsub++;
-+ syslog(LOG_NOTICE,"autocreateinbox: User %s, subscription to %s succeeded",
-+ auth_userid, name);
-+ } else
-+ syslog(LOG_WARNING, "autocreateinbox: User %s, subscription to %s failed. %s",
-+ auth_userid, name, error_message(r));
++ res = sieve_register_vacation(i, &vacation2);
++ if (res != SIEVE_OK) {
++ syslog(LOG_WARNING, "sieve_register_vacation() returns %d\n", res);
++ return TIMSIEVE_FAIL;
++ }
+
-+ break;
-+ }
++ res = sieve_register_notify(i, &sieve_notify);
++ if (res != SIEVE_OK) {
++ syslog(LOG_WARNING, "sieve_register_notify() returns %d\n", res);
++ return TIMSIEVE_FAIL;
+ }
+
-+ if (crt!=NULL && *crt)
-+ syslog(LOG_INFO, "User %s, Inbox subfolders, created %d, subscribed %d",
-+ auth_userid, numcrt, numsub);
++ res = sieve_register_parse_error(i, &mysieve_error);
++ if (res != SIEVE_OK) {
++ syslog(LOG_WARNING, "sieve_register_parse_error() returns %d\n", res);
++ return TIMSIEVE_FAIL;
++ }
+
-+ /*
-+ * Check if shared folders are available for subscription.
-+ */
-+ mboxlist_autosubscribe_sharedfolders(namespace, userid, auth_userid, auth_state);
++ rewind(stream);
+
-+#ifdef USE_SIEVE
-+ /*
-+ * Here the autocreate sieve script feature is iniated from.
-+ */
-+ source_script = config_getstring(IMAPOPT_AUTOCREATE_SIEVE_SCRIPT);
-+
-+ if (source_script) {
-+ if (!autoadd_sieve(userid, source_script))
-+ syslog(LOG_NOTICE, "autocreate_sieve: User %s, default sieve script creation succeeded", auth_userid);
-+ else
-+ syslog(LOG_WARNING, "autocreate_sieve: User %s, default sieve script creation failed", auth_userid);
++ *errstr = (char *) xmalloc(20 * sizeof(char));
++ strcpy(*errstr, "script errors:\r\n");
++
++ res = sieve_script_parse(i, stream, errstr, &s);
++
++ if (res == SIEVE_OK) {
++ if(ret) {
++ *ret = s;
++ } else {
++ sieve_script_free(&s);
++ }
++ free(*errstr);
++ *errstr = NULL;
+ }
-+#endif
+
-+ return r;
++ /* free interpreter */
++ sieve_interp_free(&i);
++
++ return (res == SIEVE_OK) ? TIMSIEVE_OK : TIMSIEVE_FAIL;
+}
+
---- cyrus-imapd-2.3.13/imap/autosieve.c.autocreate 2009-01-13 11:14:09.000000000 +0100
-+++ cyrus-imapd-2.3.13/imap/autosieve.c 2009-01-13 11:14:09.000000000 +0100
-@@ -0,0 +1,590 @@
++/*
++ * Btw the initial date of this patch is Sep, 02 2004 which is the birthday of
++ * Pavlos. Author of cyrusmaster. So consider this patch as his birthday present
++ */
++
+diff -up /dev/null cyrus-imapd-2.3.15/imap/compile_sieve.c
+--- /dev/null 2009-09-11 15:21:01.808252010 +0200
++++ cyrus-imapd-2.3.15/imap/compile_sieve.c 2009-09-18 11:11:39.779115788 +0200
+@@ -0,0 +1,365 @@
++/* This tool compiles the sieve script from a command
++line so that it can be used wby the autoadd patch */
+#include
+#include
-+#include
+
++#include
++#include
+#ifdef HAVE_UNISTD_H
+#include
+#endif
-+
+#include
+#include
+#include
@@ -437,11 +613,10 @@
+#include
+#include
+#include
-+#include
+#include
-+#include
+
+#include "global.h"
++
+#include "util.h"
+#include "xmalloc.h"
+#include "xstrlcpy.h"
@@ -451,431 +626,205 @@
+#include "sieve_interface.h"
+#include "script.h"
+
-+#define TIMSIEVE_FAIL -1
-+#define TIMSIEVE_OK 0
-+#define MAX_FILENAME 1024
++#include
+
-+static int get_script_name(char *sievename, size_t buflen, const char *filename);
-+static int get_script_dir(char *sieve_script_dir, size_t buflen, char *userid, const char *sieve_dir);
-+int autoadd_sieve(char *userid, const char *source_script);
++#define TIMSIEVE_FAIL -1
++#define TIMSIEVE_OK 0
++#define MAX_FILENAME_SIZE 100
+
-+//static void fatal(const char *s, int code);
-+static void foo(void);
-+static int sieve_notify(void *ac __attribute__((unused)),
-+ void *interp_context __attribute__((unused)),
-+ void *script_context __attribute__((unused)),
-+ void *message_context __attribute__((unused)),
-+ const char **errmsg __attribute__((unused)));
-+static int mysieve_error(int lineno, const char *msg,
-+ void *i __attribute__((unused)), void *s);
-+static int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret);
++/* Needed by libconfig */
++const int config_need_data = 0;
+
++static int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret);
+
-+sieve_vacation_t vacation2 = {
-+ 0, /* min response */
-+ 0, /* max response */
-+ (sieve_callback *) &foo, /* autorespond() */
-+ (sieve_callback *) &foo /* send_response() */
-+};
++/*static void fatal(const char *s, int code)
++{
++ printf("Fatal error: %s (%d)\r\n", s, code);
+
++ exit(1);
++}*/
+
-+/*
-+ * Find the name of the sieve script
-+ * given the source script and compiled script names
-+ */
-+static int get_script_name(char *sievename, size_t buflen, const char *filename)
++void usage(void)
+{
-+ char *p;
-+ int r;
-+
-+ p = strrchr(filename, '/');
-+ if (p == NULL)
-+ p = (char *) filename;
-+ else
-+ p++;
-+
-+ r = strlcpy(sievename, p, buflen) - buflen;
-+ return (r >= 0 || r == -buflen ? 1 : 0);
++ fprintf(stderr,
++ "Usage:\n\tcompile_sieve [-C ] [-i -o ]\n");
++ exit(-1);
+}
+
+
-+/*
-+ * Find the directory where the sieve scripts of the user
-+ * reside
-+ */
-+static int get_script_dir(char *sieve_script_dir, size_t buflen, char *userid, const char *sieve_dir)
-+{
-+ char *user = NULL, *domain = NULL;
-+
-+ /* Setup the user and the domain */
-+ if(config_virtdomains && (domain = strchr(userid, '@'))) {
-+ user = (char *) xmalloc((domain - userid +1) * sizeof(char));
-+ strlcpy(user, userid, domain - userid + 1);
-+ domain++;
-+ } else
-+ user = userid;
-+
-+ /* Find the dir path where the sieve scripts of the user will reside */
-+ if (config_virtdomains && domain) {
-+ if(snprintf(sieve_script_dir, buflen, "%s%s%c/%s/%c/%s/",
-+ sieve_dir, FNAME_DOMAINDIR, dir_hash_c(domain, config_fulldirhash), domain, dir_hash_c(user,config_fulldirhash), user) >= buflen) {
-+ free(user);
-+ return 1;
-+ }
-+ } else {
-+ if(snprintf(sieve_script_dir, buflen, "%s/%c/%s/",
-+ sieve_dir, dir_hash_c(user,config_fulldirhash), user) >= buflen)
-+ return 1;
-+ }
-+
-+ /* Free the xmalloced user memory, reserved above */
-+ if(user != userid)
-+ free(user);
-+
-+ return 0;
-+}
-+
-+int autoadd_sieve(char *userid, const char *source_script)
++int main (int argc, char **argv)
+{
++
+ sieve_script_t *s = NULL;
+ bytecode_info_t *bc = NULL;
+ char *err = NULL;
-+ FILE *in_stream, *out_fp;
-+ int out_fd, in_fd, r, k;
-+ int do_compile = 0;
-+ const char *sieve_dir = NULL;
-+ const char *compiled_source_script = NULL;
-+ char sievename[MAX_FILENAME];
-+ char sieve_script_name[MAX_FILENAME];
-+ char sieve_script_dir[MAX_FILENAME];
-+ char sieve_bcscript_name[MAX_FILENAME];
-+ char sieve_default[MAX_FILENAME];
-+ char sieve_tmpname[MAX_FILENAME];
-+ char sieve_bctmpname[MAX_FILENAME];
-+ char sieve_bclink_name[MAX_FILENAME];
-+ char buf[4096];
-+ mode_t oldmask;
-+ struct stat statbuf;
++ FILE *in_stream;
++ int out_fd, opt;
++ char *source_script = NULL;
++ char *compiled_source_script = NULL;
++ char *alt_config = NULL;
++ extern char *optarg;
++ char sieve_tmpname[MAX_MAILBOX_NAME+1];
+
-+ /* We don't support using the homedirectory, like timsieved */
-+ if (config_getswitch(IMAPOPT_SIEVEUSEHOMEDIR)) {
-+ syslog(LOG_WARNING,"autocreate_sieve: autocreate_sieve does not work with sieveusehomedir option in imapd.conf");
-+ return 1;
-+ }
++ if (geteuid() == 0) fatal("must run as the Cyrus user", EC_USAGE);
+
-+ /* Check if sievedir is defined in imapd.conf */
-+ if(!(sieve_dir = config_getstring(IMAPOPT_SIEVEDIR))) {
-+ syslog(LOG_WARNING, "autocreate_sieve: sievedir option is not defined. Check imapd.conf");
-+ return 1;
++ while((opt = getopt(argc, argv, "C:i:o:")) != EOF) {
++ switch (opt) {
++ case 'C': /* alt config file */
++ alt_config = optarg;
++ break;
++ case 'i': /* input script file */
++ source_script = optarg;
++ break;
++ case 'o': /* output script file */
++ compiled_source_script = optarg;
++ break;
++ default:
++ usage();
++ break;
++ }
+ }
+
-+ /* Check if autocreate_sieve_compiledscript is defined in imapd.conf */
-+ if(!(compiled_source_script = config_getstring(IMAPOPT_AUTOCREATE_SIEVE_COMPILEDSCRIPT))) {
-+ syslog(LOG_WARNING, "autocreate_sieve: autocreate_sieve_compiledscript option is not defined. Compiling it");
-+ do_compile = 1;
-+ }
++ if(source_script && !compiled_source_script) {
++ fprintf(stderr, "No output file was defined\n");
++ usage();
++ } else if (!source_script && compiled_source_script) {
++ fprintf(stderr, "No input file was defined\n");
++ usage();
++ }
+
-+ if(get_script_dir(sieve_script_dir, sizeof(sieve_script_dir), userid, sieve_dir)) {
-+ syslog(LOG_WARNING, "autocreate_sieve: Cannot find sieve scripts directory");
-+ return 1;
-+ }
++ /*
++ * If no has been defined, then read them from
++ * the configuration file.
++ */
++ if (!source_script && !compiled_source_script) {
++ cyrus_init(alt_config, "compile_sieve", 0);
+
-+ if (get_script_name(sievename, sizeof(sievename), source_script)) {
-+ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve script %s", source_script);
-+ return 1;
-+ }
++ /* Initially check if we want to have the sieve script created */
++ if(!(source_script = (char *) config_getstring(IMAPOPT_AUTOCREATE_SIEVE_SCRIPT))) {
++ fprintf(stderr,"autocreate_sieve_script option not defined. Check imapd.conf\n");
++ return 1;
++ }
+
-+ if(snprintf(sieve_tmpname, sizeof(sieve_tmpname), "%s%s.script.NEW",sieve_script_dir, sievename) >= sizeof(sieve_tmpname)) {
-+ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
-+ return 1;
-+ }
-+ if(snprintf(sieve_bctmpname, sizeof(sieve_bctmpname), "%s%s.bc.NEW",sieve_script_dir, sievename) >= sizeof(sieve_bctmpname)) {
-+ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
-+ return 1;
-+ }
-+ if(snprintf(sieve_script_name, sizeof(sieve_script_name), "%s%s.script",sieve_script_dir, sievename) >= sizeof(sieve_script_name)) {
-+ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
-+ return 1;
-+ }
-+ if(snprintf(sieve_bcscript_name, sizeof(sieve_bcscript_name), "%s%s.bc",sieve_script_dir, sievename) >= sizeof(sieve_bcscript_name)) {
-+ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
-+ return 1;
-+ }
-+ if(snprintf(sieve_default, sizeof(sieve_default), "%s%s",sieve_script_dir,"defaultbc") >= sizeof(sieve_default)) {
-+ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
-+ return 1;
-+ }
-+ if(snprintf(sieve_bclink_name, sizeof(sieve_bclink_name), "%s.bc", sievename) >= sizeof(sieve_bclink_name)) {
-+ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid);
-+ return 1;
-+ }
++ /* Check if we have an already compiled sieve script*/
++ if(!(compiled_source_script = (char *) config_getstring(IMAPOPT_AUTOCREATE_SIEVE_COMPILEDSCRIPT))) {
++ fprintf(stderr, "autocreate_sieve_compiledscript option not defined. Check imapd.conf\n");
++ return 1;
++ }
+
-+ /* Check if a default sieve filter alrady exists */
-+ if(!stat(sieve_default,&statbuf)) {
-+ syslog(LOG_WARNING,"autocreate_sieve: Default sieve script already exists");
-+ fclose(in_stream);
-+ return 1;
++ if(!strrchr(source_script,'/') || !strrchr(compiled_source_script,'/')) {
++ /*
++ * At this point the only think that is inconsistent is the directory
++ * that was created. But if the user will have any sieve scripts then
++ * they will eventually go there, so no big deal
++ */
++ fprintf(stderr,
++ "In imapd.conf the full path of the filenames must be defined\n");
++ return 1;
++ }
+ }
+
-+ /* Open the source script. if there is a problem with that exit */
-+ in_stream = fopen(source_script, "r");
-+ if(!in_stream) {
-+ syslog(LOG_WARNING,"autocreate_sieve: Unable to open sieve script %s. Check permissions",source_script);
-+ return 1;
++ printf("input file : %s, output file : %s\n", source_script, compiled_source_script);
++
++
++ if(strlen(compiled_source_script) + sizeof(".NEW") + 1 > sizeof(sieve_tmpname)) {
++ fprintf(stderr, "Filename %s is too big\n", compiled_source_script);
++ return 1;
+ }
-+
-+
-+ /*
-+ * At this point we start the modifications of the filesystem
-+ */
++
++ snprintf(sieve_tmpname, sizeof(sieve_tmpname), "%s.NEW", compiled_source_script);
+
-+ /* Create the directory where the sieve scripts will reside */
-+ r = cyrus_mkdir(sieve_script_dir, 0755);
-+ if(r == -1) {
-+ /* If this fails we just leave */
-+ syslog(LOG_WARNING,"autocreate_sieve: Unable to create directory %s. Check permissions",sieve_script_name);
-+ return 1;
++ in_stream = fopen(source_script,"r");
++
++ if(!in_stream) {
++ fprintf(stderr,"Unable to open %s source sieve script\n",source_script);
++ return 1;
+ }
+
-+ /*
++ /*
+ * We open the file that will be used as the bc file. If this file exists, overwrite it
+ * since something bad has happened. We open the file here so that this error checking is
+ * done before we try to open the rest of the files to start copying etc.
+ */
-+ out_fd = open(sieve_bctmpname, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
++ out_fd = open(sieve_tmpname, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+ if(out_fd < 0) {
+ if(errno == EEXIST) {
-+ syslog(LOG_WARNING,"autocreate_sieve: File %s already exists. Probaly left over. Ignoring",sieve_bctmpname);
++ fprintf(stderr, "File %s already exists\n", sieve_tmpname);
+ } else if (errno == EACCES) {
-+ syslog(LOG_WARNING,"autocreate_sieve: No access to create file %s. Check permissions",sieve_bctmpname);
-+ fclose(in_stream);
-+ return 1;
++ fprintf(stderr,"No access to create file %s. Please check that you have the correct permissions\n",
++ sieve_tmpname);
+ } else {
-+ syslog(LOG_WARNING,"autocreate_sieve: Unable to create %s. Unknown error",sieve_bctmpname);
-+ fclose(in_stream);
-+ return 1;
-+ }
-+ }
-+
-+ if(!do_compile && compiled_source_script && (in_fd = open(compiled_source_script, O_RDONLY)) != -1) {
-+ while((r = read(in_fd, buf, sizeof(buf))) > 0) {
-+ if((k=write(out_fd, buf,r)) < 0) {
-+ syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s, error: %d", sieve_bctmpname, errno);
-+ close(out_fd);
-+ close(in_fd);
-+ fclose(in_stream);
-+ unlink(sieve_bctmpname);
-+ return 1;
-+ }
-+ }
-+
-+ if(r == 0) { /* EOF */
-+ close(out_fd);
-+ close(in_fd);
-+ } else if (r < 0) {
-+ syslog(LOG_WARNING, "autocreate_sieve: Error reading compiled script file: %s. Will try to compile it",
-+ compiled_source_script);
-+ close(in_fd);
-+ do_compile = 1;
-+ if(lseek(out_fd, 0, SEEK_SET)) {
-+ syslog(LOG_WARNING, "autocreate_sieve: Major IO problem. Aborting");
-+ return 1;
-+ }
++ fprintf(stderr,"Unable to create %s. Please check that you have the correct permissions\n",
++ sieve_tmpname);
+ }
-+ close(in_fd);
-+ } else {
-+ if(compiled_source_script)
-+ syslog(LOG_WARNING,"autocreate_sieve: Problem opening compiled script file: %s. Compiling it", compiled_source_script);
-+ do_compile = 1;
++
++ fclose(in_stream);
++ return 1;
+ }
+
-+
-+ /* Because we failed to open a precompiled bc sieve script, we compile one */
-+ if(do_compile) {
-+ if(is_script_parsable(in_stream,&err, &s) == TIMSIEVE_FAIL) {
-+ if(err && *err) {
-+ syslog(LOG_WARNING,"autocreate_sieve: Error while parsing script %s.",err);
-+ free(err);
-+ } else
-+ syslog(LOG_WARNING,"autocreate_sieve: Error while parsing script");
-+
-+ unlink(sieve_bctmpname);
-+ fclose(in_stream);
-+ close(out_fd);
-+ return 1;
-+ }
-+
-+ /* generate the bytecode */
-+ if(sieve_generate_bytecode(&bc, s) == TIMSIEVE_FAIL) {
-+ syslog(LOG_WARNING,"autocreate_sieve: problem compiling sieve script");
-+ /* removing the copied script and cleaning up memory */
-+ unlink(sieve_bctmpname);
-+ sieve_script_free(&s);
-+ fclose(in_stream);
-+ close(out_fd);
-+ return 1;
++ if(is_script_parsable(in_stream,&err, &s) == TIMSIEVE_FAIL) {
++ if(err && *err) {
++ fprintf(stderr, "Error while parsing script %s\n",err);
++ free(err);
+ }
++ else
++ fprintf(stderr,"Error while parsing script\n");
++ unlink(sieve_tmpname);
++ fclose(in_stream);
++ close(out_fd);
++ return 1;
++ }
+
-+ if(sieve_emit_bytecode(out_fd, bc) == TIMSIEVE_FAIL) {
-+ syslog(LOG_WARNING,"autocreate_sieve: problem emiting sieve script");
-+ /* removing the copied script and cleaning up memory */
-+ unlink(sieve_bctmpname);
-+ sieve_free_bytecode(&bc);
-+ sieve_script_free(&s);
-+ fclose(in_stream);
-+ close(out_fd);
-+ return 1;
-+ }
+
-+ /* clean up the memory */
-+ sieve_free_bytecode(&bc);
++ /* generate the bytecode */
++ if(sieve_generate_bytecode(&bc,s) == TIMSIEVE_FAIL) {
++ fprintf(stderr,"Error occured while compiling sieve script\n");
++ /* removing the copied script and cleaning up memory */
++ unlink(sieve_tmpname);
+ sieve_script_free(&s);
-+ }
-+
-+ close(out_fd);
-+ rewind(in_stream);
-+
-+ /* Copy the initial script */
-+ oldmask = umask(077);
-+ if((out_fp = fopen(sieve_tmpname, "w")) == NULL) {
-+ syslog(LOG_WARNING,"autocreate_sieve: Unable to open %s destination sieve script", sieve_tmpname);
-+ unlink(sieve_bctmpname);
-+ umask(oldmask);
+ fclose(in_stream);
++ close(out_fd);
+ return 1;
+ }
-+ umask(oldmask);
-+
-+ while((r = fread(buf,sizeof(char), sizeof(buf), in_stream))) {
-+ if( fwrite(buf,sizeof(char), r, out_fp) != r) {
-+ syslog(LOG_WARNING,"autocreate_sieve: Problem writing to sieve script file: %s",sieve_tmpname);
-+ fclose(out_fp);
-+ unlink(sieve_tmpname);
-+ unlink(sieve_bctmpname);
-+ fclose(in_stream);
-+ return 1;
-+ }
-+ }
-+
-+ if(feof(in_stream)) {
-+ fclose(out_fp);
-+ } else { /* ferror */
-+ fclose(out_fp);
++ if(sieve_emit_bytecode(out_fd,bc) == TIMSIEVE_FAIL) {
++ fprintf(stderr, "Error occured while emitting sieve script\n");
+ unlink(sieve_tmpname);
-+ unlink(sieve_bctmpname);
++ sieve_free_bytecode(&bc);
++ sieve_script_free(&s);
+ fclose(in_stream);
++ close(out_fd);
+ return 1;
+ }
+
-+ /* Renaming the necessary stuff */
-+ if(rename(sieve_tmpname, sieve_script_name)) {
-+ unlink(sieve_tmpname);
-+ unlink(sieve_bctmpname);
-+ return 1;
-+ }
++ /* clean up the memory */
++ sieve_free_bytecode(&bc);
++ sieve_script_free(&s);
+
-+ if(rename(sieve_bctmpname, sieve_bcscript_name)) {
-+ unlink(sieve_bctmpname);
-+ unlink(sieve_bcscript_name);
-+ return 1;
-+ }
++ close(out_fd);
+
-+ /* end now with the symlink */
-+ if(symlink(sieve_bclink_name, sieve_default)) {
++ if(rename(sieve_tmpname, compiled_source_script)) {
+ if(errno != EEXIST) {
-+ syslog(LOG_WARNING, "autocreate_sieve: problem making the default link.");
-+ /* Lets delete the files */
-+ unlink(sieve_script_name);
-+ unlink(sieve_bcscript_name);
++ unlink(sieve_tmpname);
++ unlink(compiled_source_script);
++ return 1;
+ }
+ }
++ return 0;
++}
+
-+ /*
-+ * If everything has succeeded AND we have compiled the script AND we have requested
-+ * to generate the global script so that it is not compiled each time then we create it.
-+ */
-+ if(do_compile &&
-+ config_getswitch(IMAPOPT_GENERATE_COMPILED_SIEVE_SCRIPT)) {
+
-+ if(!compiled_source_script) {
-+ syslog(LOG_WARNING, "autocreate_sieve: To save a compiled sieve script, autocreate_sieve_compiledscript must have been defined in imapd.conf");
-+ return 0;
-+ }
++/* to make larry's stupid functions happy :) */
++static void foo(void)
++{
++ fatal("stub function called", 0);
++}
+
-+ if(snprintf(sieve_tmpname, sizeof(sieve_tmpname), "%s.NEW", compiled_source_script) >= sizeof(sieve_tmpname))
-+ return 0;
-+
-+ /*
-+ * Copy everything from the newly created bc sieve sieve script.
-+ */
-+ if((in_fd = open(sieve_bcscript_name, O_RDONLY))<0) {
-+ return 0;
-+ }
-+
-+ if((out_fd = open(sieve_tmpname, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
-+ if(errno == EEXIST) {
-+ /* Someone is already doing this so just bail out. */
-+ syslog(LOG_WARNING, "autocreate_sieve: %s already exists. Some other instance processing it, or it is left over", sieve_tmpname);
-+ close(in_fd);
-+ return 0;
-+ } else if (errno == EACCES) {
-+ syslog(LOG_WARNING,"autocreate_sieve: No access to create file %s. Check permissions",sieve_tmpname);
-+ close(in_fd);
-+ return 0;
-+ } else {
-+ syslog(LOG_WARNING,"autocreate_sieve: Unable to create %s",sieve_tmpname);
-+ close(in_fd);
-+ return 0;
-+ }
-+ }
-+
-+ while((r = read(in_fd, buf, sizeof(buf))) > 0) {
-+ if((k = write(out_fd,buf,r)) < 0) {
-+ syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s, error: %d", sieve_tmpname, errno);
-+ close(out_fd);
-+ close(in_fd);
-+ unlink(sieve_tmpname);
-+ return 0;
-+ }
-+ }
-+
-+ if(r == 0 ) { /*EOF */
-+ close(out_fd);
-+ close(in_fd);
-+ } else if (r < 0) {
-+ syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s, error: %d", sieve_tmpname, errno);
-+ close(out_fd);
-+ close(in_fd);
-+ unlink(sieve_tmpname);
-+ return 0;
-+ }
-+
-+ /* Rename the temporary created sieve script to its final name. */
-+ if(rename(sieve_tmpname, compiled_source_script)) {
-+ if(errno != EEXIST) {
-+ unlink(sieve_tmpname);
-+ unlink(compiled_source_script);
-+ }
-+ return 0;
-+ }
-+
-+ syslog(LOG_NOTICE, "autocreate_sieve: Compiled sieve script was successfully saved in %s", compiled_source_script);
-+ }
-+
-+ return 0;
-+}
-+
-+/*static void fatal(const char *s, int code)
-+{
-+ printf("Fatal error: %s (%d)\r\n", s, code);
-+ exit(1);
-+}*/
-+
-+/* to make larry's stupid functions happy :) */
-+static void foo(void)
-+{
-+ fatal("stub function called", 0);
-+}
++extern sieve_vacation_t vacation2;/* = {
++ 0, / min response /
++ 0, / max response /
++ (sieve_callback *) &foo, / autorespond() /
++ (sieve_callback *) &foo / send_response() /
++}; */
+
+static int sieve_notify(void *ac __attribute__((unused)),
+ void *interp_context __attribute__((unused)),
@@ -895,7 +844,7 @@
+
+ snprintf(buf, 80, "line %d: %s\r\n", lineno, msg);
+ *errstr = (char *) xrealloc(*errstr, strlen(*errstr) + strlen(buf) + 30);
-+ syslog(LOG_DEBUG, "%s", buf);
++ fprintf(stderr, "%s\n", buf);
+ strcat(*errstr, buf);
+
+ return SIEVE_OK;
@@ -912,75 +861,75 @@
+
+ res = sieve_interp_alloc(&i, NULL);
+ if (res != SIEVE_OK) {
-+ syslog(LOG_WARNING, "sieve_interp_alloc() returns %d\n", res);
++ fprintf(stderr, "sieve_interp_alloc() returns %d\n", res);
+ return TIMSIEVE_FAIL;
+ }
+
+ res = sieve_register_redirect(i, (sieve_callback *) &foo);
+ if (res != SIEVE_OK) {
-+ syslog(LOG_WARNING, "sieve_register_redirect() returns %d\n", res);
++ fprintf(stderr, "sieve_register_redirect() returns %d\n", res);
+ return TIMSIEVE_FAIL;
+ }
+ res = sieve_register_discard(i, (sieve_callback *) &foo);
+ if (res != SIEVE_OK) {
-+ syslog(LOG_WARNING, "sieve_register_discard() returns %d\n", res);
++ fprintf(stderr, "sieve_register_discard() returns %d\n", res);
+ return TIMSIEVE_FAIL;
+ }
+ res = sieve_register_reject(i, (sieve_callback *) &foo);
+ if (res != SIEVE_OK) {
-+ syslog(LOG_WARNING, "sieve_register_reject() returns %d\n", res);
++ fprintf(stderr, "sieve_register_reject() returns %d\n", res);
+ return TIMSIEVE_FAIL;
+ }
+ res = sieve_register_fileinto(i, (sieve_callback *) &foo);
+ if (res != SIEVE_OK) {
-+ syslog(LOG_WARNING, "sieve_register_fileinto() returns %d\n", res);
++ fprintf(stderr, "sieve_register_fileinto() returns %d\n", res);
+ return TIMSIEVE_FAIL;
+ }
+ res = sieve_register_keep(i, (sieve_callback *) &foo);
+ if (res != SIEVE_OK) {
-+ syslog(LOG_WARNING, "sieve_register_keep() returns %d\n", res);
++ fprintf(stderr, "sieve_register_keep() returns %d\n", res);
+ return TIMSIEVE_FAIL;
+ }
+
+ res = sieve_register_imapflags(i, NULL);
+ if (res != SIEVE_OK) {
-+ syslog(LOG_WARNING, "sieve_register_imapflags() returns %d\n", res);
++ fprintf(stderr, "sieve_register_imapflags() returns %d\n", res);
+ return TIMSIEVE_FAIL;
+ }
+
+ res = sieve_register_size(i, (sieve_get_size *) &foo);
+ if (res != SIEVE_OK) {
-+ syslog(LOG_WARNING, "sieve_register_size() returns %d\n", res);
++ fprintf(stderr, "sieve_register_size() returns %d\n", res);
+ return TIMSIEVE_FAIL;
+ }
+
+ res = sieve_register_header(i, (sieve_get_header *) &foo);
+ if (res != SIEVE_OK) {
-+ syslog(LOG_WARNING, "sieve_register_header() returns %d\n", res);
++ fprintf(stderr, "sieve_register_header() returns %d\n", res);
+ return TIMSIEVE_FAIL;
+ }
+
+ res = sieve_register_envelope(i, (sieve_get_envelope *) &foo);
+ if (res != SIEVE_OK) {
-+ syslog(LOG_WARNING, "sieve_register_envelope() returns %d\n", res);
++ fprintf(stderr, "sieve_register_envelope() returns %d\n", res);
+ return TIMSIEVE_FAIL;
+ }
+
+ res = sieve_register_vacation(i, &vacation2);
+ if (res != SIEVE_OK) {
-+ syslog(LOG_WARNING, "sieve_register_vacation() returns %d\n", res);
++ fprintf(stderr, "sieve_register_vacation() returns %d\n", res);
+ return TIMSIEVE_FAIL;
+ }
+
+ res = sieve_register_notify(i, &sieve_notify);
+ if (res != SIEVE_OK) {
-+ syslog(LOG_WARNING, "sieve_register_notify() returns %d\n", res);
++ fprintf(stderr, "sieve_register_notify() returns %d\n", res);
+ return TIMSIEVE_FAIL;
+ }
+
+ res = sieve_register_parse_error(i, &mysieve_error);
+ if (res != SIEVE_OK) {
-+ syslog(LOG_WARNING, "sieve_register_parse_error() returns %d\n", res);
++ fprintf(stderr, "sieve_register_parse_error() returns %d\n", res);
+ return TIMSIEVE_FAIL;
+ }
+
@@ -1007,393 +956,212 @@
+ return (res == SIEVE_OK) ? TIMSIEVE_OK : TIMSIEVE_FAIL;
+}
+
-+/*
-+ * Btw the initial date of this patch is Sep, 02 2004 which is the birthday of
-+ * Pavlos. Author of cyrusmaster. So consider this patch as his birthday present
-+ */
+
---- cyrus-imapd-2.3.13/imap/mboxlist.h.autocreate 2008-03-24 18:09:18.000000000 +0100
-+++ cyrus-imapd-2.3.13/imap/mboxlist.h 2009-01-13 11:14:09.000000000 +0100
-@@ -212,4 +212,8 @@
- int mboxlist_abort(struct txn *tid);
-
- int mboxlist_delayed_delete_isenabled(void);
-+int mboxlist_autocreateinbox(struct namespace *namespace,char *userid,
-+ struct auth_state *auth_state, char *mailboxname,
-+ int autocreatequota);
+
- #endif
---- cyrus-imapd-2.3.13/imap/compile_sieve.c.autocreate 2009-01-13 11:14:09.000000000 +0100
-+++ cyrus-imapd-2.3.13/imap/compile_sieve.c 2009-01-13 11:14:09.000000000 +0100
-@@ -0,0 +1,365 @@
-+/* This tool compiles the sieve script from a command
-+line so that it can be used wby the autoadd patch */
-+#include
-+#include
+
-+#include
-+#include
-+#ifdef HAVE_UNISTD_H
-+#include
-+#endif
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
+
-+#include "global.h"
+
-+#include "util.h"
-+#include "xmalloc.h"
-+#include "xstrlcpy.h"
-+#include "xstrlcat.h"
-+#include "mailbox.h"
-+#include "imap_err.h"
-+#include "sieve_interface.h"
-+#include "script.h"
+diff -up cyrus-imapd-2.3.15/imap/imapd.c.autocreate cyrus-imapd-2.3.15/imap/imapd.c
+--- cyrus-imapd-2.3.15/imap/imapd.c.autocreate 2009-07-29 17:51:21.000000000 +0200
++++ cyrus-imapd-2.3.15/imap/imapd.c 2009-09-18 11:11:39.783115781 +0200
+@@ -211,6 +211,7 @@ static const int max_monthdays[] = {
+ void motd_file(int fd);
+ void shut_down(int code);
+ void fatal(const char *s, int code);
++void autocreate_inbox(void);
+
+ void cmdloop(void);
+ void cmd_login(char *tag, char *user);
+@@ -2003,6 +2004,43 @@ void cmdloop()
+ }
+
+ /*
++ * Autocreate Inbox and subfolders upon login
++ */
++void autocreate_inbox()
++{
++ char inboxname[MAX_MAILBOX_NAME+1];
++ int autocreatequota;
++ int r;
++
++ /*
++ * Exlude admin's accounts
++ */
++ if (imapd_userisadmin || imapd_userisproxyadmin)
++ return;
++
++ /*
++ * Exclude anonymous
++ */
++ if (!strcmp(imapd_userid, "anonymous"))
++ return;
++
++ if ((autocreatequota = config_getint(IMAPOPT_AUTOCREATEQUOTA))) {
++ /* This is actyally not required
++ as long as the lenght of userid is ok */
++ r = (*imapd_namespace.mboxname_tointernal) (&imapd_namespace,
++ "INBOX", imapd_userid, inboxname);
++ if (!r)
++ r = mboxlist_lookup(inboxname, NULL, NULL);
++
++ if (r == IMAP_MAILBOX_NONEXISTENT) {
++ mboxlist_autocreateinbox(&imapd_namespace, imapd_userid,
++ imapd_authstate, inboxname, autocreatequota);
++ }
++ }
++}
+
-+#include
+
-+#define TIMSIEVE_FAIL -1
-+#define TIMSIEVE_OK 0
-+#define MAX_FILENAME_SIZE 100
++/*
+ * Perform a LOGIN command
+ */
+ void cmd_login(char *tag, char *user)
+@@ -2179,6 +2217,9 @@ void cmd_login(char *tag, char *user)
+ strcspn(imapd_userid, "@") : 0);
+
+ freebuf(&passwdbuf);
+
-+/* Needed by libconfig */
-+const int config_need_data = 0;
++ autocreate_inbox();
+
-+static int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret);
+ return;
+ }
+
+@@ -2336,6 +2377,8 @@ cmd_authenticate(char *tag, char *authty
+ config_virtdomains ?
+ strcspn(imapd_userid, "@") : 0);
+
++ autocreate_inbox();
+
-+/*static void fatal(const char *s, int code)
-+{
-+ printf("Fatal error: %s (%d)\r\n", s, code);
+ return;
+ }
+
+diff -up cyrus-imapd-2.3.15/imap/lmtpd.c.autocreate cyrus-imapd-2.3.15/imap/lmtpd.c
+--- cyrus-imapd-2.3.15/imap/lmtpd.c.autocreate 2009-04-23 19:10:06.000000000 +0200
++++ cyrus-imapd-2.3.15/imap/lmtpd.c 2009-09-18 11:11:39.780115773 +0200
+@@ -117,6 +117,8 @@ void shut_down(int code);
+ static FILE *spoolfile(message_data_t *msgdata);
+ static void removespool(message_data_t *msgdata);
+
++static int autocreate_inbox(const char *user, const char *domain);
+
-+ exit(1);
-+}*/
+ /* current namespace */
+ static struct namespace lmtpd_namespace;
+
+@@ -977,6 +979,86 @@ void shut_down(int code)
+ exit(code);
+ }
+
+
-+void usage(void)
++/*
++ * Autocreate Inbox and subfolders upon login
++ */
++int autocreate_inbox(const char *user, const char *domain)
+{
-+ fprintf(stderr,
-+ "Usage:\n\tcompile_sieve [-C ] [-i -o ]\n");
-+ exit(-1);
-+}
++ struct auth_state *auth_state;
++ char inboxname[MAX_MAILBOX_NAME+1];
++ char *rcpt_userid = NULL;
++ int autocreatequota;
++ int r = 0;
+
++ if (user == NULL)
++ return IMAP_MAILBOX_NONEXISTENT;
+
-+int main (int argc, char **argv)
-+{
++ if (domain != NULL) {
++ int k;
++
++ rcpt_userid = (char *) xmalloc((strlen(user) + strlen(domain) + 2) * sizeof(char));
++ k = strlcpy(rcpt_userid, user, strlen(user) + 1);
++ *(rcpt_userid + k) = '@';
++ strlcpy(rcpt_userid + k + 1, domain, strlen(domain) + 1);
++ } else {
++ rcpt_userid = (char *) user;
++ }
+
-+ sieve_script_t *s = NULL;
-+ bytecode_info_t *bc = NULL;
-+ char *err = NULL;
-+ FILE *in_stream;
-+ int out_fd, opt;
-+ char *source_script = NULL;
-+ char *compiled_source_script = NULL;
-+ char *alt_config = NULL;
-+ extern char *optarg;
-+ char sieve_tmpname[MAX_MAILBOX_NAME+1];
-+
-+ if (geteuid() == 0) fatal("must run as the Cyrus user", EC_USAGE);
-+
-+ while((opt = getopt(argc, argv, "C:i:o:")) != EOF) {
-+ switch (opt) {
-+ case 'C': /* alt config file */
-+ alt_config = optarg;
-+ break;
-+ case 'i': /* input script file */
-+ source_script = optarg;
-+ break;
-+ case 'o': /* output script file */
-+ compiled_source_script = optarg;
-+ break;
-+ default:
-+ usage();
-+ break;
-+ }
-+ }
-+
-+ if(source_script && !compiled_source_script) {
-+ fprintf(stderr, "No output file was defined\n");
-+ usage();
-+ } else if (!source_script && compiled_source_script) {
-+ fprintf(stderr, "No input file was defined\n");
-+ usage();
-+ }
+
+ /*
-+ * If no has been defined, then read them from
-+ * the configuration file.
++ * Exclude anonymous
+ */
-+ if (!source_script && !compiled_source_script) {
-+ cyrus_init(alt_config, "compile_sieve", 0);
-+
-+ /* Initially check if we want to have the sieve script created */
-+ if(!(source_script = (char *) config_getstring(IMAPOPT_AUTOCREATE_SIEVE_SCRIPT))) {
-+ fprintf(stderr,"autocreate_sieve_script option not defined. Check imapd.conf\n");
-+ return 1;
-+ }
-+
-+ /* Check if we have an already compiled sieve script*/
-+ if(!(compiled_source_script = (char *) config_getstring(IMAPOPT_AUTOCREATE_SIEVE_COMPILEDSCRIPT))) {
-+ fprintf(stderr, "autocreate_sieve_compiledscript option not defined. Check imapd.conf\n");
-+ return 1;
-+ }
-+
-+ if(!strrchr(source_script,'/') || !strrchr(compiled_source_script,'/')) {
-+ /*
-+ * At this point the only think that is inconsistent is the directory
-+ * that was created. But if the user will have any sieve scripts then
-+ * they will eventually go there, so no big deal
-+ */
-+ fprintf(stderr,
-+ "In imapd.conf the full path of the filenames must be defined\n");
-+ return 1;
-+ }
-+ }
-+
-+ printf("input file : %s, output file : %s\n", source_script, compiled_source_script);
-+
-+
-+ if(strlen(compiled_source_script) + sizeof(".NEW") + 1 > sizeof(sieve_tmpname)) {
-+ fprintf(stderr, "Filename %s is too big\n", compiled_source_script);
-+ return 1;
-+ }
-+
-+ snprintf(sieve_tmpname, sizeof(sieve_tmpname), "%s.NEW", compiled_source_script);
-+
-+ in_stream = fopen(source_script,"r");
++ if (!strcmp(rcpt_userid, "anonymous")) {
++ if (rcpt_userid != user) {
++ free(rcpt_userid);
++ }
+
-+ if(!in_stream) {
-+ fprintf(stderr,"Unable to open %s source sieve script\n",source_script);
-+ return 1;
++ return IMAP_MAILBOX_NONEXISTENT;
+ }
-+
-+ /*
-+ * We open the file that will be used as the bc file. If this file exists, overwrite it
-+ * since something bad has happened. We open the file here so that this error checking is
-+ * done before we try to open the rest of the files to start copying etc.
++
++ /*
++ * Check for autocreatequota and createonpost
+ */
-+ out_fd = open(sieve_tmpname, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
-+ if(out_fd < 0) {
-+ if(errno == EEXIST) {
-+ fprintf(stderr, "File %s already exists\n", sieve_tmpname);
-+ } else if (errno == EACCES) {
-+ fprintf(stderr,"No access to create file %s. Please check that you have the correct permissions\n",
-+ sieve_tmpname);
-+ } else {
-+ fprintf(stderr,"Unable to create %s. Please check that you have the correct permissions\n",
-+ sieve_tmpname);
-+ }
++ if (!(autocreatequota = config_getint(IMAPOPT_AUTOCREATEQUOTA)) ||
++ !(config_getswitch(IMAPOPT_CREATEONPOST))) {
++
++ if (rcpt_userid != user) {
++ free(rcpt_userid);
++ }
+
-+ fclose(in_stream);
-+ return 1;
-+ }
-+
-+ if(is_script_parsable(in_stream,&err, &s) == TIMSIEVE_FAIL) {
-+ if(err && *err) {
-+ fprintf(stderr, "Error while parsing script %s\n",err);
-+ free(err);
-+ }
-+ else
-+ fprintf(stderr,"Error while parsing script\n");
-+ unlink(sieve_tmpname);
-+ fclose(in_stream);
-+ close(out_fd);
-+ return 1;
-+ }
-+
-+
-+ /* generate the bytecode */
-+ if(sieve_generate_bytecode(&bc,s) == TIMSIEVE_FAIL) {
-+ fprintf(stderr,"Error occured while compiling sieve script\n");
-+ /* removing the copied script and cleaning up memory */
-+ unlink(sieve_tmpname);
-+ sieve_script_free(&s);
-+ fclose(in_stream);
-+ close(out_fd);
-+ return 1;
-+ }
-+ if(sieve_emit_bytecode(out_fd,bc) == TIMSIEVE_FAIL) {
-+ fprintf(stderr, "Error occured while emitting sieve script\n");
-+ unlink(sieve_tmpname);
-+ sieve_free_bytecode(&bc);
-+ sieve_script_free(&s);
-+ fclose(in_stream);
-+ close(out_fd);
-+ return 1;
-+ }
-+
-+ /* clean up the memory */
-+ sieve_free_bytecode(&bc);
-+ sieve_script_free(&s);
-+
-+ close(out_fd);
-+
-+ if(rename(sieve_tmpname, compiled_source_script)) {
-+ if(errno != EEXIST) {
-+ unlink(sieve_tmpname);
-+ unlink(compiled_source_script);
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+
++ return IMAP_MAILBOX_NONEXISTENT;
++ }
+
-+/* to make larry's stupid functions happy :) */
-+static void foo(void)
-+{
-+ fatal("stub function called", 0);
-+}
+
-+extern sieve_vacation_t vacation2;/* = {
-+ 0, / min response /
-+ 0, / max response /
-+ (sieve_callback *) &foo, / autorespond() /
-+ (sieve_callback *) &foo / send_response() /
-+}; */
++ /*
++ * Exclude admin's accounts
++ */
++ auth_state = auth_newstate(rcpt_userid);
++
++ if (global_authisa(auth_state, IMAPOPT_ADMINS)) {
++ if (rcpt_userid != user) {
++ free(rcpt_userid);
++ }
+
-+static int sieve_notify(void *ac __attribute__((unused)),
-+ void *interp_context __attribute__((unused)),
-+ void *script_context __attribute__((unused)),
-+ void *message_context __attribute__((unused)),
-+ const char **errmsg __attribute__((unused)))
-+{
-+ fatal("stub function called", 0);
-+ return SIEVE_FAIL;
++ return IMAP_MAILBOX_NONEXISTENT;
++ }
++
++ r = (*lmtpd_namespace.mboxname_tointernal) (&lmtpd_namespace,
++ "INBOX", rcpt_userid, inboxname);
++
++ if (!r)
++ r = mboxlist_autocreateinbox(&lmtpd_namespace, rcpt_userid,
++ auth_state, inboxname, autocreatequota);
++
++ if (rcpt_userid != user) {
++ free(rcpt_userid);
++ }
++
++ return r;
+}
+
-+static int mysieve_error(int lineno, const char *msg,
-+ void *i __attribute__((unused)), void *s)
-+{
-+ char buf[1024];
-+ char **errstr = (char **) s;
-+
-+ snprintf(buf, 80, "line %d: %s\r\n", lineno, msg);
-+ *errstr = (char *) xrealloc(*errstr, strlen(*errstr) + strlen(buf) + 30);
-+ fprintf(stderr, "%s\n", buf);
-+ strcat(*errstr, buf);
-+
-+ return SIEVE_OK;
-+}
+
-+/* end the boilerplate */
+ static int verify_user(const char *user, const char *domain, char *mailbox,
+ quota_t quotacheck, struct auth_state *authstate)
+ {
+@@ -1020,6 +1102,15 @@ static int verify_user(const char *user,
+ */
+ r = mlookup(namebuf, &server, &acl, NULL);
+
++ /* If user mailbox does not exist, then invoke autocreate inbox function */
++ if (r == IMAP_MAILBOX_NONEXISTENT) {
++ r = autocreate_inbox(user, domain);
+
-+/* returns TRUE or FALSE */
-+int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret)
-+{
-+ sieve_interp_t *i;
-+ sieve_script_t *s;
-+ int res;
++ /* Try to locate the mailbox again */
++ if (!r)
++ r = mlookup(namebuf, &server, &acl, NULL);
++ }
+
-+ res = sieve_interp_alloc(&i, NULL);
-+ if (res != SIEVE_OK) {
-+ fprintf(stderr, "sieve_interp_alloc() returns %d\n", res);
-+ return TIMSIEVE_FAIL;
-+ }
+ if (r == IMAP_MAILBOX_NONEXISTENT && !user &&
+ config_getswitch(IMAPOPT_LMTP_FUZZY_MAILBOX_MATCH) &&
+ /* see if we have a mailbox whose name is close */
+@@ -1046,6 +1137,7 @@ static int verify_user(const char *user,
+ aclcheck, (quotacheck < 0)
+ || config_getswitch(IMAPOPT_LMTP_STRICT_QUOTA) ?
+ quotacheck : 0);
+
-+ res = sieve_register_redirect(i, (sieve_callback *) &foo);
-+ if (res != SIEVE_OK) {
-+ fprintf(stderr, "sieve_register_redirect() returns %d\n", res);
-+ return TIMSIEVE_FAIL;
-+ }
-+ res = sieve_register_discard(i, (sieve_callback *) &foo);
-+ if (res != SIEVE_OK) {
-+ fprintf(stderr, "sieve_register_discard() returns %d\n", res);
-+ return TIMSIEVE_FAIL;
-+ }
-+ res = sieve_register_reject(i, (sieve_callback *) &foo);
-+ if (res != SIEVE_OK) {
-+ fprintf(stderr, "sieve_register_reject() returns %d\n", res);
-+ return TIMSIEVE_FAIL;
-+ }
-+ res = sieve_register_fileinto(i, (sieve_callback *) &foo);
-+ if (res != SIEVE_OK) {
-+ fprintf(stderr, "sieve_register_fileinto() returns %d\n", res);
-+ return TIMSIEVE_FAIL;
-+ }
-+ res = sieve_register_keep(i, (sieve_callback *) &foo);
-+ if (res != SIEVE_OK) {
-+ fprintf(stderr, "sieve_register_keep() returns %d\n", res);
-+ return TIMSIEVE_FAIL;
-+ }
-+
-+ res = sieve_register_imapflags(i, NULL);
-+ if (res != SIEVE_OK) {
-+ fprintf(stderr, "sieve_register_imapflags() returns %d\n", res);
-+ return TIMSIEVE_FAIL;
-+ }
-+
-+ res = sieve_register_size(i, (sieve_get_size *) &foo);
-+ if (res != SIEVE_OK) {
-+ fprintf(stderr, "sieve_register_size() returns %d\n", res);
-+ return TIMSIEVE_FAIL;
-+ }
-+
-+ res = sieve_register_header(i, (sieve_get_header *) &foo);
-+ if (res != SIEVE_OK) {
-+ fprintf(stderr, "sieve_register_header() returns %d\n", res);
-+ return TIMSIEVE_FAIL;
-+ }
-+
-+ res = sieve_register_envelope(i, (sieve_get_envelope *) &foo);
-+ if (res != SIEVE_OK) {
-+ fprintf(stderr, "sieve_register_envelope() returns %d\n", res);
-+ return TIMSIEVE_FAIL;
-+ }
-+
-+ res = sieve_register_vacation(i, &vacation2);
-+ if (res != SIEVE_OK) {
-+ fprintf(stderr, "sieve_register_vacation() returns %d\n", res);
-+ return TIMSIEVE_FAIL;
-+ }
-+
-+ res = sieve_register_notify(i, &sieve_notify);
-+ if (res != SIEVE_OK) {
-+ fprintf(stderr, "sieve_register_notify() returns %d\n", res);
-+ return TIMSIEVE_FAIL;
-+ }
-+
-+ res = sieve_register_parse_error(i, &mysieve_error);
-+ if (res != SIEVE_OK) {
-+ fprintf(stderr, "sieve_register_parse_error() returns %d\n", res);
-+ return TIMSIEVE_FAIL;
-+ }
-+
-+ rewind(stream);
-+
-+ *errstr = (char *) xmalloc(20 * sizeof(char));
-+ strcpy(*errstr, "script errors:\r\n");
-+
-+ res = sieve_script_parse(i, stream, errstr, &s);
-+
-+ if (res == SIEVE_OK) {
-+ if(ret) {
-+ *ret = s;
-+ } else {
-+ sieve_script_free(&s);
-+ }
-+ free(*errstr);
-+ *errstr = NULL;
-+ }
-+
-+ /* free interpreter */
-+ sieve_interp_free(&i);
-+
-+ return (res == SIEVE_OK) ? TIMSIEVE_OK : TIMSIEVE_FAIL;
-+}
-+
-+
-+
-+
-+
-+
---- cyrus-imapd-2.3.13/imap/Makefile.in.autocreate 2008-09-23 18:17:09.000000000 +0200
-+++ cyrus-imapd-2.3.13/imap/Makefile.in 2009-01-13 11:24:48.000000000 +0100
-@@ -101,7 +101,7 @@
+ }
+ }
+
+diff -up cyrus-imapd-2.3.15/imap/Makefile.in.autocreate cyrus-imapd-2.3.15/imap/Makefile.in
+--- cyrus-imapd-2.3.15/imap/Makefile.in.autocreate 2009-03-30 18:04:56.000000000 +0200
++++ cyrus-imapd-2.3.15/imap/Makefile.in 2009-09-18 11:44:04.105116069 +0200
+@@ -101,7 +101,7 @@ LOBJS= append.o mailbox.o mboxlist.o mup
convert_code.o duplicate.o saslclient.o saslserver.o signals.o \
annotate.o search_engines.o squat.o squat_internal.o mbdump.o \
imapparse.o telemetry.o user.o notify.o idle.o quota_db.o \
@@ -1402,16 +1170,16 @@
statuscache_db.o
IMAPDOBJS=pushstats.o imapd.o proxy.o imap_proxy.o index.o version.o
-@@ -118,7 +118,7 @@
+@@ -118,7 +118,7 @@ PROGS = imapd lmtpd pop3d \
fud smmapd reconstruct quota mbpath ipurge cyr_dbtool cyr_synclog \
cyrdump chk_cyrus cvt_cyrusdb deliver ctl_mboxlist \
ctl_deliver ctl_cyrusdb squatter mbexamine cyr_expire arbitron \
-- unexpunge @IMAP_PROGS@
-+ unexpunge compile_sieve @IMAP_PROGS@
+- unexpunge cyr_df @IMAP_PROGS@
++ unexpunge cyr_df compile_sieve @IMAP_PROGS@
BUILTSOURCES = imap_err.c imap_err.h pushstats.c pushstats.h \
lmtpstats.c lmtpstats.h xversion.h mupdate_err.c mupdate_err.h \
-@@ -183,9 +183,9 @@
+@@ -183,9 +183,9 @@ mupdate_err.c: mupdate_err.et
mupdate_err.h: mupdate_err.c
### Services
@@ -1423,7 +1191,7 @@
lmtpd: lmtpd.o proxy.o $(LMTPOBJS) $(SIEVE_OBJS) mutex_fake.o \
libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE)
-@@ -199,163 +199,166 @@
+@@ -199,167 +199,170 @@ lmtpd.pure: lmtpd.o proxy.o $(LMTPOBJS)
$(SERVICE) lmtpd.o proxy.o $(LMTPOBJS) $(SIEVE_OBJS) \
mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP)
@@ -1598,6 +1366,12 @@
- libimap.a $(DEPLIBS) $(LIBS)
+ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
+-cyr_df: cyr_df.o $(CLIOBJS) libimap.a $(DEPLIBS)
++cyr_df: cyr_df.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
+ $(CC) $(LDFLAGS) -o \
+- cyr_df cyr_df.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS)
++ cyr_df cyr_df.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS)
+
-mbexamine: mbexamine.o $(CLIOBJS) libimap.a $(DEPLIBS)
+mbexamine: mbexamine.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS)
$(CC) $(LDFLAGS) -o \
@@ -1660,204 +1434,418 @@
### Other Misc Targets
clean:
---- cyrus-imapd-2.3.13/imap/lmtpd.c.autocreate 2008-04-22 15:11:18.000000000 +0200
-+++ cyrus-imapd-2.3.13/imap/lmtpd.c 2009-01-13 11:14:09.000000000 +0100
-@@ -117,6 +117,8 @@
- static FILE *spoolfile(message_data_t *msgdata);
- static void removespool(message_data_t *msgdata);
+diff -up cyrus-imapd-2.3.15/imap/mboxlist.c.autocreate cyrus-imapd-2.3.15/imap/mboxlist.c
+--- cyrus-imapd-2.3.15/imap/mboxlist.c.autocreate 2009-07-28 04:46:23.000000000 +0200
++++ cyrus-imapd-2.3.15/imap/mboxlist.c 2009-09-18 11:11:39.777115766 +0200
+@@ -83,6 +83,12 @@
+ #include "quota.h"
+ #include "sync_log.h"
-+static int autocreate_inbox(const char *user, const char *domain);
++#ifdef USE_SIEVE
++extern int autoadd_sieve(char *userid,
++ const char *source_script);
++#endif
+
- /* current namespace */
- static struct namespace lmtpd_namespace;
++
+ #define DB config_mboxlist_db
+ #define SUBDB config_subscription_db
-@@ -976,6 +978,86 @@ void shut_down(int code)
- exit(code);
- }
+@@ -100,11 +106,29 @@ static int mboxlist_rmquota(const char *
+ static int mboxlist_changequota(const char *name, int matchlen, int maycreate,
+ void *rock);
++static int mboxlist_autochangesub(char *name, int matchlen, int maycreate,
++ void *rock);
++
++static int mboxlist_autosubscribe_sharedfolders(struct namespace *namespace,
++ char *userid, char *auth_userid,
++ struct auth_state *auth_state);
+
+ struct change_rock {
+ struct quota *quota;
+ struct txn **tid;
+ };
+
+/*
-+ * Autocreate Inbox and subfolders upon login
++ * Struct needed to be passed as void *rock to
++ * mboxlist_autochangesub();
+ */
-+int autocreate_inbox(const char *user, const char *domain)
-+{
-+ struct auth_state *auth_state;
-+ char inboxname[MAX_MAILBOX_NAME+1];
-+ char *rcpt_userid = NULL;
-+ int autocreatequota;
-+ int r = 0;
++struct changesub_rock_st {
++ char *userid;
++ char *auth_userid;
++ struct auth_state *auth_state;
++};
+
-+ if (user == NULL)
-+ return IMAP_MAILBOX_NONEXISTENT;
+
-+ if (domain != NULL) {
-+ int k;
-+
-+ rcpt_userid = (char *) xmalloc((strlen(user) + strlen(domain) + 2) * sizeof(char));
-+ k = strlcpy(rcpt_userid, user, strlen(user) + 1);
-+ *(rcpt_userid + k) = '@';
-+ strlcpy(rcpt_userid + k + 1, domain, strlen(domain) + 1);
-+ } else {
-+ rcpt_userid = (char *) user;
-+ }
+ #define FNAME_SUBSSUFFIX ".sub"
+
+ /*
+@@ -3413,3 +3437,349 @@ int mboxlist_delayed_delete_isenabled(vo
+
+ return(config_delete_mode == IMAP_ENUM_DELETE_MODE_DELAYED);
+ }
++
++/*
++ * Automatically subscribe user to *ALL* shared folders,
++ * one has permissions to be subscribed to.
++ * INBOX subfolders are excluded.
++ */
++static int mboxlist_autochangesub(char *name, int matchlen, int maycreate,
++ void *rock) {
++
++ struct changesub_rock_st *changesub_rock = (struct changesub_rock_st *) rock;
++ char *userid = changesub_rock->userid;
++ char *auth_userid = changesub_rock->auth_userid;
++ struct auth_state *auth_state = changesub_rock->auth_state;
++ int r;
++
++
++ if((strlen(name) == 5 && !strncmp(name, "INBOX", 5)) || /* Exclude INBOX */
++ (strlen(name) > 5 && !strncmp(name, "INBOX.",6)) || /* Exclude INBOX subfolders */
++ (strlen(name) > 4 && !strncmp(name, "user.", 5))) /* Exclude other users' folders */
++ return 0;
++
++
++ r = mboxlist_changesub(name, userid, auth_state, 1, 0);
++
++ if (r) {
++ syslog(LOG_WARNING,
++ "autosubscribe: User %s to folder %s, subscription failed: %s",
++ auth_userid, name, error_message(r));
++ } else {
++ syslog(LOG_NOTICE,
++ "autosubscribe: User %s to folder %s, subscription succeeded",
++ auth_userid, name);
++ }
++
++ return 0;
++}
+
++#define SEP '|'
++
++/*
++ * Automatically subscribe user to a shared folder.
++ * Subscription is done successfully, if the shared
++ * folder exists and the user has the necessary
++ * permissions.
++ */
++static int mboxlist_autosubscribe_sharedfolders(struct namespace *namespace,
++ char *userid, char *auth_userid,
++ struct auth_state *auth_state) {
++
++ const char *sub ;
++ char *p, *q, *next_sub;
++ char folder[MAX_MAILBOX_NAME+1], name[MAX_MAILBOX_NAME+1], mailboxname[MAX_MAILBOX_NAME+1];
++ int len;
++ int r = 0;
++ int subscribe_all_sharedfolders = 0;
++
++ subscribe_all_sharedfolders = config_getswitch(IMAPOPT_AUTOSUBSCRIBE_ALL_SHAREDFOLDERS);
+
+ /*
-+ * Exclude anonymous
++ * If subscribeallsharedfolders is set to yes in imapd.conf, then
++ * subscribe user to every shared folder one has the apropriate
++ * permissions.
+ */
-+ if (!strcmp(rcpt_userid, "anonymous")) {
-+ if (rcpt_userid != user) {
-+ free(rcpt_userid);
-+ }
++ if(subscribe_all_sharedfolders) {
++ char pattern[MAX_MAILBOX_PATH+1];
++ struct changesub_rock_st changesub_rock;
+
-+ return IMAP_MAILBOX_NONEXISTENT;
++ strcpy(pattern, "*");
++ changesub_rock.userid = userid;
++ changesub_rock.auth_userid = auth_userid;
++ changesub_rock.auth_state = auth_state;
++
++ r = mboxlist_findall(namespace, pattern, 0, userid,
++ auth_state, mboxlist_autochangesub, &changesub_rock);
++
++ return r;
+ }
-+
-+ /*
-+ * Check for autocreatequota and createonpost
-+ */
-+ if (!(autocreatequota = config_getint(IMAPOPT_AUTOCREATEQUOTA)) ||
-+ !(config_getswitch(IMAPOPT_CREATEONPOST))) {
-+
-+ if (rcpt_userid != user) {
-+ free(rcpt_userid);
-+ }
-+
-+ return IMAP_MAILBOX_NONEXISTENT;
-+ }
+
++ if ((sub=config_getstring(IMAPOPT_AUTOSUBSCRIBESHAREDFOLDERS)) == NULL)
++ return r;
++
++ next_sub = (char *) sub;
++ while (*next_sub) {
++ for (p = next_sub ; isspace((int) *p) || *p == SEP ; p++);
++ for (next_sub = p ; *next_sub && *next_sub != SEP ; next_sub++);
++ for (q = next_sub ; q > p && (isspace((int) *q) || *q == SEP || !*q) ; q--);
++ if (!*p ) continue;
+
-+ /*
-+ * Exclude admin's accounts
-+ */
-+ auth_state = auth_newstate(rcpt_userid);
-+
-+ if (global_authisa(auth_state, IMAPOPT_ADMINS)) {
-+ if (rcpt_userid != user) {
-+ free(rcpt_userid);
-+ }
++ len = q - p + 1;
++ /* Check for folder length */
++ if (len > sizeof(folder)-1)
++ continue;
+
-+ return IMAP_MAILBOX_NONEXISTENT;
-+ }
-+
-+ r = (*lmtpd_namespace.mboxname_tointernal) (&lmtpd_namespace,
-+ "INBOX", rcpt_userid, inboxname);
-+
-+ if (!r)
-+ r = mboxlist_autocreateinbox(&lmtpd_namespace, rcpt_userid,
-+ auth_state, inboxname, autocreatequota);
-+
-+ if (rcpt_userid != user) {
-+ free(rcpt_userid);
-+ }
-+
-+ return r;
++ if (!r) {
++ strncpy(folder, p, len);
++ folder[len] = '\0';
++
++ strlcpy(name, namespace->prefix[NAMESPACE_SHARED], sizeof(name));
++ len = strlcat(name, folder, sizeof(name));
++
++ r = (namespace->mboxname_tointernal) (namespace, name, userid,
++ mailboxname);
++ }
++
++ if (!r)
++ r = mboxlist_changesub(mailboxname, userid, auth_state, 1, 0);
++
++ if (!r) {
++ syslog(LOG_NOTICE, "autosubscribe: User %s to %s succeeded",
++ userid, folder);
++ } else {
++ syslog(LOG_WARNING, "autosubscribe: User %s to %s failed: %s",
++ userid, folder, error_message(r));
++ r = 0;
++ }
++ }
++
++ return r;
+}
+
+
- static int verify_user(const char *user, const char *domain, char *mailbox,
- quota_t quotacheck, struct auth_state *authstate)
- {
-@@ -1019,6 +1101,15 @@
- */
- r = mlookup(namebuf, &server, &acl, NULL);
-
-+ /* If user mailbox does not exist, then invoke autocreate inbox function */
-+ if (r == IMAP_MAILBOX_NONEXISTENT) {
-+ r = autocreate_inbox(user, domain);
+
-+ /* Try to locate the mailbox again */
-+ if (!r)
-+ r = mlookup(namebuf, &server, &acl, NULL);
-+ }
++int mboxlist_autocreateinbox(struct namespace *namespace,
++ char *userid,
++ struct auth_state *auth_state,
++ char *mailboxname, int autocreatequota) {
++ char name [MAX_MAILBOX_NAME+1];
++ char folder [MAX_MAILBOX_NAME+1];
++ char *auth_userid = NULL;
++ char *partition = NULL;
++ const char *crt;
++ const char *sub;
++ char *p, *q, *next_crt, *next_sub;
++ int len;
++ int r = 0;
++ int numcrt = 0;
++ int numsub = 0;
++#ifdef USE_SIEVE
++ const char *source_script;
++#endif
++
++
++
++ auth_userid = auth_canonuser(auth_state);
++ if (auth_userid == NULL) {
++ /*
++ * Couldn't get cannon userid
++ */
++ syslog(LOG_ERR,
++ "autocreateinbox: Could not get canonified userid for user %s", userid);
++ return IMAP_PARTITION_UNKNOWN;
++ }
++
++ /* Added this for debug information. */
++ syslog(LOG_DEBUG, "autocreateinbox: autocreate inbox for user %s was called", auth_userid);
++
++ /*
++ * While this is not needed for admins
++ * and imap_admins accounts, it would be
++ * better to separate *all* admins and
++ * proxyservers from normal accounts
++ * (accounts that have mailboxes).
++ * UOA Specific note(1): Even if we do not
++ * exclude these servers-classes here,
++ * UOA specific code, will neither return
++ * role, nor create INBOX, because none of these
++ * administrative accounts belong to the
++ * mailRecipient objectclass, or have imapPartition.
++ * UOA Specific note(2): Another good reason for doing
++ * this, is to prevent the code, from getting into
++ * cyrus_ldap.c because of the continues MSA logins to LMTPd.
++ */
++
++ /*
++ * admins and the coresponding imap
++ * service, had already been excluded.
++ */
++
++ /*
++ * Do we really need group membership
++ * for admins or service_admins?
++ */
++ if (global_authisa(auth_state, IMAPOPT_ADMINS)) return 0;
++
++ /*
++ * Do we really need group membership
++ * for proxyservers?
++ */
++ if (global_authisa(auth_state, IMAPOPT_PROXYSERVERS)) return 0;
++
++ /*
++ * Check if user belongs to the autocreate_users group. This option
++ * controls for whom the mailbox may be automatically created. Default
++ * value for this option is 'anyone'. So, if not declared, all mailboxes
++ * will be created.
++ */
++ if (!global_authisa(auth_state, IMAPOPT_AUTOCREATE_USERS)) {
++ syslog(LOG_DEBUG, "autocreateinbox: User %s does not belong to the autocreate_users. No mailbox is created",
++ auth_userid);
++ return IMAP_MAILBOX_NONEXISTENT;
++ }
++
++#if 0
++ /*
++ * Get Partition info or return.
++ * (Here you should propably use
++ * you own "get_partition(char *userid)"
++ * function. Otherwise all new INBOXes will be
++ * created into whatever partition has been declared
++ * as default in your imapd.conf)
++ */
++
++ partition = get_partition(userid);
++ if (partition == NULL) {
++ /*
++ * Couldn't get partition info
++ */
++ syslog(LOG_ERR,
++ "Could not get imapPartition info for user %s", userid);
++ return IMAP_PARTITION_UNKNOWN;
++ }
++#endif
++
++ r = mboxlist_createmailbox(mailboxname, MAILBOX_FORMAT_NORMAL, NULL,
++ 1, userid, auth_state, 0, 0, 0);
++
++ if (!r && autocreatequota > 0)
++ r = mboxlist_setquota(mailboxname, autocreatequota, 0);
++
++ if (!r)
++ r = mboxlist_changesub(mailboxname, userid,
++ auth_state, 1, 1);
++
++ if (!r) {
++ syslog(LOG_NOTICE, "autocreateinbox: User %s, INBOX was successfully created in partition %s",
++ auth_userid, partition == NULL ? "default" : partition);
++ } else {
++ syslog(LOG_ERR, "autocreateinbox: User %s, INBOX failed. %s",
++ auth_userid, error_message(r));
++ }
++
++#if 0
++ /* Allocated from get_partition, and not needed any more */
++ free_partition(partition);
++#endif
++
++ if (r) return r;
++
++ /* INBOX's subfolders */
++ if ((crt=config_getstring(IMAPOPT_AUTOCREATEINBOXFOLDERS)))
++ sub=config_getstring(IMAPOPT_AUTOSUBSCRIBEINBOXFOLDERS);
++
++ /* Roll through crt */
++ next_crt = (char *) crt;
++ while (next_crt!=NULL && *next_crt) {
++ for (p = next_crt ; isspace((int) *p) || *p == SEP ; p++);
++ for (next_crt = p ; *next_crt && *next_crt != SEP ; next_crt++);
++ for (q = next_crt ; q > p && (isspace((int) *q) || *q == SEP || !*q); q--);
++
++ if (!*p) continue;
++
++ len = q - p + 1;
++
++ /* First time we check for length */
++ if (len > sizeof(folder) - 5)
++ r = IMAP_MAILBOX_BADNAME;
++
++ if (!r) {
++ strncpy(folder, p, len);
++ folder[len] = '\0';
++
++ strlcpy(name, namespace->prefix[NAMESPACE_INBOX], sizeof(name));
++ len = strlcat(name, folder, sizeof(name));
++ }
++
++ if (!r)
++ r = (namespace->mboxname_tointernal) (namespace, name, userid,
++ mailboxname);
++ if (!r)
++ r = mboxlist_createmailbox(mailboxname, MAILBOX_FORMAT_NORMAL, NULL,
++ 1, userid, auth_state, 0, 0, 0);
++
++ if (!r) {
++ numcrt++;
++ syslog(LOG_NOTICE, "autocreateinbox: User %s, subfolder %s creation succeeded.",
++ auth_userid, name);
++ } else {
++ syslog(LOG_WARNING, "autocreateinbox: User %s, subfolder %s creation failed. %s",
++ auth_userid, name, error_message(r));
++ r=0;
++ continue;
++ }
++
++ /* Roll through sub */
++ next_sub = (char *) sub;
++ while (next_sub!=NULL && *next_sub) {
++ for (p = next_sub ; isspace((int) *p) || *p == SEP ; p++);
++ for (next_sub = p ; *next_sub && *next_sub != SEP ; next_sub++);
++ for (q = next_sub ; q > p && (isspace((int) *q) || *q == SEP || !*q) ; q--);
++ if (!*p ) continue;
++
++ len = q - p + 1;
++
++ if (len != strlen(folder) || strncmp(folder, p, len))
++ continue;
++
++ r = mboxlist_changesub(mailboxname, userid, auth_state, 1, 1);
++
++ if (!r) {
++ numsub++;
++ syslog(LOG_NOTICE,"autocreateinbox: User %s, subscription to %s succeeded",
++ auth_userid, name);
++ } else
++ syslog(LOG_WARNING, "autocreateinbox: User %s, subscription to %s failed. %s",
++ auth_userid, name, error_message(r));
+
- if (r == IMAP_MAILBOX_NONEXISTENT && !user &&
- config_getswitch(IMAPOPT_LMTP_FUZZY_MAILBOX_MATCH) &&
- /* see if we have a mailbox whose name is close */
-@@ -1045,6 +1136,7 @@
- aclcheck, (quotacheck < 0)
- || config_getswitch(IMAPOPT_LMTP_STRICT_QUOTA) ?
- quotacheck : 0);
++ break;
++ }
++ }
++
++ if (crt!=NULL && *crt)
++ syslog(LOG_INFO, "User %s, Inbox subfolders, created %d, subscribed %d",
++ auth_userid, numcrt, numsub);
+
- }
- }
-
---- cyrus-imapd-2.3.13/imap/imapd.c.autocreate 2008-10-08 17:47:06.000000000 +0200
-+++ cyrus-imapd-2.3.13/imap/imapd.c 2009-01-13 11:14:09.000000000 +0100
-@@ -209,6 +209,7 @@
- void motd_file(int fd);
- void shut_down(int code);
- void fatal(const char *s, int code);
-+void autocreate_inbox(void);
-
- void cmdloop(void);
- void cmd_login(char *tag, char *user);
-@@ -1975,6 +1976,43 @@
- }
-
- /*
-+ * Autocreate Inbox and subfolders upon login
-+ */
-+void autocreate_inbox()
-+{
-+ char inboxname[MAX_MAILBOX_NAME+1];
-+ int autocreatequota;
-+ int r;
-+
+ /*
-+ * Exlude admin's accounts
++ * Check if shared folders are available for subscription.
+ */
-+ if (imapd_userisadmin || imapd_userisproxyadmin)
-+ return;
-+
++ mboxlist_autosubscribe_sharedfolders(namespace, userid, auth_userid, auth_state);
++
++#ifdef USE_SIEVE
+ /*
-+ * Exclude anonymous
++ * Here the autocreate sieve script feature is iniated from.
+ */
-+ if (!strcmp(imapd_userid, "anonymous"))
-+ return;
-+
-+ if ((autocreatequota = config_getint(IMAPOPT_AUTOCREATEQUOTA))) {
-+ /* This is actyally not required
-+ as long as the lenght of userid is ok */
-+ r = (*imapd_namespace.mboxname_tointernal) (&imapd_namespace,
-+ "INBOX", imapd_userid, inboxname);
-+ if (!r)
-+ r = mboxlist_lookup(inboxname, NULL, NULL);
++ source_script = config_getstring(IMAPOPT_AUTOCREATE_SIEVE_SCRIPT);
+
-+ if (r == IMAP_MAILBOX_NONEXISTENT) {
-+ mboxlist_autocreateinbox(&imapd_namespace, imapd_userid,
-+ imapd_authstate, inboxname, autocreatequota);
-+ }
-+ }
-+}
-+
-+
-+/*
- * Perform a LOGIN command
- */
- void cmd_login(char *tag, char *user)
-@@ -2151,6 +2189,9 @@
- strcspn(imapd_userid, "@") : 0);
-
- freebuf(&passwdbuf);
++ if (source_script) {
++ if (!autoadd_sieve(userid, source_script))
++ syslog(LOG_NOTICE, "autocreate_sieve: User %s, default sieve script creation succeeded", auth_userid);
++ else
++ syslog(LOG_WARNING, "autocreate_sieve: User %s, default sieve script creation failed", auth_userid);
++ }
++#endif
+
-+ autocreate_inbox();
++ return r;
++}
+
- return;
- }
-
-@@ -2308,6 +2349,8 @@
- config_virtdomains ?
- strcspn(imapd_userid, "@") : 0);
+diff -up cyrus-imapd-2.3.15/imap/mboxlist.h.autocreate cyrus-imapd-2.3.15/imap/mboxlist.h
+--- cyrus-imapd-2.3.15/imap/mboxlist.h.autocreate 2009-05-05 03:20:03.000000000 +0200
++++ cyrus-imapd-2.3.15/imap/mboxlist.h 2009-09-18 11:11:39.778115814 +0200
+@@ -216,4 +216,8 @@ int mboxlist_commit(struct txn *tid);
+ int mboxlist_abort(struct txn *tid);
-+ autocreate_inbox();
+ int mboxlist_delayed_delete_isenabled(void);
++int mboxlist_autocreateinbox(struct namespace *namespace,char *userid,
++ struct auth_state *auth_state, char *mailboxname,
++ int autocreatequota);
+
- return;
- }
-
---- cyrus-imapd-2.3.13/imap/pop3d.c.autocreate 2008-04-22 15:11:18.000000000 +0200
-+++ cyrus-imapd-2.3.13/imap/pop3d.c 2009-01-13 11:14:09.000000000 +0100
-@@ -172,6 +172,8 @@
+ #endif
+diff -up cyrus-imapd-2.3.15/imap/pop3d.c.autocreate cyrus-imapd-2.3.15/imap/pop3d.c
+--- cyrus-imapd-2.3.15/imap/pop3d.c.autocreate 2009-04-23 19:10:07.000000000 +0200
++++ cyrus-imapd-2.3.15/imap/pop3d.c 2009-09-18 11:11:39.784115791 +0200
+@@ -173,6 +173,8 @@ static void bitpipe(void);
static char popd_apop_chal[45 + MAXHOSTNAMELEN + 1]; /* */
static void cmd_apop(char *response);
@@ -1866,7 +1854,7 @@
static void cmd_auth(char *arg);
static void cmd_capa(void);
static void cmd_pass(char *pass);
-@@ -1245,6 +1247,7 @@
+@@ -1246,6 +1248,7 @@ void cmd_user(char *user)
popd_userid = xstrdup(userbuf);
prot_printf(popd_out, "+OK Name is a valid mailbox\r\n");
}
@@ -1874,7 +1862,7 @@
}
void cmd_pass(char *pass)
-@@ -1548,6 +1551,43 @@
+@@ -1549,6 +1552,43 @@ void cmd_auth(char *arg)
}
/*
@@ -1918,7 +1906,7 @@
* Complete the login process by opening and locking the user's inbox
*/
int openinbox(void)
-@@ -1576,6 +1616,12 @@
+@@ -1577,6 +1617,12 @@ int openinbox(void)
if (!r) r = mboxlist_detail(inboxname, &type, NULL, NULL,
&server, &acl, NULL);
@@ -1931,21 +1919,6 @@
if (!r && (config_popuseacl = config_getswitch(IMAPOPT_POPUSEACL)) &&
(!acl ||
!((myrights = cyrus_acl_myrights(popd_authstate, acl)) & ACL_READ))) {
---- cyrus-imapd-2.3.13/ptclient/Makefile.in.autocreate 2008-03-24 19:34:22.000000000 +0100
-+++ cyrus-imapd-2.3.13/ptclient/Makefile.in 2009-01-13 11:14:09.000000000 +0100
-@@ -57,10 +57,11 @@
- AFS_LDFLAGS = @AFS_LDFLAGS@ @COM_ERR_LDFLAGS@
- AFS_LIBS = @AFS_LIBS@
- IMAP_LIBS = @IMAP_LIBS@ @LIB_RT@
-+SIEVE_LIBS = @SIEVE_LIBS@
- LIBS = $(IMAP_LIBS) @COM_ERR_LIBS@
- LIB_SASL = @LIB_SASL@
- LIB_WRAP = @LIB_WRAP@
--DEPLIBS = ../imap/libimap.a ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@
-+DEPLIBS = ../imap/libimap.a $(SIEVE_LIBS) ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@
- UTIL_LIBS = ../imap/mutex_fake.o ../imap/cli_fatal.o
-
- LDAP_LIBS=@LDAP_LIBS@
--- cyrus-imapd-2.3.13/README.autocreate.autocreate 2009-01-13 11:14:09.000000000 +0100
+++ cyrus-imapd-2.3.13/README.autocreate 2009-01-13 11:14:09.000000000 +0100
@@ -0,0 +1,211 @@
@@ -2160,9 +2133,10 @@
+
+For more information and updates please visit http://email.uoa.gr/projects/cyrus/autocreate
+
---- cyrus-imapd-2.3.13/lib/auth.c.autocreate 2008-03-24 18:43:08.000000000 +0100
-+++ cyrus-imapd-2.3.13/lib/auth.c 2009-01-13 11:14:09.000000000 +0100
-@@ -118,3 +118,11 @@
+diff -up cyrus-imapd-2.3.15/lib/auth.c.autocreate cyrus-imapd-2.3.15/lib/auth.c
+--- cyrus-imapd-2.3.15/lib/auth.c.autocreate 2008-03-24 18:43:08.000000000 +0100
++++ cyrus-imapd-2.3.15/lib/auth.c 2009-09-18 11:11:39.785115812 +0200
+@@ -118,3 +118,11 @@ struct auth_state *auth_state;
auth->freestate(auth_state);
}
@@ -2174,9 +2148,65 @@
+ return auth->auth_canonuser(auth_state);
+}
+
---- cyrus-imapd-2.3.13/lib/auth_krb.c.autocreate 2008-03-24 18:43:08.000000000 +0100
-+++ cyrus-imapd-2.3.13/lib/auth_krb.c 2009-01-13 11:14:09.000000000 +0100
-@@ -340,6 +340,15 @@
+diff -up cyrus-imapd-2.3.15/lib/auth.h.autocreate cyrus-imapd-2.3.15/lib/auth.h
+--- cyrus-imapd-2.3.15/lib/auth.h.autocreate 2008-03-24 18:43:08.000000000 +0100
++++ cyrus-imapd-2.3.15/lib/auth.h 2009-09-18 11:11:39.786115963 +0200
+@@ -55,6 +55,7 @@ struct auth_mech {
+ const char *identifier);
+ struct auth_state *(*newstate)(const char *identifier);
+ void (*freestate)(struct auth_state *auth_state);
++ char *(*auth_canonuser)(struct auth_state *auth_state);
+ };
+
+ extern struct auth_mech *auth_mechs[];
+@@ -77,5 +78,6 @@ int auth_memberof(struct auth_state *aut
+ const char *identifier);
+ struct auth_state *auth_newstate(const char *identifier);
+ void auth_freestate(struct auth_state *auth_state);
++char *auth_canonuser(struct auth_state *auth_state);
+
+ #endif /* INCLUDED_AUTH_H */
+diff -up cyrus-imapd-2.3.15/lib/auth_krb5.c.autocreate cyrus-imapd-2.3.15/lib/auth_krb5.c
+--- cyrus-imapd-2.3.15/lib/auth_krb5.c.autocreate 2008-03-24 18:43:08.000000000 +0100
++++ cyrus-imapd-2.3.15/lib/auth_krb5.c 2009-09-18 11:11:39.786115963 +0200
+@@ -199,6 +199,14 @@ static void myfreestate(struct auth_stat
+ free(auth_state);
+ }
+
++static char *mycanonuser(struct auth_state *auth_state)
++{
++ if (auth_state)
++ return auth_state->userid;
++
++ return NULL;
++}
++
+ #else /* HAVE_GSSAPI_H */
+
+ static int mymemberof(
+@@ -230,6 +238,12 @@ static void myfreestate(
+ fatal("Authentication mechanism (krb5) not compiled in", EC_CONFIG);
+ }
+
++static char *mycanonuser(
++ struct auth_state *auth_state __attribute__((unused)))
++{
++ fatal("Authentication mechanism (krb5) not compiled in", EC_CONFIG);
++}
++
+ #endif
+
+ struct auth_mech auth_krb5 =
+@@ -240,4 +254,5 @@ struct auth_mech auth_krb5 =
+ &mymemberof,
+ &mynewstate,
+ &myfreestate,
++ &mycanonuser,
+ };
+diff -up cyrus-imapd-2.3.15/lib/auth_krb.c.autocreate cyrus-imapd-2.3.15/lib/auth_krb.c
+--- cyrus-imapd-2.3.15/lib/auth_krb.c.autocreate 2009-03-31 06:11:21.000000000 +0200
++++ cyrus-imapd-2.3.15/lib/auth_krb.c 2009-09-18 11:11:39.785115812 +0200
+@@ -341,6 +341,15 @@ struct auth_state *auth_state;
free((char *)auth_state);
}
@@ -2192,7 +2222,7 @@
#else /* HAVE_KRB */
static int mymemberof(
-@@ -371,6 +380,13 @@
+@@ -372,6 +381,13 @@ static void myfreestate(
fatal("Authentication mechanism (krb) not compiled in", EC_CONFIG);
}
@@ -2206,15 +2236,16 @@
#endif
struct auth_mech auth_krb =
-@@ -381,4 +397,5 @@
+@@ -382,4 +398,5 @@ struct auth_mech auth_krb =
&mymemberof,
&mynewstate,
&myfreestate,
+ &mycanonuser,
};
---- cyrus-imapd-2.3.13/lib/auth_pts.c.autocreate 2008-03-24 18:43:08.000000000 +0100
-+++ cyrus-imapd-2.3.13/lib/auth_pts.c 2009-01-13 11:14:09.000000000 +0100
-@@ -512,6 +512,14 @@
+diff -up cyrus-imapd-2.3.15/lib/auth_pts.c.autocreate cyrus-imapd-2.3.15/lib/auth_pts.c
+--- cyrus-imapd-2.3.15/lib/auth_pts.c.autocreate 2008-03-24 18:43:08.000000000 +0100
++++ cyrus-imapd-2.3.15/lib/auth_pts.c 2009-09-18 11:11:39.785115812 +0200
+@@ -512,6 +512,14 @@ static void myfreestate(struct auth_stat
free(auth_state);
}
@@ -2229,68 +2260,42 @@
struct auth_mech auth_pts =
{
"pts", /* name */
-@@ -520,4 +528,5 @@
+@@ -520,4 +528,5 @@ struct auth_mech auth_pts =
&mymemberof,
&mynewstate,
&myfreestate,
+ &mycanonuser,
};
---- cyrus-imapd-2.3.13/lib/auth.h.autocreate 2008-03-24 18:43:08.000000000 +0100
-+++ cyrus-imapd-2.3.13/lib/auth.h 2009-01-13 11:14:09.000000000 +0100
-@@ -55,6 +55,7 @@
- const char *identifier);
- struct auth_state *(*newstate)(const char *identifier);
- void (*freestate)(struct auth_state *auth_state);
-+ char *(*auth_canonuser)(struct auth_state *auth_state);
- };
-
- extern struct auth_mech *auth_mechs[];
-@@ -77,5 +78,6 @@
- const char *identifier);
- struct auth_state *auth_newstate(const char *identifier);
- void auth_freestate(struct auth_state *auth_state);
-+char *auth_canonuser(struct auth_state *auth_state);
-
- #endif /* INCLUDED_AUTH_H */
---- cyrus-imapd-2.3.13/lib/auth_krb5.c.autocreate 2008-03-24 18:43:08.000000000 +0100
-+++ cyrus-imapd-2.3.13/lib/auth_krb5.c 2009-01-13 11:14:09.000000000 +0100
-@@ -199,6 +199,14 @@
- free(auth_state);
+diff -up cyrus-imapd-2.3.15/lib/auth_unix.c.autocreate cyrus-imapd-2.3.15/lib/auth_unix.c
+--- cyrus-imapd-2.3.15/lib/auth_unix.c.autocreate 2009-03-31 06:11:22.000000000 +0200
++++ cyrus-imapd-2.3.15/lib/auth_unix.c 2009-09-18 11:11:39.787115798 +0200
+@@ -315,6 +315,16 @@ struct auth_state *auth_state;
+ free((char *)auth_state);
}
-+static char *mycanonuser(struct auth_state *auth_state)
++static char *mycanonuser(auth_state)
++ struct auth_state *auth_state;
+{
+ if (auth_state)
-+ return auth_state->userid;
++ return auth_state->userid;
+
+ return NULL;
+}
+
- #else /* HAVE_GSSAPI_H */
-
- static int mymemberof(
-@@ -230,6 +238,12 @@
- fatal("Authentication mechanism (krb5) not compiled in", EC_CONFIG);
- }
-
-+static char *mycanonuser(
-+ struct auth_state *auth_state __attribute__((unused)))
-+{
-+ fatal("Authentication mechanism (krb5) not compiled in", EC_CONFIG);
-+}
+
- #endif
- struct auth_mech auth_krb5 =
-@@ -240,4 +254,5 @@
+ struct auth_mech auth_unix =
+ {
+@@ -324,4 +334,5 @@ struct auth_mech auth_unix =
&mymemberof,
&mynewstate,
&myfreestate,
+ &mycanonuser,
};
---- cyrus-imapd-2.3.13/lib/imapoptions.autocreate 2008-10-08 19:18:12.000000000 +0200
-+++ cyrus-imapd-2.3.13/lib/imapoptions 2009-01-13 11:14:09.000000000 +0100
-@@ -198,6 +198,55 @@
+diff -up cyrus-imapd-2.3.15/lib/imapoptions.autocreate cyrus-imapd-2.3.15/lib/imapoptions
+--- cyrus-imapd-2.3.15/lib/imapoptions.autocreate 2009-06-29 19:21:06.000000000 +0200
++++ cyrus-imapd-2.3.15/lib/imapoptions 2009-09-18 11:11:39.787115798 +0200
+@@ -198,6 +198,55 @@ are listed with ``''.
/* Number of seconds to wait before returning a timeout failure when
performing a client connection (e.g., in a murder environment) */
@@ -2346,28 +2351,47 @@
{ "configdirectory", NULL, STRING }
/* The pathname of the IMAP configuration directory. This field is
required. */
---- cyrus-imapd-2.3.13/lib/auth_unix.c.autocreate 2008-08-26 21:20:39.000000000 +0200
-+++ cyrus-imapd-2.3.13/lib/auth_unix.c 2009-01-13 11:14:09.000000000 +0100
-@@ -314,6 +314,16 @@
- free((char *)auth_state);
- }
+diff -up cyrus-imapd-2.3.15/notifyd/Makefile.in.autocreate cyrus-imapd-2.3.15/notifyd/Makefile.in
+--- cyrus-imapd-2.3.15/notifyd/Makefile.in.autocreate 2008-03-24 20:59:32.000000000 +0100
++++ cyrus-imapd-2.3.15/notifyd/Makefile.in 2009-09-18 11:11:39.776115765 +0200
+@@ -71,10 +71,11 @@ NOTIFYD_LIBS = @NOTIFYD_LIBS@
+ SERVICE=../master/service.o
-+static char *mycanonuser(auth_state)
-+ struct auth_state *auth_state;
-+{
-+ if (auth_state)
-+ return auth_state->userid;
-+
-+ return NULL;
-+}
-+
-+
+ IMAP_LIBS = @IMAP_LIBS@ @LIB_RT@
++SIEVE_LIBS = @SIEVE_LIBS@
+ IMAP_COM_ERR_LIBS = @IMAP_COM_ERR_LIBS@
+ LIB_WRAP = @LIB_WRAP@
+ LIBS = @ZEPHYR_LIBS@ @LIBS@ $(IMAP_COM_ERR_LIBS)
+-DEPLIBS=../imap/mutex_fake.o ../imap/libimap.a ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@
++DEPLIBS=../imap/mutex_fake.o ../imap/libimap.a $(SIEVE_LIBS) ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@
- struct auth_mech auth_unix =
+ PURIFY=/usr/local/bin/purify
+ PUREOPT=-best-effort
+diff -up cyrus-imapd-2.3.15/notifyd/notifyd.c.autocreate cyrus-imapd-2.3.15/notifyd/notifyd.c
+--- cyrus-imapd-2.3.15/notifyd/notifyd.c.autocreate 2008-03-24 20:59:32.000000000 +0100
++++ cyrus-imapd-2.3.15/notifyd/notifyd.c 2009-09-18 11:11:39.776115765 +0200
+@@ -96,7 +96,7 @@ char *fetch_arg(char *head, char* tail)
+
+ #define NOTIFY_MAXSIZE 8192
+
+-int do_notify()
++static int do_notify()
{
-@@ -323,4 +333,5 @@
- &mymemberof,
- &mynewstate,
- &myfreestate,
-+ &mycanonuser,
- };
+ struct sockaddr_un sun_data;
+ socklen_t sunlen = sizeof(sun_data);
+diff -up cyrus-imapd-2.3.15/ptclient/Makefile.in.autocreate cyrus-imapd-2.3.15/ptclient/Makefile.in
+--- cyrus-imapd-2.3.15/ptclient/Makefile.in.autocreate 2008-03-24 19:34:22.000000000 +0100
++++ cyrus-imapd-2.3.15/ptclient/Makefile.in 2009-09-18 11:11:39.784115791 +0200
+@@ -57,10 +57,11 @@ CPPFLAGS = -I.. -I$(srcdir)/../imap -I$(
+ AFS_LDFLAGS = @AFS_LDFLAGS@ @COM_ERR_LDFLAGS@
+ AFS_LIBS = @AFS_LIBS@
+ IMAP_LIBS = @IMAP_LIBS@ @LIB_RT@
++SIEVE_LIBS = @SIEVE_LIBS@
+ LIBS = $(IMAP_LIBS) @COM_ERR_LIBS@
+ LIB_SASL = @LIB_SASL@
+ LIB_WRAP = @LIB_WRAP@
+-DEPLIBS = ../imap/libimap.a ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@
++DEPLIBS = ../imap/libimap.a $(SIEVE_LIBS) ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@
+ UTIL_LIBS = ../imap/mutex_fake.o ../imap/cli_fatal.o
+
+ LDAP_LIBS=@LDAP_LIBS@
diff --git a/cyrus-imapd-2.3.13-bufov.patch b/cyrus-imapd-2.3.13-bufov.patch
index a223fe4..d2a2a1d 100644
--- a/cyrus-imapd-2.3.13-bufov.patch
+++ b/cyrus-imapd-2.3.13-bufov.patch
@@ -1,80 +1,57 @@
---- src/sieve/script.c 2008/03/24 20:08:46 1.67
-+++ src/sieve/script.c 2009/09/02 13:56:18 1.68
-@@ -40,7 +40,7 @@
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
-- * $Id: script.c,v 1.67 2008/03/24 20:08:46 murch Exp $
-+ * $Id: script.c,v 1.68 2009/09/02 13:56:18 brong Exp $
- */
-
- #ifdef HAVE_CONFIG_H
-@@ -688,7 +688,7 @@ static int do_sieve_error(int ret,
- ret |= keep_ret;
- if (keep_ret == SIEVE_OK)
- snprintf(actions_string+strlen(actions_string),
-- sizeof(actions_string)-strlen(actions_string),
-+ ACTIONS_STRING_LEN-strlen(actions_string),
- "Kept\n");
- else {
- implicit_keep = 0; /* don't try an implicit keep again */
-@@ -742,7 +742,7 @@ static int do_action_list(sieve_interp_t
-
- if (ret == SIEVE_OK)
- snprintf(actions_string+strlen(actions_string),
-- sizeof(actions_string)-strlen(actions_string),
-+ ACTIONS_STRING_LEN-strlen(actions_string),
- "Rejected with: %s\n", a->u.rej.msg);
-
- break;
-@@ -757,7 +757,7 @@ static int do_action_list(sieve_interp_t
-
- if (ret == SIEVE_OK)
- snprintf(actions_string+strlen(actions_string),
-- sizeof(actions_string)-strlen(actions_string),
-+ ACTIONS_STRING_LEN-strlen(actions_string),
- "Filed into: %s\n",a->u.fil.mailbox);
- break;
- case ACTION_KEEP:
-@@ -770,7 +770,7 @@ static int do_action_list(sieve_interp_t
- &errmsg);
- if (ret == SIEVE_OK)
- snprintf(actions_string+strlen(actions_string),
-- sizeof(actions_string)-strlen(actions_string),
-+ ACTIONS_STRING_LEN-strlen(actions_string),
- "Kept\n");
- break;
- case ACTION_REDIRECT:
-@@ -783,7 +783,7 @@ static int do_action_list(sieve_interp_t
- &errmsg);
- if (ret == SIEVE_OK)
- snprintf(actions_string+strlen(actions_string),
-- sizeof(actions_string)-strlen(actions_string),
-+ ACTIONS_STRING_LEN-strlen(actions_string),
- "Redirected to %s\n", a->u.red.addr);
- break;
- case ACTION_DISCARD:
-@@ -794,7 +794,7 @@ static int do_action_list(sieve_interp_t
- &errmsg);
- if (ret == SIEVE_OK)
- snprintf(actions_string+strlen(actions_string),
-- sizeof(actions_string)-strlen(actions_string),
-+ ACTIONS_STRING_LEN-strlen(actions_string),
- "Discarded\n");
- break;
-
-@@ -820,12 +820,12 @@ static int do_action_list(sieve_interp_t
-
- if (ret == SIEVE_OK)
- snprintf(actions_string+strlen(actions_string),
-- sizeof(actions_string)-strlen(actions_string),
-+ ACTIONS_STRING_LEN-strlen(actions_string),
- "Sent vacation reply\n");
-
- } else if (ret == SIEVE_DONE) {
- snprintf(actions_string+strlen(actions_string),
-- sizeof(actions_string)-strlen(actions_string),
-+ ACTIONS_STRING_LEN-strlen(actions_string),
- "Vacation reply suppressed\n");
-
- ret = SIEVE_OK;
+diff -up cyrus-imapd-2.3.15/sieve/bc_eval.c.bufov cyrus-imapd-2.3.15/sieve/bc_eval.c
+--- cyrus-imapd-2.3.15/sieve/bc_eval.c.bufov 2009-03-31 06:11:30.000000000 +0200
++++ cyrus-imapd-2.3.15/sieve/bc_eval.c 2009-09-18 15:05:29.187990786 +0200
+@@ -500,7 +500,7 @@ static int eval_bc_test(sieve_interp_t *
+ int comparator=ntohl(bc[i+3].value);
+ int apart=ntohl(bc[i+4].value);
+ int count=0;
+- char scount[3];
++ char scount[21];
+ int isReg = (match==B_REGEX);
+ int ctag = 0;
+ regex_t *reg;
+@@ -669,7 +669,7 @@ static int eval_bc_test(sieve_interp_t *
+ int relation=ntohl(bc[i+2].value);
+ int comparator=ntohl(bc[i+3].value);
+ int count=0;
+- char scount[3];
++ char scount[21];
+ int isReg = (match==B_REGEX);
+ int ctag = 0;
+ regex_t *reg;
+@@ -790,7 +790,7 @@ static int eval_bc_test(sieve_interp_t *
+ int transform=ntohl(bc[i+4].value);
+ /* ntohl(bc[i+5].value) is the now unused 'offset' */
+ int count=0;
+- char scount[3];
++ char scount[21];
+ int isReg = (match==B_REGEX);
+ int ctag = 0;
+ regex_t *reg;
+diff -up cyrus-imapd-2.3.15/sieve/script.c.bufov cyrus-imapd-2.3.15/sieve/script.c
+--- cyrus-imapd-2.3.15/sieve/script.c.bufov 2009-09-02 15:56:18.000000000 +0200
++++ cyrus-imapd-2.3.15/sieve/script.c 2009-09-18 15:04:00.728927938 +0200
+@@ -668,9 +668,9 @@ static int do_sieve_error(int ret,
+ if ((ret != SIEVE_OK) && interp->err) {
+ char buf[1024];
+ if (lastaction == -1) /* we never executed an action */
+- sprintf(buf, "%s", errmsg ? errmsg : sieve_errstr(ret));
++ snprintf(buf, sizeof(buf), "%s", errmsg ? errmsg : sieve_errstr(ret));
+ else
+- sprintf(buf, "%s: %s", action_to_string(lastaction),
++ snprintf(buf, sizeof(buf), "%s: %s", action_to_string(lastaction),
+ errmsg ? errmsg : sieve_errstr(ret));
+
+ ret |= interp->execute_err(buf, interp->interp_context,
+diff -up cyrus-imapd-2.3.15/sieve/sieve.y.bufov cyrus-imapd-2.3.15/sieve/sieve.y
+--- cyrus-imapd-2.3.15/sieve/sieve.y.bufov 2009-03-26 00:58:54.000000000 +0100
++++ cyrus-imapd-2.3.15/sieve/sieve.y 2009-09-18 15:04:00.734928038 +0200
+@@ -1159,7 +1159,7 @@ static int verify_relat(char *r)
+ else if (!strcmp(r, "ne")) {return NE;}
+ else if (!strcmp(r, "eq")) {return EQ;}
+ else{
+- sprintf(errbuf, "flag '%s': not a valid relational operation", r);
++ snprintf(errbuf, sizeof(errbuf), "flag '%s': not a valid relational operation", r);
+ yyerror(errbuf);
+ return -1;
+ }
diff --git a/cyrus-imapd-2.3.7-notify_sms.patch b/cyrus-imapd-2.3.7-notify_sms.patch
index ec7d6e6..08b7e5d 100644
--- a/cyrus-imapd-2.3.7-notify_sms.patch
+++ b/cyrus-imapd-2.3.7-notify_sms.patch
@@ -1,7 +1,7 @@
-diff -Naur cyrus-imapd-2.3.7.orig/doc/man/imapd.conf.5.html cyrus-imapd-2.3.7/doc/man/imapd.conf.5.html
---- cyrus-imapd-2.3.7.orig/doc/man/imapd.conf.5.html 2006-07-10 16:31:53.000000000 +0200
-+++ cyrus-imapd-2.3.7/doc/man/imapd.conf.5.html 2006-07-14 10:27:29.000000000 +0200
-@@ -3130,6 +3130,24 @@
+diff -up cyrus-imapd-2.3.15/doc/man/imapd.conf.5.html.notify_sms cyrus-imapd-2.3.15/doc/man/imapd.conf.5.html
+--- cyrus-imapd-2.3.15/doc/man/imapd.conf.5.html.notify_sms 2009-09-09 15:19:50.000000000 +0200
++++ cyrus-imapd-2.3.15/doc/man/imapd.conf.5.html 2009-09-18 11:49:42.207115959 +0200
+@@ -3469,6 +3469,24 @@ proxying CREATE.
|
@@ -26,10 +26,10 @@ diff -Naur cyrus-imapd-2.3.7.orig/doc/man/imapd.conf.5.html cyrus-imapd-2.3.7/do
servername: <none> |
-diff -Naur cyrus-imapd-2.3.7.orig/doc/man/notifyd.8.html cyrus-imapd-2.3.7/doc/man/notifyd.8.html
---- cyrus-imapd-2.3.7.orig/doc/man/notifyd.8.html 2006-07-10 16:31:54.000000000 +0200
-+++ cyrus-imapd-2.3.7/doc/man/notifyd.8.html 2006-07-14 10:27:29.000000000 +0200
-@@ -181,6 +181,18 @@
+diff -up cyrus-imapd-2.3.15/doc/man/notifyd.8.html.notify_sms cyrus-imapd-2.3.15/doc/man/notifyd.8.html
+--- cyrus-imapd-2.3.15/doc/man/notifyd.8.html.notify_sms 2009-09-09 15:19:51.000000000 +0200
++++ cyrus-imapd-2.3.15/doc/man/notifyd.8.html 2009-09-18 11:49:42.208116026 +0200
+@@ -181,6 +181,18 @@ a Sieve ’notify’ action as i
|
@@ -48,10 +48,10 @@ diff -Naur cyrus-imapd-2.3.7.orig/doc/man/notifyd.8.html cyrus-imapd-2.3.7/doc/m
zephyr
|
-diff -Naur cyrus-imapd-2.3.7.orig/lib/imapoptions cyrus-imapd-2.3.7/lib/imapoptions
---- cyrus-imapd-2.3.7.orig/lib/imapoptions 2006-06-27 17:58:42.000000000 +0200
-+++ cyrus-imapd-2.3.7/lib/imapoptions 2006-07-14 10:27:29.000000000 +0200
-@@ -829,6 +829,10 @@
+diff -up cyrus-imapd-2.3.15/lib/imapoptions.notify_sms cyrus-imapd-2.3.15/lib/imapoptions
+--- cyrus-imapd-2.3.15/lib/imapoptions.notify_sms 2009-09-18 11:49:42.189116010 +0200
++++ cyrus-imapd-2.3.15/lib/imapoptions 2009-09-18 11:50:38.230115954 +0200
+@@ -966,6 +966,10 @@ are listed with ``''.
/* The pathname of the sendmail executable. Sieve invokes sendmail
for sending rejections, redirects and vacation responses. */
@@ -59,26 +59,26 @@ diff -Naur cyrus-imapd-2.3.7.orig/lib/imapoptions cyrus-imapd-2.3.7/lib/imapopti
+/* The pathname of the sendsms executable. Sieve invokes sendsms
+ for sending SMS notifications. */
+
- { "servername", NULL, STRING }
- /* This is the hostname visible in the greeting messages of the POP,
- IMAP and LMTP daemons. If it is unset, then the result returned
-diff -Naur cyrus-imapd-2.3.7.orig/man/imapd.conf.5 cyrus-imapd-2.3.7/man/imapd.conf.5
---- cyrus-imapd-2.3.7.orig/man/imapd.conf.5 2006-07-10 16:31:52.000000000 +0200
-+++ cyrus-imapd-2.3.7/man/imapd.conf.5 2006-07-14 10:27:29.000000000 +0200
-@@ -691,6 +691,9 @@
+ { "serverlist", NULL, STRING }
+ /* Whitespace separated list of backend server names. Used for
+ finding server with the most available free space for proxying
+diff -up cyrus-imapd-2.3.15/man/imapd.conf.5.notify_sms cyrus-imapd-2.3.15/man/imapd.conf.5
+--- cyrus-imapd-2.3.15/man/imapd.conf.5.notify_sms 2009-09-09 15:19:48.000000000 +0200
++++ cyrus-imapd-2.3.15/man/imapd.conf.5 2009-09-18 11:51:26.441839866 +0200
+@@ -771,6 +771,9 @@ Allowed values: \fIflat\fR, \fIberkeley\
.IP "\fBsendmail:\fR /usr/lib/sendmail" 5
The pathname of the sendmail executable. Sieve invokes sendmail
for sending rejections, redirects and vacation responses.
+.IP "\fBsendsms:\fR /usr/bin/sendsms" 5
+The pathname of the sendsms executable. Sieve invokes sendsms
+for sending SMS notifications.
- .IP "\fBservername:\fR " 5
- This is the hostname visible in the greeting messages of the POP,
- IMAP and LMTP daemons. If it is unset, then the result returned
-diff -Naur cyrus-imapd-2.3.7.orig/man/notifyd.8 cyrus-imapd-2.3.7/man/notifyd.8
---- cyrus-imapd-2.3.7.orig/man/notifyd.8 2003-08-10 01:43:14.000000000 +0200
-+++ cyrus-imapd-2.3.7/man/notifyd.8 2006-07-14 10:27:29.000000000 +0200
-@@ -110,6 +110,11 @@
+ .IP "\fBserverlist:\fR " 5
+ Whitespace separated list of backend server names. Used for
+ finding server with the most available free space for proxying
+diff -up cyrus-imapd-2.3.15/man/notifyd.8.notify_sms cyrus-imapd-2.3.15/man/notifyd.8
+--- cyrus-imapd-2.3.15/man/notifyd.8.notify_sms 2008-04-04 14:47:00.000000000 +0200
++++ cyrus-imapd-2.3.15/man/notifyd.8 2009-09-18 11:49:42.225115999 +0200
+@@ -111,6 +111,11 @@ Email the notification. This method can
Sieve 'notify' action as it requires a \fImailto:\fR URL to be
specified as an \fI:option\fR.
.TP
@@ -90,10 +90,10 @@ diff -Naur cyrus-imapd-2.3.7.orig/man/notifyd.8 cyrus-imapd-2.3.7/man/notifyd.8
.B zephyr
Send the notification as a zephyrgram. If used in a Sieve 'notify'
action, additional recipients can be specified as \fI:options\fR.
-diff -Naur cyrus-imapd-2.3.7.orig/notifyd/Makefile.in cyrus-imapd-2.3.7/notifyd/Makefile.in
---- cyrus-imapd-2.3.7.orig/notifyd/Makefile.in 2004-05-31 20:22:59.000000000 +0200
-+++ cyrus-imapd-2.3.7/notifyd/Makefile.in 2006-07-14 10:27:29.000000000 +0200
-@@ -82,7 +82,7 @@
+diff -up cyrus-imapd-2.3.15/notifyd/Makefile.in.notify_sms cyrus-imapd-2.3.15/notifyd/Makefile.in
+--- cyrus-imapd-2.3.15/notifyd/Makefile.in.notify_sms 2009-09-18 11:49:42.172115947 +0200
++++ cyrus-imapd-2.3.15/notifyd/Makefile.in 2009-09-18 11:49:42.225115999 +0200
+@@ -85,7 +85,7 @@ all: notifyd
install:
$(INSTALL) -m 755 notifyd $(DESTDIR)$(service_path)
@@ -102,10 +102,10 @@ diff -Naur cyrus-imapd-2.3.7.orig/notifyd/Makefile.in cyrus-imapd-2.3.7/notifyd/
notifytest: notifytest.o
$(CC) $(LDFLAGS) -o notifytest \
-diff -Naur cyrus-imapd-2.3.7.orig/notifyd/notifyd.h cyrus-imapd-2.3.7/notifyd/notifyd.h
---- cyrus-imapd-2.3.7.orig/notifyd/notifyd.h 2003-02-13 21:15:48.000000000 +0100
-+++ cyrus-imapd-2.3.7/notifyd/notifyd.h 2006-07-14 10:27:29.000000000 +0200
-@@ -48,6 +48,7 @@
+diff -up cyrus-imapd-2.3.15/notifyd/notifyd.h.notify_sms cyrus-imapd-2.3.15/notifyd/notifyd.h
+--- cyrus-imapd-2.3.15/notifyd/notifyd.h.notify_sms 2008-03-24 20:59:32.000000000 +0100
++++ cyrus-imapd-2.3.15/notifyd/notifyd.h 2009-09-18 11:49:42.233116003 +0200
+@@ -47,6 +47,7 @@
#include "notify_null.h"
#include "notify_log.h"
#include "notify_mailto.h"
@@ -113,7 +113,7 @@ diff -Naur cyrus-imapd-2.3.7.orig/notifyd/notifyd.h cyrus-imapd-2.3.7/notifyd/no
#include "notify_zephyr.h"
/* Notify method dispatch table definition */
-@@ -64,6 +65,7 @@
+@@ -63,6 +64,7 @@ notifymethod_t methods[] = {
{ "null", notify_null }, /* do nothing */
{ "log", notify_log }, /* use syslog (for testing) */
{ "mailto", notify_mailto }, /* send an email */
@@ -121,9 +121,9 @@ diff -Naur cyrus-imapd-2.3.7.orig/notifyd/notifyd.h cyrus-imapd-2.3.7/notifyd/no
#ifdef HAVE_ZEPHYR
{ "zephyr", notify_zephyr }, /* send a zephyrgram */
#endif
-diff -Naur cyrus-imapd-2.3.7.orig/notifyd/notify_sms.c cyrus-imapd-2.3.7/notifyd/notify_sms.c
---- cyrus-imapd-2.3.7.orig/notifyd/notify_sms.c 1970-01-01 01:00:00.000000000 +0100
-+++ cyrus-imapd-2.3.7/notifyd/notify_sms.c 2006-07-14 10:29:10.000000000 +0200
+diff -up /dev/null cyrus-imapd-2.3.15/notifyd/notify_sms.c
+--- /dev/null 2009-09-11 15:21:01.808252010 +0200
++++ cyrus-imapd-2.3.15/notifyd/notify_sms.c 2009-09-18 11:49:42.233116003 +0200
@@ -0,0 +1,116 @@
+/* notify_sms.c -- SMS notification method
+ * Simon Matter
@@ -241,9 +241,9 @@ diff -Naur cyrus-imapd-2.3.7.orig/notifyd/notify_sms.c cyrus-imapd-2.3.7/notifyd
+
+ return strdup("OK sms notification successful");
+}
-diff -Naur cyrus-imapd-2.3.7.orig/notifyd/notify_sms.h cyrus-imapd-2.3.7/notifyd/notify_sms.h
---- cyrus-imapd-2.3.7.orig/notifyd/notify_sms.h 1970-01-01 01:00:00.000000000 +0100
-+++ cyrus-imapd-2.3.7/notifyd/notify_sms.h 2006-07-14 10:29:10.000000000 +0200
+diff -up /dev/null cyrus-imapd-2.3.15/notifyd/notify_sms.h
+--- /dev/null 2009-09-11 15:21:01.808252010 +0200
++++ cyrus-imapd-2.3.15/notifyd/notify_sms.h 2009-09-18 11:49:42.233116003 +0200
@@ -0,0 +1,61 @@
+/* notify_sms.h -- SMS notification method
+ * Simon Matter
diff --git a/cyrus-imapd.spec b/cyrus-imapd.spec
index 27702cd..70c5d3e 100644
--- a/cyrus-imapd.spec
+++ b/cyrus-imapd.spec
@@ -1,6 +1,6 @@
Name: cyrus-imapd
-Version: 2.3.14
-Release: 2%{?dist}
+Version: 2.3.15
+Release: 1%{?dist}
# ********************** BUILD TIME OPTIONS START **********************
@@ -72,7 +72,6 @@ URL: http://cyrusimap.web.cmu.edu/
#Vendor: Invoca Systems
#Distribution: Invoca Linux Server
Source0: ftp://ftp.andrew.cmu.edu/pub/cyrus/%{name}-%{version}.tar.gz
-#Source2: http://ftp.gnu.org/gnu/autoconf/autoconf-%{_acversion}.tar.gz
Source3: cyrus-deliver-wrapper.c
Source4: cyrus-user-procmailrc.template
Source5: cyrus-imapd.logrotate
@@ -600,6 +599,7 @@ fi
%{_cyrexecdir}/arbitronsort.pl
%{_cyrexecdir}/chk_cyrus
%{_cyrexecdir}/convert-sieve.pl
+%{_cyrexecdir}/cyr_df
%{_cyrexecdir}/ctl_cyrusdb
%{_cyrexecdir}/ctl_deliver
%{_cyrexecdir}/ctl_mboxlist
@@ -731,6 +731,9 @@ fi
%{_mandir}/man1/*
%changelog
+* Fri Sep 18 2009 Michal Hlavinka - 2.3.15-1
+- fix another buffer overflow in cyrus sieve (CVE-2009-3235)
+
* Mon Sep 07 2009 Michal Hlavinka - 2.3.14-2
- fix buffer overflow in cyrus sieve (#521010)
diff --git a/sources b/sources
index 67ce220..4dddef4 100644
--- a/sources
+++ b/sources
@@ -1,2 +1,2 @@
-1030d4d9d04036b2fb9830165723908e cyrus-imapd-2.3.14.tar.gz
+d89cb1b55023188938f332b7ef120fae cyrus-imapd-2.3.15.tar.gz
8f7a26b0556369827bb5c8084a3e3ea1 cyrus_sharedbackup-0.1.tar.gz
|