diff -ur postfix-2.7-20091115.clean/makedefs postfix-2.7-20091115/makedefs
--- postfix-2.7-20091115.clean/makedefs	2009-11-09 19:44:41.000000000 -0500
+++ postfix-2.7-20091115/makedefs	2009-11-18 14:19:01.000000000 -0500
@@ -282,9 +282,9 @@
 		#     GDBM_LIBS=gdbm
 		# fi
 		SYSLIBS="-ldb"
-		for name in nsl resolv $GDBM_LIBS
+		for name in nsl resolv val-threads sres crypto $GDBM_LIBS
 		do
-		    for lib in /usr/lib64 /lib64 /usr/lib /lib
+		    for lib in /usr/lib64 /lib64 /usr/lib /lib /usr/local/lib
 		    do
 			test -e $lib/lib$name.a -o -e $lib/lib$name.so && {
 			    SYSLIBS="$SYSLIBS -l$name"
diff -ur postfix-2.7-20091115.clean/src/dns/dns.h postfix-2.7-20091115/src/dns/dns.h
--- postfix-2.7-20091115.clean/src/dns/dns.h	2008-11-09 16:42:03.000000000 -0500
+++ postfix-2.7-20091115/src/dns/dns.h	2009-11-18 14:19:01.000000000 -0500
@@ -171,6 +171,8 @@
   * Status codes. Failures must have negative codes so they will not collide
   * with valid counts of answer records etc.
   */
+                                        /* DNS_INSECURE dnssec patch added */
+#define DNS_INSECURE	(-6)		/* query was not validated */
 #define DNS_INVAL	(-5)		/* query ok, malformed reply */
 #define DNS_FAIL	(-4)		/* query failed, don't retry */
 #define DNS_NOTFOUND	(-3)		/* query ok, data not found */
diff -ur postfix-2.7-20091115.clean/src/dns/dns_lookup.c postfix-2.7-20091115/src/dns/dns_lookup.c
--- postfix-2.7-20091115.clean/src/dns/dns_lookup.c	2009-08-06 15:25:33.000000000 -0400
+++ postfix-2.7-20091115/src/dns/dns_lookup.c	2009-11-18 14:19:01.000000000 -0500
@@ -146,6 +146,7 @@
 #include <msg.h>
 #include <valid_hostname.h>
 #include <stringops.h>
+#include <validator/validator.h>
 
 /* DNS library. */
 
@@ -215,7 +216,15 @@
     for (;;) {
 	_res.options &= ~saved_options;
 	_res.options |= flags;
-	len = res_search((char *) name, C_IN, type, reply->buf, reply->buf_len);
+
+        /* dns query using dnssec validator library */
+        val_status_t val_status;
+        len = val_res_query((val_context_t *) NULL,
+                            (char *) name, 
+                            C_IN, type, 
+                            reply->buf, reply->buf_len,
+                            &val_status);
+
 	_res.options &= ~flags;
 	_res.options |= saved_options;
 	if (len < 0) {
@@ -236,8 +245,22 @@
 		return (DNS_RETRY);
 	    }
 	}
-	if (msg_verbose)
-	    msg_info("dns_query: %s (%s): OK", name, dns_strtype(type));
+
+        /* check that the dnssec query is trusted */
+        if (!val_istrusted(val_status)) {
+            if (why || msg_verbose)
+                vstring_sprintf(why, "Validation error during Name Service lookup."
+                                " Error %d : %s  for name=%s type=%s",
+                                val_status, p_val_error(val_status),
+                                name, dns_strtype(type));
+            
+            return(DNS_FAIL);
+        }
+ 
+        if (msg_verbose)
+            msg_info("dns_query: %s (%s): OK   validation: %s (%d)", 
+                     name, dns_strtype(type), 
+                     p_val_error(val_status), val_status);
 
 	reply_header = (HEADER *) reply->buf;
 	if (reply_header->tc == 0 || reply->buf_len >= MAX_DNS_REPLY_SIZE)
diff -ur postfix-2.7-20091115.clean/src/util/myaddrinfo.c postfix-2.7-20091115/src/util/myaddrinfo.c
--- postfix-2.7-20091115.clean/src/util/myaddrinfo.c	2006-09-29 19:34:20.000000000 -0400
+++ postfix-2.7-20091115/src/util/myaddrinfo.c	2009-11-23 13:44:24.216393943 -0500
@@ -427,7 +427,26 @@
 	}
 #endif
     }
-    err = getaddrinfo(hostname, service, &hints, res);
+
+    /* 
+     * Call dnssec aware getaddrinfo.  If it returns a regular
+     * getaddrinfo error, return with that error.
+     * If the return query is not trusted, return a
+     * dnssec failure condition. 
+     */
+    val_status_t  vstatus;
+    err = val_getaddrinfo((val_context_t *)NULL, hostname, 
+                          service, &hints, res, &vstatus);
+    if (VAL_GETADDRINFO_HAS_STATUS(err) &&  (0 == val_istrusted(vstatus)))  {
+        err = DNSSECAI_FAIL;
+        msg_warn("DNSSEC, hostname information not trusted for host, %s (status: %d:%s, dnssec status %d:%s, val_getaddrinfo)", 
+                 hostname ? hostname : "NULL", err, MAI_STRERROR(err), 
+                 vstatus, p_val_status(vstatus));
+    }
+    else if(err) {
+      msg_warn("failed to get host information for host, %s (status %d:%s, val_getaddrinfo)", 
+               hostname ? hostname : "NULL", err, MAI_STRERROR(err));
+    }
 #if defined(BROKEN_AI_NULL_SERVICE)
     if (service == 0 && err == 0) {
 	struct addrinfo *r;
@@ -543,7 +562,27 @@
 	}
 #endif
     }
-    err = getaddrinfo(hostaddr, service, &hints, res);
+
+    /* 
+     * Call dnssec aware getaddrinfo.  If it returns a regular
+     * getaddrinfo error, return with that error.
+     * If the return query is not trusted, return a 
+     * dnssec failure condition. 
+     */
+    val_status_t  vstatus;
+    err = val_getaddrinfo((val_context_t *)NULL, hostaddr, service, &hints, 
+                          res, &vstatus);
+    if (VAL_GETADDRINFO_HAS_STATUS(err) && (0 == val_istrusted(vstatus)))  {
+        err = DNSSECAI_FAIL;
+        msg_warn("DNSSEC, host address information not trusted for host, %s (status %d:%s, dnssec status %d:%s, val_getaddrinfo)",
+                 hostaddr ? hostaddr : "NULL", err, MAI_STRERROR(err),
+                 vstatus, p_val_status(vstatus));
+    }
+    else {
+      msg_warn("failed to get host information for host, %s (status %d:%s, val_getaddrinfo)", 
+               hostaddr ? hostaddr : "NULL",
+               err, MAI_STRERROR(err));
+    }
 #if defined(BROKEN_AI_NULL_SERVICE)
     if (service == 0 && err == 0) {
 	struct addrinfo *r;
@@ -769,6 +808,29 @@
 
 #endif
 
+
+/* 
+ * dnssec_strerror - looks for dnssec errors (currently there is
+ *                   only one), passes back dnssec specific error
+ *                   string or calls the system gai_strerror. 
+ */
+
+static const char* dnssecai_fail_string = "DNSSEC Error";
+static const char* dnssecai_noerror_string = "DNSSEC Success";
+
+const char   *dnssec_strerror(int ecode)  
+{
+  switch (ecode) {
+  case 0:
+    return (dnssecai_noerror_string);
+  case DNSSECAI_FAIL:
+    return (dnssecai_fail_string);
+  }
+  /* default response*/
+  return (gai_strerror(ecode));
+} /* denssec_strerror */
+
+
 #ifdef TEST
 
  /*
@@ -797,46 +859,59 @@
     msg_info("=== hostname %s ===", argv[2]);
 
     if ((err = hostname_to_sockaddr(argv[2], (char *) 0, 0, &info)) != 0) {
-	msg_info("hostname_to_sockaddr(%s): %s",
-	  argv[2], err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
+	msg_info("hostname_to_sockaddr(%s): Error: %s",
+                 argv[2], MAI_STRERROR(err));
     } else {
+	msg_info("hostname_to_sockaddr(%s): Success: %s",
+                 argv[2], MAI_STRERROR(err));
 	for (ip = info; ip != 0; ip = ip->ai_next) {
 	    if ((err = sockaddr_to_hostaddr(ip->ai_addr, ip->ai_addrlen, &addr,
 					 (MAI_SERVPORT_STR *) 0, 0)) != 0) {
-		msg_info("sockaddr_to_hostaddr: %s",
-		   err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
+		msg_info("sockaddr_to_hostaddr: Error: %s",
+		   MAI_STRERROR(err));
 		continue;
 	    }
+            else {
+              msg_info("sockaddr_to_hostaddr: Success: %s",
+                       MAI_STRERROR(err));
+            }
 	    msg_info("%s -> family=%d sock=%d proto=%d %s", argv[2],
 		 ip->ai_family, ip->ai_socktype, ip->ai_protocol, addr.buf);
 	    if ((err = sockaddr_to_hostname(ip->ai_addr, ip->ai_addrlen, &host,
 					 (MAI_SERVNAME_STR *) 0, 0)) != 0) {
-		msg_info("sockaddr_to_hostname: %s",
-		   err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
+		msg_info("sockaddr_to_hostname: Error: %s",
+		   MAI_STRERROR(err));
 		continue;
 	    }
+            else {
+              msg_info("sockaddr_to_hostname: Success: %s",
+                       MAI_STRERROR(err));
+            }
 	    msg_info("%s -> %s", addr.buf, host.buf);
 	}
 	freeaddrinfo(info);
     }
 
+    msg_info(" ");
     msg_info("=== host address %s ===", argv[3]);
 
     if ((err = hostaddr_to_sockaddr(argv[3], (char *) 0, 0, &ip)) != 0) {
-	msg_info("hostaddr_to_sockaddr(%s): %s",
-	  argv[3], err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
+	msg_info("hostaddr_to_sockaddr(%s): Error: %s",
+	  argv[3], MAI_STRERROR(err));
     } else {
+	msg_info("hostaddr_to_sockaddr(%s): Success: %s",
+                 argv[3], MAI_STRERROR(err));
 	if ((err = sockaddr_to_hostaddr(ip->ai_addr, ip->ai_addrlen, &addr,
 					(MAI_SERVPORT_STR *) 0, 0)) != 0) {
-	    msg_info("sockaddr_to_hostaddr: %s",
-		   err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
+	    msg_info("sockaddr_to_hostaddr: Error: %s",
+		   MAI_STRERROR(err));
 	} else {
 	    msg_info("%s -> family=%d sock=%d proto=%d %s", argv[3],
 		 ip->ai_family, ip->ai_socktype, ip->ai_protocol, addr.buf);
 	    if ((err = sockaddr_to_hostname(ip->ai_addr, ip->ai_addrlen, &host,
 					 (MAI_SERVNAME_STR *) 0, 0)) != 0) {
 		msg_info("sockaddr_to_hostname: %s",
-		   err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
+		   MAI_STRERROR(err));
 	    } else
 		msg_info("%s -> %s", addr.buf, host.buf);
 	    freeaddrinfo(ip);
Only in postfix-2.7-20091115/src/util: myaddrinfo.e
diff -ur postfix-2.7-20091115.clean/src/util/myaddrinfo.h postfix-2.7-20091115/src/util/myaddrinfo.h
--- postfix-2.7-20091115.clean/src/util/myaddrinfo.h	2008-11-27 14:10:17.000000000 -0500
+++ postfix-2.7-20091115/src/util/myaddrinfo.h	2009-11-18 14:19:01.000000000 -0500
@@ -21,6 +21,7 @@
 #include <string.h>
 #include <errno.h>			/* MAI_STRERROR() */
 #include <limits.h>			/* CHAR_BIT */
+#include <validator/validator.h>
 
  /*
   * Backwards compatibility support for IPV4 systems without addrinfo API.
@@ -32,8 +33,6 @@
   * provides its own addrinfo() implementation. This also allows us to test
   * the IPV4 emulation code on an IPV6 enabled system.
   */
-#undef  freeaddrinfo
-#define freeaddrinfo	mai_freeaddrinfo
 #undef  gai_strerror
 #define gai_strerror	mai_strerror
 #undef  addrinfo
@@ -103,6 +102,16 @@
 
 #endif
 
+
+/* start dnssec patch additions */
+
+#define DNSSECAI_FAIL   -600  /* sharing number space with netdb.h errors */
+
+const char   *dnssec_strerror(int ecode);
+
+/* end dnssec patch additions (except for MAI_STRERROR below)*/
+
+
  /*
   * Bounds grow in leaps. These macros attempt to keep non-library code free
   * from IPV6 #ifdef pollution. Avoid macro names that end in STRLEN because
@@ -166,7 +175,8 @@
 
 #define MAI_CTL_END	0		/* list terminator */
 
-#define MAI_STRERROR(e) ((e) == EAI_SYSTEM ? strerror(errno) : gai_strerror(e))
+/* redefined by dnssec patch */
+#define MAI_STRERROR(e) ((e) == EAI_SYSTEM ? strerror(errno) : dnssec_strerror(e))
 
  /*
   * Macros for the case where we really don't want to be bothered with things
