in the same way that multiple DNS records for a single item are handled. A
different separator can be specified, as described above.
+Modifiers for &(dnsdb)& lookups are givien by optional keywords,
+each followed by a comma,
+that may appear before the record type.
+
The &(dnsdb)& lookup fails only if all the DNS lookups fail. If there is a
temporary DNS error for any of them, the behaviour is controlled by
-an optional keyword followed by a comma that may appear before the record
-type. The possible keywords are &"defer_strict"&, &"defer_never"&, and
-&"defer_lax"&. With &"strict"& behaviour, any temporary DNS error causes the
+a defer-option modifier.
+The possible keywords are
+&"defer_strict"&, &"defer_never"&, and &"defer_lax"&.
+With &"strict"& behaviour, any temporary DNS error causes the
whole lookup to defer. With &"never"& behaviour, a temporary DNS error is
ignored, and the behaviour is as if the DNS lookup failed to find anything.
With &"lax"& behaviour, all the queries are attempted, but a temporary DNS
Thus, in the default case, as long as at least one of the DNS lookups
yields some data, the lookup succeeds.
+Use of &(DNSSEC)& is controlled by a dnssec modifier.
+The possible keywords are
+&"dnssec_strict"&, &"dnssec_lax"&, and &"dnssec_never"&.
+With &"strict"& or &"lax"& DNSSEC information is requested
+with the lookup.
+With &"strict"& a response from the DNS resolver that
+is not labelled as authenticated data
+is treated as equivalent to a temporary DNS error.
+The default is &"never".
+
whole lookup to defer only if none of the DNS queries succeeds; and 'never',
where all defers are as if the lookup failed. The default is 'lax'.
-(d) If the next sequence of characters is a sequence of letters and digits
+(d) Another optional comma-sep field: 'dnssec_FOO', with 'strict', 'lax'
+and 'never' (default); can appear before or after (c). The meanings are
+require, try and don't-try dnssec respectively.
+
+(e) If the next sequence of characters is a sequence of letters and digits
followed by '=', it is interpreted as the name of the DNS record type. The
default is "TXT".
-(e) Then there follows list of domain names. This is a generalized Exim list,
+(f) Then there follows list of domain names. This is a generalized Exim list,
which may start with '<' in order to set a specific separator. The default
separator, as always, is colon. */
int ptr = 0;
int sep = 0;
int defer_mode = PASS;
+int dnssec_mode = OK;
int type;
int failrc = FAIL;
uschar *outsep = US"\n";
while (isspace(*keystring)) keystring++;
}
-/* Check for a defer behaviour keyword. */
+/* Check for a modifier keyword. */
-if (strncmpic(keystring, US"defer_", 6) == 0)
+while ( strncmpic(keystring, US"defer_", 6) == 0
+ || strncmpic(keystring, US"dnssec_", 7) == 0
+ )
{
- keystring += 6;
- if (strncmpic(keystring, US"strict", 6) == 0)
+ if (strncmpic(keystring, US"defer_", 6) == 0)
{
- defer_mode = DEFER;
keystring += 6;
- }
- else if (strncmpic(keystring, US"lax", 3) == 0)
- {
- defer_mode = PASS;
- keystring += 3;
- }
- else if (strncmpic(keystring, US"never", 5) == 0)
- {
- defer_mode = OK;
- keystring += 5;
+ if (strncmpic(keystring, US"strict", 6) == 0)
+ {
+ defer_mode = DEFER;
+ keystring += 6;
+ }
+ else if (strncmpic(keystring, US"lax", 3) == 0)
+ {
+ defer_mode = PASS;
+ keystring += 3;
+ }
+ else if (strncmpic(keystring, US"never", 5) == 0)
+ {
+ defer_mode = OK;
+ keystring += 5;
+ }
+ else
+ {
+ *errmsg = US"unsupported dnsdb defer behaviour";
+ return DEFER;
+ }
}
else
{
- *errmsg = US"unsupported dnsdb defer behaviour";
- return DEFER;
+ keystring += 7;
+ if (strncmpic(keystring, US"strict", 6) == 0)
+ {
+ dnssec_mode = DEFER;
+ keystring += 6;
+ }
+ else if (strncmpic(keystring, US"lax", 3) == 0)
+ {
+ dnssec_mode = PASS;
+ keystring += 3;
+ }
+ else if (strncmpic(keystring, US"never", 5) == 0)
+ {
+ dnssec_mode = OK;
+ keystring += 5;
+ }
+ else
+ {
+ *errmsg = US"unsupported dnsdb dnssec behaviour";
+ return DEFER;
+ }
}
while (isspace(*keystring)) keystring++;
if (*keystring++ != ',')
{
- *errmsg = US"dnsdb defer behaviour syntax error";
+ *errmsg = US"dnsdb modifier syntax error";
return DEFER;
}
while (isspace(*keystring)) keystring++;
/* Initialize the resolver in case this is the first time it has been used. */
-dns_init(FALSE, FALSE, FALSE); /*XXX dnssec? */
+dns_init(FALSE, FALSE, dnssec_mode != OK);
/* The remainder of the string must be a list of domains. As long as the lookup
for at least one of them succeeds, we return success. Failure means that none
if (rc == DNS_NOMATCH || rc == DNS_NODATA) continue;
if (rc != DNS_SUCCEED)
{
- if (defer_mode == DEFER) return DEFER; /* always defer */
+ if (defer_mode == DEFER)
+ {
+ dns_init(FALSE, FALSE, FALSE);
+ return DEFER; /* always defer */
+ }
if (defer_mode == PASS) failrc = DEFER; /* defer only if all do */
continue; /* treat defer as fail */
}
+ if (dnssec_mode == DEFER && !dns_is_secure(&dnsa))
+ {
+ failrc = DEFER;
+ continue;
+ }
+
/* Search the returned records */
/* If ptr == 0 we have not found anything. Otherwise, insert the terminating
zero and return the result. */
+dns_init(FALSE, FALSE, FALSE); /* clear the dnssec bit for getaddrbyname */
+
if (ptr == 0) return failrc;
yield[ptr] = 0;
*result = yield;
static lookup_info *_lookup_list[] = { &_lookup_info };
lookup_module_info dnsdb_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
+/* vi: aw ai sw=2
+*/
/* End of lookups/dnsdb.c */