RDO_REALLOG |
RDO_REWRITE,
NULL, /* No :include: restriction (not used in filter) */
- NULL, /* No sieve vacation directory (not sieve!) */
- NULL, /* No sieve enotify mailto owner (not sieve!) */
- NULL, /* No sieve user address (not sieve!) */
- NULL, /* No sieve subaddress (not sieve!) */
+ NULL, /* No sieve info (not sieve!) */
&ugid, /* uid/gid data */
&addr_new, /* Where to hang generated addresses */
&filter_message, /* Where to put error message */
else
{
yield = filter_type == FILTER_SIEVE
- ? sieve_interpret(filebuf, RDO_REWRITE, NULL, NULL, NULL, NULL, &generated, &error)
+ ? sieve_interpret(filebuf, RDO_REWRITE, NULL, &generated, &error)
: filter_interpret(filebuf, RDO_REWRITE, &generated, &error);
}
extern int random_number(int);
extern const uschar *rc_to_string(int);
-extern int rda_interpret(redirect_block *, int, const uschar *, const uschar *,
- const uschar *, const uschar *, const uschar *, const ugid_block *, address_item **,
- uschar **, error_block **, int *, const uschar *);
+extern int rda_interpret(redirect_block *, int, const uschar *,
+ const sieve_block *, const ugid_block *, address_item **,
+ uschar **, error_block **, int *, const uschar *);
extern int rda_is_filter(const uschar *);
extern BOOL readconf_depends(driver_instance *, uschar *);
extern void readconf_driver_init(uschar *, driver_instance **,
extern void sha1_end(hctx *, const uschar *, int, uschar *);
extern void sha1_mid(hctx *, const uschar *);
extern void sha1_start(hctx *);
-extern int sieve_interpret(const uschar *, int, const uschar *,
- const uschar *, const uschar *, const uschar *,
+extern int sieve_interpret(const uschar *, int, const sieve_block *,
address_item **, uschar **);
extern void sigalrm_handler(int);
extern void single_queue_run(qrunner *, const uschar *, const uschar *);
rdata the redirection block
options the options bits
include_directory restrain to this directory
- sieve_vacation_directory passed to sieve_interpret
- sieve_enotify_mailto_owner passed to sieve_interpret
- sieve_useraddress passed to sieve_interpret
- sieve_subaddress passed to sieve_interpret
+ sieve passed to sieve_interpret
generated where to hang generated addresses
error for error messages
eblockp for details of skipped syntax errors
static int
rda_extract(const redirect_block * rdata, int options,
- const uschar * include_directory, const uschar * sieve_vacation_directory,
- const uschar * sieve_enotify_mailto_owner, const uschar * sieve_useraddress,
- const uschar * sieve_subaddress, address_item ** generated, uschar ** error,
+ const uschar * include_directory, const sieve_block * sieve,
+ address_item ** generated, uschar ** error,
error_block ** eblockp, int * filtertype)
{
const uschar * data;
if (*filtertype == FILTER_EXIM)
{
- if ((options & RDO_EXIM_FILTER) != 0)
+ if (options & RDO_EXIM_FILTER)
{
*error = US"Exim filtering not enabled";
return FF_ERROR;
*error = US"Sieve filtering not enabled";
return FF_ERROR;
}
- frc = sieve_interpret(data, options, sieve_vacation_directory,
- sieve_enotify_mailto_owner, sieve_useraddress, sieve_subaddress,
- generated, error);
+ frc = sieve_interpret(data, options, sieve, generated, error);
}
expand_forbid = old_expand_forbid;
options options to pass to the extraction functions,
plus ENOTDIR and EACCES handling bits
include_directory restrain :include: to this directory
- sieve_vacation_directory directory passed to sieve_interpret
- sieve_enotify_mailto_owner passed to sieve_interpret
- sieve_useraddress passed to sieve_interpret
- sieve_subaddress passed to sieve_interpret
+ sieve passed to sieve_interpret
ugid uid/gid to run under - if NULL, no change
generated where to hang generated addresses, initially NULL
error pointer for error message
int
rda_interpret(redirect_block * rdata, int options,
- const uschar * include_directory, const uschar * sieve_vacation_directory,
- const uschar * sieve_enotify_mailto_owner, const uschar * sieve_useraddress,
- const uschar * sieve_subaddress, const ugid_block * ugid, address_item ** generated,
+ const uschar * include_directory, const sieve_block * sieve,
+ const ugid_block * ugid, address_item ** generated,
uschar ** error, error_block ** eblockp, int * filtertype, const uschar * rname)
{
int fd, rc, pfd[2];
work in this process. Note that for a system filter, we always have a file, so
the work is done in this process only if no user is supplied. */
-if (!ugid->uid_set || /* Either there's no uid, or */
- (!rdata->isfile && /* We've got the data, and */
- rda_is_filter(data) == FILTER_FORWARD && /* It's not a filter script, */
- Ustrstr(data, ":include:") == NULL)) /* and there's no :include: */
- return rda_extract(rdata, options, include_directory,
- sieve_vacation_directory, sieve_enotify_mailto_owner, sieve_useraddress,
- sieve_subaddress, generated, error, eblockp, filtertype);
+if ( !ugid->uid_set /* Either there's no uid, or */
+ || ( !rdata->isfile /* We've got the data, and */
+ && rda_is_filter(data) == FILTER_FORWARD /* It's not a filter script, */
+ && Ustrstr(data, ":include:") == NULL /* and there's no :include: */
+ ) )
+ return rda_extract(rdata, options, include_directory, sieve,
+ generated, error, eblockp, filtertype);
/* We need to run the processing code in a sub-process. However, if we can
determine the non-existence of a file first, we can decline without having to
/* Now do the business */
- yield = rda_extract(rdata, options, include_directory,
- sieve_vacation_directory, sieve_enotify_mailto_owner, sieve_useraddress,
- sieve_subaddress, generated, error, eblockp, filtertype);
+ yield = rda_extract(rdata, options, include_directory, sieve,
+ generated, error, eblockp, filtertype);
/* Pass back whether it was a filter, and the return code and any overall
error text via the pipe. */
RDO_INCLUDE | /* forbid :include: */
RDO_REWRITE, /* rewrite generated addresses */
NULL, /* :include: directory not relevant */
- NULL, /* sieve vacation directory not relevant */
- NULL, /* sieve enotify mailto owner not relevant */
- NULL, /* sieve useraddress not relevant */
- NULL, /* sieve subaddress not relevant */
+ NULL, /* sieve info not relevant */
&ugid, /* uid/gid (but not set) */
&generated, /* where to hang the results */
&addr->message, /* where to put messages */
LOFF(bit_options) },
{ "sieve_enotify_mailto_owner", opt_stringptr, LOFF(sieve_enotify_mailto_owner) },
- { "sieve_subaddress", opt_stringptr, LOFF(sieve_subaddress) },
- { "sieve_useraddress", opt_stringptr, LOFF(sieve_useraddress) },
+ { "sieve_subaddress", opt_stringptr, LOFF(sieve_subaddress) },
+ { "sieve_useraddress", opt_stringptr, LOFF(sieve_useraddress) },
{ "sieve_vacation_directory", opt_stringptr, LOFF(sieve_vacation_directory) },
{ "skip_syntax_errors", opt_bool, LOFF(skip_syntax_errors) },
{ "syntax_errors_text", opt_stringptr, LOFF(syntax_errors_text) },
-/* Default private options block for the redirect router. */
+/* Default private options block for the redirect router.
+Unlisted elements are 0/NULL/FALSE */
redirect_router_options_block redirect_router_option_defaults = {
- NULL, /* directory_transport */
- NULL, /* file_transport */
- NULL, /* pipe_transport */
- NULL, /* reply_transport */
- NULL, /* data */
- NULL, /* directory_transport_name */
- NULL, /* file */
- NULL, /* file_dir */
- NULL, /* file_transport_name */
- NULL, /* include_directory */
- NULL, /* pipe_transport_name */
- NULL, /* reply_transport_name */
- NULL, /* sieve_subaddress */
- NULL, /* sieve_useraddress */
- NULL, /* sieve_vacation_directory */
- NULL, /* sieve_enotify_mailto_owner */
- NULL, /* syntax_errors_text */
- NULL, /* syntax_errors_to */
- NULL, /* qualify_domain */
- NULL, /* owners */
- NULL, /* owngroups */
- 022, /* modemask */
- RDO_REWRITE | RDO_PREPEND_HOME, /* bit_options */
- FALSE, /* check_ancestor */
- TRUE_UNSET, /* check_owner */
- TRUE_UNSET, /* check_group */
- FALSE, /* forbid_file */
- FALSE, /* forbid_filter_reply */
- FALSE, /* forbid_pipe */
- FALSE, /* forbid_smtp_code */
- FALSE, /* hide_child_in_errmsg */
- FALSE, /* one_time */
- FALSE, /* qualify_preserve_domain */
- FALSE /* skip_syntax_errors */
+ .modemask = 022,
+ .bit_options = RDO_REWRITE | RDO_PREPEND_HOME,
+ .check_owner = TRUE_UNSET,
+ .check_group = TRUE_UNSET,
};
error_block *eblock = NULL;
ugid_block ugid;
redirect_block redirect;
+sieve_block sieve;
int filtertype = FILTER_UNSET;
int yield = OK;
int options = ob->bit_options;
redirect.string = (redirect.isfile = (ob->file != NULL))
? ob->file : ob->data;
-frc = rda_interpret(&redirect, options, ob->include_directory,
- ob->sieve_vacation_directory, ob->sieve_enotify_mailto_owner,
- ob->sieve_useraddress, ob->sieve_subaddress, &ugid, &generated,
- &addr->message, ob->skip_syntax_errors? &eblock : NULL, &filtertype,
- string_sprintf("%s router (recipient is %s)", rblock->name, addr->address));
+sieve.vacation_dir = ob->sieve_vacation_directory;
+sieve.enotify_mailto_owner = ob->sieve_enotify_mailto_owner;
+sieve.useraddress = ob->sieve_useraddress;
+sieve.subaddress = ob->sieve_subaddress;
+
+frc = rda_interpret(&redirect, options, ob->include_directory, &sieve, &ugid,
+ &generated, &addr->message, ob->skip_syntax_errors ? &eblock : NULL,
+ &filtertype, string_sprintf("%s router (recipient is %s)", rblock->name,
+ addr->address));
qualify_domain_recipient = save_qualify_domain_recipient;
uschar *include_directory;
uschar *pipe_transport_name;
uschar *reply_transport_name;
+
+ uschar *sieve_enotify_mailto_owner;
+ uschar *sieve_inbox;
uschar *sieve_subaddress;
uschar *sieve_useraddress;
uschar *sieve_vacation_directory;
- uschar *sieve_enotify_mailto_owner;
+
uschar *syntax_errors_text;
uschar *syntax_errors_to;
uschar *qualify_domain;
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)
- 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
+ sieve
+ 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
error where to pass back an error text
*/
int
-sieve_interpret(const uschar * filter, int options,
- const uschar * vacation_directory, const uschar * enotify_mailto_owner,
- const uschar * useraddress, const uschar * subaddress,
+sieve_interpret(const uschar * filter, int options, const sieve_block * sb,
address_item ** generated, uschar ** error)
{
struct Sieve sieve;
expand_level++;
sieve.filter = filter;
-if (!vacation_directory)
+if (!sb || !sb->vacation_dir)
sieve.vacation_directory = NULL;
-else if (!(sieve.vacation_directory = expand_cstring(vacation_directory)))
+else if (!(sieve.vacation_directory = expand_cstring(sb->vacation_dir)))
{
*error = string_sprintf("failed to expand \"%s\" "
- "(sieve_vacation_directory): %s", vacation_directory,
+ "(sieve_vacation_directory): %s", sb->vacation_dir,
expand_string_message);
return FF_ERROR;
}
-if (!enotify_mailto_owner)
+if (!sb || !sb->enotify_mailto_owner)
sieve.enotify_mailto_owner = NULL;
-else if (!(sieve.enotify_mailto_owner = expand_cstring(enotify_mailto_owner)))
+else if (!(sieve.enotify_mailto_owner = expand_cstring(sb->enotify_mailto_owner)))
{
*error = string_sprintf("failed to expand \"%s\" "
- "(sieve_enotify_mailto_owner): %s", enotify_mailto_owner,
+ "(sieve_enotify_mailto_owner): %s", sb->enotify_mailto_owner,
expand_string_message);
return FF_ERROR;
}
-sieve.useraddress = useraddress
- ? useraddress : CUS "$local_part_prefix$local_part$local_part_suffix";
-sieve.subaddress = subaddress;
+sieve.useraddress = sb && sb->useraddress
+ ? sb->useraddress : CUS "$local_part_prefix$local_part$local_part_suffix";
+sieve.subaddress = sb ? sb->subaddress : NULL;
#ifdef COMPILE_SYNTAX_CHECKER
if (parse_start(&sieve, 0, generated) == 1)
BOOL check_group; /* TRUE, FALSE, or TRUE_UNSET */
} redirect_block;
+/* Sieve control data */
+
+typedef struct sieve_block {
+ const uschar * vacation_dir;
+ const uschar * enotify_mailto_owner;
+ const uschar * useraddress;
+ const uschar * subaddress;
+} sieve_block;
+
/* Structure for passing arguments to check_host() */
typedef struct check_host_block {