X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Flookups%2Fdnsdb.c;h=70e6c8c637586a3bafea0815104be05ad63be60c;hb=3a2ac12bcabf06f73ef372dfa23e6edead237aa7;hp=a0a457ab2eb0312f7abf4d02ec2b1b38062fb483;hpb=fd7f7910649e935c3bf5d48fe2742320dedfd82d;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c index a0a457ab2..70e6c8c63 100644 --- a/src/src/lookups/dnsdb.c +++ b/src/src/lookups/dnsdb.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2014 */ +/* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ #include "../exim.h" @@ -41,6 +41,7 @@ static const char *type_names[] = { "mxh", "ns", "ptr", + "soa", "spf", "srv", "tlsa", @@ -60,6 +61,7 @@ static int type_values[] = { T_MXH, /* Private type for "MX hostnames" */ T_NS, T_PTR, + T_SOA, T_SPF, T_SRV, T_TLSA, @@ -129,7 +131,7 @@ separator, as always, is colon. */ static int dnsdb_find(void *handle, uschar *filename, const uschar *keystring, int length, - uschar **result, uschar **errmsg, BOOL *do_cache) + uschar **result, uschar **errmsg, uint *do_cache) { int rc; int size = 256; @@ -228,7 +230,7 @@ for (;;) else if (strncmpic(keystring, US"retry_", 6) == 0) { int retries; - if ((retries = (int)strtol(keystring + 6, CSS &keystring, 0)) < 0) + if ((retries = (int)strtol(CCS keystring + 6, CSS &keystring, 0)) < 0) { *errmsg = US"unsupported dnsdb retry count"; return DEFER; @@ -386,14 +388,13 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0))) { if (rr->type != searchtype) continue; - /* There may be several addresses from an A6 record. Put the configured - separator between them, just as for between several records. However, A6 - support is not normally configured these days. */ + if (*do_cache > rr->ttl) + *do_cache = rr->ttl; if (type == T_A || type == T_AAAA || type == T_ADDRESSES) { dns_address *da; - for (da = dns_address_from_rr(&dnsa, rr); da != NULL; da = da->next) + for (da = dns_address_from_rr(&dnsa, rr); da; da = da->next) { if (ptr != 0) yield = string_cat(yield, &size, &ptr, outsep, 1); yield = string_cat(yield, &size, &ptr, da->address, @@ -436,7 +437,7 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0))) uint16_t i, payload_length; uschar s[MAX_TLSA_EXPANDED_SIZE]; uschar * sp = s; - uschar *p = (uschar *)(rr->data); + uschar * p = US rr->data; usage = *p++; selector = *p++; @@ -449,72 +450,75 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0))) for (i=0; i < payload_length && sp-s < (MAX_TLSA_EXPANDED_SIZE - 4); i++) - { sp += sprintf(CS sp, "%02x", (unsigned char)p[i]); - } + yield = string_cat(yield, &size, &ptr, s, Ustrlen(s)); } - else /* T_CNAME, T_CSA, T_MX, T_MXH, T_NS, T_PTR, T_SRV */ + else /* T_CNAME, T_CSA, T_MX, T_MXH, T_NS, T_PTR, T_SOA, T_SRV */ { int priority, weight, port; uschar s[264]; - uschar *p = (uschar *)(rr->data); - - if (type == T_MXH) - { - /* mxh ignores the priority number and includes only the hostnames */ - GETSHORT(priority, p); - } - else if (type == T_MX) - { - GETSHORT(priority, p); - sprintf(CS s, "%d%c", priority, *outsep2); - yield = string_cat(yield, &size, &ptr, s, Ustrlen(s)); - } - else if (type == T_SRV) - { - GETSHORT(priority, p); - GETSHORT(weight, p); - GETSHORT(port, p); - sprintf(CS s, "%d%c%d%c%d%c", priority, *outsep2, - weight, *outsep2, port, *outsep2); - yield = string_cat(yield, &size, &ptr, s, Ustrlen(s)); - } - else if (type == T_CSA) - { - /* See acl_verify_csa() for more comments about CSA. */ - - GETSHORT(priority, p); - GETSHORT(weight, p); - GETSHORT(port, p); - - if (priority != 1) continue; /* CSA version must be 1 */ - - /* If the CSA record we found is not the one we asked for, analyse - the subdomain assertions in the port field, else analyse the direct - authorization status in the weight field. */ - - if (Ustrcmp(found, domain) != 0) - { - if (port & 1) *s = 'X'; /* explicit authorization required */ - else *s = '?'; /* no subdomain assertions here */ - } - else - { - if (weight < 2) *s = 'N'; /* not authorized */ - else if (weight == 2) *s = 'Y'; /* authorized */ - else if (weight == 3) *s = '?'; /* unauthorizable */ - else continue; /* invalid */ - } - - s[1] = ' '; - yield = string_cat(yield, &size, &ptr, s, 2); - } + uschar * p = US rr->data; + + switch (type) + { + case T_MXH: + /* mxh ignores the priority number and includes only the hostnames */ + GETSHORT(priority, p); + break; + + case T_MX: + GETSHORT(priority, p); + sprintf(CS s, "%d%c", priority, *outsep2); + yield = string_cat(yield, &size, &ptr, s, Ustrlen(s)); + break; + + case T_SRV: + GETSHORT(priority, p); + GETSHORT(weight, p); + GETSHORT(port, p); + sprintf(CS s, "%d%c%d%c%d%c", priority, *outsep2, + weight, *outsep2, port, *outsep2); + yield = string_cat(yield, &size, &ptr, s, Ustrlen(s)); + break; + + case T_CSA: + /* See acl_verify_csa() for more comments about CSA. */ + GETSHORT(priority, p); + GETSHORT(weight, p); + GETSHORT(port, p); + + if (priority != 1) continue; /* CSA version must be 1 */ + + /* If the CSA record we found is not the one we asked for, analyse + the subdomain assertions in the port field, else analyse the direct + authorization status in the weight field. */ + + if (Ustrcmp(found, domain) != 0) + { + if (port & 1) *s = 'X'; /* explicit authorization required */ + else *s = '?'; /* no subdomain assertions here */ + } + else + { + if (weight < 2) *s = 'N'; /* not authorized */ + else if (weight == 2) *s = 'Y'; /* authorized */ + else if (weight == 3) *s = '?'; /* unauthorizable */ + else continue; /* invalid */ + } + + s[1] = ' '; + yield = string_cat(yield, &size, &ptr, s, 2); + break; + + default: + break; + } /* GETSHORT() has advanced the pointer to the target domain. */ rc = dn_expand(dnsa.answer, dnsa.answer + dnsa.answerlen, p, - (DN_EXPAND_ARG4_TYPE)(s), sizeof(s)); + (DN_EXPAND_ARG4_TYPE)s, sizeof(s)); /* If an overlong response was received, the data will have been truncated and dn_expand may fail. */ @@ -526,6 +530,32 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0))) break; } else yield = string_cat(yield, &size, &ptr, s, Ustrlen(s)); + + if (type == T_SOA && outsep2 != NULL) + { + unsigned long serial, refresh, retry, expire, minimum; + + p += rc; + yield = string_cat(yield, &size, &ptr, outsep2, 1); + + rc = dn_expand(dnsa.answer, dnsa.answer + dnsa.answerlen, p, + (DN_EXPAND_ARG4_TYPE)s, sizeof(s)); + if (rc < 0) + { + log_write(0, LOG_MAIN, "responsible-mailbox truncated: type=%s " + "domain=%s", dns_text_type(type), domain); + break; + } + else yield = string_cat(yield, &size, &ptr, s, Ustrlen(s)); + + p += rc; + GETLONG(serial, p); GETLONG(refresh, p); + GETLONG(retry, p); GETLONG(expire, p); GETLONG(minimum, p); + sprintf(CS s, "%c%lu%c%lu%c%lu%c%lu%c%lu", + *outsep2, serial, *outsep2, refresh, + *outsep2, retry, *outsep2, expire, *outsep2, minimum); + yield = string_cat(yield, &size, &ptr, s, Ustrlen(s)); + } } } /* Loop for list of returned records */