Lacking testsuite coverage
in the same way that multiple DNS records for a single item are handled. A
different separator can be specified, as described above.
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
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
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.
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".
+
of ldap servers used for a specific lookup. Patch provided by Heiko
Schlichting.
of ldap servers used for a specific lookup. Patch provided by Heiko
Schlichting.
+JH/18 New options dnssec_lax, dnssec_strict on dnsdb lookups.
+
+
Exim version 4.82
-----------------
Exim version 4.82
-----------------
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'.
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".
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. */
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 ptr = 0;
int sep = 0;
int defer_mode = PASS;
int type;
int failrc = FAIL;
uschar *outsep = US"\n";
int type;
int failrc = FAIL;
uschar *outsep = US"\n";
while (isspace(*keystring)) keystring++;
}
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)
- }
- 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;
+ }
- *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++ != ',')
{
}
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++;
return DEFER;
}
while (isspace(*keystring)) keystring++;
/* Initialize the resolver in case this is the first time it has been used. */
/* 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
/* 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 (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 (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 */
/* Search the returned records */
/* If ptr == 0 we have not found anything. Otherwise, insert the terminating
zero and return the result. */
/* 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;
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 };
static lookup_info *_lookup_list[] = { &_lookup_info };
lookup_module_info dnsdb_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
/* End of lookups/dnsdb.c */
/* End of lookups/dnsdb.c */