whose name is the key by calling the &[lstat()]& function. The key may not
contain any forward slash characters. If &[lstat()]& succeeds, the result of
the lookup is the name of the entry, which may be a file, directory,
-symbolic link, or any other kind of directory entry. An example of how this
+symbolic link, or any other kind of directory entry.
+.new
+.cindex "tainted data" "dsearch result"
+It is regarded as untainted.
+.wen
+An example of how this
lookup can be used to support virtual domains is given in section
&<<SECTvirtualdomains>>&.
.next
virtual:
driver = redirect
domains = dsearch;/etc/mail/virtual
- data = ${lookup{$local_part}lsearch{/etc/mail/virtual/$domain}}
+ data = ${lookup{$local_part}lsearch{/etc/mail/virtual/$domain_data}}
no_more
.endd
+.new
The &%domains%& option specifies that the router is to be skipped, unless there
is a file in the &_/etc/mail/virtual_& directory whose name is the same as the
-domain that is being processed. When the router runs, it looks up the local
+domain that is being processed.
+The &(dsearch)& lookup used results in an untainted version of &$domain$&
+being placed into the &$domain_data$& variable.
+.wen
+
+When the router runs, it looks up the local
part in the file to find a new address (or list of addresses). The &%no_more%&
setting ensures that if the lookup fails (leading to &%data%& being an empty
string), Exim gives up on the address without trying any subsequent routers.
JH/32 Bug 2541: Fix segfault on bad cmdline -f (sender) argument. Previously
an attempt to copy the string was made before checking it.
+JH/33 Fix the dsearch lookup to return an untainted result. Previously the
+ taint of the lookup key was maintained; we now regard the presence in the
+ filesystem as sufficient validation.
+
Exim version 4.93
-----------------
dsearch_open(uschar *dirname, uschar **errmsg)
{
DIR *dp = opendir(CS dirname);
-if (dp == NULL)
+if (!dp)
{
int save_errno = errno;
*errmsg = string_open_failed(errno, "%s for directory search", dirname);
/* The handle will always be (void *)(-1), but don't try casting it to an
integer as this gives warnings on 64-bit systems. */
-BOOL
-static dsearch_check(void *handle, uschar *filename, int modemask, uid_t *owners,
+static BOOL
+dsearch_check(void *handle, uschar *filename, int modemask, uid_t *owners,
gid_t *owngroups, uschar **errmsg)
{
handle = handle;
filename = string_sprintf("%s/%s", dirname, keystring);
if (Ulstat(filename, &statbuf) >= 0)
{
- *result = string_copy(keystring);
+ /* Since the filename exists in the filesystem, we can return a
+ non-tainted result. */
+ *result = string_copy_taint(keystring, FALSE);
return OK;
}
virtual:
driver = redirect
domains = *.virt.test.ex
- address_data = ${if match{$domain}{^(.*)\\.virt\\.test\\.ex\$}{${bless:$1}}}
- data = ${if exists{DIR/aux-fixed/TESTNUM.alias.$address_data} \
- {${lookup{$local_part}lsearch{DIR/aux-fixed/TESTNUM.alias.$address_data}}} \
- fail}
+ address_data = ${lookup {TESTNUM.alias.${extract {1}{.}{$domain}}} \
+ dsearch{DIR/aux-fixed} {$value}fail}
+ data = ${lookup{$local_part}lsearch{DIR/aux-fixed/$address_data}}
no_more
list: