contain any forward slash characters.
If &[lstat()]& succeeds then so does the lookup.
.new
+.cindex "tainted data" "dsearch result"
+The result is regarded as untainted.
+
Options for the lookup can be given by appending them after the word "dsearch",
-separated by a comma. Options, if present, are a comma-separated list with
+separated by a comma. Options, if present, are a comma-separated list having
each element starting with a tag name and an equals.
-The only option currently supported requests an alternate output value of
+Two options are supported, for the return value and for filtering match
+candidates.
+The "ret" option requests an alternate result value of
the entire path for the entry. Example:
.code
${lookup {passwd} dsearch,ret=full {/etc}}
.endd
The default result is just the requested entry.
-
-The matching entry may be a file, directory,
-symbolic link, or any other kind of directory entry.
-.cindex "tainted data" "dsearch result"
-The result is regarded as untainted.
+The "filter" option requests that only directory entries of a given type
+are matched. The match value is one of "file", "dir" or "subdir" (the latter
+not matching "." or ".."). Example:
+.code
+${lookup {passwd} dsearch,filter=file {/etc}}
+.endd
+The default matching is for any entry type, including directories
+and symlinks.
.wen
+
An example of how this
lookup can be used to support virtual domains is given in section
&<<SECTvirtualdomains>>&.
.oindex &%sqlite_dbfile%&
The preferred way of specifying the file is by using the
&%sqlite_dbfile%& option, set to
-.wen
an absolute path.
+.wen
A deprecated method is available, prefixing the query with the filename
separated by white space.
This means that the path name cannot contain white space.
the entire query including the filename - resulting in a refusal to open
the file.
+.new
Here is a lookup expansion example:
.code
sqlite_dbfile = /some/thing/sqlitedb
domainlist relay_to_domains = sqlite;\
select * from relays where ip='$sender_host_address';
.endd
+.wen
The only character affected by the &%quote_sqlite%& operator is a single
quote, which it doubles.
in the lookup, as the filename becomes tainted. The new method keeps the
filename separate.
12. An option on the dsearch lookup, to return the full path.
+12. Options on the dsearch lookup, to return the full path and to filter
+ filetypes for matching.
*************************************************/
#define RET_FULL BIT(0)
+#define FILTER_TYPE BIT(1)
+#define FILTER_ALL BIT(1)
+#define FILTER_FILE BIT(2)
+#define FILTER_DIR BIT(3)
+#define FILTER_SUBDIR BIT(4)
/* See local README for interface description. We use lstat() instead of
scanning the directory, as it is hopefully faster to let the OS do the scanning
while ((ele = string_nextinlist(&opts, &sep, NULL, 0)))
if (Ustrcmp(ele, "ret=full") == 0)
flags |= RET_FULL;
+ else if (Ustrncmp(ele, "filter=", 7) == 0)
+ {
+ ele += 7;
+ if (Ustrcmp(ele, "file") == 0)
+ flags |= FILTER_TYPE | FILTER_FILE;
+ else if (Ustrcmp(ele, "dir") == 0)
+ flags |= FILTER_TYPE | FILTER_DIR;
+ else if (Ustrcmp(ele, "subdir") == 0)
+ flags |= FILTER_TYPE | FILTER_SUBDIR; /* like dir but not "." or ".." */
+ }
}
filename = string_sprintf("%s/%s", dirname, keystring);
-if (Ulstat(filename, &statbuf) >= 0)
+if ( Ulstat(filename, &statbuf) >= 0
+ && ( !(flags & FILTER_TYPE)
+ || (flags & FILTER_FILE && S_ISREG(statbuf.st_mode))
+ || ( flags & (FILTER_DIR | FILTER_SUBDIR)
+ && S_ISDIR(statbuf.st_mode)
+ && ( flags & FILTER_DIR
+ || keystring[0] != '.'
+ || keystring[1] != '.'
+ || keystring[1] && keystring[2]
+ ) ) ) )
{
/* Since the filename exists in the filesystem, we can return a
non-tainted result. */
fail(case): ${lookup{TESTNUM.TST} dsearch{DIR/aux-fixed}{$value}{FAIL}}
fail(case): ${lookup{TESTNUM.TST} dsearch{DIR/AUX-fixed}{$value}{FAIL}}
fail(path): ${lookup{TESTNUM.tst} dsearch{.}{$value}{OTHER}}
-ok,full: ${lookup{TESTNUM.tst} dsearch,ret=full {DIR/aux-fixed}{$value}{FAIL}}
+ok,full: ${lookup{TESTNUM.tst} dsearch,ret=full {DIR/aux-fixed}{$value}{FAIL}}
+ok,file: ${lookup{TESTNUM.tst} dsearch,filter=file {DIR/aux-fixed}{$value}{FAIL}}
+fail,file: ${lookup{TESTNUM.dir} dsearch,filter=file {DIR/aux-fixed}{$value}{FAIL}}
+ok,dir: ${lookup{TESTNUM.dir} dsearch,filter=dir {DIR/aux-fixed}{$value}{FAIL}}
+fail,dir: ${lookup{TESTNUM.tst} dsearch,filter=dir {DIR/aux-fixed}{$value}{FAIL}}
+ok,subdir: ${lookup{TESTNUM.dir} dsearch,filter=subdir {DIR/aux-fixed}{$value}{FAIL}}
+fail,subdir:${lookup{..} dsearch,filter=subdir {DIR/aux-fixed}{$value}{FAIL}}
+fail,subdir:${lookup{TESTNUM.tst} dsearch,filter=subdir {DIR/aux-fixed}{$value}{FAIL}}
****
#
1
LRU list:
internal_search_find: file="NULL"
type=dnsdb key="a=shorthost.test.ex" opts=NULL
- cached data found but past valid time; database lookup required for a=shorthost.test.ex
+ cached data found but either wrong opts or dated; database lookup required for a=shorthost.test.ex
dnsdb key: shorthost.test.ex
lookup yielded: 127.0.0.1
LOG: MAIN
LRU list:
internal_search_find: file="NULL"
type=dnsdb key="a=shorthost.test.ex" opts=NULL
-cached data found but past valid time; database lookup required for a=shorthost.test.ex
+cached data found but either wrong opts or dated; database lookup required for a=shorthost.test.ex
dnsdb key: shorthost.test.ex
lookup yielded: 127.0.0.1
LOG: MAIN
dropping to exim gid; retaining priv uid
search_open: sqlite "NULL"
search_find: file="NULL"
- key="select name from them where id='userx';" partial=-1 affix=NULL starflags=0
+ key="select name from them where id='userx';" partial=-1 affix=NULL starflags=0 opts=NULL
LRU list:
internal_search_find: file="NULL"
- type=sqlite key="select name from them where id='userx';"
+ type=sqlite key="select name from them where id='userx';" opts=NULL
database lookup required for select name from them where id='userx';
lookup yielded: Ayen Other
search_tidyup called
> Failed: failed to open TESTSUITE/AUX-fixed for directory search: No such file or directory
> Failed: dirname '.' for dsearch is not absolute
> ok,full: TESTSUITE/aux-fixed/2500.tst
+> ok,file: 2500.tst
+> fail,file: FAIL
+> ok,dir: 2500.dir
+> fail,dir: FAIL
+> ok,subdir: 2500.dir
+> fail,subdir:FAIL
+> fail,subdir:FAIL
>