diff -c -r postfix-2.2.11.orig/makedefs postfix-2.2.11/makedefs
*** postfix-2.2.11.orig/makedefs	2006-01-03 13:50:25.000000000 -0800
--- postfix-2.2.11/makedefs	2007-03-20 11:46:54.000000000 -0700
***************
*** 245,253 ****
  		#     GDBM_LIBS=gdbm
  		# fi
  		SYSLIBS="-ldb"
! 		for name in nsl resolv $GDBM_LIBS
  		do
! 		    for lib in /usr/lib64 /lib64 /usr/lib /lib
  		    do
  			test -e $lib/lib$name.a -o -e $lib/lib$name.so && {
  			    SYSLIBS="$SYSLIBS -l$name"
--- 245,253 ----
  		#     GDBM_LIBS=gdbm
  		# fi
  		SYSLIBS="-ldb"
! 		for name in nsl resolv val-threads sres crypto $GDBM_LIBS
  		do
! 		    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 -c -r postfix-2.2.11.orig/src/dns/dns.h postfix-2.2.11/src/dns/dns.h
*** postfix-2.2.11.orig/src/dns/dns.h	2006-01-04 11:52:05.000000000 -0800
--- postfix-2.2.11/src/dns/dns.h	2007-03-20 11:46:54.000000000 -0700
***************
*** 169,174 ****
--- 169,176 ----
    * Status codes. Failures must have negative codes so they will not collide
    * with valid counts of answer records etc.
    */
+                                        /* DNS_INSECURE added by dnssec patch */
+ #define DNS_INSECURE	(-5)		/* query was not validated */
  #define DNS_FAIL	(-4)		/* query failed, don't retry */
  #define DNS_NOTFOUND	(-3)		/* query ok, data not found */
  #define DNS_RETRY	(-2)		/* query failed, try again */
Only in postfix-2.2.11/src/dns: #dns_lookup.c#
diff -c -r postfix-2.2.11.orig/src/dns/dns_lookup.c postfix-2.2.11/src/dns/dns_lookup.c
*** postfix-2.2.11.orig/src/dns/dns_lookup.c	2006-02-02 11:59:23.000000000 -0800
--- postfix-2.2.11/src/dns/dns_lookup.c	2007-03-21 09:02:29.000000000 -0700
***************
*** 137,142 ****
--- 137,143 ----
  #include <msg.h>
  #include <valid_hostname.h>
  #include <stringops.h>
+ #include <validator/validator.h>
  
  /* DNS library. */
  
***************
*** 195,201 ****
       * Perform the lookup. Claim that the information cannot be found if and
       * only if the name server told us so.
       */
!     len = res_search((char *) name, C_IN, type, reply->buf, sizeof(reply->buf));
      _res.options &= ~flags;
      _res.options |= saved_options;
      if (len < 0) {
--- 196,210 ----
       * Perform the lookup. Claim that the information cannot be found if and
       * only if the name server told us so.
       */
! 
!     /* 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, sizeof(reply->buf),
!                         &val_status);
!         
      _res.options &= ~flags;
      _res.options |= saved_options;
      if (len < 0) {
***************
*** 216,223 ****
  	    return (DNS_RETRY);
  	}
      }
      if (msg_verbose)
! 	msg_info("dns_query: %s (%s): OK", name, dns_strtype(type));
  
      /*
       * Paranoia.
--- 225,244 ----
  	    return (DNS_RETRY);
  	}
      }
+     /* 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);
  
      /*
       * Paranoia.
diff -c -r postfix-2.2.11.orig/src/util/myaddrinfo.c postfix-2.2.11/src/util/myaddrinfo.c
*** postfix-2.2.11.orig/src/util/myaddrinfo.c	2005-06-16 11:26:29.000000000 -0700
--- postfix-2.2.11/src/util/myaddrinfo.c	2007-03-21 09:21:37.000000000 -0700
***************
*** 422,428 ****
  	}
  #endif
      }
!     return (getaddrinfo(hostname, service, &hints, res));
  #endif
  }
  
--- 422,453 ----
  	}
  #endif
      }
!     /* 
!      * 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. 
!      */
!     int retVal = 0;
!     val_status_t  vstatus;
!     if (0 == (retVal = val_getaddrinfo((val_context_t *)NULL, hostname, 
!                                        service, &hints, 
!                                        (struct val_addrinfo **)res,
!                                        &vstatus))) {
! 
!       if (0 == val_istrusted(vstatus))  {
!           retVal = DNSSECAI_FAIL;
!           msg_warn("DNSSEC, hostname information not trusted for host, %s (status: %d:%s, dnssec status %d:%s, val_getaddrinfo)", 
!                    hostname ? hostname : "NULL",
!                    retVal, MAI_STRERROR(retVal), 
!                    vstatus, p_val_status(vstatus));
!       }
!     }
!     else {
!       msg_warn("failed to get host information for host, %s (status %d:%s, val_getaddrinfo)", 
!                hostname ? hostname : "NULL", retVal, MAI_STRERROR(retVal));
!     }
!     return(retVal);
  #endif
  }
  
***************
*** 523,529 ****
  	}
  #endif
      }
!     return (getaddrinfo(hostaddr, service, &hints, res));
  #endif
  }
  
--- 548,581 ----
  	}
  #endif
      }
! 
!     /* 
!      * 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. 
!      */
!     int retVal = 0;
!     val_status_t  vstatus;
!     if (0 == (retVal = val_getaddrinfo((val_context_t *)NULL, hostaddr, 
!                                        service, &hints, 
!                                        (struct val_addrinfo **)res,
!                                        &vstatus))) {
! 
!       if (0 == val_istrusted(vstatus))  {
!           retVal = 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",
!                    retVal, MAI_STRERROR(retVal),
!                    vstatus, p_val_status(vstatus));
!       }
!     }
!     else {
!       msg_warn("failed to get host information for host, %s (status %d:%s, val_getaddrinfo)", 
!                hostaddr ? hostaddr : "NULL",
!                retVal, MAI_STRERROR(retVal));
!     }
!     return(retVal);
  #endif
  }
  
***************
*** 738,743 ****
--- 790,828 ----
  
  #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 */
+ 
+ 
+ /* 
+  * free_pf_dnssec_addrinfo - frees struct val_addrinfo.  Does a
+  *                           pointer conversion to call validator
+  *                           library free function. 
+  */
+ void free_pf_dnssec_addrinfo(struct addrinfo *ainfo){
+   free_val_addrinfo((struct val_addrinfo *) ainfo);
+ }
+ 
+ 
  #ifdef TEST
  
   /*
***************
*** 763,811 ****
  
      inet_proto_init(argv[0], argv[1]);
  
!     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));
      } else {
  	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));
  		continue;
  	    }
  	    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));
  		continue;
  	    }
  	    msg_info("%s -> %s", addr.buf, host.buf);
  	}
  	freeaddrinfo(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));
      } else {
  	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));
  	} 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));
  	    } else
  		msg_info("%s -> %s", addr.buf, host.buf);
  	    freeaddrinfo(ip);
--- 848,909 ----
  
      inet_proto_init(argv[0], argv[1]);
  
!      msg_info("=== hostname %s ===", argv[2]);
  
      if ((err = hostname_to_sockaddr(argv[2], (char *) 0, 0, &info)) != 0) {
! 	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: 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: 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): 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: 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",
! 		   MAI_STRERROR(err));
  	    } else
  		msg_info("%s -> %s", addr.buf, host.buf);
  	    freeaddrinfo(ip);
***************
*** 814,817 ****
      exit(0);
  }
  
! #endif
--- 912,915 ----
      exit(0);
  }
  
! #endif 
diff -c -r postfix-2.2.11.orig/src/util/myaddrinfo.h postfix-2.2.11/src/util/myaddrinfo.h
*** postfix-2.2.11.orig/src/util/myaddrinfo.h	2005-01-18 17:22:19.000000000 -0800
--- postfix-2.2.11/src/util/myaddrinfo.h	2007-03-20 11:46:54.000000000 -0700
***************
*** 21,26 ****
--- 21,27 ----
  #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,39 ****
    * 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
--- 33,38 ----
***************
*** 103,108 ****
--- 102,123 ----
  
  #endif
  
+ 
+ /* start dnssec patch additions */
+ 
+ #define DNSSECAI_FAIL   -600  /* sharing number space with netdb.h errors */
+ 
+ /* Used for explicit pointer conversion (i.e. gets rid of compiler
+    warnings). */
+ void free_pf_dnssec_addrinfo(struct addrinfo *ainfo);
+ #undef  freeaddrinfo
+ #define freeaddrinfo	free_pf_dnssec_addrinfo
+ 
+ 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
***************
*** 159,165 ****
  
  #define MAI_CTL_END	0		/* list terminator */
  
! #define MAI_STRERROR(e) ((e) == EAI_SYSTEM ? strerror(errno) : gai_strerror(e))
  
   /*
    * Macros for the case where we really don't want to be bothered with things
--- 174,181 ----
  
  #define MAI_CTL_END	0		/* list terminator */
  
! /* 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
