Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

t114 dont replicate compiled sieve bytecode #13

Merged
13 changes: 7 additions & 6 deletions Makefile.am
Expand Up @@ -835,14 +835,14 @@ backup_backupd_SOURCES = \
imap/sync_support.h \
master/service.c \
backup/backupd.c
backup_backupd_LDADD = backup/libcyrus_backup.la $(LD_SERVER_ADD)
backup_backupd_LDADD = backup/libcyrus_backup.la $(LD_SIEVE_ADD) $(LD_SERVER_ADD)

backup_ctl_backups_SOURCES = \
imap/mutex_fake.c \
imap/sync_support.c \
imap/sync_support.h \
backup/ctl_backups.c
backup_ctl_backups_LDADD = backup/libcyrus_backup.la $(LD_UTILITY_ADD)
backup_ctl_backups_LDADD = backup/libcyrus_backup.la $(LD_SIEVE_ADD) $(LD_UTILITY_ADD)

backup_cyr_backup_SOURCES = \
imap/mutex_fake.c \
Expand All @@ -854,7 +854,7 @@ backup_restore_SOURCES = \
imap/sync_support.c \
imap/sync_support.h \
backup/restore.c
backup_restore_LDADD = backup/libcyrus_backup.la $(LD_UTILITY_ADD)
backup_restore_LDADD = backup/libcyrus_backup.la $(LD_SIEVE_ADD) $(LD_UTILITY_ADD)

imap_arbitron_SOURCES = imap/arbitron.c imap/cli_fatal.c imap/mutex_fake.c
imap_arbitron_LDADD = $(LD_UTILITY_ADD)
Expand Down Expand Up @@ -1288,13 +1288,13 @@ imap_squat_dump_SOURCES = imap/cli_fatal.c imap/mutex_fake.c imap/squat_dump.c
imap_squat_dump_LDADD = $(LD_UTILITY_ADD)

imap_sync_client_SOURCES = imap/mutex_fake.c imap/sync_client.c imap/sync_support.c imap/sync_support.h
imap_sync_client_LDADD = $(LD_UTILITY_ADD)
imap_sync_client_LDADD = $(LD_SIEVE_ADD) $(LD_UTILITY_ADD)

imap_sync_reset_SOURCES = imap/mutex_fake.c imap/sync_reset.c imap/sync_support.c imap/sync_support.h
imap_sync_reset_LDADD = $(LD_UTILITY_ADD)
imap_sync_reset_LDADD = $(LD_SIEVE_ADD) $(LD_UTILITY_ADD)

imap_sync_server_SOURCES = imap/mutex_fake.c imap/sync_server.c imap/sync_support.c imap/sync_support.h master/service.c
imap_sync_server_LDADD = $(LD_SERVER_ADD)
imap_sync_server_LDADD = $(LD_SIEVE_ADD) $(LD_SERVER_ADD)

imap_tls_prune_SOURCES = imap/cli_fatal.c imap/mutex_fake.c imap/tls_prune.c
imap_tls_prune_LDADD = $(LD_UTILITY_ADD)
Expand Down Expand Up @@ -1670,6 +1670,7 @@ sieve_libcyrus_sieve_la_SOURCES = \
sieve/interp.h \
sieve/message.c \
sieve/message.h \
sieve/rebuild.c \
sieve/script.c \
sieve/script.h \
sieve/sieve-lex.l \
Expand Down
3 changes: 3 additions & 0 deletions imap/imap_err.et
Expand Up @@ -77,6 +77,9 @@ ec IMAP_MAILBOX_BADFORMAT,
ec IMAP_SYNC_CHECKSUM,
"Replication inconsistency detected"

ec IMAP_SYNC_BADSIEVE,
"Sieve script compilation failure"

ec IMAP_MAILBOX_CHECKSUM,
"Mailbox format corruption detected"

Expand Down
18 changes: 18 additions & 0 deletions imap/lmtp_sieve.c
Expand Up @@ -836,9 +836,12 @@ static void _rm_dots(char *p)
if (*p == '.') *p = '^';
}
}

static int sieve_find_script(const char *user, const char *domain,
const char *script, char *fname, size_t size)
{
char *ext = NULL;

if (!user && !script) {
return -1;
}
Expand Down Expand Up @@ -876,13 +879,28 @@ static int sieve_find_script(const char *user, const char *domain,
free(usercopy);

if (!script) { /* default script */
char *bc_fname;

strlcat(fname, "defaultbc", size);

bc_fname = sieve_getdefaultbcfname(fname);
if (bc_fname) {
sieve_rebuild(NULL, bc_fname, 0, NULL);
free(bc_fname);
}

return 0;
}
}

snprintf(fname+len, size-len, "%s.bc", script);
}

/* don't do this for ~username ones */
ext = strrchr(fname, '.');
if (ext && !strcmp(ext, ".bc"))
sieve_rebuild(NULL, fname, 0, NULL);

return 0;
}

Expand Down
42 changes: 41 additions & 1 deletion imap/sync_support.c
Expand Up @@ -78,6 +78,10 @@
#include "dlist.h"
#include "xstrlcat.h"

#ifdef USE_SIEVE
#include "sieve/sieve_interface.h"
#endif

/* generated headers are not necessarily in current directory */
#include "imap/imap_err.h"

Expand Down Expand Up @@ -1005,11 +1009,18 @@ int sync_sieve_upload(const char *userid, const char *name,
const char *sieve_path = user_sieve_path(userid);
char tmpname[2048];
char newname[2048];
char *ext;
FILE *file;
int r = 0;
struct stat sbuf;
struct utimbuf utimbuf;

ext = strrchr(name, '.');
if (ext && !strcmp(ext, ".bc")) {
/* silently ignore attempts to upload compiled bytecode */
return 0;
}

if (stat(sieve_path, &sbuf) == -1 && errno == ENOENT) {
if (cyrus_mkdir(sieve_path, 0755) == -1) return IMAP_IOERROR;
if (mkdir(sieve_path, 0755) == -1 && errno != EEXIST) {
Expand All @@ -1023,7 +1034,7 @@ int sync_sieve_upload(const char *userid, const char *name,
snprintf(newname, sizeof(newname), "%s/%s", sieve_path, name);

if ((file=fopen(tmpname, "w")) == NULL) {
return(IMAP_IOERROR);
return IMAP_IOERROR;
}

/* XXX - error handling */
Expand All @@ -1043,6 +1054,14 @@ int sync_sieve_upload(const char *userid, const char *name,
if (!r && (rename(tmpname, newname) < 0))
r = IMAP_IOERROR;

#ifdef USE_SIEVE
if (!r) {
r = sieve_rebuild(newname, NULL, /*force*/ 1, NULL);
if (r == SIEVE_PARSE_ERROR || r == SIEVE_FAIL)
r = IMAP_SYNC_BADSIEVE;
}
#endif

sync_log_sieve(userid);

return r;
Expand All @@ -1058,6 +1077,15 @@ int sync_sieve_activate(const char *userid, const char *name)
snprintf(active, sizeof(active), "%s/%s", sieve_path, "defaultbc");
unlink(active);

#ifdef USE_SIEVE
char *bc_fname = strconcat(sieve_path, "/", target, NULL);
sieve_rebuild(NULL, bc_fname, 0, NULL);
free(bc_fname);
#endif

/* N.B symlink() does NOT verify target for anything but string validity,
* so activation of a nonexistent script will report success.
*/
if (symlink(target, active) < 0)
return(IMAP_IOERROR);

Expand Down Expand Up @@ -1643,6 +1671,9 @@ int sync_parse_response(const char *cmd, struct protstream *in,
else if (!strncmp(errmsg.s, "IMAP_SYNC_CHECKSUM ",
strlen("IMAP_SYNC_CHECKSUM ")))
return IMAP_SYNC_CHECKSUM;
else if (!strncmp(errmsg.s, "IMAP_SYNC_BADSIEVE ",
strlen("IMAP_SYNC_BADSIEVE ")))
return IMAP_SYNC_BADSIEVE;
else if (!strncmp(errmsg.s, "IMAP_PROTOCOL_ERROR ",
strlen("IMAP_PROTOCOL_ERROR ")))
return IMAP_PROTOCOL_ERROR;
Expand Down Expand Up @@ -3500,6 +3531,9 @@ static const char *sync_response(int r)
case IMAP_SYNC_CHECKSUM:
resp = "NO IMAP_SYNC_CHECKSUM Checksum Failure";
break;
case IMAP_SYNC_BADSIEVE:
resp = "NO IMAP_SYNC_BADSIEVE Sieve script compilation failure";
break;
case IMAP_PROTOCOL_ERROR:
resp = "NO IMAP_PROTOCOL_ERROR Protocol error";
break;
Expand Down Expand Up @@ -5592,6 +5626,7 @@ int sync_do_user_sieve(const char *userid, struct sync_sieve_list *replica_sieve
struct sync_sieve *mitem, *ritem;
int master_active = 0;
int replica_active = 0;
char *ext;

master_sieve = sync_sieve_list_generate(userid);
if (!master_sieve) {
Expand All @@ -5615,6 +5650,11 @@ int sync_do_user_sieve(const char *userid, struct sync_sieve_list *replica_sieve
continue; /* changed */
}

/* Don't upload compiled bytecode */
ext = strrchr(mitem->name, '.');
if (ext && !strcmp(ext, ".bc"))
continue;

r = sieve_upload(userid, mitem->name, mitem->last_update,
sync_be, flags);
if (r) goto bail;
Expand Down