diff --git a/include/xpldns.h b/include/xpldns.h index bd78abc..f9de130 100644 --- a/include/xpldns.h +++ b/include/xpldns.h @@ -93,6 +93,7 @@ typedef struct{ typedef struct { XplDns_ResultCode status; int preference; + int null_mx; char current_mx[XPLDNS_NAMELEN + 1]; XplDns_Result *_mx_result; XplDns_RecordList *_mx_current; @@ -101,6 +102,7 @@ typedef struct { int XplDnsInit(void); void XplDnsResultFree(XplDns_Result *result); XplDns_Result * XplDnsLookupIP(const char *domain); +int XplDnsMxRecordsAreNull(const XplDns_RecordList *records); XplDns_MxLookup *XplDnsNewMxLookup(const char *domain); XplDns_IpList * XplDnsNextMxLookupIpList(XplDns_MxLookup *mx); void XplDnsFreeMxLookup(XplDns_MxLookup *mx); diff --git a/src/agents/smtp/smtpc.c b/src/agents/smtp/smtpc.c index 4bbe9aa..60fbccc 100755 --- a/src/agents/smtp/smtpc.c +++ b/src/agents/smtp/smtpc.c @@ -494,6 +494,10 @@ Connection *LookupRemoteMX(RecipStruct *Recipient, char *hostname, break; } } + if (mx->null_mx) { + Recipient->Result = DELIVER_HOST_UNKNOWN; + goto finish; + } while ((list = XplDnsNextMxLookupIpList(mx)) != NULL) { int x; diff --git a/src/agents/smtp/smtpd.c b/src/agents/smtp/smtpd.c index 386ef4c..1a83b82 100644 --- a/src/agents/smtp/smtpd.c +++ b/src/agents/smtp/smtpd.c @@ -3601,6 +3601,9 @@ DeliverRemoteMessage (ConnectionStruct * Client, char *Sender, DELIVER_ERROR(RetVal); goto finish; } + if (mx->null_mx) { + DELIVER_ERROR(DELIVER_HOST_UNKNOWN); + } while ((list = XplDnsNextMxLookupIpList(mx)) != NULL) { int x; diff --git a/src/libs/xpl/CMakeLists.txt b/src/libs/xpl/CMakeLists.txt index 932346c..187b591 100644 --- a/src/libs/xpl/CMakeLists.txt +++ b/src/libs/xpl/CMakeLists.txt @@ -30,4 +30,8 @@ if(BUILD_TESTING) add_executable(xpl-init-test tests/init-test.c) target_link_libraries(xpl-init-test PRIVATE bongoxpl Threads::Threads) add_test(NAME xpl-init COMMAND xpl-init-test) + + add_executable(xpl-dns-mx-test tests/dns-mx-test.c) + target_link_libraries(xpl-dns-mx-test PRIVATE bongoxpl) + add_test(NAME xpl-dns-mx COMMAND xpl-dns-mx-test) endif() diff --git a/src/libs/xpl/dns.c b/src/libs/xpl/dns.c index ea92ead..7e5693a 100644 --- a/src/libs/xpl/dns.c +++ b/src/libs/xpl/dns.c @@ -192,6 +192,22 @@ XplDnsResultFree(XplDns_Result *result) MemFree(result); } +int +XplDnsMxRecordsAreNull(const XplDns_RecordList *records) +{ + const XplDns_RecordList *record; + const XplDns_MxRecord *only_mx = NULL; + unsigned int mx_count = 0U; + + for (record = records; record != NULL; record = record->next) { + if (record->type != XPLDNS_RR_MX) continue; + only_mx = &record->record.MX; + mx_count++; + } + return mx_count == 1U && only_mx->preference == 0 && + only_mx->mxname[0] == '\0'; +} + XplDns_MxLookup * XplDnsNewMxLookup(const char *domain) { @@ -248,7 +264,9 @@ restart_query: result->status = mx_query->status; result->_mx_result = mx_query; - result->_mx_current = mx_query->list; + result->null_mx = mx_query->status == XPLDNS_SUCCESS && + XplDnsMxRecordsAreNull(mx_query->list); + result->_mx_current = result->null_mx ? NULL : mx_query->list; return result; } diff --git a/src/libs/xpl/tests/dns-mx-test.c b/src/libs/xpl/tests/dns-mx-test.c new file mode 100644 index 0000000..8ff8ad9 --- /dev/null +++ b/src/libs/xpl/tests/dns-mx-test.c @@ -0,0 +1,53 @@ +/**************************************************************************** + * + * Copyright (c) 2001 Novell, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, contact Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, you + * may find current contact information at www.novell.com. + * + ****************************************************************************/ + +#include + +#include +#include + +int +main(void) +{ + XplDns_RecordList null_mx; + XplDns_RecordList regular_mx; + + memset(&null_mx, 0, sizeof(null_mx)); + null_mx.type = XPLDNS_RR_MX; + null_mx.record.MX.preference = 0; + assert(XplDnsMxRecordsAreNull(&null_mx)); + + null_mx.record.MX.preference = 10; + assert(!XplDnsMxRecordsAreNull(&null_mx)); + null_mx.record.MX.preference = 0; + strcpy(null_mx.record.MX.mxname, "mail.example.test."); + assert(!XplDnsMxRecordsAreNull(&null_mx)); + + null_mx.record.MX.mxname[0] = '\0'; + memset(®ular_mx, 0, sizeof(regular_mx)); + regular_mx.type = XPLDNS_RR_MX; + regular_mx.record.MX.preference = 10; + strcpy(regular_mx.record.MX.mxname, "backup.example.test."); + null_mx.next = ®ular_mx; + assert(!XplDnsMxRecordsAreNull(&null_mx)); + assert(!XplDnsMxRecordsAreNull(NULL)); + return 0; +}