X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/c61f2b4f6b4216c8bbd17f371f4b63035b2b739a..d43cbe256c751f2f2e8c9b55dd8a718967571c21:/src/src/sieve.c diff --git a/src/src/sieve.c b/src/src/sieve.c index f96db3586..7653993da 100644 --- a/src/src/sieve.c +++ b/src/src/sieve.c @@ -1,5 +1,3 @@ -/* $Cambridge: exim/src/src/sieve.c,v 1.34 2008/01/29 12:08:43 michael Exp $ */ - /************************************************* * Exim - an Internet mail transport agent * *************************************************/ @@ -71,6 +69,7 @@ struct Sieve int require_enotify; struct Notification *notified; #endif + uschar *enotify_mailto_owner; #ifdef SUBADDRESS int require_subaddress; #endif @@ -108,6 +107,38 @@ struct Notification struct Notification *next; }; +/* This should be a complete list of supported extensions, so that an external +ManageSieve (RFC 5804) program can interrogate the current Exim binary for the +list of extensions and provide correct information to a client. + +We'll emit the list in the order given here; keep it alphabetically sorted, so +that callers don't get surprised. + +List *MUST* end with a NULL. Which at least makes ifdef-vs-comma easier. */ + +const uschar *exim_sieve_extension_list[] = { + CUS"comparator-i;ascii-numeric", + CUS"copy", +#ifdef ENCODED_CHARACTER + CUS"encoded-character", +#endif +#ifdef ENOTIFY + CUS"enotify", +#endif + CUS"envelope", +#ifdef ENVELOPE_AUTH + CUS"envelope-auth", +#endif + CUS"fileinto", +#ifdef SUBADDRESS + CUS"subaddress", +#endif +#ifdef VACATION + CUS"vacation", +#endif + NULL +}; + static int eq_asciicase(const struct String *needle, const struct String *haystack, int match_prefix); static int parse_test(struct Sieve *filter, int *cond, int exec); static int parse_commands(struct Sieve *filter, int exec, address_item **generated); @@ -1041,7 +1072,7 @@ if (file) setflag(new_addr, af_pfr|af_file); new_addr->mode = 0; } -new_addr->p.errors_address = NULL; +new_addr->prop.errors_address = NULL; new_addr->next = *generated; *generated = new_addr; } @@ -2706,8 +2737,8 @@ Returns: 2 success by stop 1 other success -1 syntax or execution error */ -static int parse_commands(struct Sieve *filter, int exec, - address_item **generated) +static int +parse_commands(struct Sieve *filter, int exec, address_item **generated) { while (*filter->pc) { @@ -2939,7 +2970,6 @@ while (*filter->pc) int m; struct String from; struct String importance; - struct String *options; struct String message; struct String method; struct Notification *already; @@ -2960,7 +2990,6 @@ while (*filter->pc) from.length=-1; importance.character=(uschar*)0; importance.length=-1; - options=(struct String*)0; message.character=(uschar*)0; message.length=-1; recipient=NULL; @@ -2970,7 +2999,7 @@ while (*filter->pc) subject.character=(uschar*)0; body.length=-1; body.character=(uschar*)0; - envelope_from=(sender_address && sender_address[0]) ? expand_string("$local_part_prefix$local_part$local_part_suffix@$domain") : US ""; + envelope_from=(sender_address && sender_address[0]) ? expand_string(US"$local_part_prefix$local_part$local_part_suffix@$domain") : US ""; for (;;) { if (parse_white(filter)==-1) return -1; @@ -3037,11 +3066,11 @@ while (*filter->pc) for (already=filter->notified; already; already=already->next) { if (already->method.length==method.length - && (method.length==-1 || strcmp(already->method.character,method.character)==0) + && (method.length==-1 || Ustrcmp(already->method.character,method.character)==0) && already->importance.length==importance.length - && (importance.length==-1 || strcmp(already->importance.character,importance.character)==0) + && (importance.length==-1 || Ustrcmp(already->importance.character,importance.character)==0) && already->message.length==message.length - && (message.length==-1 || strcmp(already->message.character,message.character)==0)) + && (message.length==-1 || Ustrcmp(already->message.character,message.character)==0)) break; } if (already==(struct Notification*)0) @@ -3058,7 +3087,6 @@ while (*filter->pc) if (filter_test == FTEST_NONE) { string_item *p; - header_line *h; int pid,fd; if ((pid = child_open_exim2(&fd,envelope_from,envelope_from))>=1) @@ -3068,11 +3096,9 @@ while (*filter->pc) int buffer_capacity; f = fdopen(fd, "wb"); - for (h = header_list; h != NULL; h = h->next) - if (h->type == htype_received) fprintf(f,"%s",h->text); - fprintf(f,"From: %s\n",from.length==-1 ? expand_string("$local_part_prefix$local_part$local_part_suffix@$domain") : from.character); + fprintf(f,"From: %s\n",from.length==-1 ? expand_string(US"$local_part_prefix$local_part$local_part_suffix@$domain") : from.character); for (p=recipient; p; p=p->next) fprintf(f,"To: %s\n",p->text); - fprintf(f,"Auto-submitted: sieve-notify\n"); + fprintf(f,"Auto-Submitted: auto-notified; %s\n",filter->enotify_mailto_owner); if (header.length>0) fprintf(f,"%s",header.character); if (message.length==-1) { @@ -3334,7 +3360,8 @@ while (*filter->pc) /* Allocation is larger than neccessary, but enough even for split MIME words */ buffer_capacity=32+4*subject.length; buffer=store_get(buffer_capacity); - addr->reply->subject=parse_quote_2047(subject.character, subject.length, US"utf-8", buffer, buffer_capacity, TRUE); + /* deconst cast safe as we pass in a non-const item */ + addr->reply->subject = US parse_quote_2047(subject.character, subject.length, US"utf-8", buffer, buffer_capacity, TRUE); addr->reply->oncelog=once; addr->reply->once_repeat=days*86400; @@ -3403,8 +3430,8 @@ Returns: 1 success -1 syntax or execution error */ -static int parse_start(struct Sieve *filter, int exec, - address_item **generated) +static int +parse_start(struct Sieve *filter, int exec, address_item **generated) { filter->pc=filter->filter; filter->line=1; @@ -3493,7 +3520,15 @@ while (parse_identifier(filter,CUS "require")) else if (eq_octet(check,&str_envelope_auth,0)) filter->require_envelope_auth=1; #endif #ifdef ENOTIFY - else if (eq_octet(check,&str_enotify,0)) filter->require_enotify=1; + else if (eq_octet(check,&str_enotify,0)) + { + if (filter->enotify_mailto_owner == NULL) + { + filter->errmsg=CUS "enotify disabled"; + return -1; + } + filter->require_enotify=1; + } #endif #ifdef SUBADDRESS else if (eq_octet(check,&str_subaddress,0)) filter->require_subaddress=1; @@ -3541,7 +3576,8 @@ Arguments: filter points to the entire file, read into store as a single string options controls whether various special things are allowed, and requests special actions (not currently used) - sieve_vacation_directory where to store vacation "once" files + vacation_directory where to store vacation "once" files + enotify_mailto_owner owner of mailto notifications useraddress string expression for :user part of address subaddress string expression for :subaddress part of address generated where to hang newly-generated addresses @@ -3557,7 +3593,8 @@ Returns: FF_DELIVERED success, a significant action was taken int sieve_interpret(uschar *filter, int options, uschar *vacation_directory, - uschar *useraddress, uschar *subaddress, address_item **generated, uschar **error) + uschar *enotify_mailto_owner, uschar *useraddress, uschar *subaddress, + address_item **generated, uschar **error) { struct Sieve sieve; int r; @@ -3583,6 +3620,20 @@ else } } +if (enotify_mailto_owner == NULL) + sieve.enotify_mailto_owner = NULL; +else + { + sieve.enotify_mailto_owner=expand_string(enotify_mailto_owner); + if (sieve.enotify_mailto_owner == NULL) + { + *error = string_sprintf("failed to expand \"%s\" " + "(sieve_enotify_mailto_owner): %s", enotify_mailto_owner, + expand_string_message); + return FF_ERROR; + } + } + sieve.useraddress = useraddress == NULL ? CUS "$local_part_prefix$local_part$local_part_suffix" : useraddress; sieve.subaddress = subaddress;