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