]> git.ipfire.org Git - people/ms/dma.git/blobdiff - dns.c
dma - Fix security hole (#46)
[people/ms/dma.git] / dns.c
diff --git a/dns.c b/dns.c
index ce80745730e91d2bc728ed068bfdc30ffa87dcc7..bd28c4db724c9706f152bfc677a3743212cf79bd 100644 (file)
--- a/dns.c
+++ b/dns.c
@@ -1,8 +1,9 @@
 /*
+ * Copyright (c) 2008-2014, Simon Schubert <2@0x2c.org>.
  * Copyright (c) 2008 The DragonFly Project.  All rights reserved.
  *
  * This code is derived from software contributed to The DragonFly Project
- * by Simon 'corecode' Schubert <corecode@fs.ei.tum.de>
+ * by Simon Schubert <2@0x2c.org>.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,6 +34,7 @@
  */
 
 #include <sys/types.h>
+#include <sys/param.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
@@ -66,11 +68,7 @@ add_host(int pref, const char *host, int port, struct mx_hostentry **he, size_t
        struct addrinfo hints, *res, *res0 = NULL;
        char servname[10];
        struct mx_hostentry *p;
-       size_t onhosts;
        const int count_inc = 10;
-       int err;
-
-       onhosts = *ps;
 
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = PF_UNSPEC;
@@ -78,9 +76,26 @@ add_host(int pref, const char *host, int port, struct mx_hostentry **he, size_t
        hints.ai_protocol = IPPROTO_TCP;
 
        snprintf(servname, sizeof(servname), "%d", port);
-       err = getaddrinfo(host, servname, &hints, &res0);
-       if (err)
-               return (err == EAI_AGAIN ? 1 : -1);
+       switch (getaddrinfo(host, servname, &hints, &res0)) {
+       case 0:
+               break;
+       case EAI_AGAIN:
+       case EAI_NONAME:
+               /*
+                * EAI_NONAME gets returned for:
+                * SMARTHOST set but DNS server not reachable -> defer
+                * SMARTHOST set but DNS server returns "host does not exist"
+                *           -> buggy configuration
+                *           -> either defer or bounce would be ok -> defer
+                * MX entry was returned by DNS server but name doesn't resolve
+                *           -> hopefully transient situation -> defer
+                * all other DNS problems should have been caught earlier
+                * in dns_get_mx_list().
+                */
+               goto out;
+       default:
+               return(-1);
+       }
 
        for (res = res0; res != NULL; res = res->ai_next) {
                if (*ps + 1 >= roundup(*ps, count_inc)) {