* Exim - an Internet mail transport agent *
*************************************************/
+/* Copyright (c) The Exim Maintainers 2020 - 2024 */
/* Copyright (c) University of Cambridge 1995 - 2015 */
-/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/* The idea for this code came from Matthew Byng-Maddick, but his original has
been heavily reworked a lot for Exim 4 (and it now uses stat() (more precisely:
#define FILTER_FILE BIT(2)
#define FILTER_DIR BIT(3)
#define FILTER_SUBDIR BIT(4)
+#define ALLOW_PATH BIT(5)
/* 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
uschar * filename;
unsigned flags = 0;
-if (Ustrchr(keystring, '/') != 0)
- {
- *errmsg = string_sprintf("key for dsearch lookup contains a slash: %s",
- keystring);
- return DEFER;
- }
-
if (opts)
{
int sep = ',';
else if (Ustrcmp(ele, "subdir") == 0)
flags |= FILTER_TYPE | FILTER_SUBDIR; /* like dir but not "." or ".." */
}
+ else if (Ustrcmp(ele, "key=path") == 0)
+ flags |= ALLOW_PATH;
+ }
+
+if (flags & ALLOW_PATH)
+ {
+ if (Ustrstr(keystring, "/../") != NULL || Ustrstr(keystring, "/./"))
+ {
+ *errmsg = string_sprintf(
+ "key for dsearch lookup contains bad component: %s", keystring);
+ return DEFER;
+ }
+ }
+else if (Ustrchr(keystring, '/') != NULL)
+ {
+ *errmsg = string_sprintf("key for dsearch lookup contains a slash: %s",
+ keystring);
+ return DEFER;
}
filename = string_sprintf("%s/%s", dirname, keystring);
&& S_ISDIR(statbuf.st_mode)
&& ( flags & FILTER_DIR
|| keystring[0] != '.'
- || keystring[1] && keystring[1] != '.'
+ || keystring[1] && (keystring[1] != '.' || keystring[2])
) ) ) )
{
/* Since the filename exists in the filesystem, we can return a
non-tainted result. */
- *result = string_copy_taint(flags & RET_FULL ? filename : keystring, FALSE);
+ *result = string_copy_taint(flags & RET_FULL ? filename : keystring, GET_UNTAINTED);
return OK;
}
#include "../version.h"
-void
-dsearch_version_report(FILE *f)
+gstring *
+dsearch_version_report(gstring * g)
{
#ifdef DYNLOOKUP
-fprintf(f, "Library version: dsearch: Exim version %s\n", EXIM_VERSION_STR);
+g = string_fmt_append(g, "Library version: dsearch: Exim version %s\n", EXIM_VERSION_STR);
#endif
+return g;
}
lookup_module_info dsearch_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
/* End of lookups/dsearch.c */
+/* vi: aw ai sw=2
+*/