*************************************************/
/* Copyright (c) University of Cambridge 1995 - 2015 */
+/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */
/* A set of functions to search databases in various formats. An open
*opts = string_copy(t+1);
}
else
- * opts = NULL;
+ *opts = NULL;
/* Check for the individual search type. Only those that are actually in the
binary are valid. For query-style types, "partial" and default types are
static void
tidyup_subtree(tree_node *t)
{
-search_cache *c = (search_cache *)(t->data.ptr);
-if (t->left != NULL) tidyup_subtree(t->left);
-if (t->right != NULL) tidyup_subtree(t->right);
-if (c != NULL &&
- c->handle != NULL &&
- lookup_list[c->search_type]->close != NULL)
+search_cache * c = (search_cache *)(t->data.ptr);
+if (t->left) tidyup_subtree(t->left);
+if (t->right) tidyup_subtree(t->right);
+if (c && c->handle && lookup_list[c->search_type]->close)
lookup_list[c->search_type]->close(c->handle);
}
DEBUG(D_lookup)
{
if (t)
- debug_printf_indent("cached data found but either wrong opts or dated; ");
+ debug_printf_indent("cached data found but %s; ",
+ e->expiry && e->expiry <= time(NULL) ? "out-of-date" : "wrong opts");
debug_printf_indent("%s lookup required for %s%s%s\n",
filename ? US"file" : US"database",
keystring,
else if (do_cache)
{
- if (!t) /* No existing entry. Create new one. */
+ if (!t) /* No existing entry. Create new one. */
{
int len = keylength + 1;
e = store_get(sizeof(expiring_data) + sizeof(tree_node) + len, is_tainted(keystring));
- e->expiry = do_cache == UINT_MAX ? 0 : time(NULL)+do_cache;
- e->opts = opts;
- e->data.ptr = data;
t = (tree_node *)(e+1);
memcpy(t->name, keystring, len);
t->data.ptr = e;
/* Else previous, out-of-date cache entry. Update with the */
/* new result and forget the old one */
e->expiry = do_cache == UINT_MAX ? 0 : time(NULL)+do_cache;
- e->opts = opts;
+ e->opts = opts ? string_copy(opts) : NULL;
e->data.ptr = data;
}
else
{
DEBUG(D_lookup) debug_printf_indent("lookup forced cache cleanup\n");
- c->item_cache = NULL;
+ c->item_cache = NULL; /* forget all lookups on this connection */
}
}
/* The key in its entirety did not match a wild entry; try chopping off
leading components. */
- if (yield == NULL)
+ if (!yield)
{
int dotcount = 0;
uschar *keystring3 = keystring2 + affixlen;
expand_nlength[*expand_setup] = Ustrlen(keystring);
}
+/* If we have a result, check the options to see if the key was wanted rather
+than the result. Return a de-tainted version of the key on the grounds that
+it have been validated by the lookup. */
+
+if (yield && opts)
+ {
+ int sep = ',';
+ uschar * ele;
+ while ((ele = string_nextinlist(&opts, &sep, NULL, 0)))
+ if (Ustrcmp(ele, "ret=key") == 0)
+ { yield = string_copy_taint(keystring, FALSE); break; }
+ }
+
return yield;
}