summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2014-04-24 00:49:56 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2014-04-24 14:02:19 +0100
commitfd3b6a4ad699259b80dcaed6287ec01ab5ec0105 (patch)
tree6e5f0a344816c8e54a16b744e963c1509caeee39
parentdeae092e544ecfb3d8a362a260fc00ec01f0883f (diff)
dnssec_strict, _lax, _never modifiers for dnsdb lookups
Lacking testsuite coverage
-rw-r--r--doc/doc-docbook/spec.xfpt21
-rw-r--r--doc/doc-txt/ChangeLog3
-rw-r--r--src/src/lookups/dnsdb.c92
3 files changed, 91 insertions, 25 deletions
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 6f0a16f37..612d147a5 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -6959,11 +6959,16 @@ The data from each lookup is concatenated, with newline separators by default,
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
@@ -6976,6 +6981,16 @@ ${lookup dnsdb{a=one.host.com:two.host.com}}
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".
+
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 30b27a012..649b730f0 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -91,6 +91,9 @@ TL/08 Bugzilla 1453: New LDAP "SERVERS=" option allows admin to override list
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
-----------------
diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c
index a1eb2b658..b7e50588b 100644
--- a/src/src/lookups/dnsdb.c
+++ b/src/src/lookups/dnsdb.c
@@ -114,11 +114,15 @@ any defer causes the whole lookup to defer; 'lax', where a defer causes the
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. */
@@ -131,6 +135,7 @@ int size = 256;
int ptr = 0;
int sep = 0;
int defer_mode = PASS;
+int dnssec_mode = OK;
int type;
int failrc = FAIL;
uschar *outsep = US"\n";
@@ -173,35 +178,64 @@ if (*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)
{
- 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++;
@@ -241,7 +275,7 @@ if ((equals = Ustrchr(keystring, '=')) != NULL)
/* 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
@@ -323,10 +357,20 @@ while ((domain = string_nextinlist(&keystring, &sep, buffer, sizeof(buffer)))
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 */
@@ -494,6 +538,8 @@ store_reset(yield + ptr + 1);
/* 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;
@@ -538,4 +584,6 @@ static lookup_info _lookup_info = {
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 */