summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcvs2git2004-05-15 11:01:15 (GMT)
committercvs2git2012-06-24 12:13:13 (GMT)
commita3d69a8b435df9ab0da845a268aa49dc30773473 (patch)
tree68a1c611b4f8a519b2db899bb8d8f0589d34621b
parenta2a35b148558b7858f7773f2bd0f82925e89e91f (diff)
downloadpostfix-a3d69a8b435df9ab0da845a268aa49dc30773473.zip
postfix-a3d69a8b435df9ab0da845a268aa49dc30773473.tar.gz
This commit was manufactured by cvs2git to create branch 'POSTFIX_2_1'.
Sprout from master 2004-05-15 11:01:15 UTC Tomek Orzechowski <orzech@pld-linux.org> '- updated' Delete: postfix-authinfo.patch postfix-dict_ldap.patch postfix-ipv6.patch postfix-ns-mx-acl.patch postfix-pgsql.patch postfix-pl.patch postfix-sasl2.patch
-rw-r--r--postfix-authinfo.patch48
-rw-r--r--postfix-dict_ldap.patch1162
-rw-r--r--postfix-ipv6.patch3031
-rw-r--r--postfix-ns-mx-acl.patch478
-rw-r--r--postfix-pgsql.patch916
-rw-r--r--postfix-pl.patch386
-rw-r--r--postfix-sasl2.patch298
7 files changed, 0 insertions, 6319 deletions
diff --git a/postfix-authinfo.patch b/postfix-authinfo.patch
deleted file mode 100644
index 85c1b53..0000000
--- a/postfix-authinfo.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-diff -Nur snapshot-20011114.orig/src/global/mail_params.h snapshot-20011114/src/global/mail_params.h
---- snapshot-20011114.orig/src/global/mail_params.h Thu Nov 15 15:13:42 2001
-+++ snapshot-20011114/src/global/mail_params.h Thu Nov 15 15:15:21 2001
-@@ -961,6 +961,10 @@
- #define DEF_SMTPD_SASL_REALM "$myhostname"
- extern char *var_smtpd_sasl_realm;
-
-+#define VAR_PUBLISH_SASL_USERNAME "publish_sasl_username"
-+#define DEF_PUBLISH_SASL_USERNAME 0
-+extern bool var_publish_sasl_username;
-+
- /*
- * SASL authentication support, SMTP client side.
- */
-Binary files snapshot-20011114.orig/src/smtpd/.smtpd.c.rej.swp and snapshot-20011114/src/smtpd/.smtpd.c.rej.swp differ
-diff -Nur snapshot-20011114.orig/src/smtpd/smtpd.c snapshot-20011114/src/smtpd/smtpd.c
---- snapshot-20011114.orig/src/smtpd/smtpd.c Thu Nov 15 15:13:42 2001
-+++ snapshot-20011114/src/smtpd/smtpd.c Thu Nov 15 15:20:19 2001
-@@ -359,6 +359,7 @@
- bool var_smtpd_sasl_enable;
- char *var_smtpd_sasl_opts;
- char *var_smtpd_sasl_realm;
-+bool var_publish_sasl_username;
- char *var_filter_xport;
- bool var_broken_auth_clients;
- char *var_perm_mx_networks;
-@@ -1011,6 +1012,13 @@
- "Received: from %s (%s [%s])",
- state->helo_name ? state->helo_name : state->name,
- state->name, state->addr);
-+#ifdef USE_SASL_AUTH
-+ if (var_publish_sasl_username)
-+ rec_fprintf(state->cleanup, REC_TYPE_NORM,
-+ "\tsender authenticated as: \"%s\"",
-+ state->sasl_username ? state->sasl_username : "<none>");
-+#endif
-+
- if (var_smtpd_tls_received_header && state->tls_active) {
- rec_fprintf(state->cleanup, REC_TYPE_NORM,
- "\t(using %s with cipher %s (%d/%d bits))",
-@@ -1839,6 +1847,7 @@
- VAR_DISABLE_VRFY_CMD, DEF_DISABLE_VRFY_CMD, &var_disable_vrfy_cmd,
- VAR_ALLOW_UNTRUST_ROUTE, DEF_ALLOW_UNTRUST_ROUTE, &var_allow_untrust_route,
- VAR_SMTPD_SASL_ENABLE, DEF_SMTPD_SASL_ENABLE, &var_smtpd_sasl_enable,
-+ VAR_PUBLISH_SASL_USERNAME, DEF_PUBLISH_SASL_USERNAME, &var_publish_sasl_username,
- VAR_BROKEN_AUTH_CLNTS, DEF_BROKEN_AUTH_CLNTS, &var_broken_auth_clients,
- VAR_SMTPD_TLS_WRAPPER, DEF_SMTPD_TLS_WRAPPER, &var_smtpd_tls_wrappermode,
- VAR_SMTPD_USE_TLS, DEF_SMTPD_USE_TLS, &var_smtpd_use_tls,
diff --git a/postfix-dict_ldap.patch b/postfix-dict_ldap.patch
deleted file mode 100644
index 185d098..0000000
--- a/postfix-dict_ldap.patch
+++ /dev/null
@@ -1,1162 +0,0 @@
---- postfix-2.0.19.old/src/util/dict_ldap.c 2002-10-17 02:26:41.000000000 +0200
-+++ postfix-2.0.19.new/src/util/dict_ldap.c 2004-04-10 21:08:37.000000000 +0200
-@@ -26,7 +26,9 @@
- /* .PP
- /* Configuration parameters:
- /* .IP \fIldapsource_\fRserver_host
--/* The host at which all LDAP queries are directed.
-+/* List of hosts at which all LDAP queries are directed.
-+/* The host names can also be LDAP URLs if the LDAP client library used
-+/* is OpenLDAP.
- /* .IP \fIldapsource_\fRserver_port
- /* The port the LDAP server listens on.
- /* .IP \fIldapsource_\fRsearch_base
-@@ -57,14 +59,56 @@
- /* If you must bind to the server, do it with this distinguished name ...
- /* .IP \fIldapsource_\fRbind_pw
- /* \&... and this password.
--/* .IP \fIldapsource_\fRcache
-+/* .IP \fIldapsource_\fRcache (no longer supported)
- /* Whether or not to turn on client-side caching.
--/* .IP \fIldapsource_\fRcache_expiry
-+/* .IP \fIldapsource_\fRcache_expiry (no longer supported)
- /* If you do cache results, expire them after this many seconds.
--/* .IP \fIldapsource_\fRcache_size
-+/* .IP \fIldapsource_\fRcache_size (no longer supported)
- /* The cache size in bytes. Does nothing if the cache is off, of course.
-+/* .IP \fIldapsource_\fRrecursion_limit
-+/* Maximum recursion depth when expanding DN or URL references.
-+/* Queries which exceed the recursion limit fail with
-+/* dict_errno = DICT_ERR_RETRY.
-+/* .IP \fIldapsource_\fRexpansion_limit
-+/* Limit (if any) on the total number of lookup result values. Lookups which
-+/* exceed the limit fail with dict_errno=DICT_ERR_RETRY. Note that
-+/* each value of a multivalued result attribute counts as one result.
-+/* .IP \fIldapsource_\fRsize_limit
-+/* Limit on the number of entries returned by individual LDAP queries.
-+/* Queries which exceed the limit fail with dict_errno=DICT_ERR_RETRY.
-+/* This is an *entry* count, for any single query performed during the
-+/* possibly recursive lookup.
-+/* .IP \fIldapsource_\fRchase_referrals
-+/* Controls whether LDAP referrals are obeyed.
- /* .IP \fIldapsource_\fRdereference
- /* How to handle LDAP aliases. See ldap.h or ldap_open(3) man page.
-+/* .IP \fIldapsource_\fRversion
-+/* Specifies the LDAP protocol version to use. Default is version
-+/* \fI2\fR.
-+/* .IP \fIldapsource_\fRstart_tls
-+/* Whether or not to issue STARTTLS upon connection to the server.
-+/* At this time, STARTTLS and LDAP SSL are only available if the
-+/* LDAP client library used is OpenLDAP. Default is \fIno\fR.
-+/* .IP \fIldapsource_\fRtls_ca_cert_file
-+/* File containing certificates for all of the X509 Certificate
-+/* Authorities the client will recognize. Takes precedence over
-+/* tls_ca_cert_dir.
-+/* .IP \fIldapsource_\fRtls_ca_cert_dir
-+/* Directory containing X509 Certificate Authority certificates
-+/* in separate individual files.
-+/* .IP \fIldapsource_\fRtls_cert
-+/* File containing client's X509 certificate.
-+/* .IP \fIldapsource_\fRtls_key
-+/* File containing the private key corresponding to
-+/* tls_cert.
-+/* .IP \fIldapsource_\fRtls_require_cert
-+/* Whether or not to request server's X509 certificate and check its
-+/* validity.
-+/* .IP \fIldapsource_\fRtls_random_file
-+/* Path of a file to obtain random bits from when /dev/[u]random is
-+/* not available. Generally set to the name of the EGD/PRNGD socket.
-+/* .IP \fIldapsource_\fRtls_cipher_suite
-+/* Cipher suite to use in SSL/TLS negotiations.
- /* .IP \fIldapsource_\fRdebuglevel
- /* Debug level. See 'loglevel' option in slapd.conf(5) man page.
- /* Currently only in openldap libraries (and derivatives).
-@@ -102,6 +146,8 @@
- #include <lber.h>
- #include <ldap.h>
- #include <string.h>
-+#include <ctype.h>
-+#include <unistd.h>
-
- /*
- * Older APIs have weird memory freeing behavior.
-@@ -126,12 +172,22 @@
- #include "mymalloc.h"
- #include "vstring.h"
- #include "dict.h"
-+#include "stringops.h"
-+#include "binhash.h"
-+
- #include "dict_ldap.h"
-
- /* AAARGH!! */
-
- #include "../global/mail_conf.h"
-
-+#include "dict_ldap.h"
-+
-+typedef struct {
-+ LDAP *conn_ld;
-+ int conn_refcount;
-+} LDAP_CONN;
-+
- /*
- * Structure containing all the configuration parameters for a given
- * LDAP source, plus its connection handle.
-@@ -152,17 +208,33 @@
- char *bind_dn;
- char *bind_pw;
- int timeout;
-- int cache;
-- long cache_expiry;
-- long cache_size;
- int dereference;
-+ long recursion_limit;
-+ long expansion_limit;
-+ long size_limit;
- int chase_referrals;
- int debuglevel;
- int version;
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ int ldap_ssl;
-+ int start_tls;
-+ int tls_require_cert;
-+ char *tls_ca_cert_file;
-+ char *tls_ca_cert_dir;
-+ char *tls_cert;
-+ char *tls_key;
-+ char *tls_random_file;
-+ char *tls_cipher_suite;
-+#endif
-+ BINHASH_INFO *ht; /* hash entry for LDAP connection */
- LDAP *ld;
- } DICT_LDAP;
-
--#ifndef LDAP_OPT_NETWORK_TIMEOUT
-+#define DICT_LDAP_CONN(d) ((LDAP_CONN *)((d)->ht->value))
-+
-+static BINHASH *conn_hash = 0;
-+
-+#if defined(LDAP_API_FEATURE_X_OPENLDAP) || !defined(LDAP_OPT_NETWORK_TIMEOUT)
- /*
- * LDAP connection timeout support.
- */
-@@ -178,8 +250,17 @@
- static void dict_ldap_logprint(LDAP_CONST char *data)
- {
- char *myname = "dict_ldap_debug";
-+ char *buf,
-+ *p;
-
-- msg_info("%s: %s", myname, data);
-+ buf = mystrdup(data);
-+ if (*buf) {
-+ p = buf + strlen(buf) - 1;
-+ while (p - buf >= 0 && ISSPACE(*p))
-+ *p-- = 0;
-+ }
-+ msg_info("%s: %s", myname, buf);
-+ myfree(buf);
- }
-
-
-@@ -225,24 +306,97 @@
- return (ldap_result2error(dict_ldap->ld, res, 1));
- }
-
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+static void dict_ldap_set_tls_options(DICT_LDAP *dict_ldap)
-+{
-+ char *myname = "dict_ldap_set_tls_options";
-+ int rc;
-+
-+ if (dict_ldap->start_tls || dict_ldap->ldap_ssl) {
-+ if (*dict_ldap->tls_random_file) {
-+ if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_RANDOM_FILE,
-+ dict_ldap->tls_random_file)) != LDAP_SUCCESS)
-+ msg_warn("%s: Unable to set tls_random_file to %s: %d: %s",
-+ myname, dict_ldap->tls_random_file,
-+ rc, ldap_err2string(rc));
-+ }
-+ if (*dict_ldap->tls_ca_cert_file) {
-+ if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
-+ dict_ldap->tls_ca_cert_file)) != LDAP_SUCCESS)
-+ msg_warn("%s: Unable to set tls_ca_cert_file to %s: %d: %s",
-+ myname, dict_ldap->tls_ca_cert_file,
-+ rc, ldap_err2string(rc));
-+ }
-+ if (*dict_ldap->tls_ca_cert_dir) {
-+ if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTDIR,
-+ dict_ldap->tls_ca_cert_dir)) != LDAP_SUCCESS)
-+ msg_warn("%s: Unable to set tls_ca_cert_dir to %s: %d: %s",
-+ myname, dict_ldap->tls_ca_cert_dir,
-+ rc, ldap_err2string(rc));
-+ }
-+ if (*dict_ldap->tls_cert) {
-+ if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CERTFILE,
-+ dict_ldap->tls_cert)) != LDAP_SUCCESS)
-+ msg_warn("%s: Unable to set tls_cert to %s: %d: %s",
-+ myname, dict_ldap->tls_cert,
-+ rc, ldap_err2string(rc));
-+ }
-+ if (*dict_ldap->tls_key) {
-+ if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_KEYFILE,
-+ dict_ldap->tls_key)) != LDAP_SUCCESS)
-+ msg_warn("%s: Unable to set tls_key to %s: %d: %s",
-+ myname, dict_ldap->tls_key,
-+ rc, ldap_err2string(rc));
-+ }
-+ if (*dict_ldap->tls_cipher_suite) {
-+ if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CIPHER_SUITE,
-+ dict_ldap->tls_cipher_suite)) != LDAP_SUCCESS)
-+ msg_warn("%s: Unable to set tls_cipher_suite to %s: %d: %s",
-+ myname, dict_ldap->tls_cipher_suite,
-+ rc, ldap_err2string(rc));
-+ }
-+ if (dict_ldap->tls_require_cert) {
-+ if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
-+ &(dict_ldap->tls_require_cert))) != LDAP_SUCCESS)
-+ msg_warn("%s: Unable to set tls_require_cert to %d: %d: %s",
-+ myname, dict_ldap->tls_require_cert,
-+ rc, ldap_err2string(rc));
-+ }
-+ }
-+}
-+
-+#endif
-+
-+
- /* Establish a connection to the LDAP server. */
- static int dict_ldap_connect(DICT_LDAP *dict_ldap)
- {
- char *myname = "dict_ldap_connect";
- int rc = 0;
-
--#ifdef LDAP_API_FEATURE_X_MEMCACHE
-- LDAPMemCache *dircache;
--
--#endif
--
- #ifdef LDAP_OPT_NETWORK_TIMEOUT
- struct timeval mytimeval;
-
--#else
-+#endif
-+
-+#if defined(LDAP_API_FEATURE_X_OPENLDAP) || !defined(LDAP_OPT_NETWORK_TIMEOUT)
- void (*saved_alarm) (int);
-
- #endif
-+#if defined(LDAP_OPT_DEBUG_LEVEL) && defined(LBER_OPT_LOG_PRINT_FN)
-+ if (dict_ldap->debuglevel > 0 &&
-+ ber_set_option(NULL, LBER_OPT_LOG_PRINT_FN,
-+ (LDAP_CONST *) dict_ldap_logprint) != LBER_OPT_SUCCESS)
-+ msg_warn("%s: Unable to set ber logprint function.", myname);
-+#if defined(LBER_OPT_DEBUG_LEVEL)
-+ if (ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL,
-+ &(dict_ldap->debuglevel)) != LBER_OPT_SUCCESS)
-+ msg_warn("%s: Unable to set BER debug level.", myname);
-+#endif
-+ if (ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL,
-+ &(dict_ldap->debuglevel)) != LDAP_OPT_SUCCESS)
-+ msg_warn("%s: Unable to set LDAP debug level.", myname);
-+#endif
-
- dict_errno = 0;
-
-@@ -251,8 +405,13 @@
- dict_ldap->server_host);
-
- #ifdef LDAP_OPT_NETWORK_TIMEOUT
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ dict_ldap_set_tls_options(dict_ldap);
-+ ldap_initialize(&(dict_ldap->ld), dict_ldap->server_host);
-+#else
- dict_ldap->ld = ldap_init(dict_ldap->server_host,
- (int) dict_ldap->server_port);
-+#endif
- if (dict_ldap->ld == NULL) {
- msg_warn("%s: Unable to init LDAP server %s",
- myname, dict_ldap->server_host);
-@@ -308,12 +467,22 @@
- &dict_ldap->version) != LDAP_OPT_SUCCESS)
- msg_warn("%s: Unable to get LDAP protocol version", myname);
- else
-- msg_warn("%s: Actual Protocol version used is %d.",
-+ msg_info("%s: Actual Protocol version used is %d.",
- myname, dict_ldap->version);
- }
- #endif
-
- /*
-+ * Limit the number of entries returned by each query.
-+ */
-+ if (dict_ldap->size_limit) {
-+ if (ldap_set_option(dict_ldap->ld, LDAP_OPT_SIZELIMIT,
-+ &dict_ldap->size_limit) != LDAP_OPT_SUCCESS)
-+ msg_warn("%s: %s: Unable to set query result size limit to %ld.",
-+ myname, dict_ldap->ldapsource, dict_ldap->size_limit);
-+ }
-+
-+ /*
- * Configure alias dereferencing for this connection. Thanks to Mike
- * Mattice for this, and to Hery Rakotoarisoa for the v3 update.
- */
-@@ -321,16 +490,6 @@
- &(dict_ldap->dereference)) != LDAP_OPT_SUCCESS)
- msg_warn("%s: Unable to set dereference option.", myname);
-
--#if defined(LDAP_OPT_DEBUG_LEVEL) && defined(LBER_OPT_LOG_PRINT_FN)
-- if (dict_ldap->debuglevel > 0 &&
-- ber_set_option(NULL, LBER_OPT_LOG_PRINT_FN,
-- (LDAP_CONST *) dict_ldap_logprint) != LBER_OPT_SUCCESS)
-- msg_warn("%s: Unable to set ber logprint function.", myname);
-- if (ldap_set_option(dict_ldap->ld, LDAP_OPT_DEBUG_LEVEL,
-- &(dict_ldap->debuglevel)) != LDAP_OPT_SUCCESS)
-- msg_warn("%s: Unable to set LDAP debug level.", myname);
--#endif
--
- /* Chase referrals. */
-
- /*
-@@ -348,6 +507,36 @@
- }
- #endif
-
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ if (dict_ldap->start_tls) {
-+ if ((saved_alarm = signal(SIGALRM, dict_ldap_timeout)) == SIG_ERR) {
-+ msg_warn("%s: Error setting signal handler for STARTTLS timeout: %m",
-+ myname);
-+ dict_errno = DICT_ERR_RETRY;
-+ return (-1);
-+ }
-+ alarm(dict_ldap->timeout);
-+ if (setjmp(env) == 0)
-+ rc = ldap_start_tls_s(dict_ldap->ld, NULL, NULL);
-+ else
-+ rc = LDAP_TIMEOUT;
-+ alarm(0);
-+
-+ if (signal(SIGALRM, saved_alarm) == SIG_ERR) {
-+ msg_warn("%s: Error resetting signal handler after STARTTLS: %m",
-+ myname);
-+ dict_errno = DICT_ERR_RETRY;
-+ return (-1);
-+ }
-+ if (rc != LDAP_SUCCESS) {
-+ msg_error("%s: Unable to set STARTTLS: %d: %s", myname,
-+ rc, ldap_err2string(rc));
-+ dict_errno = DICT_ERR_RETRY;
-+ return (-1);
-+ }
-+ }
-+#endif
-+
- /*
- * If this server requires a bind, do so. Thanks to Sam Tardieu for
- * noticing that the original bind call was broken.
-@@ -370,52 +559,9 @@
- msg_info("%s: Successful bind to server %s as %s ",
- myname, dict_ldap->server_host, dict_ldap->bind_dn);
- }
-+ /* Save connection handle in shared container */
-+ DICT_LDAP_CONN(dict_ldap)->conn_ld = dict_ldap->ld;
-
-- /*
-- * Set up client-side caching if it's configured.
-- */
-- if (dict_ldap->cache) {
-- if (msg_verbose)
-- msg_info
-- ("%s: Enabling %ld-byte cache for %s with %ld-second expiry",
-- myname, dict_ldap->cache_size, dict_ldap->ldapsource,
-- dict_ldap->cache_expiry);
--
--#ifdef LDAP_API_FEATURE_X_MEMCACHE
-- rc = ldap_memcache_init(dict_ldap->cache_expiry, dict_ldap->cache_size,
-- NULL, NULL, &dircache);
-- if (rc != LDAP_SUCCESS) {
-- msg_warn
-- ("%s: Unable to configure cache for %s: %d (%s) -- continuing",
-- myname, dict_ldap->ldapsource, rc, ldap_err2string(rc));
-- } else {
-- rc = ldap_memcache_set(dict_ldap->ld, dircache);
-- if (rc != LDAP_SUCCESS) {
-- msg_warn
-- ("%s: Unable to configure cache for %s: %d (%s) -- continuing",
-- myname, dict_ldap->ldapsource, rc, ldap_err2string(rc));
-- } else {
-- if (msg_verbose)
-- msg_info("%s: Caching enabled for %s",
-- myname, dict_ldap->ldapsource);
-- }
-- }
--#else
--
-- rc = ldap_enable_cache(dict_ldap->ld, dict_ldap->cache_expiry,
-- dict_ldap->cache_size);
-- if (rc != LDAP_SUCCESS) {
-- msg_warn
-- ("%s: Unable to configure cache for %s: %d (%s) -- continuing",
-- myname, dict_ldap->ldapsource, rc, ldap_err2string(rc));
-- } else {
-- if (msg_verbose)
-- msg_info("%s: Caching enabled for %s",
-- myname, dict_ldap->ldapsource);
-- }
--
--#endif
-- }
- if (msg_verbose)
- msg_info("%s: Cached connection handle for LDAP source %s",
- myname, dict_ldap->ldapsource);
-@@ -424,9 +570,65 @@
- }
-
- /*
-+ * Locate or allocate connection cache entry.
-+ */
-+static void dict_ldap_conn_find(DICT_LDAP *dict_ldap)
-+{
-+ VSTRING *keybuf = vstring_alloc(10);
-+ char *key;
-+ int len;
-+
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ int sslon = dict_ldap->start_tls || dict_ldap->ldap_ssl;
-+
-+#endif
-+ LDAP_CONN *conn;
-+
-+#define ADDSTR(vp, s) vstring_memcat((vp), (s), strlen((s))+1)
-+#define ADDINT(vp, i) vstring_sprintf_append((vp), "%lu", (unsigned long)(i))
-+
-+ ADDSTR(keybuf, dict_ldap->server_host);
-+ ADDINT(keybuf, dict_ldap->server_port);
-+ ADDINT(keybuf, dict_ldap->bind);
-+ ADDSTR(keybuf, dict_ldap->bind ? dict_ldap->bind_dn : "");
-+ ADDSTR(keybuf, dict_ldap->bind ? dict_ldap->bind_pw : "");
-+ ADDINT(keybuf, dict_ldap->dereference);
-+ ADDINT(keybuf, dict_ldap->chase_referrals);
-+ ADDINT(keybuf, dict_ldap->debuglevel);
-+ ADDINT(keybuf, dict_ldap->version);
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ ADDINT(keybuf, dict_ldap->ldap_ssl);
-+ ADDINT(keybuf, dict_ldap->start_tls);
-+ ADDINT(keybuf, sslon ? dict_ldap->tls_require_cert : 0);
-+ ADDSTR(keybuf, sslon ? dict_ldap->tls_ca_cert_file : "");
-+ ADDSTR(keybuf, sslon ? dict_ldap->tls_ca_cert_dir : "");
-+ ADDSTR(keybuf, sslon ? dict_ldap->tls_cert : "");
-+ ADDSTR(keybuf, sslon ? dict_ldap->tls_key : "");
-+ ADDSTR(keybuf, sslon ? dict_ldap->tls_random_file : "");
-+ ADDSTR(keybuf, sslon ? dict_ldap->tls_cipher_suite : "");
-+#endif
-+
-+ key = vstring_str(keybuf);
-+ len = VSTRING_LEN(keybuf);
-+
-+ if (conn_hash == 0)
-+ conn_hash = binhash_create(0);
-+
-+ if ((dict_ldap->ht = binhash_locate(conn_hash, key, len)) == 0) {
-+ conn = (LDAP_CONN *) mymalloc(sizeof(LDAP_CONN));
-+ conn->conn_ld = 0;
-+ conn->conn_refcount = 0;
-+ dict_ldap->ht = binhash_enter(conn_hash, key, len, (char *) conn);
-+ }
-+ ++DICT_LDAP_CONN(dict_ldap)->conn_refcount;
-+
-+ vstring_free(keybuf);
-+}
-+
-+/*
- * expand a filter (lookup or result)
- */
--static void dict_ldap_expand_filter(char *filter, char *value, VSTRING *out)
-+static void dict_ldap_expand_filter(char *ldapsource, char *filter, char *value, VSTRING *out)
- {
- char *myname = "dict_ldap_expand_filter";
- char *sub,
-@@ -462,8 +664,8 @@
- break;
- default:
- msg_warn
-- ("%s: Invalid filter substitution format '%%%c'!",
-- myname, *(sub + 1));
-+ ("%s: %s: Invalid filter substitution format '%%%c'!",
-+ myname, ldapsource, *(sub + 1));
- /* fall through */
- case 's':
- vstring_strcat(out, u);
-@@ -486,6 +688,9 @@
- static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage * res,
- VSTRING *result)
- {
-+ static int recursion = 0;
-+ static int expansion;
-+ long entries = 0;
- long i = 0;
- int rc = 0;
- LDAPMessage *resloop = 0;
-@@ -500,13 +705,27 @@
- tv.tv_sec = dict_ldap->timeout;
- tv.tv_usec = 0;
-
-+ if (++recursion == 1)
-+ expansion = 0;
-+
- if (msg_verbose)
-- msg_info("%s: Search found %d match(es)", myname,
-+ msg_info("%s[%d]: Search found %d match(es)", myname, recursion,
- ldap_count_entries(dict_ldap->ld, res));
-
- for (entry = ldap_first_entry(dict_ldap->ld, res); entry != NULL;
- entry = ldap_next_entry(dict_ldap->ld, entry)) {
- ber = NULL;
-+
-+ /*
-+ * LDAP should not, but may produce more than the requested maximum
-+ * number of entries.
-+ */
-+ if (dict_errno == 0 && ++entries > dict_ldap->size_limit
-+ && dict_ldap->size_limit) {
-+ msg_warn("%s[%d]: %s: Query size limit (%ld) exceeded", myname,
-+ recursion, dict_ldap->ldapsource, dict_ldap->size_limit);
-+ dict_errno = DICT_ERR_RETRY;
-+ }
- for (attr = ldap_first_attribute(dict_ldap->ld, entry, &ber);
- attr != NULL;
- ldap_memfree(attr), attr = ldap_next_attribute(dict_ldap->ld,
-@@ -514,17 +733,38 @@
- vals = ldap_get_values(dict_ldap->ld, entry, attr);
- if (vals == NULL) {
- if (msg_verbose)
-- msg_info("%s: Entry doesn't have any values for %s",
-- myname, attr);
-+ msg_info("%s[%d]: Entry doesn't have any values for %s",
-+ myname, recursion, attr);
- continue;
- }
-+
-+ /*
-+ * If we previously encountered an error, we still continue
-+ * through the loop, to avoid memory leaks, but we don't waste
-+ * time accumulating any further results.
-+ *
-+ * XXX: There may be a more efficient way to exit the loop with no
-+ * leaks, but it will likely be more fragile and not worth the
-+ * extra code.
-+ */
-+ if (dict_errno != 0 || vals[0] == 0) {
-+ ldap_value_free(vals);
-+ continue;
-+ }
-+
-+ /*
-+ * The "result_attributes" list enumerates all the requested
-+ * attributes, first the ordinary result attribtutes and then the
-+ * special result attributes that hold DN or LDAP URL values.
-+ *
-+ * The number of ordinary attributes is "num_attributes".
-+ *
-+ * We compute the attribute type (ordinary or special) from its
-+ * index on the "result_attributes" list.
-+ */
- for (i = 0; dict_ldap->result_attributes->argv[i]; i++) {
-- if (strcasecmp(dict_ldap->result_attributes->argv[i],
-- attr) == 0) {
-- if (msg_verbose)
-- msg_info("%s: search returned %ld value(s) for requested result attribute %s", myname, i, attr);
-+ if (strcasecmp(dict_ldap->result_attributes->argv[i], attr) == 0)
- break;
-- }
- }
-
- /*
-@@ -532,20 +772,38 @@
- * recursing (for dn or url attributes).
- */
- if (i < dict_ldap->num_attributes) {
-+ /* Ordinary result attribute */
- for (i = 0; vals[i] != NULL; i++) {
-+ if (++expansion > dict_ldap->expansion_limit &&
-+ dict_ldap->expansion_limit) {
-+ msg_warn("%s[%d]: %s: Expansion limit exceeded at"
-+ " result attribute %s=%s", myname, recursion,
-+ dict_ldap->ldapsource, attr, vals[i]);
-+ dict_errno = DICT_ERR_RETRY;
-+ break;
-+ }
- if (VSTRING_LEN(result) > 0)
- vstring_strcat(result, ",");
- if (dict_ldap->result_filter == NULL)
- vstring_strcat(result, vals[i]);
- else
-- dict_ldap_expand_filter(dict_ldap->result_filter,
-+ dict_ldap_expand_filter(dict_ldap->ldapsource,
-+ dict_ldap->result_filter,
- vals[i], result);
- }
-- } else if (dict_ldap->result_attributes->argv[i]) {
-+ if (dict_errno != 0)
-+ continue;
-+ if (msg_verbose)
-+ msg_info("%s[%d]: search returned %ld value(s) for"
-+ " requested result attribute %s",
-+ myname, recursion, i, attr);
-+ } else if (recursion < dict_ldap->recursion_limit
-+ && dict_ldap->result_attributes->argv[i]) {
-+ /* Special result attribute */
- for (i = 0; vals[i] != NULL; i++) {
- if (ldap_is_ldap_url(vals[i])) {
- if (msg_verbose)
-- msg_info("%s: looking up URL %s", myname,
-+ msg_info("%s[%d]: looking up URL %s", myname, recursion,
- vals[i]);
- rc = ldap_url_parse(vals[i], &url);
- if (rc == 0) {
-@@ -557,7 +815,7 @@
- }
- } else {
- if (msg_verbose)
-- msg_info("%s: looking up DN %s", myname, vals[i]);
-+ msg_info("%s[%d]: looking up DN %s", myname, recursion, vals[i]);
- rc = ldap_search_st(dict_ldap->ld, vals[i],
- LDAP_SCOPE_BASE, "objectclass=*",
- dict_ldap->result_attributes->argv,
-@@ -573,11 +831,11 @@
- * Go ahead and treat this as though the DN existed
- * and just didn't have any result attributes.
- */
-- msg_warn("%s: DN %s not found, skipping ", myname,
-- vals[i]);
-+ msg_warn("%s[%d]: DN %s not found, skipping ", myname,
-+ recursion, vals[i]);
- break;
- default:
-- msg_warn("%s: search error %d: %s ", myname, rc,
-+ msg_warn("%s[%d]: search error %d: %s ", myname, recursion, rc,
- ldap_err2string(rc));
- dict_errno = DICT_ERR_RETRY;
- break;
-@@ -585,7 +843,21 @@
-
- if (resloop != 0)
- ldap_msgfree(resloop);
-+ if (dict_errno != 0)
-+ break;
- }
-+ if (dict_errno != 0)
-+ continue;
-+ if (msg_verbose)
-+ msg_info("%s[%d]: search returned %ld value(s) for"
-+ " special result attribute %s",
-+ myname, recursion, i, attr);
-+ } else if (recursion >= dict_ldap->recursion_limit
-+ && dict_ldap->result_attributes->argv[i]) {
-+ msg_warn("%s[%d]: %s: Recursion limit exceeded"
-+ " for special attribute %s=%s",
-+ myname, recursion, dict_ldap->ldapsource, attr, vals[0]);
-+ dict_errno = DICT_ERR_RETRY;
- }
- ldap_value_free(vals);
- }
-@@ -593,7 +865,8 @@
- ber_free(ber, 0);
- }
- if (msg_verbose)
-- msg_info("%s: Leaving %s", myname, myname);
-+ msg_info("%s[%d]: Leaving %s", myname, recursion, myname);
-+ --recursion;
- }
-
- /* dict_ldap_lookup - find database entry */
-@@ -608,6 +881,7 @@
- VSTRING *escaped_name = 0,
- *filter_buf = 0;
- int rc = 0;
-+ int sizelimit;
- char *sub,
- *end;
-
-@@ -624,11 +898,8 @@
- if (dict_ldap->domain) {
- const char *p = strrchr(name, '@');
-
-- if (p != 0)
-- p = p + 1;
-- else
-- p = name;
-- if (match_list_match(dict_ldap->domain, p) == 0) {
-+ if (p == 0 || p == name ||
-+ match_list_match(dict_ldap->domain, ++p) == 0) {
- if (msg_verbose)
- msg_info("%s: domain of %s not found in domain list", myname,
- name);
-@@ -644,6 +915,13 @@
- vstring_strcpy(result, "");
-
- /*
-+ * Because the connection may be shared and invalidated via queries for
-+ * another map, update private copy of "ld" from shared connection
-+ * container.
-+ */
-+ dict_ldap->ld = DICT_LDAP_CONN(dict_ldap)->conn_ld;
-+
-+ /*
- * Connect to the LDAP server, if necessary.
- */
- if (dict_ldap->ld == NULL) {
-@@ -663,6 +941,18 @@
- msg_info("%s: Using existing connection for LDAP source %s",
- myname, dict_ldap->ldapsource);
-
-+ /*
-+ * Connection caching, means that the connection handle may have the
-+ * wrong size limit. Re-adjust before each query. This is cheap, just
-+ * sets a field in the ldap connection handle. We also do this in the
-+ * connect code, because we sometimes reconnect (below) in the middle of
-+ * a query.
-+ */
-+ sizelimit = dict_ldap->size_limit ? dict_ldap->size_limit : LDAP_NO_LIMIT;
-+ if (ldap_set_option(dict_ldap->ld, LDAP_OPT_SIZELIMIT, &sizelimit)
-+ != LDAP_OPT_SUCCESS)
-+ msg_warn("%s: %s: Unable to set query result size limit to %ld.",
-+ myname, dict_ldap->ldapsource, dict_ldap->size_limit);
-
- /*
- * Prepare the query.
-@@ -720,11 +1010,11 @@
- /*
- * No, log the fact and continue.
- */
-- msg_warn("%s: Fixed query_filter %s is probably useless", myname,
-- dict_ldap->query_filter);
-+ msg_warn("%s: %s: Fixed query_filter %s is probably useless", myname,
-+ dict_ldap->ldapsource, dict_ldap->query_filter);
- vstring_strcpy(filter_buf, dict_ldap->query_filter);
- } else {
-- dict_ldap_expand_filter(dict_ldap->query_filter,
-+ dict_ldap_expand_filter(dict_ldap->ldapsource, dict_ldap->query_filter,
- vstring_str(escaped_name), filter_buf);
- }
-
-@@ -747,7 +1037,7 @@
- myname, dict_ldap->ldapsource);
-
- ldap_unbind(dict_ldap->ld);
-- dict_ldap->ld = NULL;
-+ dict_ldap->ld = DICT_LDAP_CONN(dict_ldap)->conn_ld = 0;
- dict_ldap_connect(dict_ldap);
-
- /*
-@@ -799,7 +1089,7 @@
- * next lookup.
- */
- ldap_unbind(dict_ldap->ld);
-- dict_ldap->ld = NULL;
-+ dict_ldap->ld = DICT_LDAP_CONN(dict_ldap)->conn_ld = 0;
-
- /*
- * And tell the caller to try again later.
-@@ -830,9 +1120,18 @@
- {
- char *myname = "dict_ldap_close";
- DICT_LDAP *dict_ldap = (DICT_LDAP *) dict;
-+ LDAP_CONN *conn = DICT_LDAP_CONN(dict_ldap);
-+ BINHASH_INFO *ht = dict_ldap->ht;
-
-- if (dict_ldap->ld)
-- ldap_unbind(dict_ldap->ld);
-+ if (--conn->conn_refcount == 0) {
-+ if (conn->conn_ld) {
-+ if (msg_verbose)
-+ msg_info("%s: Closed connection handle for LDAP source %s",
-+ myname, dict_ldap->ldapsource);
-+ ldap_unbind(conn->conn_ld);
-+ }
-+ binhash_delete(conn_hash, ht->key, ht->key_len, myfree);
-+ }
-
- myfree(dict_ldap->ldapsource);
- myfree(dict_ldap->server_host);
-@@ -845,19 +1144,32 @@
- argv_free(dict_ldap->result_attributes);
- myfree(dict_ldap->bind_dn);
- myfree(dict_ldap->bind_pw);
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ myfree(dict_ldap->tls_ca_cert_file);
-+ myfree(dict_ldap->tls_ca_cert_dir);
-+ myfree(dict_ldap->tls_cert);
-+ myfree(dict_ldap->tls_key);
-+ myfree(dict_ldap->tls_random_file);
-+ myfree(dict_ldap->tls_cipher_suite);
-+#endif
- dict_free(dict);
- }
-
- /* dict_ldap_open - create association with data base */
-
--DICT *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
-+DICT *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
- {
- char *myname = "dict_ldap_open";
- DICT_LDAP *dict_ldap;
- VSTRING *config_param;
-+ VSTRING *url_list;
-+ char *s;
-+ char *h;
- char *domainlist;
-+ char *server_host;
- char *scope;
- char *attr;
-+ int tmp;
-
- if (msg_verbose)
- msg_info("%s: Using LDAP source %s", myname, ldapsource);
-@@ -870,15 +1182,14 @@
-
- dict_ldap->ldapsource = mystrdup(ldapsource);
-
-+ dict_ldap->ld = NULL;
-+
- config_param = vstring_alloc(15);
- vstring_sprintf(config_param, "%s_server_host", ldapsource);
-
-- dict_ldap->server_host =
-+ server_host =
- mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
-- "localhost", 0, 0));
-- if (msg_verbose)
-- msg_info("%s: %s is %s", myname, vstring_str(config_param),
-- dict_ldap->server_host);
-+ "localhost", 1, 0));
-
- /*
- * get configured value of "ldapsource_server_port"; default to LDAP_PORT
-@@ -892,11 +1203,87 @@
- dict_ldap->server_port);
-
- /*
-+ * Define LDAP Version.
-+ */
-+ vstring_sprintf(config_param, "%s_version", ldapsource);
-+ dict_ldap->version = get_mail_conf_int(vstring_str(config_param), 2, 2, 0);
-+ switch (dict_ldap->version) {
-+ case 2:
-+ dict_ldap->version = LDAP_VERSION2;
-+ break;
-+ case 3:
-+ dict_ldap->version = LDAP_VERSION3;
-+ break;
-+ default:
-+ msg_warn("%s: Unknown version %d.", myname, dict_ldap->version);
-+ dict_ldap->version = LDAP_VERSION2;
-+ }
-+
-+#if defined(LDAP_API_FEATURE_X_OPENLDAP)
-+ dict_ldap->ldap_ssl = 0;
-+#endif
-+
-+ url_list = vstring_alloc(32);
-+ s = server_host;
-+ while ((h = mystrtok(&s, " \t\n\r,")) != NULL) {
-+#if defined(LDAP_API_FEATURE_X_OPENLDAP)
-+
-+ /*
-+ * Convert (host, port) pairs to LDAP URLs
-+ */
-+ if (ldap_is_ldap_url(h)) {
-+ LDAPURLDesc *url_desc;
-+ int rc;
-+
-+ if ((rc = ldap_url_parse(h, &url_desc)) != 0) {
-+ msg_error("%s: error parsing URL %s: %d: %s; skipping", myname,
-+ h, rc, ldap_err2string(rc));
-+ continue;
-+ }
-+ if (strcasecmp(url_desc->lud_scheme, "ldap") != 0 &&
-+ dict_ldap->version != LDAP_VERSION3) {
-+ msg_warn("%s: URL scheme %s requires protocol version 3", myname,
-+ url_desc->lud_scheme);
-+ dict_ldap->version = LDAP_VERSION3;
-+ }
-+ if (strcasecmp(url_desc->lud_scheme, "ldaps") == 0)
-+ dict_ldap->ldap_ssl = 1;
-+ ldap_free_urldesc(url_desc);
-+ vstring_sprintf_append(url_list, " %s", h);
-+ } else {
-+ if (strrchr(h, ':'))
-+ vstring_sprintf_append(url_list, " ldap://%s", h);
-+ else
-+ vstring_sprintf_append(url_list, " ldap://%s:%d", h,
-+ dict_ldap->server_port);
-+ }
-+#else
-+ vstring_sprintf_append(url_list, " %s", h);
-+#endif
-+ }
-+
-+ dict_ldap->server_host =
-+ mystrdup(VSTRING_LEN(url_list) > 0 ? vstring_str(url_list) + 1 : "");
-+
-+#if defined(LDAP_API_FEATURE_X_OPENLDAP)
-+ /*
-+ * With URL scheme, clear port to normalize connection cache key
-+ */
-+
-+ dict_ldap->server_port = LDAP_PORT;
-+ if (msg_verbose)
-+ msg_info("%s: %s server_host URL is %s", myname, ldapsource,
-+ dict_ldap->server_host);
-+#endif
-+ myfree(server_host);
-+ vstring_free(url_list);
-+
-+ /*
- * Scope handling thanks to Carsten Hoeger of SuSE.
- */
- vstring_sprintf(config_param, "%s_scope", ldapsource);
- scope =
-- (char *) get_mail_conf_str(vstring_str(config_param), "sub", 0, 0);
-+ (char *) get_mail_conf_str(vstring_str(config_param), "sub", 1, 0);
-
- if (strcasecmp(scope, "one") == 0) {
- dict_ldap->scope = LDAP_SCOPE_ONELEVEL;
-@@ -910,12 +1297,15 @@
- msg_info("%s: %s is LDAP_SCOPE_BASE", myname,
- vstring_str(config_param));
-
-- } else {
-+ } else if (strcasecmp(scope, "sub") == 0) {
- dict_ldap->scope = LDAP_SCOPE_SUBTREE;
- if (msg_verbose)
- msg_info("%s: %s is LDAP_SCOPE_SUBTREE", myname,
- vstring_str(config_param));
--
-+ } else {
-+ dict_ldap->scope = LDAP_SCOPE_SUBTREE;
-+ msg_warn("%s: %s: Unrecognized value %s specified for scope; using sub",
-+ myname, vstring_str(config_param), scope);
- }
-
- myfree(scope);
-@@ -992,6 +1382,8 @@
- msg_info("%s: %s is %s", myname, vstring_str(config_param), attr);;
- dict_ldap->result_attributes = argv_split(attr, " ,\t\r\n");
- dict_ldap->num_attributes = dict_ldap->result_attributes->argc;
-+
-+ myfree(attr);
-
- vstring_sprintf(config_param, "%s_special_result_attribute", ldapsource);
- attr = mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
-@@ -1003,6 +1395,8 @@
- argv_split_append(dict_ldap->result_attributes, attr, " ,\t\r\n");
- }
-
-+ myfree(attr);
-+
- /*
- * get configured value of "ldapsource_bind"; default to true
- */
-@@ -1040,31 +1434,60 @@
- * get configured value of "ldapsource_cache"; default to false
- */
- vstring_sprintf(config_param, "%s_cache", ldapsource);
-- dict_ldap->cache = get_mail_conf_bool(vstring_str(config_param), 0);
-- if (msg_verbose)
-- msg_info("%s: %s is %d", myname, vstring_str(config_param),
-- dict_ldap->cache);
-+ tmp = get_mail_conf_bool(vstring_str(config_param), 0);
-+ if (tmp)
-+ msg_warn("%s: %s ignoring cache", myname, vstring_str(config_param));
-
- /*
- * get configured value of "ldapsource_cache_expiry"; default to 30
- * seconds
- */
- vstring_sprintf(config_param, "%s_cache_expiry", ldapsource);
-- dict_ldap->cache_expiry = get_mail_conf_int(vstring_str(config_param),
-- 30, 0, 0);
-- if (msg_verbose)
-- msg_info("%s: %s is %ld", myname, vstring_str(config_param),
-- dict_ldap->cache_expiry);
-+ tmp = get_mail_conf_int(vstring_str(config_param), -1, 0, 0);
-+
-+ if (tmp >= 0)
-+ msg_warn("%s: %s ignoring cache_expiry", myname, vstring_str(config_param));
-
- /*
- * get configured value of "ldapsource_cache_size"; default to 32k
- */
- vstring_sprintf(config_param, "%s_cache_size", ldapsource);
-- dict_ldap->cache_size = get_mail_conf_int(vstring_str(config_param),
-- 32768, 0, 0);
-+ tmp = get_mail_conf_int(vstring_str(config_param),
-+ -1, 0, 0);
-+ if (tmp >= 0)
-+ msg_warn("%s: %s ignoring cache_size", myname, vstring_str(config_param));
-+
-+ /*
-+ * get configured value of "recursion_limit"; default to 1000
-+ */
-+ vstring_sprintf(config_param, "%s_recursion_limit", ldapsource);
-+ dict_ldap->recursion_limit = get_mail_conf_int(vstring_str(config_param),
-+ 1000, 1, 0);
-+
-+ if (msg_verbose)
-+ msg_info("%s: %s is %ld", myname, vstring_str(config_param),
-+ dict_ldap->recursion_limit);
-+
-+ /*
-+ * Define LDAP Version.
-+ * get configured value of "expansion_limit"; default to 0
-+ */
-+
-+ vstring_sprintf(config_param, "%s_expansion_limit", ldapsource);
-+ dict_ldap->expansion_limit = get_mail_conf_int(vstring_str(config_param),
-+ 0, 0, 0);
-+ if (msg_verbose)
-+ msg_info("%s: %s is %ld", myname, vstring_str(config_param),
-+ dict_ldap->expansion_limit);
-+ /*
-+ * get configured value of "size_limit"; default to expansion_limit
-+ */
-+ vstring_sprintf(config_param, "%s_size_limit", ldapsource);
-+ dict_ldap->size_limit = get_mail_conf_int(vstring_str(config_param),
-+ dict_ldap->expansion_limit, 0, 0);
- if (msg_verbose)
-- msg_info("%s: %s is %ld", myname, vstring_str(config_param),
-- dict_ldap->cache_size);
-+ msg_info("%s: %s is %ld", myname, vstring_str(config_param),
-+ dict_ldap->size_limit);
-
- /*
- * Alias dereferencing suggested by Mike Mattice.
-@@ -1074,29 +1497,11 @@
- 0);
-
- /*
-- * Define LDAP Version.
-- */
-- vstring_sprintf(config_param, "%s_version", ldapsource);
-- dict_ldap->version = get_mail_conf_int(vstring_str(config_param), 2, 0,
-- 0);
-- switch (dict_ldap->version) {
-- case 2:
-- dict_ldap->version = LDAP_VERSION2;
-- break;
-- case 3:
-- dict_ldap->version = LDAP_VERSION3;
-- break;
-- default:
-- msg_warn("%s: Unknown version %d.", myname, dict_ldap->version);
-- dict_ldap->version = LDAP_VERSION2;
-- }
--
-- /*
- * Make sure only valid options for alias dereferencing are used.
- */
- if (dict_ldap->dereference < 0 || dict_ldap->dereference > 3) {
-- msg_warn("%s: Unrecognized value %d specified for %s; using 0",
-- myname, dict_ldap->dereference, vstring_str(config_param));
-+ msg_warn("%s: %s: Unrecognized value %d specified for %s; using 0",
-+ myname, ldapsource, dict_ldap->dereference, vstring_str(config_param));
- dict_ldap->dereference = 0;
- }
- if (msg_verbose)
-@@ -1110,6 +1515,68 @@
- msg_info("%s: %s is %d", myname, vstring_str(config_param),
- dict_ldap->chase_referrals);
-
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+
-+ /*
-+ * TLS options
-+ */
-+ /* get configured value of "start_tls"; default to no */
-+ vstring_sprintf(config_param, "%s_start_tls", ldapsource);
-+ dict_ldap->start_tls = get_mail_conf_bool(vstring_str(config_param), 0);
-+ if (dict_ldap->start_tls && dict_ldap->version < LDAP_VERSION3) {
-+ msg_warn("%s: %s start_tls requires protocol version 3",
-+ myname, ldapsource);
-+ dict_ldap->version = LDAP_VERSION3;
-+ }
-+
-+ /* get configured value of "tls_require_cert"; default to no */
-+ vstring_sprintf(config_param, "%s_tls_require_cert", ldapsource);
-+ dict_ldap->tls_require_cert = get_mail_conf_bool(vstring_str(config_param), 0);
-+
-+ /* get configured value of "tls_ca_cert_file"; default "" */
-+ vstring_sprintf(config_param, "%s_tls_ca_cert_file", ldapsource);
-+ dict_ldap->tls_ca_cert_file = mystrdup((char *)
-+ get_mail_conf_str(vstring_str
-+ (config_param), "", 0,
-+ 0));
-+
-+ /* get configured value of "tls_ca_cert_dir"; default "" */
-+ vstring_sprintf(config_param, "%s_tls_ca_cert_dir", ldapsource);
-+ dict_ldap->tls_ca_cert_dir = mystrdup((char *)
-+ get_mail_conf_str(vstring_str
-+ (config_param), "", 0,
-+ 0));
-+
-+ /* get configured value of "tls_cert"; default "" */
-+ vstring_sprintf(config_param, "%s_tls_cert", ldapsource);
-+ dict_ldap->tls_cert = mystrdup((char *)
-+ get_mail_conf_str(vstring_str
-+ (config_param), "", 0,
-+ 0));
-+
-+ /* get configured value of "tls_key"; default "" */
-+ vstring_sprintf(config_param, "%s_tls_key", ldapsource);
-+ dict_ldap->tls_key = mystrdup((char *)
-+ get_mail_conf_str(vstring_str
-+ (config_param), "", 0,
-+ 0));
-+
-+ /* get configured value of "tls_random_file"; default "" */
-+ vstring_sprintf(config_param, "%s_tls_random_file", ldapsource);
-+ dict_ldap->tls_random_file = mystrdup((char *)
-+ get_mail_conf_str(vstring_str
-+ (config_param), "", 0,
-+ 0));
-+
-+ /* get configured value of "tls_cipher_suite"; default "" */
-+ vstring_sprintf(config_param, "%s_tls_cipher_suite", ldapsource);
-+ dict_ldap->tls_cipher_suite = mystrdup((char *)
-+ get_mail_conf_str(vstring_str
-+ (config_param), "", 0,
-+ 0));
-+#endif
-+
-+
- /*
- * Debug level.
- */
-@@ -1122,21 +1589,13 @@
- dict_ldap->debuglevel);
- #endif
-
-- dict_ldap_connect(dict_ldap);
--
- /*
-- * if dict_ldap_connect() set dict_errno, free dict_ldap and abort.
-+ * Find or allocate shared LDAP connection container.
- */
-- if (dict_errno) {
-- if (dict_ldap->ld)
-- ldap_unbind(dict_ldap->ld);
--
-- myfree((char *) dict_ldap);
-- return (0);
-- }
-+ dict_ldap_conn_find(dict_ldap);
-
- /*
-- * Otherwise, we're all set. Return the new dict_ldap structure.
-+ * Return the new dict_ldap structure.
- */
- return (DICT_DEBUG (&dict_ldap->dict));
- }
diff --git a/postfix-ipv6.patch b/postfix-ipv6.patch
deleted file mode 100644
index f2bff74..0000000
--- a/postfix-ipv6.patch
+++ /dev/null
@@ -1,3031 +0,0 @@
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/makedefs postfix-2.0.16/makedefs
---- postfix-2.0.16.orig/makedefs 2003-01-23 14:45:02.000000000 +0100
-+++ postfix-2.0.16/makedefs 2005-01-07 18:25:30.197331464 +0100
-@@ -52,6 +52,21 @@
- SYSTEM=`(uname -s) 2>/dev/null`
- RELEASE=`(uname -r) 2>/dev/null`
- VERSION=`(uname -v) 2>/dev/null`
-+if test -f /usr/include/netinet6/in6.h; then
-+ grep __KAME__ /usr/include/netinet6/in6.h 2>&1 >/dev/null
-+ if [ $? = 1 ]; then
-+ INET6=
-+ else
-+ if [ -f /usr/local/v6/lib/libinet6.a ]; then
-+ INET6=kame
-+ else
-+ INET6=kame-merged
-+ fi
-+ fi
-+fi
-+if [ -z "$INET6" -a -f /usr/include/netinet/ip6.h -a -f /usr/include/linux/icmpv6.h ]; then
-+ INET6=linux
-+fi
-
- case "$VERSION" in
- dcosx*) SYSTEM=$VERSION;;
-@@ -318,6 +333,26 @@
-
- : ${CC='gcc $(WARN)'} ${OPT='-O'} ${DEBUG='-g'} ${AWK=awk}
-
-+case "$INET6" in
-+kame)
-+ CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len"
-+ if test -f /usr/local/v6/lib/libinet6.a; then
-+ SYSLIBS="$SYSLIBS -L/usr/local/v6/lib -linet6"
-+ fi
-+ ;;
-+kame-merged)
-+ CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len"
-+ ;;
-+linux)
-+ CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family"
-+ if test -f /usr/include/libinet6/netinet/ip6.h
-+ then
-+ CCARGS="$CCARGS -I/usr/include/libinet6 -DUSAGI_LIBINET6"
-+ SYSLIBS="$SYSLIBS -linet6"
-+ fi
-+ ;;
-+esac
-+
- export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG AWK OPTS
-
- sed 's/ / /g' <<EOF
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/global/Makefile.in postfix-2.0.16/src/global/Makefile.in
---- postfix-2.0.16.orig/src/global/Makefile.in 2005-01-07 18:22:25.286442192 +0100
-+++ postfix-2.0.16/src/global/Makefile.in 2005-01-07 18:25:30.198331312 +0100
-@@ -19,7 +19,7 @@
- timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \
- tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c \
- flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c \
-- verp_sender.c match_parent_style.c mime_state.c header_token.c \
-+ verp_sender.c match_parent_style.c mime_state.c header_token.c wildcard_inet_addr.c\
- strip_addr.c virtual8_maps.c hold_message.c dict_proxy.c mail_dict.c \
- pfixtls.c
- OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
-@@ -42,7 +42,7 @@
- timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \
- tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o \
- flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o \
-- verp_sender.o match_parent_style.o mime_state.o header_token.o \
-+ verp_sender.o match_parent_style.o mime_state.o header_token.o wildcard_inet_addr.o\
- strip_addr.o virtual8_maps.o hold_message.o dict_proxy.o mail_dict.o \
- pfixtls.o
- HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
-@@ -61,7 +61,7 @@
- rewrite_clnt.h sent.h smtp_stream.h split_addr.h string_list.h \
- sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h flush_clnt.h \
- mbox_conf.h mbox_open.h abounce.h qmqp_proto.h verp_sender.h \
-- match_parent_style.h quote_flags.h mime_state.h header_token.h \
-+ match_parent_style.h quote_flags.h mime_state.h header_token.h wildcard_inet_addr.h\
- lex_822.h strip_addr.h virtual8_maps.h hold_message.h dict_proxy.h \
- mail_dict.h pfixtls.h
- TESTSRC = rec2stream.c stream2rec.c recdump.c
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/global/mynetworks.c postfix-2.0.16/src/global/mynetworks.c
---- postfix-2.0.16.orig/src/global/mynetworks.c 2001-02-25 02:46:07.000000000 +0100
-+++ postfix-2.0.16/src/global/mynetworks.c 2005-01-07 18:32:30.872379136 +0100
-@@ -50,6 +50,12 @@
- #include <vstring.h>
- #include <inet_addr_list.h>
- #include <name_mask.h>
-+#ifdef INET6
-+#include <sys/socket.h>
-+#include <netinet/in.h>
-+#include <netdb.h>
-+#endif
-+#include <string.h>
-
- /* Global library. */
-
-@@ -75,6 +81,9 @@
- const char *mynetworks(void)
- {
- static VSTRING *result;
-+#ifdef INET6
-+ char hbuf[NI_MAXHOST];
-+#endif
-
- if (result == 0) {
- char *myname = "mynetworks";
-@@ -87,6 +96,13 @@
- int junk;
- int i;
- int mask_style;
-+#ifdef INET6
-+ struct sockaddr *sa;
-+ struct sockaddr_in6 *addr6;
-+ struct sockaddr_in6 *mask6;
-+ struct in6_addr net6;
-+ int j;
-+#endif
-
- mask_style = name_mask("mynetworks mask style", mask_styles,
- var_mynetworks_style);
-@@ -96,8 +112,45 @@
- my_mask_list = own_inet_mask_list();
-
- for (i = 0; i < my_addr_list->used; i++) {
-+#ifdef INET6
-+ sa = (struct sockaddr *)&my_addr_list->addrs[i];
-+ if (sa->sa_family == AF_INET6) {
-+ addr6 = (struct sockaddr_in6 *)sa;
-+ mask6 = (struct sockaddr_in6 *)&my_mask_list->addrs[i];
-+
-+ switch (mask_style) {
-+ case MASK_STYLE_CLASS:
-+ /* treat as subnet for IPv6 */
-+ case MASK_STYLE_SUBNET:
-+ for (j=0; j<16; j++)
-+ net6.s6_addr[j] = addr6->sin6_addr.s6_addr[j] & mask6->sin6_addr.s6_addr[j];
-+ for(shift=128; shift>0; shift--)
-+ if ((mask6->sin6_addr.s6_addr[(shift-1) / 8]) & (0x80 >> ((shift-1) % 8)))
-+ break;
-+ break;
-+ case MASK_STYLE_HOST:
-+ memcpy (&net6, &(addr6->sin6_addr), sizeof(net6));
-+ shift=128;
-+ break;
-+ default:
-+ msg_panic("unknown mynetworks mask style: %s",
-+ var_mynetworks_style);
-+ }
-+ inet_ntop(AF_INET6, &net6, hbuf, sizeof(hbuf));
-+ if (!shift)
-+ msg_warn("%s: skipped network with zero mask: [%s/0]", myname, hbuf);
-+ else
-+ vstring_sprintf_append(result, "[%s/%d] ", hbuf, shift);
-+ continue;
-+ } else if (sa->sa_family != AF_INET) {
-+ continue;
-+ }
-+ addr = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr);
-+ mask = ntohl(((struct sockaddr_in *)&my_mask_list->addrs[i])->sin_addr.s_addr);
-+#else
- addr = ntohl(my_addr_list->addrs[i].s_addr);
- mask = ntohl(my_mask_list->addrs[i].s_addr);
-+#endif
-
- switch (mask_style) {
-
-@@ -119,8 +172,15 @@
- mask = IN_CLASSD_NET;
- shift = IN_CLASSD_NSHIFT;
- } else {
-+#ifdef INET6
-+ if (getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
-+ NI_NUMERICHOST))
-+ strncpy(hbuf, "???", sizeof(hbuf));
-+ msg_fatal("%s: bad address class: %s", myname, hbuf);
-+#else
- msg_fatal("%s: bad address class: %s",
- myname, inet_ntoa(my_addr_list->addrs[i]));
-+#endif
- }
- break;
-
-@@ -146,6 +206,18 @@
- var_mynetworks_style);
- }
- net.s_addr = htonl(addr & mask);
-+ if (shift == BITS_PER_ADDR) {
-+#ifdef INET6
-+ if (getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
-+ NI_NUMERICHOST))
-+ strncpy(hbuf, "???", sizeof(hbuf));
-+ msg_warn("%s: skipped network with zero mask: %s/0", myname, hbuf);
-+#else
-+ msg_warn("%s: skipped network with zero mask: %s/0",
-+ myname, inet_ntoa(my_addr_list->addrs[i]));
-+#endif
-+ continue;
-+ }
- vstring_sprintf_append(result, "%s/%d ",
- inet_ntoa(net), BITS_PER_ADDR - shift);
- }
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/global/own_inet_addr.c postfix-2.0.16/src/global/own_inet_addr.c
---- postfix-2.0.16.orig/src/global/own_inet_addr.c 2002-10-25 01:19:19.000000000 +0200
-+++ postfix-2.0.16/src/global/own_inet_addr.c 2005-01-07 18:25:30.198331312 +0100
-@@ -50,6 +50,10 @@
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <string.h>
-+#ifdef INET6
-+#include <sys/socket.h>
-+#include <netdb.h>
-+#endif
-
- #ifdef STRCASECMP_IN_STRINGS_H
- #include <strings.h>
-@@ -113,10 +117,11 @@
- */
- else {
- bufp = hosts = mystrdup(var_inet_interfaces);
-- while ((host = mystrtok(&bufp, sep)) != 0)
-+ while ((host = mystrtok(&bufp, sep)) != 0) {
- if (inet_addr_host(addr_list, host) == 0)
- msg_fatal("config variable %s: host not found: %s",
- VAR_INET_INTERFACES, host);
-+ }
- myfree(hosts);
-
- /*
-@@ -133,15 +138,39 @@
- msg_fatal("could not find any active network interfaces");
- for (nvirtual = 0; nvirtual < addr_list->used; nvirtual++) {
- for (nlocal = 0; /* see below */ ; nlocal++) {
-- if (nlocal >= local_addrs.used)
-+ if (nlocal >= local_addrs.used) {
-+#ifdef INET6
-+ char hbuf[NI_MAXHOST];
-+ if (getnameinfo((struct sockaddr *)&addr_list->addrs[nvirtual],
-+ SS_LEN(addr_list->addrs[nvirtual]), hbuf,
-+ sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
-+ strncpy(hbuf, "???", sizeof(hbuf));
-+ msg_fatal("parameter %s: no local interface found for %s",
-+ VAR_INET_INTERFACES, hbuf);
-+#else
- msg_fatal("parameter %s: no local interface found for %s",
- VAR_INET_INTERFACES,
- inet_ntoa(addr_list->addrs[nvirtual]));
-+#endif
-+ }
-+#ifdef INET6
-+ if (addr_list->addrs[nvirtual].ss_family ==
-+ local_addrs.addrs[nlocal].ss_family &&
-+ SS_LEN(addr_list->addrs[nvirtual]) ==
-+ SS_LEN(local_addrs.addrs[nlocal]) &&
-+ memcmp(&addr_list->addrs[nvirtual],
-+ &local_addrs.addrs[nlocal],
-+ SS_LEN(local_addrs.addrs[nlocal])) == 0) {
-+ inet_addr_list_append(mask_list, (struct sockaddr *)&local_masks.addrs[nlocal]);
-+ break;
-+ }
-+#else
- if (addr_list->addrs[nvirtual].s_addr
- == local_addrs.addrs[nlocal].s_addr) {
- inet_addr_list_append(mask_list, &local_masks.addrs[nlocal]);
- break;
- }
-+#endif
- }
- }
- inet_addr_list_free(&local_addrs);
-@@ -151,6 +180,42 @@
-
- /* own_inet_addr - is this my own internet address */
-
-+#ifdef INET6
-+int own_inet_addr(struct sockaddr * addr)
-+{
-+ int i;
-+ char *p, *q;
-+ int l;
-+ struct sockaddr *sa;
-+
-+ if (addr_list.used == 0)
-+ own_inet_addr_init(&addr_list, &mask_list);
-+
-+ for (i = 0; i < addr_list.used; i++) {
-+ sa = (struct sockaddr *)&addr_list.addrs[i];
-+ if (addr->sa_family != sa->sa_family)
-+ continue;
-+ switch (addr->sa_family) {
-+ case AF_INET:
-+ p = (char *)&((struct sockaddr_in *)addr)->sin_addr;
-+ q = (char *)&((struct sockaddr_in *)&addr_list.addrs[i])->sin_addr;
-+ l = sizeof(struct in_addr);
-+ break;
-+ case AF_INET6:
-+ /* XXX scope */
-+ p = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr;
-+ q = (char *)&((struct sockaddr_in6 *)&addr_list.addrs[i])->sin6_addr;
-+ l = sizeof(struct in6_addr);
-+ break;
-+ default:
-+ continue;
-+ }
-+ if (memcmp(p, q, l) == 0)
-+ return (1);
-+ }
-+ return (0);
-+}
-+#else
- int own_inet_addr(struct in_addr * addr)
- {
- int i;
-@@ -161,8 +226,8 @@
- for (i = 0; i < addr_list.used; i++)
- if (addr->s_addr == addr_list.addrs[i].s_addr)
- return (1);
-- return (0);
- }
-+#endif
-
- /* own_inet_addr_list - return list of addresses */
-
-@@ -213,6 +278,45 @@
-
- /* proxy_inet_addr - is this my proxy internet address */
-
-+#ifdef INET6
-+int proxy_inet_addr(struct sockaddr * addr)
-+{
-+ int i;
-+ char *p, *q;
-+ int l;
-+ struct sockaddr *sa;
-+
-+ if (*var_proxy_interfaces == 0)
-+ return (0);
-+
-+ if (proxy_list.used == 0)
-+ proxy_inet_addr_init(&proxy_list);
-+
-+ for (i = 0; i < proxy_list.used; i++) {
-+ sa = (struct sockaddr *)&proxy_list.addrs[i];
-+ if (addr->sa_family != sa->sa_family)
-+ continue;
-+ switch (addr->sa_family) {
-+ case AF_INET:
-+ p = (char *)&((struct sockaddr_in *)addr)->sin_addr;
-+ q = (char *)&((struct sockaddr_in *)&addr_list.addrs[i])->sin_addr;
-+ l = sizeof(struct in_addr);
-+ break;
-+ case AF_INET6:
-+ /* XXX scope */
-+ p = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr;
-+ q = (char *)&((struct sockaddr_in6 *)&addr_list.addrs[i])->sin6_addr;
-+ l = sizeof(struct in6_addr);
-+ break;
-+ default:
-+ continue;
-+ }
-+ if (memcmp(p, q, l) == 0)
-+ return (1);
-+ }
-+ return (0);
-+}
-+#else
- int proxy_inet_addr(struct in_addr * addr)
- {
- int i;
-@@ -228,6 +332,7 @@
- return (1);
- return (0);
- }
-+#endif
-
- /* proxy_inet_addr_list - return list of addresses */
-
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/global/own_inet_addr.h postfix-2.0.16/src/global/own_inet_addr.h
---- postfix-2.0.16.orig/src/global/own_inet_addr.h 2002-10-25 01:07:05.000000000 +0200
-+++ postfix-2.0.16/src/global/own_inet_addr.h 2005-01-07 18:25:30.199331160 +0100
-@@ -15,14 +15,25 @@
- * System library.
- */
- #include <netinet/in.h>
-+#ifdef INET6
-+#include <sys/socket.h>
-+#endif
-
- /*
- * External interface.
- */
-+#ifdef INET6
-+extern int own_inet_addr(struct sockaddr *);
-+#else
- extern int own_inet_addr(struct in_addr *);
-+#endif
- extern struct INET_ADDR_LIST *own_inet_addr_list(void);
- extern struct INET_ADDR_LIST *own_inet_mask_list(void);
-+#ifdef INET6
-+extern int proxy_inet_addr(struct sockaddr *);
-+#else
- extern int proxy_inet_addr(struct in_addr *);
-+#endif
- extern struct INET_ADDR_LIST *proxy_inet_addr_list(void);
-
- /* LICENSE
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/global/peer_name.c postfix-2.0.16/src/global/peer_name.c
---- postfix-2.0.16.orig/src/global/peer_name.c 2001-01-28 16:23:02.000000000 +0100
-+++ postfix-2.0.16/src/global/peer_name.c 2005-01-07 18:25:30.199331160 +0100
-@@ -69,12 +69,32 @@
- PEER_NAME *peer_name(int sock)
- {
- static PEER_NAME peer;
-- struct sockaddr_in sin;
-- SOCKADDR_SIZE len = sizeof(sin);
-+ union sockunion {
-+ struct {
-+ u_char si_len;
-+ u_char si_family;
-+ u_short si_port;
-+ } su_si;
-+ struct sockaddr peer_un;
-+ struct sockaddr_in peer_un4;
-+#ifdef INET6
-+ struct sockaddr_in6 peer_un6;
-+#endif
-+ } p_un;
-+#define sun p_un.peer_un
-+#define sin p_un.peer_un4
-+#ifdef INET6
-+#define sin6 p_un.peer_un6
-+ static char hbuf[NI_MAXHOST];
-+ static char abuf[NI_MAXHOST];
-+#else
- struct hostent *hp;
-+#endif
-+ SOCKADDR_SIZE len = sizeof(p_un);
-
-- if (getpeername(sock, (struct sockaddr *) & sin, &len) == 0) {
-- switch (sin.sin_family) {
-+ if (getpeername(sock, (struct sockaddr *)&p_un, &len) == 0) {
-+ switch (p_un.peer_un.sa_family) {
-+#ifndef INET6
- case AF_INET:
- peer.type = PEER_TYPE_INET;
- hp = gethostbyaddr((char *) &(sin.sin_addr),
-@@ -83,6 +103,24 @@
- hp->h_name : "unknown");
- peer.addr = inet_ntoa(sin.sin_addr);
- return (&peer);
-+#else
-+ case AF_INET:
-+ peer.type = PEER_TYPE_INET;
-+ if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
-+ peer.name = "unknown";
-+ else
-+ peer.name = hbuf;
-+ peer.addr = abuf;
-+ return (&peer);
-+ case AF_INET6:
-+ peer.type = PEER_TYPE_INET6;
-+ if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
-+ peer.name = "unknown";
-+ else
-+ peer.name = hbuf;
-+ peer.addr = abuf;
-+ return (&peer);
-+#endif
- case AF_UNSPEC:
- case AF_UNIX:
- peer.type = PEER_TYPE_LOCAL;
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/global/peer_name.h postfix-2.0.16/src/global/peer_name.h
---- postfix-2.0.16.orig/src/global/peer_name.h 1998-12-11 19:55:32.000000000 +0100
-+++ postfix-2.0.16/src/global/peer_name.h 2005-01-07 18:25:30.199331160 +0100
-@@ -22,6 +22,9 @@
- #define PEER_TYPE_UNKNOWN 0
- #define PEER_TYPE_INET 1
- #define PEER_TYPE_LOCAL 2
-+#ifdef INET6
-+#define PEER_TYPE_INET6 3
-+#endif
-
- extern PEER_NAME *peer_name(int);
-
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/global/resolve_local.c postfix-2.0.16/src/global/resolve_local.c
---- postfix-2.0.16.orig/src/global/resolve_local.c 2002-10-25 01:21:20.000000000 +0200
-+++ postfix-2.0.16/src/global/resolve_local.c 2005-01-07 18:25:30.199331160 +0100
-@@ -43,6 +43,7 @@
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <string.h>
-+#include <netdb.h>
-
- #ifndef INADDR_NONE
- #define INADDR_NONE 0xffffffff
-@@ -80,7 +81,12 @@
- {
- char *saved_addr = mystrdup(addr);
- char *dest;
-+#ifdef INET6
-+ struct addrinfo hints, *res, *res0;
-+ int error;
-+#else
- struct in_addr ipaddr;
-+#endif
- int len;
-
- #define RETURN(x) { myfree(saved_addr); return(x); }
-@@ -118,9 +124,25 @@
- if (*dest == '[' && dest[len - 1] == ']') {
- dest++;
- dest[len -= 2] = 0;
-+#ifdef INET6
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_socktype = SOCK_DGRAM;
-+ error = getaddrinfo(dest, NULL, &hints, &res0);
-+ if (!error) {
-+ for (res = res0; res; res = res->ai_next) {
-+ if (own_inet_addr(res->ai_addr)) {
-+ freeaddrinfo(res0);
-+ RETURN(1);
-+ }
-+ }
-+ freeaddrinfo(res0);
-+ }
-+#else
- if ((ipaddr.s_addr = inet_addr(dest)) != INADDR_NONE
- && (own_inet_addr(&ipaddr) || proxy_inet_addr(&ipaddr)))
- RETURN(1);
-+#endif
- }
-
- /*
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/global/wildcard_inet_addr.c postfix-2.0.16/src/global/wildcard_inet_addr.c
---- postfix-2.0.16.orig/src/global/wildcard_inet_addr.c 1970-01-01 01:00:00.000000000 +0100
-+++ postfix-2.0.16/src/global/wildcard_inet_addr.c 2005-01-07 18:25:30.200331008 +0100
-@@ -0,0 +1,82 @@
-+/* System library. */
-+
-+#include <sys_defs.h>
-+#include <netinet/in.h>
-+#include <arpa/inet.h>
-+#include <string.h>
-+#ifdef INET6
-+#include <sys/socket.h>
-+#endif
-+#include <netdb.h>
-+
-+#ifdef STRCASECMP_IN_STRINGS_H
-+#include <strings.h>
-+#endif
-+
-+/* Utility library. */
-+
-+#include <msg.h>
-+#include <mymalloc.h>
-+#include <inet_addr_list.h>
-+#include <inet_addr_local.h>
-+#include <inet_addr_host.h>
-+#include <stringops.h>
-+
-+/* Global library. */
-+
-+#include <mail_params.h>
-+#include <wildcard_inet_addr.h>
-+
-+/* Application-specific. */
-+static INET_ADDR_LIST addr_list;
-+
-+/* wildcard_inet_addr_init - initialize my own address list */
-+
-+static void wildcard_inet_addr_init(INET_ADDR_LIST *addr_list)
-+{
-+#ifdef INET6
-+ struct addrinfo hints, *res, *res0;
-+ char hbuf[NI_MAXHOST];
-+ int error;
-+#ifdef NI_WITHSCOPEID
-+ const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
-+#else
-+ const int niflags = NI_NUMERICHOST;
-+#endif
-+
-+ inet_addr_list_init(addr_list);
-+
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM;
-+ hints.ai_flags = AI_PASSIVE;
-+ error = getaddrinfo(NULL, "0", &hints, &res0);
-+ if (error)
-+ msg_fatal("could not get list of wildcard addresses");
-+ for (res = res0; res; res = res->ai_next) {
-+ if (res->ai_family != AF_INET && res->ai_family != AF_INET6)
-+ continue;
-+ if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
-+ NULL, 0, niflags) != 0)
-+ continue;
-+ if (inet_addr_host(addr_list, hbuf) == 0)
-+ continue; /* msg_fatal("config variable %s: host not found: %s",
-+ VAR_INET_INTERFACES, hbuf); */
-+ }
-+ freeaddrinfo(res0);
-+#else
-+ if (inet_addr_host(addr_list, "0.0.0.0") == 0)
-+ msg_fatal("config variable %s: host not found: %s",
-+ VAR_INET_INTERFACES, "0.0.0.0");
-+#endif
-+}
-+
-+/* wildcard_inet_addr_list - return list of addresses */
-+
-+INET_ADDR_LIST *wildcard_inet_addr_list(void)
-+{
-+ if (addr_list.used == 0)
-+ wildcard_inet_addr_init(&addr_list);
-+
-+ return (&addr_list);
-+}
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/global/wildcard_inet_addr.h postfix-2.0.16/src/global/wildcard_inet_addr.h
---- postfix-2.0.16.orig/src/global/wildcard_inet_addr.h 1970-01-01 01:00:00.000000000 +0100
-+++ postfix-2.0.16/src/global/wildcard_inet_addr.h 2005-01-07 18:25:30.200331008 +0100
-@@ -0,0 +1,36 @@
-+#ifndef _WILDCARD_INET_ADDR_H_INCLUDED_
-+#define _WILDCARD_INET_ADDR_H_INCLUDED_
-+
-+/*++
-+/* NAME
-+/* wildcard_inet_addr_list 3h
-+/* SUMMARY
-+/* grab the list of wildcard IP addresses.
-+/* SYNOPSIS
-+/* #include <own_inet_addr.h>
-+/* DESCRIPTION
-+/* .nf
-+/*--*/
-+
-+ /*
-+ * System library.
-+ */
-+#include <netinet/in.h>
-+#ifdef INET6
-+#include <sys/socket.h>
-+#endif
-+
-+ /*
-+ * External interface.
-+ */
-+extern struct INET_ADDR_LIST *wildcard_inet_addr_list(void);
-+
-+/* LICENSE
-+/* .ad
-+/* .fi
-+/* foo
-+/* AUTHOR(S)
-+/* Jun-ichiro itojun Hagino
-+/*--*/
-+
-+#endif
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/master/master_ent.c postfix-2.0.16/src/master/master_ent.c
---- postfix-2.0.16.orig/src/master/master_ent.c 2003-06-18 21:19:46.000000000 +0200
-+++ postfix-2.0.16/src/master/master_ent.c 2005-01-07 18:35:28.571364784 +0100
-@@ -92,6 +92,7 @@
- #include <mail_proto.h>
- #include <mail_params.h>
- #include <own_inet_addr.h>
-+#include <wildcard_inet_addr.h>
-
- /* Local stuff. */
-
-@@ -307,8 +308,13 @@
- inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv));
- serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
- } else if (strcasecmp(saved_interfaces, DEF_INET_INTERFACES) == 0) {
-+#ifdef INET6
-+ MASTER_INET_ADDRLIST(serv) = wildcard_inet_addr_list();
-+ serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
-+#else
- MASTER_INET_ADDRLIST(serv) = 0; /* wild-card */
- serv->listen_fd_count = 1;
-+#endif
- } else {
- MASTER_INET_ADDRLIST(serv) = own_inet_addr_list(); /* virtual */
- inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv));
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/master/master_listen.c postfix-2.0.16/src/master/master_listen.c
---- postfix-2.0.16.orig/src/master/master_listen.c 2001-05-01 00:47:57.000000000 +0200
-+++ postfix-2.0.16/src/master/master_listen.c 2005-01-07 18:25:30.201330856 +0100
-@@ -64,13 +64,22 @@
-
- #include "master.h"
-
-+#ifdef INET6
-+#include <netdb.h>
-+#include <stdio.h>
-+#endif
-+
- /* master_listen_init - enable connection requests */
-
- void master_listen_init(MASTER_SERV *serv)
- {
- char *myname = "master_listen_init";
- char *end_point;
-- int n;
-+ int n,m,tmpfd;
-+#ifdef INET6
-+ char hbuf[NI_MAXHOST];
-+ SOCKADDR_SIZE salen;
-+#endif
-
- /*
- * Find out what transport we should use, then create one or more
-@@ -111,18 +120,31 @@
- serv->listen_fd[0] =
- inet_listen(MASTER_INET_PORT(serv),
- serv->max_proc > var_proc_limit ?
-- serv->max_proc : var_proc_limit, NON_BLOCKING);
-+ serv->max_proc : var_proc_limit, NON_BLOCKING, 1);
- close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
- } else { /* virtual or host:port */
-- for (n = 0; n < serv->listen_fd_count; n++) {
-+ for (m = n = 0; n < serv->listen_fd_count; n++) {
-+#ifdef INET6
-+ if (getnameinfo((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n],
-+ SA_LEN((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n]),
-+ hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) {
-+ strncpy(hbuf, "?????", sizeof(hbuf));
-+ }
-+ end_point = concatenate(hbuf, ":", MASTER_INET_PORT(serv), (char *) 0);
-+#else
- end_point = concatenate(inet_ntoa(MASTER_INET_ADDRLIST(serv)->addrs[n]),
- ":", MASTER_INET_PORT(serv), (char *) 0);
-- serv->listen_fd[n]
-+#endif
-+ tmpfd
- = inet_listen(end_point, serv->max_proc > var_proc_limit ?
-- serv->max_proc : var_proc_limit, NON_BLOCKING);
-- close_on_exec(serv->listen_fd[n], CLOSE_ON_EXEC);
-+ serv->max_proc : var_proc_limit, NON_BLOCKING, 0);
-+ if (tmpfd >= 0) {
-+ serv->listen_fd[m] = tmpfd;
-+ close_on_exec(serv->listen_fd[m++], CLOSE_ON_EXEC);
-+ }
- myfree(end_point);
- }
-+ serv->listen_fd_count=m;
- }
- break;
- default:
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/smtp/Makefile.in postfix-2.0.16/src/smtp/Makefile.in
---- postfix-2.0.16.orig/src/smtp/Makefile.in 2005-01-07 18:22:25.253447208 +0100
-+++ postfix-2.0.16/src/smtp/Makefile.in 2005-01-07 18:25:30.201330856 +0100
-@@ -144,6 +144,7 @@
- smtp_connect.o: ../../include/mail_params.h
- smtp_connect.o: ../../include/own_inet_addr.h
- smtp_connect.o: ../../include/dns.h
-+smtp_connect.o: ../../include/get_port.h
- smtp_connect.o: smtp.h
- smtp_connect.o: ../../include/argv.h
- smtp_connect.o: ../../include/deliver_request.h
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/smtp/smtp_addr.c postfix-2.0.16/src/smtp/smtp_addr.c
---- postfix-2.0.16.orig/src/smtp/smtp_addr.c 2002-10-25 01:03:11.000000000 +0200
-+++ postfix-2.0.16/src/smtp/smtp_addr.c 2005-01-07 18:25:30.201330856 +0100
-@@ -134,18 +134,68 @@
- static void smtp_print_addr(char *what, DNS_RR *addr_list)
- {
- DNS_RR *addr;
-- struct in_addr in_addr;
-+#ifdef INET6
-+ struct sockaddr_storage ss;
-+#else
-+ struct sockaddr ss;
-+#endif
-+ struct sockaddr_in *sin;
-+#ifdef INET6
-+ struct sockaddr_in6 *sin6;
-+ char hbuf[NI_MAXHOST];
-+#else
-+ char hbuf[sizeof("255.255.255.255") + 1];
-+#endif
-
- msg_info("begin %s address list", what);
- for (addr = addr_list; addr; addr = addr->next) {
-- if (addr->data_len > sizeof(addr)) {
-- msg_warn("skipping address length %d", addr->data_len);
-- } else {
-- memcpy((char *) &in_addr, addr->data, sizeof(in_addr));
-- msg_info("pref %4d host %s/%s",
-- addr->pref, addr->name,
-- inet_ntoa(in_addr));
-+ if (addr->class != C_IN) {
-+ msg_warn("skipping unsupported address (class=%u)", addr->class);
-+ continue;
- }
-+ switch (addr->type) {
-+ case T_A:
-+ if (addr->data_len != sizeof(sin->sin_addr)) {
-+ msg_warn("skipping invalid address (AAAA, len=%u)",
-+ addr->data_len);
-+ continue;
-+ }
-+ sin = (struct sockaddr_in *)&ss;
-+ memset(sin, 0, sizeof(*sin));
-+ sin->sin_family = AF_INET;
-+#ifdef HAS_SA_LEN
-+ sin->sin_len = sizeof(*sin);
-+#endif
-+ memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr));
-+ break;
-+#ifdef INET6
-+ case T_AAAA:
-+ if (addr->data_len != sizeof(sin6->sin6_addr)) {
-+ msg_warn("skipping invalid address (AAAA, len=%u)",
-+ addr->data_len);
-+ continue;
-+ }
-+ sin6 = (struct sockaddr_in6 *)&ss;
-+ memset(sin6, 0, sizeof(*sin6));
-+ sin6->sin6_family = AF_INET6;
-+#ifdef HAS_SA_LEN
-+ sin6->sin6_len = sizeof(*sin6);
-+#endif
-+ memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr));
-+ break;
-+#endif
-+ default:
-+ msg_warn("skipping unsupported address (type=%u)", addr->type);
-+ continue;
-+ }
-+
-+#ifdef INET6
-+ (void)getnameinfo((struct sockaddr *)&ss, SS_LEN(ss),
-+ hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
-+#else
-+ (void)inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf));
-+#endif
-+ msg_info("pref %4d host %s/%s", addr->pref, addr->name, hbuf);
- }
- msg_info("end %s address list", what);
- }
-@@ -155,15 +205,23 @@
- static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRING *why)
- {
- char *myname = "smtp_addr_one";
-+#ifndef INET6
- struct in_addr inaddr;
-- DNS_FIXED fixed;
- DNS_RR *addr = 0;
- DNS_RR *rr;
- struct hostent *hp;
-+#else
-+ struct addrinfo hints, *res0, *res;
-+ int error = -1;
-+ char *addr;
-+ size_t addrlen;
-+#endif
-+ DNS_FIXED fixed;
-
- if (msg_verbose)
- msg_info("%s: host %s", myname, host);
-
-+#ifndef INET6
- /*
- * Interpret a numerical name as an address.
- */
-@@ -216,6 +274,48 @@
- smtp_errno = SMTP_FAIL;
- break;
- }
-+#else
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM;
-+ error = getaddrinfo(host, NULL, &hints, &res0);
-+ if (error) {
-+ switch (error) {
-+ case EAI_AGAIN:
-+ smtp_errno = SMTP_RETRY;
-+ break;
-+ default:
-+ vstring_sprintf(why, "[%s]: %s",host,gai_strerror(error));
-+ smtp_errno = SMTP_FAIL;
-+ break;
-+ }
-+ return (addr_list);
-+ }
-+ for (res = res0; res; res = res->ai_next) {
-+ memset((char *) &fixed, 0, sizeof(fixed));
-+ switch(res->ai_family) {
-+ case AF_INET6:
-+ /* XXX not scope friendly */
-+ fixed.type = T_AAAA;
-+ addr = (char *)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
-+ addrlen = sizeof(struct in6_addr);
-+ break;
-+ case AF_INET:
-+ fixed.type = T_A;
-+ addr = (char *)&((struct sockaddr_in *)res->ai_addr)->sin_addr;
-+ addrlen = sizeof(struct in_addr);
-+ break;
-+ default:
-+ msg_warn("%s: unknown address family %d for %s",
-+ myname, res->ai_family, host);
-+ continue;
-+ }
-+ addr_list = dns_rr_append(addr_list,
-+ dns_rr_create(host, &fixed, pref, addr, addrlen));
-+ }
-+ if (res0)
-+ freeaddrinfo(res0);
-+#endif
- return (addr_list);
- }
-
-@@ -251,6 +351,9 @@
- INET_ADDR_LIST *self;
- DNS_RR *addr;
- int i;
-+#ifdef INET6
-+ struct sockaddr *sa;
-+#endif
-
- /*
- * Find the first address that lists any address that this mail system is
-@@ -260,12 +363,36 @@
-
- self = own_inet_addr_list();
- for (addr = addr_list; addr; addr = addr->next) {
-- for (i = 0; i < self->used; i++)
-+ for (i = 0; i < self->used; i++) {
-+#ifdef INET6
-+ sa = (struct sockaddr *)&self->addrs[i];
-+ switch(addr->type) {
-+ case T_AAAA:
-+ /* XXX scope */
-+ if (sa->sa_family != AF_INET6)
-+ break;
-+ if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr,
-+ addr->data, sizeof(struct in6_addr)) == 0) {
-+ return(addr);
-+ }
-+ break;
-+ case T_A:
-+ if (sa->sa_family != AF_INET)
-+ break;
-+ if (memcmp(&((struct sockaddr_in *)sa)->sin_addr,
-+ addr->data, sizeof(struct in_addr)) == 0) {
-+ return(addr);
-+ }
-+ break;
-+ }
-+#else
- if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) {
- if (msg_verbose)
- msg_info("%s: found at pref %d", myname, addr->pref);
- return (addr);
- }
-+#endif
-+ }
- }
-
- /*
-@@ -273,12 +400,36 @@
- */
- self = proxy_inet_addr_list();
- for (addr = addr_list; addr; addr = addr->next) {
-- for (i = 0; i < self->used; i++)
-+ for (i = 0; i < self->used; i++) {
-+#ifdef INET6
-+ sa = (struct sockaddr *)&self->addrs[i];
-+ switch(addr->type) {
-+ case T_AAAA:
-+ /* XXX scope */
-+ if (sa->sa_family != AF_INET6)
-+ break;
-+ if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr,
-+ addr->data, sizeof(struct in6_addr)) == 0) {
-+ return(addr);
-+ }
-+ break;
-+ case T_A:
-+ if (sa->sa_family != AF_INET)
-+ break;
-+ if (memcmp(&((struct sockaddr_in *)sa)->sin_addr,
-+ addr->data, sizeof(struct in_addr)) == 0) {
-+ return(addr);
-+ }
-+ break;
-+ }
-+#else
- if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) {
- if (msg_verbose)
- msg_info("%s: found at pref %d", myname, addr->pref);
- return (addr);
- }
-+#endif
-+ }
- }
-
- /*
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/smtp/smtp_connect.c postfix-2.0.16/src/smtp/smtp_connect.c
---- postfix-2.0.16.orig/src/smtp/smtp_connect.c 2005-01-07 18:22:25.254447056 +0100
-+++ postfix-2.0.16/src/smtp/smtp_connect.c 2005-01-07 18:25:30.202330704 +0100
-@@ -81,6 +81,7 @@
- /* System library. */
-
- #include <sys_defs.h>
-+#include <stdlib.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
-@@ -110,6 +111,7 @@
- #include <inet_addr_list.h>
- #include <iostuff.h>
- #include <timed_connect.h>
-+#include <get_port.h>
- #include <stringops.h>
- #include <host_port.h>
- #include <sane_connect.h>
-@@ -135,19 +137,45 @@
- VSTRING *why)
- {
- char *myname = "smtp_connect_addr";
-- struct sockaddr_in sin;
-- int sock;
-+#ifdef INET6
-+ struct sockaddr_storage ss;
-+#else
-+ struct sockaddr ss;
-+#endif
-+ struct sockaddr *sa;
-+ struct sockaddr_in *sin;
-+#ifdef INET6
-+ struct sockaddr_in6 *sin6;
-+#endif
-+ SOCKADDR_SIZE salen;
-+#ifdef INET6
-+ char hbuf[NI_MAXHOST];
-+#else
-+ char hbuf[sizeof("255.255.255.255") + 1];
-+#endif
-+ int sock = -1;
- INET_ADDR_LIST *addr_list;
- int conn_stat;
- int saved_errno;
- VSTREAM *stream;
- int ch;
-- unsigned long inaddr;
-+
-+ sa = (struct sockaddr *)&ss;
-+ sin = (struct sockaddr_in *)&ss;
-+#ifdef INET6
-+ sin6 = (struct sockaddr_in6 *)&ss;
-+#endif
-
- /*
- * Sanity checks.
- */
-- if (addr->data_len > sizeof(sin.sin_addr)) {
-+#ifdef INET6
-+ if (((addr->type==T_A) && (addr->data_len > sizeof(sin->sin_addr))) ||
-+ ((addr->type==T_AAAA) && (addr->data_len > sizeof(sin6->sin6_addr))))
-+#else
-+ if (addr->data_len > sizeof(sin->sin_addr))
-+#endif
-+ {
- msg_warn("%s: skip address with length %d", myname, addr->data_len);
- smtp_errno = SMTP_RETRY;
- return (0);
-@@ -156,17 +184,39 @@
- /*
- * Initialize.
- */
-- memset((char *) &sin, 0, sizeof(sin));
-- sin.sin_family = AF_INET;
--
-- if ((sock = socket(sin.sin_family, SOCK_STREAM, 0)) < 0)
-- msg_fatal("%s: socket: %m", myname);
--
-+ switch (addr->type) {
-+#ifdef INET6
-+ case T_AAAA:
-+ memset(sin6, 0, sizeof(*sin6));
-+ sin6->sin6_family = AF_INET6;
-+ salen = sizeof(*sin6);
-+ break;
-+#endif
-+ default: /* T_A: */
-+ memset(sin, 0, sizeof(*sin));
-+ sin->sin_family = AF_INET;
-+ salen = sizeof(*sin);
-+ break;
-+ }
-+#ifdef HAS_SA_LEN
-+ sa->sa_len = salen;
-+#endif
-+ if ((sock = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
-+ msg_warn("%s: socket: %m", myname);
-+
- /*
- * Allow the sysadmin to specify the source address, for example, as "-o
- * smtp_bind_address=x.x.x.x" in the master.cf file.
- */
- if (*var_smtp_bind_addr) {
-+#ifndef INET6
-+ struct sockaddr_in sin;
-+
-+ memset(&sin, 0, sizeof(sin));
-+ sin.sin_family = AF_INET;
-+#ifdef HAS_SA_LEN
-+ sin.sin_len = sizeof(sin);
-+#endif
- sin.sin_addr.s_addr = inet_addr(var_smtp_bind_addr);
- if (sin.sin_addr.s_addr == INADDR_NONE)
- msg_fatal("%s: bad %s parameter: %s",
-@@ -175,6 +225,25 @@
- msg_warn("%s: bind %s: %m", myname, inet_ntoa(sin.sin_addr));
- if (msg_verbose)
- msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
-+#else
-+ char hbufl[NI_MAXHOST];
-+ struct addrinfo hints, *res;
-+
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = sa->sa_family;
-+ hints.ai_socktype = SOCK_STREAM;
-+ hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST;
-+ snprintf(hbufl, sizeof(hbufl)-1, "%s", var_smtp_bind_addr);
-+ if (getaddrinfo(hbufl, NULL, &hints, &res) == 0) {
-+ (void)getnameinfo(res->ai_addr, res->ai_addrlen, hbufl,
-+ sizeof(hbufl), NULL, 0, NI_NUMERICHOST);
-+ if (bind(sock, res->ai_addr, res->ai_addrlen) < 0)
-+ msg_warn("%s: bind %s: %m", myname, hbufl);
-+ freeaddrinfo(res);
-+ if (msg_verbose)
-+ msg_info("%s: bind %s", myname, hbufl);
-+ }
-+#endif
- }
-
- /*
-@@ -182,8 +251,17 @@
- * the mail appears to come from the "right" machine address.
- */
- else if ((addr_list = own_inet_addr_list())->used == 1) {
-+#ifndef INET6
-+ struct sockaddr_in sin;
-+ unsigned long inaddr; /*XXX BAD!*/
-+
-+ memset(&sin, 0, sizeof(sin));
-+ sin.sin_family = AF_INET;
-+#ifdef HAS_SA_LEN
-+ sin.sin_len = sizeof(sin);
-+#endif
- memcpy((char *) &sin.sin_addr, addr_list->addrs, sizeof(sin.sin_addr));
-- inaddr = ntohl(sin.sin_addr.s_addr);
-+ inaddr = (unsigned long)ntohl(sin.sin_addr.s_addr);
- if (!IN_CLASSA(inaddr)
- || !(((inaddr & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)) {
- if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
-@@ -191,30 +269,85 @@
- if (msg_verbose)
- msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
- }
-+#else
-+ char hbufl[NI_MAXHOST];
-+ struct addrinfo hints, *res = NULL, *loopback = NULL;
-+
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = sa->sa_family;
-+ hints.ai_socktype = SOCK_STREAM;
-+ if (getaddrinfo(NULL, "0", &hints, &loopback) != 0)
-+ loopback = NULL;
-+
-+ /*
-+ * getnameinfo -> getaddrinfo loop is here so that we can
-+ * get rid of port.
-+ */
-+ (void)getnameinfo((struct sockaddr *)addr_list->addrs, SA_LEN((struct sockaddr *)addr_list->addrs),
-+ hbufl, sizeof(hbufl), NULL, 0, NI_NUMERICHOST);
-+ hbufl[sizeof(hbufl)-1] = 0;
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = sa->sa_family;
-+ hints.ai_socktype = SOCK_STREAM;
-+ hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST;
-+ if (getaddrinfo(hbufl, NULL, &hints, &res) == 0 &&
-+ !(res->ai_addrlen == loopback->ai_addrlen &&
-+ memcmp(res->ai_addr, loopback->ai_addr, res->ai_addrlen) == 0)) {
-+ if (bind(sock, res->ai_addr, res->ai_addrlen) < 0)
-+ msg_warn("%s: bind %s: %m", myname, hbufl);
-+ if (msg_verbose)
-+ msg_info("%s: bind %s", myname, hbufl);
-+ }
-+ if (res)
-+ freeaddrinfo(res);
-+ if (loopback)
-+ freeaddrinfo(loopback);
-+#endif
- }
-
- /*
- * Connect to the SMTP server.
- */
-- sin.sin_port = port;
-- memcpy((char *) &sin.sin_addr, addr->data, sizeof(sin.sin_addr));
-+ switch (addr->type) {
-+#ifdef INET6
-+ case T_AAAA:
-+ /* XXX scope unfriendly */
-+ memset(sin6, 0, sizeof(*sin6));
-+ sin6->sin6_port = port;
-+ sin6->sin6_family = AF_INET6;
-+ salen = sizeof(*sin6);
-+ memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr));
-+ inet_ntop(AF_INET6, &sin6->sin6_addr, hbuf, sizeof(hbuf));
-+ break;
-+#endif
-+ default: /* T_A */
-+ memset(sin, 0, sizeof(*sin));
-+ sin->sin_port = port;
-+ sin->sin_family = AF_INET;
-+ salen = sizeof(*sin);
-+ memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr));
-+ inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf));
-+ break;
-+ }
-+#ifdef HAS_SA_LEN
-+ sa->sa_len = salen;
-+#endif
-
- if (msg_verbose)
- msg_info("%s: trying: %s[%s] port %d...",
-- myname, addr->name, inet_ntoa(sin.sin_addr), ntohs(port));
-+ myname, addr->name, hbuf, ntohs(port));
- if (var_smtp_conn_tmout > 0) {
- non_blocking(sock, NON_BLOCKING);
-- conn_stat = timed_connect(sock, (struct sockaddr *) & sin,
-- sizeof(sin), var_smtp_conn_tmout);
-+ conn_stat = timed_connect(sock, sa, salen, var_smtp_conn_tmout);
- saved_errno = errno;
- non_blocking(sock, BLOCKING);
- errno = saved_errno;
- } else {
-- conn_stat = sane_connect(sock, (struct sockaddr *) & sin, sizeof(sin));
-+ conn_stat = connect(sock, sa, salen);
- }
- if (conn_stat < 0) {
- vstring_sprintf(why, "connect to %s[%s]: %m",
-- addr->name, inet_ntoa(sin.sin_addr));
-+ addr->name, hbuf);
- smtp_errno = SMTP_RETRY;
- close(sock);
- return (0);
-@@ -224,8 +357,8 @@
- * Skip this host if it takes no action within some time limit.
- */
- if (read_wait(sock, var_smtp_helo_tmout) < 0) {
-- vstring_sprintf(why, "connect to %s[%s]: read timeout",
-- addr->name, inet_ntoa(sin.sin_addr));
-+ vstring_sprintf(why, "connect to %s [%s]: read timeout",
-+ addr->name, hbuf);
- smtp_errno = SMTP_RETRY;
- close(sock);
- return (0);
-@@ -237,7 +370,7 @@
- stream = vstream_fdopen(sock, O_RDWR);
- if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) {
- vstring_sprintf(why, "connect to %s[%s]: server dropped connection without sending the initial greeting",
-- addr->name, inet_ntoa(sin.sin_addr));
-+ addr->name, hbuf);
- smtp_errno = SMTP_RETRY;
- vstream_fclose(stream);
- return (0);
-@@ -249,7 +382,7 @@
- */
- if (ch == '4' && var_smtp_skip_4xx_greeting) {
- vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
-- addr->name, inet_ntoa(sin.sin_addr));
-+ addr->name, hbuf);
- smtp_errno = SMTP_RETRY;
- vstream_fclose(stream);
- return (0);
-@@ -260,12 +393,12 @@
- */
- if (ch == '5' && var_smtp_skip_5xx_greeting) {
- vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
-- addr->name, inet_ntoa(sin.sin_addr));
-+ addr->name, hbuf);
- smtp_errno = SMTP_RETRY;
- vstream_fclose(stream);
- return (0);
- }
-- return (smtp_session_alloc(dest, stream, addr->name, inet_ntoa(sin.sin_addr)));
-+ return (smtp_session_alloc(dest, stream, addr->name, hbuf));
- }
-
- /* smtp_connect_host - direct connection to host */
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/smtp/smtp_unalias.c postfix-2.0.16/src/smtp/smtp_unalias.c
---- postfix-2.0.16.orig/src/smtp/smtp_unalias.c 2000-09-28 19:06:09.000000000 +0200
-+++ postfix-2.0.16/src/smtp/smtp_unalias.c 2005-01-07 18:25:30.202330704 +0100
-@@ -86,7 +86,11 @@
- if ((result = htable_find(cache, name)) == 0) {
- fqdn = vstring_alloc(10);
- if (dns_lookup_types(name, smtp_unalias_flags, (DNS_RR **) 0,
-- fqdn, (VSTRING *) 0, T_MX, T_A, 0) != DNS_OK)
-+ fqdn, (VSTRING *) 0, T_MX, T_A,
-+#ifdef INET6
-+ T_AAAA,
-+#endif
-+ 0) != DNS_OK)
- vstring_strcpy(fqdn, name);
- htable_enter(cache, name, result = vstring_export(fqdn));
- }
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/smtpd/smtpd_check.c postfix-2.0.16/src/smtpd/smtpd_check.c
---- postfix-2.0.16.orig/src/smtpd/smtpd_check.c 2005-01-07 18:22:25.302439760 +0100
-+++ postfix-2.0.16/src/smtpd/smtpd_check.c 2005-01-07 18:25:30.218328272 +0100
-@@ -1393,6 +1393,49 @@
- static int has_my_addr(SMTPD_STATE *state, const char *host,
- const char *reply_name, const char *reply_class)
- {
-+#ifdef INET6
-+ char *myname = "has_my_addr";
-+ struct addrinfo hints, *res, *res0;
-+ int error;
-+ char hbuf[NI_MAXHOST];
-+
-+ if (msg_verbose)
-+ msg_info("%s: host %s", myname, host);
-+
-+ /*
-+ * If we can't lookup the host, play safe and assume it is OK.
-+ */
-+#define YUP 1
-+#define NOPE 0
-+
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_socktype = SOCK_DGRAM;
-+ error = getaddrinfo(host, NULL, &hints, &res0);
-+ if (error) {
-+ if (msg_verbose)
-+ msg_info("%s: host %s: %s", myname, host, gai_strerror(error));
-+ return (YUP);
-+ }
-+ for (res = res0; res; res = res->ai_next) {
-+ if (msg_verbose) {
-+ if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
-+ NULL, 0, NI_NUMERICHOST)) {
-+ strncpy(hbuf, "???", sizeof(hbuf));
-+ }
-+ msg_info("%s: addr %s", myname, hbuf);
-+ }
-+ if (own_inet_addr(res->ai_addr)) {
-+ freeaddrinfo(res0);
-+ return (YUP);
-+ }
-+ }
-+ freeaddrinfo(res0);
-+ if (msg_verbose)
-+ msg_info("%s: host %s: no match", myname, host);
-+
-+ return (NOPE);
-+#else
- char *myname = "has_my_addr";
- struct in_addr addr;
- char **cpp;
-@@ -1431,6 +1474,7 @@
- msg_info("%s: host %s: no match", myname, host);
-
- return (NOPE);
-+#endif
- }
-
- /* i_am_mx - is this machine listed as MX relay */
-@@ -2015,11 +2059,28 @@
- #define CHK_ADDR_RETURN(x,y) { *found = y; return(x); }
-
- addr = STR(vstring_strcpy(error_text, address));
--
-+#ifdef INET6
-+ if (strncmp(addr, "::ffff:", 7) == 0 && msg_verbose)
-+ msg_info("%s: %s v6 addr in v4 compat-mode, "
-+ "converted to v4 for map checking compatibility (%s)", \
-+ myname, addr, addr+7);
-+#endif
-+
- if ((dict = dict_handle(table)) == 0)
- msg_panic("%s: dictionary not found: %s", myname, table);
- do {
- if (flags == 0 || (flags & dict->flags) != 0) {
-+#ifdef INET6
-+ if (strncmp(addr, "::ffff:", 7) == 0) {
-+ /* try if ::ffff: formati is present in map, if not, try
-+ traditional IPv4 format striping :ffff: part */
-+ if ((value = dict_get(dict, addr)) != 0 || \
-+ (value = dict_get(dict, addr+7)) != 0)
-+ CHK_ADDR_RETURN(check_table_result(state, table, value, address,
-+ reply_name, reply_class,
-+ def_acl), FOUND);
-+ } else
-+#endif
- if ((value = dict_get(dict, addr)) != 0)
- CHK_ADDR_RETURN(check_table_result(state, table, value, address,
- reply_name, reply_class,
-@@ -2579,16 +2640,32 @@
- VSTRING *query;
- int i;
- SMTPD_RBL_STATE *rbl;
-+#ifdef INET6
-+ struct in_addr a;
-+#else
-+ struct in6_addr a;
-+#endif
-
- if (msg_verbose)
- msg_info("%s: %s %s", myname, reply_class, addr);
-
-- /*
-- * IPv4 only for now
-- */
--#ifdef INET6
-+#ifndef INET6
-+ /* IPv4 only for now */
- if (inet_pton(AF_INET, addr, &a) != 1)
- return SMTPD_CHECK_DUNNO;
-+ octets = argv_split(state->addr, ".");
-+#else
-+ /* IPv4 and IPv6-mapped IPv4 only for now */
-+ if (inet_pton(AF_INET, state->addr, &a) == 1)
-+ octets = argv_split(state->addr, ".");
-+ else {
-+ struct in6_addr a6;
-+ if (inet_pton(AF_INET6, state->addr, &a6) != 1)
-+ return SMTPD_CHECK_DUNNO;
-+ if (!IN6_IS_ADDR_V4MAPPED(&a6) || (strrchr(state->addr,':') == NULL))
-+ return SMTPD_CHECK_DUNNO;
-+ octets = argv_split(strrchr(state->addr,':')+1, ".");
-+ }
- #endif
-
- /*
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/smtpd/smtpd_peer.c postfix-2.0.16/src/smtpd/smtpd_peer.c
---- postfix-2.0.16.orig/src/smtpd/smtpd_peer.c 2002-08-22 19:50:51.000000000 +0200
-+++ postfix-2.0.16/src/smtpd/smtpd_peer.c 2005-01-07 18:25:30.205330248 +0100
-@@ -63,6 +63,15 @@
- #include <netdb.h>
- #include <string.h>
-
-+/* Utility library. */
-+
-+#include <msg.h>
-+#include <mymalloc.h>
-+#include <valid_hostname.h>
-+#include <stringops.h>
-+
-+/* Global library. */
-+
- /*
- * Older systems don't have h_errno. Even modern systems don't have
- * hstrerror().
-@@ -84,16 +93,11 @@
- )
- #endif
-
--/* Utility library. */
--
--#include <msg.h>
--#include <mymalloc.h>
--#include <valid_hostname.h>
--#include <stringops.h>
--
--/* Global library. */
--
--
-+#ifdef INET6
-+#define GAI_STRERROR(error) \
-+ ((error = EAI_SYSTEM) ? gai_strerror(error) : strerror(errno))
-+#endif
-+
- /* Application-specific. */
-
- #include "smtpd.h"
-@@ -102,21 +106,28 @@
-
- void smtpd_peer_init(SMTPD_STATE *state)
- {
-- struct sockaddr_in sin;
-- SOCKADDR_SIZE len = sizeof(sin);
-+#ifdef INET6
-+ struct sockaddr_storage ss;
-+#else
-+ struct sockaddr ss;
-+ struct in_addr *in;
- struct hostent *hp;
-- int i;
-+#endif
-+ struct sockaddr *sa;
-+ SOCKADDR_SIZE len;
-+
-+ sa = (struct sockaddr *)&ss;
-+ len = sizeof(ss);
-
- /*
- * Avoid suprious complaints from Purify on Solaris.
- */
-- memset((char *) &sin, 0, len);
-+ memset((char *) sa, 0, len);
-
- /*
- * Look up the peer address information.
- */
-- if (getpeername(vstream_fileno(state->client),
-- (struct sockaddr *) & sin, &len) >= 0) {
-+ if (getpeername(vstream_fileno(state->client), sa, &len) >= 0) {
- errno = 0;
- }
-
-@@ -132,23 +143,56 @@
- /*
- * Look up and "verify" the client hostname.
- */
-- else if (errno == 0 && sin.sin_family == AF_INET) {
-- state->addr = mystrdup(inet_ntoa(sin.sin_addr));
-- hp = gethostbyaddr((char *) &(sin.sin_addr),
-- sizeof(sin.sin_addr), AF_INET);
-- if (hp == 0) {
-+ else if (errno == 0 && (sa->sa_family == AF_INET
-+#ifdef INET6
-+ || sa->sa_family == AF_INET6
-+#endif
-+ )) {
-+#ifdef INET6
-+ char hbuf[NI_MAXHOST];
-+ char abuf[NI_MAXHOST];
-+ struct addrinfo hints, *rnull = NULL;
-+#else
-+ char abuf[sizeof("255.255.255.255") + 1];
-+ char *hbuf;
-+#endif
-+ int error = -1;
-+
-+#ifdef INET6
-+ (void)getnameinfo(sa, len, abuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
-+#else
-+ in = &((struct sockaddr_in *)sa)->sin_addr;
-+ inet_ntop(AF_INET, in, abuf, sizeof(hbuf));
-+#endif
-+ state->addr = mystrdup(abuf);
-+#ifdef INET6
-+ error = getnameinfo(sa, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD);
-+#else
-+ hbuf = NULL;
-+ hp = gethostbyaddr((char *)in, sizeof(*in), AF_INET);
-+ if (hp) {
-+ error = 0;
-+ hbuf = mystrdup(hp->h_name);
-+ } else
-+ error = 1;
-+#endif
-+ if (error) {
- state->name = mystrdup("unknown");
-+#ifdef INET6
-+ state->peer_code = (error == EAI_AGAIN ? 4 : 5);
-+#else
- state->peer_code = (h_errno == TRY_AGAIN ? 4 : 5);
-- } else if (valid_hostaddr(hp->h_name, DONT_GRIPE)) {
-+#endif
-+ } else if (valid_hostaddr(hbuf, DONT_GRIPE)) {
- msg_warn("numeric result %s in address->name lookup for %s",
-- hp->h_name, state->addr);
-+ hbuf, state->addr);
- state->name = mystrdup("unknown");
- state->peer_code = 5;
-- } else if (!valid_hostname(hp->h_name, DONT_GRIPE)) {
-+ } else if (!valid_hostname(hbuf, DONT_GRIPE)) {
- state->name = mystrdup("unknown");
- state->peer_code = 5;
- } else {
-- state->name = mystrdup(hp->h_name); /* hp->name is clobbered!! */
-+ state->name = mystrdup(hbuf); /* hp->name is clobbered!! */
- state->peer_code = 2;
-
- /*
-@@ -160,16 +204,31 @@
- state->peer_code = code; \
- }
-
-+#ifdef INET6
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = AF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM;
-+ error = getaddrinfo(state->name, NULL, &hints, &rnull);
-+ if (error) {
-+ msg_warn("%s: hostname %s verification failed: %s",
-+ state->addr, state->name, GAI_STRERROR(error));
-+ REJECT_PEER_NAME(state, (error == EAI_AGAIN ? 4 : 5));
-+ }
-+ /* memcmp() isn't needed if we use getaddrinfo */
-+ if (rnull)
-+ freeaddrinfo(rnull);
-+#else
- hp = gethostbyname(state->name); /* clobbers hp->name!! */
- if (hp == 0) {
- msg_warn("%s: hostname %s verification failed: %s",
- state->addr, state->name, HSTRERROR(h_errno));
- REJECT_PEER_NAME(state, (h_errno == TRY_AGAIN ? 4 : 5));
-- } else if (hp->h_length != sizeof(sin.sin_addr)) {
-+ } else if (hp->h_length != sizeof(*in)) {
- msg_warn("%s: hostname %s verification failed: bad address size %d",
- state->addr, state->name, hp->h_length);
- REJECT_PEER_NAME(state, 5);
- } else {
-+ int i;
- for (i = 0; /* void */ ; i++) {
- if (hp->h_addr_list[i] == 0) {
- msg_warn("%s: address not listed for hostname %s",
-@@ -177,12 +236,11 @@
- REJECT_PEER_NAME(state, 5);
- break;
- }
-- if (memcmp(hp->h_addr_list[i],
-- (char *) &sin.sin_addr,
-- sizeof(sin.sin_addr)) == 0)
-+ if (memcmp(hp->h_addr_list[i], (char *)in, sizeof(*in)) == 0)
- break; /* keep peer name */
- }
- }
-+#endif
- }
- }
-
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/smtpstone/smtp-sink.c postfix-2.0.16/src/smtpstone/smtp-sink.c
---- postfix-2.0.16.orig/src/smtpstone/smtp-sink.c 2003-09-13 02:46:56.000000000 +0200
-+++ postfix-2.0.16/src/smtpstone/smtp-sink.c 2005-01-07 18:25:30.205330248 +0100
-@@ -607,7 +607,7 @@
- } else {
- if (strncmp(argv[optind], "inet:", 5) == 0)
- argv[optind] += 5;
-- sock = inet_listen(argv[optind], backlog, BLOCKING);
-+ sock = inet_listen(argv[optind], backlog, BLOCKING, 1);
- }
-
- /*
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/util/Makefile.in postfix-2.0.16/src/util/Makefile.in
---- postfix-2.0.16.orig/src/util/Makefile.in 2005-01-07 18:22:25.293441128 +0100
-+++ postfix-2.0.16/src/util/Makefile.in 2005-01-07 18:25:30.209329640 +0100
-@@ -8,7 +8,7 @@
- dict_tcp.c dict_unix.c dir_forest.c doze.c duplex_pipe.c \
- environ.c events.c exec_command.c fifo_listen.c fifo_trigger.c \
- file_limit.c find_inet.c fsspace.c fullname.c get_domainname.c \
-- get_hostname.c hex_quote.c htable.c inet_addr_host.c \
-+ get_hostname.c get_port.c hex_quote.c htable.c inet_addr_host.c \
- inet_addr_list.c inet_addr_local.c inet_connect.c inet_listen.c \
- inet_trigger.c inet_util.c intv.c line_wrap.c lowercase.c \
- lstat_as.c mac_expand.c mac_parse.c make_dirs.c match_list.c \
-@@ -37,7 +37,7 @@
- dict_tcp.o dict_unix.o dir_forest.o doze.o duplex_pipe.o \
- environ.o events.o exec_command.o fifo_listen.o fifo_trigger.o \
- file_limit.o find_inet.o fsspace.o fullname.o get_domainname.o \
-- get_hostname.o hex_quote.o htable.o inet_addr_host.o \
-+ get_hostname.o get_port.o hex_quote.o htable.o inet_addr_host.o \
- inet_addr_list.o inet_addr_local.o inet_connect.o inet_listen.o \
- inet_trigger.o inet_util.o intv.o line_wrap.o lowercase.o \
- lstat_as.o mac_expand.o mac_parse.o make_dirs.o match_list.o \
-@@ -62,7 +62,7 @@
- dict_ht.h dict_ldap.h dict_mysql.h dict_ni.h dict_nis.h \
- dict_nisplus.h dict_pcre.h dict_pgsql.h dict_regexp.h dict_static.h dict_tcp.h \
- dict_unix.h dir_forest.h events.h exec_command.h find_inet.h \
-- fsspace.h fullname.h get_domainname.h get_hostname.h hex_quote.h \
-+ fsspace.h fullname.h get_domainname.h get_hostname.h get_port.h hex_quote.h \
- htable.h inet_addr_host.h inet_addr_list.h inet_addr_local.h \
- inet_util.h intv.h iostuff.h line_wrap.h listen.h lstat_as.h \
- mac_expand.h mac_parse.h make_dirs.h match_list.h match_ops.h \
-@@ -785,6 +785,7 @@
- get_domainname.o: mymalloc.h
- get_domainname.o: get_hostname.h
- get_domainname.o: get_domainname.h
-+get_port.o: sys_defs.h
- get_hostname.o: get_hostname.c
- get_hostname.o: sys_defs.h
- get_hostname.o: mymalloc.h
-@@ -911,6 +912,7 @@
- match_list.o: stringops.h
- match_list.o: argv.h
- match_list.o: dict.h
-+match_list.o: inet_util.h
- match_list.o: match_ops.h
- match_list.o: match_list.h
- match_ops.o: match_ops.c
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/util/get_port.c postfix-2.0.16/src/util/get_port.c
---- postfix-2.0.16.orig/src/util/get_port.c 1970-01-01 01:00:00.000000000 +0100
-+++ postfix-2.0.16/src/util/get_port.c 2005-01-07 18:25:30.206330096 +0100
-@@ -0,0 +1,65 @@
-+/*++
-+/* NAME
-+/* get_port 3
-+/* SUMMARY
-+/* trivial host and port extracter
-+/* SYNOPSIS
-+/* #include <get_port.h>
-+/*
-+/* char *get_port(data)
-+/* char *data;
-+/*
-+/* DESCRIPTION
-+/* get_port() extract host name or ip address from
-+/* strings such as [3ffe:902:12::10]:25, [::1]
-+/* or 192.168.0.1:25, and null-terminates the
-+/* \fIdata\fR at the first occurrence of port separator.
-+/* DIAGNOSTICS
-+/* If port not found return null pointer.
-+/* LICENSE
-+/* .ad
-+/* .fi
-+/* BSD Style (or BSD like) license.
-+/* AUTHOR(S)
-+/* Arkadiusz Miśkiewicz <misiek@pld.org.pl>
-+/* Wroclaw, POLAND
-+/*--*/
-+
-+/* System libraries */
-+
-+#include <sys_defs.h>
-+#include <string.h>
-+
-+/* Utility library. */
-+
-+#include "get_port.h"
-+
-+/* get_port - extract port number from string */
-+
-+char *get_port(char *data)
-+{
-+ const char *escl=strchr(data,'[');
-+ const char *sepl=strchr(data,':');
-+ char *escr=strrchr(data,']');
-+ char *sepr=strrchr(data,':');
-+
-+ /* extract from "[address]:port" or "[address]"*/
-+ if (escl && escr)
-+ {
-+ memmove(data, data + 1, strlen(data) - strlen(escr));
-+ data[strlen(data) - strlen(escr) - 1] = 0;
-+ *escr++ = 0;
-+ if (*escr == ':')
-+ escr++;
-+ return (*escr ? escr : NULL);
-+ }
-+ /* extract from "address:port" or "address" */
-+ if ((sepl == sepr) && sepr && sepl)
-+ {
-+ *sepr++ = 0;
-+ return sepr;
-+ }
-+
-+ /* return empty string */
-+ return NULL;
-+}
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/util/get_port.h postfix-2.0.16/src/util/get_port.h
---- postfix-2.0.16.orig/src/util/get_port.h 1970-01-01 01:00:00.000000000 +0100
-+++ postfix-2.0.16/src/util/get_port.h 2005-01-07 18:25:30.206330096 +0100
-@@ -0,0 +1,28 @@
-+#ifndef _GET_PORT_H_INCLUDED_
-+#define _GET_PORT_H_INCLUDED_
-+
-+/*++
-+/* NAME
-+/* get_port 3h
-+/* SUMMARY
-+/* trivial host and port extracter
-+/* SYNOPSIS
-+/* #include <get_port.h>
-+/* DESCRIPTION
-+/* .nf
-+
-+ /* External interface. */
-+
-+extern char *get_port(char *);
-+
-+
-+/* LICENSE
-+/* .ad
-+/* .fi
-+/* BSD Style (or BSD like) license.
-+/* AUTHOR(S)
-+/* Arkadiusz Miśkiewicz <misiek@pld.org.pl>
-+/* Wroclaw, POLAND
-+/*--*/
-+
-+#endif
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/util/inet_addr_host.c postfix-2.0.16/src/util/inet_addr_host.c
---- postfix-2.0.16.orig/src/util/inet_addr_host.c 1998-12-11 19:55:35.000000000 +0100
-+++ postfix-2.0.16/src/util/inet_addr_host.c 2005-01-07 18:28:55.469125408 +0100
-@@ -38,7 +38,11 @@
- #include <sys_defs.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
-+#include <sys/socket.h>
- #include <netdb.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <unistd.h>
-
- #ifndef INADDR_NONE
- #define INADDR_NONE 0xffffffff
-@@ -48,15 +52,47 @@
-
- #include <inet_addr_list.h>
- #include <inet_addr_host.h>
-+#ifdef TEST
-+#include <msg.h>
-+#endif
-
- /* inet_addr_host - look up address list for host */
-
- int inet_addr_host(INET_ADDR_LIST *addr_list, const char *hostname)
- {
-+#ifdef INET6
-+ int s;
-+ struct addrinfo hints, *res0, *res;
-+#ifdef TEST
-+ char buforhosta[1024];
-+#endif
-+ int error;
-+#else
- struct hostent *hp;
- struct in_addr addr;
-+#endif
- int initial_count = addr_list->used;
-
-+#ifdef INET6
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_socktype = SOCK_DGRAM;
-+ error = getaddrinfo(hostname, NULL, &hints, &res0);
-+ if (error == 0) {
-+ for (res = res0; res; res = res->ai_next) {
-+ if(res->ai_family != AF_INET && res->ai_family != AF_INET6)
-+ continue;
-+ /* filter out address families that are not supported */
-+ s = socket(res->ai_family, SOCK_DGRAM, 0);
-+ if (s < 0)
-+ continue;
-+ close(s);
-+
-+ inet_addr_list_append(addr_list, res->ai_addr);
-+ }
-+ freeaddrinfo(res0);
-+ }
-+#else
- if ((addr.s_addr = inet_addr(hostname)) != INADDR_NONE) {
- inet_addr_list_append(addr_list, &addr);
- } else {
-@@ -65,9 +101,12 @@
- inet_addr_list_append(addr_list,
- (struct in_addr *) * hp->h_addr_list++);
- }
-+#endif
-+
- return (addr_list->used - initial_count);
- }
-
-+
- #ifdef TEST
-
- #include <msg.h>
-@@ -78,6 +117,8 @@
- {
- INET_ADDR_LIST addr_list;
- int i;
-+ struct sockaddr *sa;
-+ char hbuf[NI_MAXHOST];
-
- msg_vstream_init(argv[0], VSTREAM_ERR);
-
-@@ -89,8 +130,12 @@
- if (inet_addr_host(&addr_list, *argv) == 0)
- msg_fatal("not found: %s", *argv);
-
-- for (i = 0; i < addr_list.used; i++)
-- vstream_printf("%s\n", inet_ntoa(addr_list.addrs[i]));
-+ for (i = 0; i < addr_list.used; i++) {
-+ sa = (struct sockaddr *)&addr_list.addrs[i];
-+ getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
-+ NI_NUMERICHOST);
-+ vstream_printf("%s\n", hbuf);
-+ }
- vstream_fflush(VSTREAM_OUT);
- }
- inet_addr_list_free(&addr_list);
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/util/inet_addr_list.c postfix-2.0.16/src/util/inet_addr_list.c
---- postfix-2.0.16.orig/src/util/inet_addr_list.c 2001-07-31 20:13:41.000000000 +0200
-+++ postfix-2.0.16/src/util/inet_addr_list.c 2005-01-07 18:25:30.207329944 +0100
-@@ -51,6 +51,13 @@
- #include <arpa/inet.h>
- #include <stdlib.h>
-
-+#include <netdb.h>
-+
-+#ifdef INET6
-+#include <string.h>
-+#include <sys/socket.h>
-+#endif
-+
- /* Utility library. */
-
- #include <msg.h>
-@@ -63,12 +70,39 @@
- {
- list->used = 0;
- list->size = 2;
-+#ifdef INET6
-+ list->addrs = (struct sockaddr_storage *)
-+#else
- list->addrs = (struct in_addr *)
-+#endif
- mymalloc(sizeof(*list->addrs) * list->size);
- }
-
- /* inet_addr_list_append - append address to internet address list */
-
-+#ifdef INET6
-+void inet_addr_list_append(INET_ADDR_LIST *list,
-+ struct sockaddr * addr)
-+{
-+ char *myname = "inet_addr_list_append";
-+ char hbuf[NI_MAXHOST];
-+
-+ if (msg_verbose > 1) {
-+ if (getnameinfo(addr, SA_LEN(addr), hbuf, sizeof(hbuf), NULL, 0,
-+ NI_NUMERICHOST)) {
-+ strncpy(hbuf, "??????", sizeof(hbuf));
-+ }
-+ msg_info("%s: %s", myname, hbuf);
-+ }
-+
-+ if (list->used >= list->size)
-+ list->size *= 2;
-+ list->addrs = (struct sockaddr_storage *)
-+ myrealloc((char *) list->addrs,
-+ sizeof(*list->addrs) * list->size);
-+ memcpy(&list->addrs[list->used++], addr, SA_LEN(addr));
-+}
-+#else
- void inet_addr_list_append(INET_ADDR_LIST *list, struct in_addr * addr)
- {
- char *myname = "inet_addr_list_append";
-@@ -83,15 +117,22 @@
- sizeof(*list->addrs) * list->size);
- list->addrs[list->used++] = *addr;
- }
-+#endif
-
- /* inet_addr_list_comp - compare addresses */
-
- static int inet_addr_list_comp(const void *a, const void *b)
- {
-+#ifdef INET6
-+ if(((struct sockaddr*)a)->sa_family != ((struct sockaddr*)b)->sa_family)
-+ return ( ((struct sockaddr*)a)->sa_family - ((struct sockaddr*)b)->sa_family );
-+ return memcmp(a,b,SA_LEN((struct sockaddr*)a));
-+#else
- const struct in_addr *a_addr = (const struct in_addr *) a;
- const struct in_addr *b_addr = (const struct in_addr *) b;
-
- return (a_addr->s_addr - b_addr->s_addr);
-+#endif
- }
-
- /* inet_addr_list_uniq - weed out duplicates */
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/util/inet_addr_list.h postfix-2.0.16/src/util/inet_addr_list.h
---- postfix-2.0.16.orig/src/util/inet_addr_list.h 2001-07-31 19:56:47.000000000 +0200
-+++ postfix-2.0.16/src/util/inet_addr_list.h 2005-01-07 18:25:30.207329944 +0100
-@@ -16,19 +16,38 @@
- */
- #include <netinet/in.h>
-
-+#ifndef SA_LEN
-+#ifndef HAS_SA_LEN
-+#define SA_LEN(x) (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
-+#define SS_LEN(x) (((x).ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
-+#else
-+#define SA_LEN(x) ((x)->sa_len)
-+#define SS_LEN(x) ((x).ss_len)
-+#endif
-+#endif
-+
- /*
- * External interface.
- */
- typedef struct INET_ADDR_LIST {
- int used; /* nr of elements in use */
- int size; /* actual list size */
-+#ifdef INET6
-+ struct sockaddr_storage *addrs; /* payload */
-+#else
- struct in_addr *addrs; /* payload */
-+#endif
- } INET_ADDR_LIST;
-
- extern void inet_addr_list_init(INET_ADDR_LIST *);
- extern void inet_addr_list_free(INET_ADDR_LIST *);
- extern void inet_addr_list_uniq(INET_ADDR_LIST *);
-+#ifdef INET6
-+struct sockaddr;
-+extern void inet_addr_list_append(INET_ADDR_LIST *, struct sockaddr *);
-+#else
- extern void inet_addr_list_append(INET_ADDR_LIST *, struct in_addr *);
-+#endif
-
- /* LICENSE
- /* .ad
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/util/inet_addr_local.c postfix-2.0.16/src/util/inet_addr_local.c
---- postfix-2.0.16.orig/src/util/inet_addr_local.c 2001-02-25 19:20:19.000000000 +0100
-+++ postfix-2.0.16/src/util/inet_addr_local.c 2005-01-07 18:25:30.207329944 +0100
-@@ -47,6 +47,13 @@
- #endif
- #include <errno.h>
- #include <string.h>
-+#if defined(INET6) && (defined (LINUX) || defined (LINUX2))
-+#include <netdb.h>
-+#include <stdio.h>
-+#endif
-+#ifdef HAVE_GETIFADDRS
-+#include <ifaddrs.h>
-+#endif
-
- /* Utility library. */
-
-@@ -78,18 +85,104 @@
-
- int inet_addr_local(INET_ADDR_LIST *addr_list, INET_ADDR_LIST *mask_list)
- {
-+#ifdef HAVE_GETIFADDRS
-+ char *myname = "inet_addr_local";
-+ struct ifaddrs *ifap, *ifa;
-+ int initial_count = addr_list->used;
-+ struct sockaddr *sa, *sam;
-+#ifdef INET6
-+#ifdef __KAME__
-+ struct sockaddr_in6 addr6;
-+#endif
-+#else
-+ void *addr,*addrm;
-+#endif
-+
-+ if (getifaddrs(&ifap) < 0)
-+ msg_fatal("%s: getifaddrs: %m", myname);
-+
-+ for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
-+ if ((!(ifa->ifa_flags & IFF_RUNNING)) || (ifa->ifa_addr == NULL) || (ifa->ifa_netmask == NULL))
-+ continue;
-+ sa = ifa->ifa_addr;
-+ sam = ifa->ifa_netmask;
-+ switch (ifa->ifa_addr->sa_family) {
-+ case AF_INET:
-+#ifndef INET6
-+ addr = (void *)&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
-+ addrm = (void *)&((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
-+#endif
-+ break;
-+#ifdef INET6
-+ case AF_INET6:
-+#ifdef __KAME__
-+ memcpy(&addr6, ifa->ifa_addr, ifa->ifa_addr->sa_len);
-+ /* decode scoped address notation */
-+ if ((IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) ||
-+ IN6_IS_ADDR_SITELOCAL(&addr6.sin6_addr)) &&
-+ addr6.sin6_scope_id == 0) {
-+ addr6.sin6_scope_id = ntohs(addr6.sin6_addr.s6_addr[3] |
-+ (unsigned int)addr6.sin6_addr.s6_addr[2] << 8);
-+ addr6.sin6_addr.s6_addr[2] = addr6.sin6_addr.s6_addr[3] = 0;
-+ sa = (struct sockaddr *)&addr6;
-+ }
-+#endif
-+ break;
-+#endif
-+ default:
-+ continue;
-+ }
-+
-+#ifdef INET6
-+ inet_addr_list_append(addr_list, sa);
-+ if (mask_list != NULL)
-+ inet_addr_list_append(mask_list, sam);
-+#else
-+ inet_addr_list_append(addr_list, (struct in_addr *)addr);
-+ if (mask_list != NULL)
-+ inet_addr_list_append(mask_list, (struct in_addr *)addrm);
-+#endif
-+ }
-+
-+ freeifaddrs(ifap);
-+ return (addr_list->used - initial_count);
-+#else
- char *myname = "inet_addr_local";
- struct ifconf ifc;
- struct ifreq *ifr;
- struct ifreq *the_end;
- int sock;
-- VSTRING *buf = vstring_alloc(1024);
-+ VSTRING *buf;
- int initial_count = addr_list->used;
- struct in_addr addr;
- struct ifreq *ifr_mask;
-+ int af = AF_INET;
-+#ifdef INET6
-+#if defined (LINUX) || defined (LINUX2)
-+#define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"
-+ FILE *f;
-+ char addr6p[8][5], addr6res[40], devname[20];
-+ int plen, scope, dad_status, if_idx, gaierror;
-+ struct addrinfo hints, *res, *res0;
-+#endif
-+ struct sockaddr_in6 addr6;
-
-- if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
-+other_socket_type:
-+#endif
-+ buf = vstring_alloc(1024);
-+
-+ if ((sock = socket(af, SOCK_DGRAM, 0)) < 0) {
-+#ifdef INET6
-+ if (af == AF_INET6)
-+ {
-+ if (msg_verbose)
-+ msg_warn("%s: socket: %m", myname);
-+ goto end;
-+ }
-+ else
-+#endif
- msg_fatal("%s: socket: %m", myname);
-+ }
-
- /*
- * Get the network interface list. XXX The socket API appears to have no
-@@ -126,10 +219,15 @@
- */
- the_end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
- for (ifr = ifc.ifc_req; ifr < the_end;) {
-- if (ifr->ifr_addr.sa_family == AF_INET) { /* IP interface */
-+ if ((ifr->ifr_addr.sa_family == AF_INET) &&
-+ (ifr->ifr_addr.sa_family == af)) { /* IP interface */
- addr = ((struct sockaddr_in *) & ifr->ifr_addr)->sin_addr;
- if (addr.s_addr != INADDR_ANY) { /* has IP address */
-+#ifdef INET6
-+ inet_addr_list_append(addr_list, &ifr->ifr_addr);
-+#else
- inet_addr_list_append(addr_list, &addr);
-+#endif
- if (mask_list) {
- ifr_mask = (struct ifreq *) mymalloc(IFREQ_SIZE(ifr));
- memcpy((char *) ifr_mask, (char *) ifr, IFREQ_SIZE(ifr));
-@@ -141,11 +239,70 @@
- }
- }
- }
-+#ifdef INET6
-+ else if ((ifr->ifr_addr.sa_family == AF_INET6) &&
-+ (ifr->ifr_addr.sa_family == af)) { /* IPv6 interface */
-+ addr6 = *((struct sockaddr_in6 *) & ifr->ifr_addr);
-+#ifdef __KAME__
-+ /* decode scoped address notation */
-+ if ((IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) ||
-+ IN6_IS_ADDR_SITELOCAL(&addr6.sin6_addr)) &&
-+ addr6.sin6_scope_id == 0) {
-+ addr6.sin6_scope_id = ntohs(addr6.sin6_addr.s6_addr[3] |
-+ (unsigned int)addr6.sin6_addr.s6_addr[2] << 8);
-+ addr6.sin6_addr.s6_addr[2] = addr6.sin6_addr.s6_addr[3] = 0;
-+ }
-+#endif
-+ if (!(IN6_IS_ADDR_UNSPECIFIED(&addr6.sin6_addr))) {
-+ inet_addr_list_append(addr_list, (struct sockaddr *)&addr6);
-+ if (mask_list) {
-+#error "mask_list for IPv6 without libinet6 not done yet (error to avoid open-relay)"
-+ /* TODO: how to get netmask here? */
-+ }
-+ }
-+ }
-+#endif
- ifr = NEXT_INTERFACE(ifr);
- }
- vstring_free(buf);
- (void) close(sock);
-+#ifdef INET6
-+end:
-+ if (af != AF_INET6) {
-+ af = AF_INET6;
-+ goto other_socket_type;
-+ }
-+#if defined (LINUX) || defined (LINUX2)
-+ if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
-+ while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
-+ addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4],
-+ addr6p[5], addr6p[6], addr6p[7],
-+ &if_idx, &plen, &scope, &dad_status, devname) != EOF) {
-+ sprintf(addr6res, "%s:%s:%s:%s:%s:%s:%s:%s",
-+ addr6p[0], addr6p[1], addr6p[2], addr6p[3],
-+ addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
-+ addr6res[sizeof(addr6res) - 1] = 0;
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_flags = AI_NUMERICHOST;
-+ hints.ai_family = AF_UNSPEC;
-+ hints.ai_socktype = SOCK_DGRAM;
-+ gaierror = getaddrinfo(addr6res, NULL, &hints, &res0);
-+ if (!gaierror) {
-+ for (res = res0; res; res = res->ai_next) {
-+ inet_addr_list_append(addr_list, res->ai_addr);
-+ if (mask_list) {
-+#error "mask_list for IPv6 without libinet6 not done yet (error to avoid open-relay)"
-+ /* TODO: calculate netmask basing on plen */
-+ }
-+ }
-+ freeaddrinfo(res0);
-+ }
-+ }
-+ }
-+#endif /* linux */
-+#endif
- return (addr_list->used - initial_count);
-+#endif
- }
-
- #ifdef TEST
-@@ -158,6 +315,8 @@
- INET_ADDR_LIST addr_list;
- INET_ADDR_LIST mask_list;
- int i;
-+ char abuf[NI_MAXHOST], mbuf[NI_MAXHOST];
-+ struct sockaddr *sa;
-
- msg_vstream_init(argv[0], VSTREAM_ERR);
-
-@@ -172,8 +331,17 @@
- msg_warn("found only one active network interface");
-
- for (i = 0; i < addr_list.used; i++) {
-- vstream_printf("%s/", inet_ntoa(addr_list.addrs[i]));
-- vstream_printf("%s\n", inet_ntoa(mask_list.addrs[i]));
-+ sa = (struct sockaddr *)&addr_list.addrs[i];
-+ if (getnameinfo(sa, SA_LEN(sa), abuf, sizeof(abuf), NULL, 0,
-+ NI_NUMERICHOST)) {
-+ strncpy(abuf, "???", sizeof(abuf));
-+ }
-+ sa = (struct sockaddr *)&mask_list.addrs[i];
-+ if (getnameinfo(sa, SA_LEN(sa), mbuf, sizeof(mbuf), NULL, 0,
-+ NI_NUMERICHOST)) {
-+ strncpy(mbuf, "???", sizeof(mbuf));
-+ }
-+ vstream_printf("%s/%s\n", abuf, mbuf);
- }
- vstream_fflush(VSTREAM_OUT);
- inet_addr_list_free(&addr_list);
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/util/inet_connect.c postfix-2.0.16/src/util/inet_connect.c
---- postfix-2.0.16.orig/src/util/inet_connect.c 2003-09-13 03:04:12.000000000 +0200
-+++ postfix-2.0.16/src/util/inet_connect.c 2005-01-07 18:25:30.208329792 +0100
-@@ -55,6 +55,9 @@
- #include <string.h>
- #include <unistd.h>
- #include <errno.h>
-+#ifdef INET6
-+#include <netdb.h>
-+#endif
-
- /* Utility library. */
-
-@@ -74,7 +77,12 @@
- char *buf;
- char *host;
- char *port;
-+#ifdef INET6
-+ struct addrinfo hints, *res, *res0;
-+ int error;
-+#else
- struct sockaddr_in sin;
-+#endif
- int sock;
-
- /*
-@@ -82,14 +90,58 @@
- * the local host.
- */
- buf = inet_parse(addr, &host, &port);
-+#ifdef INET6
-+ if (*host == 0)
-+ host = NULL;
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM;
-+ hints.ai_flags = AI_NUMERICHOST; /* find_inet_addr is numeric only */
-+ if (getaddrinfo(host, port, &hints, &res0))
-+ msg_fatal("host not found: %s", host);
-+#else
- if (*host == 0)
- host = "localhost";
- memset((char *) &sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = find_inet_addr(host);
- sin.sin_port = find_inet_port(port, "tcp");
-+#endif
- myfree(buf);
-
-+#ifdef INET6
-+ sock = -1;
-+ for (res = res0; res; res = res->ai_next) {
-+ if ((res->ai_family != AF_INET) && (res->ai_family != AF_INET6))
-+ continue;
-+
-+ sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
-+ if (sock < 0)
-+ continue;
-+ if (timeout > 0) {
-+ non_blocking(sock, NON_BLOCKING);
-+ if (timed_connect(sock, res->ai_addr, res->ai_addrlen, timeout) < 0) {
-+ close(sock);
-+ sock = -1;
-+ continue;
-+ }
-+ if (block_mode != NON_BLOCKING)
-+ non_blocking(sock, block_mode);
-+ break;
-+ } else {
-+ non_blocking(sock, block_mode);
-+ if (connect(sock, res->ai_addr, res->ai_addrlen) < 0
-+ && errno != EINPROGRESS) {
-+ close(sock);
-+ sock = -1;
-+ continue;
-+ }
-+ break;
-+ }
-+ }
-+ freeaddrinfo(res0);
-+ return sock;
-+#else
- /*
- * Create a client socket.
- */
-@@ -122,4 +174,5 @@
- }
- return (sock);
- }
-+#endif
- }
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/util/inet_listen.c postfix-2.0.16/src/util/inet_listen.c
---- postfix-2.0.16.orig/src/util/inet_listen.c 2003-09-13 01:50:50.000000000 +0200
-+++ postfix-2.0.16/src/util/inet_listen.c 2005-01-07 18:25:30.208329792 +0100
-@@ -6,7 +6,7 @@
- /* SYNOPSIS
- /* #include <listen.h>
- /*
--/* int inet_listen(addr, backlog, block_mode)
-+/* int inet_listen(addr, backlog, block_mode, addinuse_fatal)
- /* const char *addr;
- /* int backlog;
- /* int block_mode;
-@@ -51,11 +51,17 @@
- #include <sys_defs.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
-+#ifdef INET6
-+#if (! __GLIBC__ >= 2 && __GLIBC_MINOR__ >=1 )
-+#include <netinet6/in6.h>
-+#endif
-+#endif
- #include <arpa/inet.h>
- #include <netdb.h>
- #ifndef MAXHOSTNAMELEN
- #include <sys/param.h>
- #endif
-+#include <errno.h>
- #include <string.h>
- #include <unistd.h>
-
-@@ -77,35 +83,116 @@
-
- /* inet_listen - create inet-domain listener */
-
--int inet_listen(const char *addr, int backlog, int block_mode)
-+int inet_listen(const char *addr, int backlog, int block_mode, int addrinuse_fatal)
- {
-+#ifdef INET6
-+ struct addrinfo *res, *res0, hints;
-+ int error;
-+#else
-+ struct ai {
-+ int ai_family;
-+ int ai_socktype;
-+ int ai_protocol;
-+ struct sockaddr *ai_addr;
-+ SOCKADDR_SIZE ai_addrlen;
-+ struct ai *ai_next;
-+ } *res, *res0, resbody;
- struct sockaddr_in sin;
-+#endif
- int sock;
- int t = 1;
-+ int addrinuse = 0;
- char *buf;
- char *host;
- char *port;
-+#ifdef INET6
-+ char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
-+#else
-+ char hbuf[sizeof("255.255.255.255") + 1];
-+ char pbuf[sizeof("255.255.255.255") + 1];
-+#endif
-+ char *cause = "unknown";
-
- /*
- * Translate address information to internal form.
- */
- buf = inet_parse(addr, &host, &port);
-- memset((char *) &sin, 0, sizeof(sin));
-+#ifdef INET6
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_flags = AI_PASSIVE;
-+ hints.ai_family = AF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM;
-+ error = getaddrinfo(*host ? host : NULL, *port ? port : "0", &hints, &res0);
-+ if (error) {
-+ msg_fatal("getaddrinfo: %s", gai_strerror(error));
-+ }
-+ myfree(buf);
-+#else
-+ memset(&sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
-+#ifdef HAS_SA_LEN
-+ sin.sin_len = sizeof(sin);
-+#endif
- sin.sin_port = find_inet_port(port, "tcp");
- sin.sin_addr.s_addr = (*host ? find_inet_addr(host) : INADDR_ANY);
-- myfree(buf);
-
-- /*
-- * Create a listener socket.
-- */
-- if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
-- msg_fatal("socket: %m");
-- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &t, sizeof(t)) < 0)
-- msg_fatal("setsockopt: %m");
-- if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
-- msg_fatal("bind %s port %d: %m", sin.sin_addr.s_addr == INADDR_ANY ?
-- "INADDR_ANY" : inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
-+ memset(&resbody, 0, sizeof(resbody));
-+ resbody.ai_socktype = SOCK_STREAM;
-+ resbody.ai_family = AF_INET;
-+ resbody.ai_addr = (struct sockaddr *)&sin;
-+ resbody.ai_addrlen = sizeof(sin);
-+
-+ res0 = &resbody;
-+#endif
-+
-+ sock = -1;
-+ for (res = res0; res; res = res->ai_next) {
-+ if ((res->ai_family != AF_INET) && (res->ai_family != AF_INET6))
-+ continue;
-+
-+ /*
-+ * Create a listener socket.
-+ */
-+ if ((sock = socket(res->ai_family, res->ai_socktype, 0)) < 0) {
-+ cause = "socket";
-+ continue;
-+ }
-+#ifdef IPV6_V6ONLY
-+ if (res->ai_family == AF_INET6 &&
-+ setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &t, sizeof(t)) < 0) {
-+ /* if kernel/libc don't support this simple ignore it
-+ cause = "setsockopt(IPV6_V6ONLY)";
-+ close(sock);
-+ sock = -1;
-+ continue;
-+ */
-+ ;
-+ }
-+#endif
-+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &t, sizeof(t)) < 0) {
-+ cause = "setsockopt(SO_REUSEADDR)";
-+ close(sock);
-+ sock = -1;
-+ continue;
-+ }
-+
-+ if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
-+ cause = "bind";
-+ if (errno == EADDRINUSE)
-+ addrinuse = 1;
-+ close(sock);
-+ sock = -1;
-+ continue;
-+ }
-+ break;
-+ }
-+ if (sock < 0 && (addrinuse_fatal || !addrinuse))
-+ msg_fatal("%s: %m", cause);
-+#ifdef INET6
-+ freeaddrinfo(res0);
-+#endif
-+ if (sock < 0)
-+ return -1;
- non_blocking(sock, block_mode);
- if (listen(sock, backlog) < 0)
- msg_fatal("listen: %m");
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/util/listen.h postfix-2.0.16/src/util/listen.h
---- postfix-2.0.16.orig/src/util/listen.h 1999-03-22 02:57:11.000000000 +0100
-+++ postfix-2.0.16/src/util/listen.h 2005-01-07 18:25:30.208329792 +0100
-@@ -20,7 +20,7 @@
- * Listener external interface.
- */
- extern int unix_listen(const char *, int, int);
--extern int inet_listen(const char *, int, int);
-+extern int inet_listen(const char *, int, int, int);
- extern int fifo_listen(const char *, int, int);
- extern int stream_listen(const char *, int, int);
-
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/util/match_list.c postfix-2.0.16/src/util/match_list.c
---- postfix-2.0.16.orig/src/util/match_list.c 2001-11-20 21:07:15.000000000 +0100
-+++ postfix-2.0.16/src/util/match_list.c 2005-01-07 18:25:30.209329640 +0100
-@@ -118,7 +118,7 @@
- list = match_list_parse(list, vstring_str(buf));
- if (vstream_fclose(fp))
- msg_fatal("%s: read file %s: %m", myname, pattern);
-- } else if (strchr(pattern, ':') != 0) { /* type:table */
-+ } else if ((strchr(pattern, ']') == 0) && (strchr(pattern, ':') != 0)) { /* type:table */
- for (cp = pattern; *cp == '!'; cp++)
- /* void */ ;
- if (dict_handle(pattern) == 0)
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/util/match_ops.c postfix-2.0.16/src/util/match_ops.c
---- postfix-2.0.16.orig/src/util/match_ops.c 2003-04-14 16:44:19.000000000 +0200
-+++ postfix-2.0.16/src/util/match_ops.c 2005-01-07 18:25:30.210329488 +0100
-@@ -81,6 +81,308 @@
- #include <match_ops.h>
- #include <stringops.h>
-
-+#ifdef INET6
-+/*
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ *
-+ * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
-+ *
-+ * Modifications:
-+ * Artur Frysiak <wiget@pld.org.pl>
-+ * Arkadiusz Miśkiewicz <misiek@pld.org.pl>
-+ */
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <syslog.h>
-+#include <fcntl.h>
-+#include <sys/socket.h>
-+#include <netinet/in.h>
-+#include <string.h>
-+#include <netdb.h>
-+#include <arpa/inet.h>
-+#include <resolv.h>
-+
-+#ifndef AF_DECnet
-+#define AF_DECnet 12
-+#endif
-+
-+#ifndef PF_PACKET
-+#define PF_PACKET 17
-+#endif
-+
-+typedef struct
-+{
-+ unsigned char family;
-+ unsigned char bytelen;
-+ signed short bitlen;
-+ unsigned int data[4];
-+} inet_prefix;
-+
-+/* prototypes */
-+int masked_match(char *, char *, char *);
-+int get_integer(int *, char *, int);
-+int get_addr_1(inet_prefix *, char *, int);
-+int get_prefix_1(inet_prefix *, char *, int);
-+int get_addr(inet_prefix *, char *, int);
-+int get_prefix(inet_prefix *, char *, int);
-+unsigned int get_addr32(char *);
-+int matches(char *, char *);
-+int inet_addr_match(inet_prefix *, inet_prefix *, int);
-+int mask_match(char *, char *, char *);
-+
-+int get_integer(int *val, char *arg, int base)
-+{
-+ long res;
-+ char *ptr;
-+
-+ if (!arg || !*arg)
-+ return -1;
-+ res = strtol(arg, &ptr, base);
-+ if (!ptr || ptr == arg || *ptr || res > INT_MAX || res < INT_MIN)
-+ return -1;
-+ *val = res;
-+ return 0;
-+}
-+
-+int get_addr_1(inet_prefix *addr, char *name, int family)
-+{
-+ char *cp;
-+ unsigned char *ap = (unsigned char*)addr->data;
-+ int i;
-+
-+ memset(addr, 0, sizeof(*addr));
-+
-+ if (strcmp(name, "default") == 0 || strcmp(name, "any") == 0) {
-+ if (family == AF_DECnet)
-+ return -1;
-+ addr->family = family;
-+ addr->bytelen = (family == AF_INET6 ? 16 : 4);
-+ addr->bitlen = -1;
-+ return 0;
-+ }
-+
-+ if (strchr(name, ':')) {
-+ addr->family = AF_INET6;
-+ if (family != AF_UNSPEC && family != AF_INET6)
-+ return -1;
-+ if (inet_pton(AF_INET6, name, addr->data) <= 0)
-+ return -1;
-+ addr->bytelen = 16;
-+ addr->bitlen = -1;
-+ return 0;
-+ }
-+ addr->family = AF_INET;
-+ if (family != AF_UNSPEC && family != AF_INET)
-+ return -1;
-+ addr->bytelen = 4;
-+ addr->bitlen = -1;
-+ for (cp = name, i = 0; *cp; cp++) {
-+ if (*cp <= '9' && *cp >= '0') {
-+ ap[i] = 10*ap[i] + (*cp-'0');
-+ continue;
-+ }
-+ if (*cp == '.' && ++i <= 3)
-+ continue;
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+int get_prefix_1(inet_prefix *dst, char *arg, int family)
-+{
-+ int err;
-+ unsigned plen;
-+ char *slash;
-+
-+ memset(dst, 0, sizeof(*dst));
-+
-+ if (strcmp(arg, "default") == 0 || strcmp(arg, "any") == 0) {
-+ if (family == AF_DECnet)
-+ return -1;
-+ dst->family = family;
-+ dst->bytelen = 0;
-+ dst->bitlen = 0;
-+ return 0;
-+ }
-+
-+ slash = strchr(arg, '/');
-+ if (slash)
-+ *slash = 0;
-+ err = get_addr_1(dst, arg, family);
-+ if (err == 0) {
-+ switch(dst->family) {
-+ case AF_INET6:
-+ dst->bitlen = 128;
-+ break;
-+ case AF_DECnet:
-+ dst->bitlen = 16;
-+ break;
-+ default:
-+ case AF_INET:
-+ dst->bitlen = 32;
-+ }
-+ if (slash) {
-+ if (get_integer(&plen, slash+1, 0) || plen > dst->bitlen) {
-+ err = -1;
-+ goto done;
-+ }
-+ dst->bitlen = plen;
-+ }
-+ }
-+done:
-+ if (slash)
-+ *slash = '/';
-+ return err;
-+}
-+
-+int get_addr(inet_prefix *dst, char *arg, int family)
-+{
-+#ifdef AF_PACKET
-+ if (family == AF_PACKET)
-+ return -1;
-+#endif
-+ if (get_addr_1(dst, arg, family))
-+ return -1;
-+ return 0;
-+}
-+
-+int get_prefix(inet_prefix *dst, char *arg, int family)
-+{
-+#ifdef AF_PACKET
-+ if (family == AF_PACKET)
-+ return -1;
-+#endif
-+ if (get_prefix_1(dst, arg, family))
-+ return -1;
-+ return 0;
-+}
-+
-+unsigned int get_addr32(char *name)
-+{
-+ inet_prefix addr;
-+ if (get_addr_1(&addr, name, AF_INET))
-+ return -1;
-+ return addr.data[0];
-+}
-+
-+int matches(char *cmd, char *pattern)
-+{
-+ int len = strlen(cmd);
-+ if (len > strlen(pattern))
-+ return -1;
-+ return memcmp(pattern, cmd, len);
-+}
-+
-+int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits)
-+{
-+ unsigned int *a1 = a->data;
-+ unsigned int *a2 = b->data;
-+ int words = bits >> 0x05;
-+
-+ bits &= 0x1f;
-+
-+ if (words)
-+ if (memcmp(a1, a2, words << 2))
-+ return -1;
-+
-+ if (bits) {
-+ unsigned int w1, w2;
-+ unsigned int mask;
-+
-+ w1 = a1[words];
-+ w2 = a2[words];
-+
-+ mask = htonl((0xffffffff) << (0x20 - bits));
-+
-+ if ((w1 ^ w2) & mask)
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+/* zero if matches */
-+int mask_match(char *network, char *cprefix, char *address)
-+{
-+ inet_prefix *inetwork;
-+ inet_prefix *iaddress;
-+ int ret, prefix;
-+
-+ if (!(network && address && cprefix))
-+ return -1;
-+ prefix = strtol(cprefix, (char **)NULL, 10);
-+ if ((prefix < 0) || (prefix > 128))
-+ return -1;
-+ if ((strlen(network) == 0) || (strlen(address) == 0))
-+ return -1;
-+
-+ inetwork = malloc(sizeof(inet_prefix));
-+ iaddress = malloc(sizeof(inet_prefix));
-+
-+ if ((get_addr(iaddress, address, AF_UNSPEC) >= 0)
-+ && (get_addr(inetwork, network, AF_UNSPEC) >= 0))
-+ ret = inet_addr_match(inetwork, iaddress, prefix);
-+ else
-+ ret = -1;
-+ free(inetwork);
-+ free(iaddress);
-+
-+ /* 1 if matches */
-+ /* return (!ret); */
-+ /* 0 if matches */
-+ return ret;
-+}
-+
-+/*
-+ * masked_match() - universal for IPv4 and IPv6 - 1 if matches
-+ */
-+int masked_match(net_tok, mask_tok, string)
-+char *net_tok;
-+char *mask_tok;
-+char *string;
-+{
-+#ifdef INET6
-+ struct in6_addr in6[2];
-+ char v4addr[2][INET_ADDRSTRLEN];
-+ char newmask[6];
-+ int plen;
-+#endif
-+
-+ /* Check for NULL */
-+ if (!(net_tok && mask_tok && string))
-+ return 0; /* doesn't match!!! */
-+
-+ /* If IPv6 mapped convert to native-IPv4 */
-+#ifdef INET6
-+ if (inet_pton(AF_INET6, net_tok, &in6[0]) == 1 &&
-+ inet_pton(AF_INET6, string, &in6[1]) == 1 &&
-+ IN6_IS_ADDR_V4MAPPED(&in6[0]) && IN6_IS_ADDR_V4MAPPED(&in6[1])) {
-+ plen = atoi(mask_tok);
-+ if (32 < plen && plen < 129) {
-+ sprintf(newmask, "%d", plen - 96);
-+ mask_tok = newmask;
-+ }
-+
-+ (void)inet_ntop(AF_INET, &in6[0].s6_addr[12], v4addr[0],
-+ sizeof(v4addr[0]));
-+ net_tok = v4addr[0];
-+ (void)inet_ntop(AF_INET, &in6[1].s6_addr[12], v4addr[1],
-+ sizeof(v4addr[1]));
-+ string = v4addr[1];
-+ }
-+#endif
-+ return (!mask_match(net_tok, mask_tok, string));
-+}
-+#endif
-+
-+
- /* match_string - match a string literal */
-
- int match_string(int unused_flags, const char *string, const char *pattern)
-@@ -177,6 +479,7 @@
- return (0);
- }
-
-+#ifndef INET6
- /* match_parse_mask - parse net/mask pattern */
-
- static int match_parse_mask(const char *pattern, unsigned long *net_bits,
-@@ -198,28 +501,55 @@
- return (mask != 0);
- }
-
-+#endif
- /* match_hostaddr - match host by address */
-
- int match_hostaddr(int unused_flags, const char *addr, const char *pattern)
- {
- char *myname = "match_hostaddr";
-+#ifdef INET6
-+ char *network, *mask, *escl, *escr, *patternx;
-+ struct in6_addr in6;
-+ char v4addr[INET_ADDRSTRLEN];
-+#else
- int mask_shift;
- unsigned long mask_bits;
- unsigned long net_bits;
- unsigned long addr_bits;
- struct in_addr net_addr;
-+#endif
-
- if (msg_verbose)
- msg_info("%s: %s ~? %s", myname, addr, pattern);
-
-+#ifdef INET6
-+ if (addr[strspn(addr, "01234567890./:abcdef")] != 0)
-+#else
- if (addr[strspn(addr, "01234567890./:")] != 0)
-+#endif
- return (0);
-
-+#ifdef INET6
-+ patternx = mystrdup(pattern);
-+ escl = strchr(patternx,'[');
-+ escr = strrchr(patternx,']');
-+ if (escl && escr) {
-+ *escr = 0;
-+ sprintf(patternx, "%s%s", escl + 1, escr + 1);
-+ pattern = patternx;
-+ }
-+#endif
-+
- /*
- * Try dictionary lookup. This can be case insensitive. XXX Probably
- * should also try again after stripping least significant octets.
- */
-- if (strchr(pattern, ':') != 0) {
-+#ifdef INET6
-+ if (!(escl && escr) && strchr(pattern, ':') != 0)
-+#else
-+ if (strchr(pattern, ':') != 0)
-+#endif
-+ {
- if (dict_lookup(pattern, addr) != 0)
- return (1);
- if (dict_errno != 0)
-@@ -230,6 +560,12 @@
- /*
- * Try an exact match with the host address.
- */
-+#ifdef INET6
-+ if (inet_pton(AF_INET6, addr, &in6) == 1 && IN6_IS_ADDR_V4MAPPED(&in6)) {
-+ (void)inet_ntop(AF_INET, &in6.s6_addr[12], v4addr, sizeof(v4addr));
-+ addr = v4addr;
-+ }
-+#endif
- if (strcasecmp(addr, pattern) == 0) {
- return (1);
- }
-@@ -238,6 +574,20 @@
- * In a net/mask pattern, the mask is specified as the number of bits of
- * the network part.
- */
-+#ifdef INET6
-+ network = mystrdup(patternx);
-+ mask = split_at(network, '/');
-+
-+ if (masked_match(network, mask, (char *)addr)) {
-+ myfree(network);
-+ myfree(patternx);
-+ return (1);
-+ } else {
-+ myfree(network);
-+ myfree(patternx);
-+ }
-+#else
-+
- if (match_parse_mask(pattern, &net_bits, &mask_shift)) {
- addr_bits = inet_addr(addr);
- if (addr_bits == INADDR_NONE)
-@@ -252,5 +602,6 @@
- pattern, inet_ntoa(net_addr), mask_shift);
- }
- }
-+#endif
- return (0);
- }
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/util/sys_defs.h postfix-2.0.16/src/util/sys_defs.h
---- postfix-2.0.16.orig/src/util/sys_defs.h 2005-01-07 18:22:25.289441736 +0100
-+++ postfix-2.0.16/src/util/sys_defs.h 2005-01-07 18:25:30.211329336 +0100
-@@ -73,6 +73,10 @@
- #define DEF_MAILBOX_LOCK "flock, dotlock"
- #endif
-
-+#if ((defined(__NetBSD_Version__) && __NetBSD_Version__ >= 105000000) || defined(USAGI_LIBINET6))
-+#define HAVE_GETIFADDRS
-+#endif
-+
- /*
- * UNIX on MAC.
- */
-diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/util/valid_hostname.c postfix-2.0.16/src/util/valid_hostname.c
---- postfix-2.0.16.orig/src/util/valid_hostname.c 2002-12-20 02:33:41.000000000 +0100
-+++ postfix-2.0.16/src/util/valid_hostname.c 2005-01-07 18:25:30.211329336 +0100
-@@ -53,6 +53,13 @@
- #include <string.h>
- #include <ctype.h>
-
-+#ifdef INET6
-+#include <netinet/in.h>
-+#include <sys/socket.h>
-+#include <arpa/inet.h>
-+#include <netdb.h>
-+#endif
-+
- /* Utility library. */
-
- #include "msg.h"
-@@ -109,7 +116,23 @@
- msg_warn("%s: misplaced hyphen: %.100s", myname, name);
- return (0);
- }
-- } else {
-+ }
-+#ifdef INET6
-+ else if (ch == ':') {
-+ struct addrinfo hints, *res;
-+
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = AF_INET6;
-+ hints.ai_socktype = SOCK_STREAM; /*dummy*/
-+ hints.ai_flags = AI_NUMERICHOST;
-+ if (getaddrinfo(name, "0", &hints, &res) == 0) {
-+ freeaddrinfo(res);
-+ return 1;
-+ } else
-+ return 0;
-+ }
-+#endif
-+ else {
- if (gripe)
- msg_warn("%s: invalid character %d(decimal): %.100s",
- myname, ch, name);
-@@ -141,6 +164,9 @@
- int byte_count = 0;
- int byte_val = 0;
- int ch;
-+#ifdef INET6
-+ struct addrinfo hints, *res;
-+#endif
-
- #define BYTES_NEEDED 4
-
-@@ -166,6 +192,17 @@
- return (1);
- }
-
-+#ifdef INET6
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = AF_INET6;
-+ hints.ai_socktype = SOCK_STREAM; /*dummy*/
-+ hints.ai_flags = AI_NUMERICHOST;
-+ if (getaddrinfo(addr, "0", &hints, &res) == 0) {
-+ freeaddrinfo(res);
-+ return 1;
-+ }
-+#endif
-+
- /*
- * Scary code to avoid sscanf() overflow nasties.
- */
diff --git a/postfix-ns-mx-acl.patch b/postfix-ns-mx-acl.patch
deleted file mode 100644
index 6c29adc..0000000
--- a/postfix-ns-mx-acl.patch
+++ /dev/null
@@ -1,478 +0,0 @@
-This is an unofficial patch for Postfix stable release 2.0 that
-back-ports a new feature from the after-2.0 snapshot releases.
-
-This feature can be used to block mail from so-called spammer
-havens, from sender addresses that resolve to Verisign's wild-card
-mail responder, or from domains that claim to have mail servers in
-reserved networks such as 127.0.0.1.
-
-This patch is a revised version; the first implementation of the
-check_{helo,sender,recipient}_ns_access feature did not correctly
-look up name server records and caused mail to be deferred with a
-450 status code; the second revision no longer defers mail when
-some NS or MX host lookup fails.
-
------------------
-
-The check_{helo,sender,recipient}_{ns,mx}_access maptype:mapname
-restriction applies the specified access table to the NS or MX
-hosts of the host/domain given in HELO, EHLO, MAIL FROM or RCPT TO
-commands.
-
- /etc/postfix/main.cf:
- smtpd_mumble_restrictions =
- ...
- reject_unknown_sender_domain
- check_sender_mx_access hash:/etc/postfix/mx_access
- ...
-
- /etc/postfix/mx_access:
- spammer.haven.tld reject spammer mx host
- 64.94.110.11 reject mail server in verisign wild-card domain
- 127 reject mail server in loopback network
- 0 reject mail server in broadcast network
-
-The following entries block mail from domains that claim to have
-have mail servers or domain servers in reserved networks.
-
- 10 reject mail server in RFC 1918 private network
- 169.254 reject mail server in link local network
- 172.16 reject mail server in RFC 1918 private network
- ...similar entries for 172.17...172.31
- 192.0.2 reject mail server in TEST-NET network
- 192.168 reject mail server in RFC 1918 private network
- 224 reject mail server in class D multicast network
- ...similar entries for 225...239
- 240 reject mail server in class E reserved network
- ...similar entries for 241...247
- 248 reject mail server in reserved network
- ...similar entries for 249...255
-
-diff -cr /tmp/postfix-2.0.16/conf/sample-smtpd.cf ./conf/sample-smtpd.cf
-*** /tmp/postfix-2.0.16/conf/sample-smtpd.cf Tue Aug 12 12:28:46 2003
---- ./conf/sample-smtpd.cf Fri Sep 19 11:17:34 2003
-***************
-*** 311,316 ****
---- 311,321 ----
- # check_helo_access maptype:mapname
- # look up HELO hostname or parent domains.
- # see access(5) for possible lookup results.
-+ # check_helo_mx_access maptype:mapname
-+ # check_helo_ns_access maptype:mapname
-+ # look up the helo hostname MX hosts (or name servers) and apply the
-+ # specified access table to those hosts.
-+ # Note: the OK result is not allowed here for security reasons.
- # reject: reject the request. Place this at the end of a restriction.
- # permit: permit the request. Place this at the end of a restriction.
- # warn_if_reject: next restriction logs a warning instead of rejecting.
-***************
-*** 343,348 ****
---- 348,358 ----
- # check_sender_access maptype:mapname
- # look up sender address, parent domain, or localpart@.
- # see access(5) for possible lookup results.
-+ # check_sender_mx_access maptype:mapname
-+ # check_sender_ns_access maptype:mapname
-+ # look up sender address MX hosts (or name servers) and apply the
-+ # specified access table to those hosts.
-+ # Note: the OK result is not allowed here for security reasons.
- # reject_sender_login_mismatch: reject if $smtpd_sender_login_maps specifies
- # a MAIL FROM address owner, but the client is not (SASL) logged in as
- # that MAIL FROM address owner; or if the client is (SASL) logged in, but
-***************
-*** 409,414 ****
---- 419,429 ----
- # check_recipient_access maptype:mapname
- # look up recipient address, parent domain, or localpart@.
- # see access(5) for possible lookup results.
-+ # check_recipient_mx_access maptype:mapname
-+ # check_recipient_ns_access maptype:mapname
-+ # look up the recipient address MX hosts (or name servers) and apply the
-+ # specified access table to those hosts.
-+ # Note: the OK result is not allowed here for security reasons.
- # reject_non_fqdn_recipient: reject recipient address that is not in FQDN form
- # reject: reject the request. Place this at the end of a restriction.
- # permit: permit the request. Place this at the end of a restriction.
-diff -cr /tmp/postfix-2.0.16/html/uce.html ./html/uce.html
-*** /tmp/postfix-2.0.16/html/uce.html Mon Aug 25 09:54:11 2003
---- ./html/uce.html Fri Sep 19 11:17:34 2003
-***************
-*** 567,572 ****
---- 567,588 ----
-
- <p>
-
-+ <a name="check_helo_ns_access">
-+
-+ <dt> <b>check_helo_ns_access</b> <i>maptype</i>:<i>mapname</i>
-+
-+ <a name="check_helo_mx_access">
-+
-+ <dt> <b>check_helo_mx_access</b> <i>maptype</i>:<i>mapname</i>
-+
-+ <dd> Apply the specified <a href="access.5.html">access database</a>
-+ to the DNS (or MX) servers for the host or domain name given with
-+ the HELO (or EHLO) command.
-+
-+ <dd> Note: an OK result is not allowed for safety reasons.
-+
-+ <p>
-+
- <dt> <b><a href="#permit">permit</a></b>
-
- <dt> <b><a href="#defer">defer</a></b>
-***************
-*** 714,719 ****
---- 730,751 ----
-
- <p>
-
-+ <a name="check_sender_ns_access">
-+
-+ <dt> <b>check_sender_ns_access</b> <i>maptype</i>:<i>mapname</i>
-+
-+ <a name="check_sender_mx_access">
-+
-+ <dt> <b>check_sender_mx_access</b> <i>maptype</i>:<i>mapname</i>
-+
-+ <dd> Apply the specified <a href="access.5.html">access database</a>
-+ to the DNS (or MX) servers for the host or domain name given with
-+ the MAIL FROM command.
-+
-+ <dd> Note: an OK result is not allowed for safety reasons.
-+
-+ <p>
-+
- <a name="reject_non_fqdn_sender">
-
- <dt> <b>reject_non_fqdn_sender</b> <dd> Reject the request when
-***************
-*** 921,926 ****
---- 953,974 ----
- <dt> <i>maptype</i>:<i>mapname</i> <dd> Search the named <a
- href="access.5.html">access database</a> for the resolved destination
- address, recipient domain or parent domain, or <i>localpart</i>@.
-+
-+ <p>
-+
-+ <a name="check_recipient_ns_access">
-+
-+ <dt> <b>check_recipient_ns_access</b> <i>maptype</i>:<i>mapname</i>
-+
-+ <a name="check_recipient_mx_access">
-+
-+ <dt> <b>check_recipient_mx_access</b> <i>maptype</i>:<i>mapname</i>
-+
-+ <dd> Apply the specified <a href="access.5.html">access database</a>
-+ to the DNS servers (or MX hosts) for the host or domain name given
-+ with the RCPT TO command.
-+
-+ <dd> Note: an OK result is not allowed for safety reasons.
-
- <p>
-
-diff -cr /tmp/postfix-2.0.16/src/dns/dns_lookup.c ./src/dns/dns_lookup.c
-*** /tmp/postfix-2.0.16/src/dns/dns_lookup.c Sun Dec 8 09:09:11 2002
---- ./src/dns/dns_lookup.c Fri Sep 19 11:17:34 2003
-***************
-*** 509,514 ****
---- 509,515 ----
- vstring_sprintf(why,
- "Name service error for %s: invalid host or domain name",
- name);
-+ h_errno = HOST_NOT_FOUND;
- return (DNS_NOTFOUND);
- }
-
-***************
-*** 520,525 ****
---- 521,527 ----
- vstring_sprintf(why,
- "Name service error for %s: invalid host or domain name",
- name);
-+ h_errno = HOST_NOT_FOUND;
- return (DNS_NOTFOUND);
- }
-
-diff -cr /tmp/postfix-2.0.16/src/global/mail_params.h ./src/global/mail_params.h
-*** /tmp/postfix-2.0.16/src/global/mail_params.h Mon Mar 3 17:07:03 2003
---- ./src/global/mail_params.h Fri Sep 19 11:17:35 2003
-***************
-*** 1249,1254 ****
---- 1249,1261 ----
- #define CHECK_RECIP_ACL "check_recipient_access"
- #define CHECK_ETRN_ACL "check_etrn_access"
-
-+ #define CHECK_HELO_MX_ACL "check_helo_mx_access"
-+ #define CHECK_SENDER_MX_ACL "check_sender_mx_access"
-+ #define CHECK_RECIP_MX_ACL "check_recipient_mx_access"
-+ #define CHECK_HELO_NS_ACL "check_helo_ns_access"
-+ #define CHECK_SENDER_NS_ACL "check_sender_ns_access"
-+ #define CHECK_RECIP_NS_ACL "check_recipient_ns_access"
-+
- #define WARN_IF_REJECT "warn_if_reject"
-
- #define REJECT_RBL "reject_rbl" /* LaMont compatibility */
-diff -cr /tmp/postfix-2.0.16/src/smtpd/smtpd_check.c ./src/smtpd/smtpd_check.c
-*** /tmp/postfix-2.0.16/src/smtpd/smtpd_check.c Tue Aug 12 10:53:25 2003
---- ./src/smtpd/smtpd_check.c Fri Sep 19 11:17:52 2003
-***************
-*** 86,91 ****
---- 86,103 ----
- /* .IP "check_recipient_access maptype:mapname"
- /* Look up the resolved recipient address in the named access table,
- /* any parent domains of the recipient domain, and the localpart@.
-+ /* .IP "check_helo_mx_access maptype:mapname"
-+ /* .IP "check_sender_mx_access maptype:mapname"
-+ /* .IP "check_recipient_mx_access maptype:mapname"
-+ /* Apply the specified access table to the MX server host name and IP
-+ /* addresses for the helo hostname, sender, or recipient, respectively.
-+ /* If no MX record is found the A record is used instead.
-+ /* .IP "check_helo_ns_access maptype:mapname"
-+ /* .IP "check_sender_ns_access maptype:mapname"
-+ /* .IP "check_recipient_ns_access maptype:mapname"
-+ /* Apply the specified access table to the DNS server host name and IP
-+ /* addresses for the helo hostname, sender, or recipient, respectively.
-+ /* If no NS record is found, the parent domain is used instead.
- /* .IP "check_recipient_maps"
- /* Reject recipients not listed as valid local, virtual or relay
- /* recipients.
-***************
-*** 455,460 ****
---- 467,484 ----
- else \
- (void) smtpd_check_reject((state), (class), (fmt), (a1), (a2)); \
- } while (0)
-+ #define DEFER_IF_PERMIT3(state, class, fmt, a1, a2, a3) do { \
-+ if ((state)->warn_if_reject == 0) \
-+ defer_if(&(state)->defer_if_permit, (class), (fmt), (a1), (a2), (a3)); \
-+ else \
-+ (void) smtpd_check_reject((state), (class), (fmt), (a1), (a2), (a3)); \
-+ } while (0)
-+ #define DEFER_IF_PERMIT4(state, class, fmt, a1, a2, a3, a4) do { \
-+ if ((state)->warn_if_reject == 0) \
-+ defer_if(&(state)->defer_if_permit, (class), (fmt), (a1), (a2), (a3), (a4)); \
-+ else \
-+ (void) smtpd_check_reject((state), (class), (fmt), (a1), (a2), (a3), (a4)); \
-+ } while (0)
-
- /*
- * Cached RBL lookup state.
-***************
-*** 2005,2010 ****
---- 2029,2151 ----
- return (SMTPD_CHECK_DUNNO);
- }
-
-+ /* check_server_access - access control by server host name or address */
-+
-+ static int check_server_access(SMTPD_STATE *state, const char *table,
-+ const char *name,
-+ int type,
-+ const char *reply_name,
-+ const char *reply_class,
-+ const char *def_acl)
-+ {
-+ const char *myname = "check_server_access";
-+ const char *domain;
-+ int dns_status;
-+ DNS_RR *server_list;
-+ DNS_RR *server;
-+ int found = 0;
-+ struct in_addr addr;
-+ struct hostent *hp;
-+ char *addr_string;
-+ int status;
-+ char **cpp;
-+ static DNS_FIXED fixed;
-+
-+ /*
-+ * Sanity check.
-+ */
-+ if (type != T_MX && type != T_NS)
-+ msg_panic("%s: unexpected resource type \"%s\" in request",
-+ myname, dns_strtype(type));
-+
-+ if (msg_verbose)
-+ msg_info("%s: %s %s", myname, dns_strtype(type), name);
-+
-+ /*
-+ * Skip over local-part.
-+ */
-+ if ((domain = strrchr(name, '@')) != 0)
-+ domain += 1;
-+ else
-+ domain = name;
-+
-+ /*
-+ * If the domain name does not exist then we apply no restriction.
-+ *
-+ * If the domain name exists but no MX record exists, fabricate an MX record
-+ * that points to the domain name itself.
-+ *
-+ * If the domain name exists but no NS record exists, look up parent domain
-+ * NS records.
-+ */
-+ dns_status = dns_lookup(domain, type, 0, &server_list,
-+ (VSTRING *) 0, (VSTRING *) 0);
-+ if (dns_status == DNS_NOTFOUND && h_errno == NO_DATA) {
-+ if (type == T_MX) {
-+ server_list = dns_rr_create(domain, &fixed, 0,
-+ domain, strlen(domain) + 1);
-+ dns_status = DNS_OK;
-+ } else if (type == T_NS) {
-+ while ((domain = strchr(domain, '.')) != 0 && domain[1]) {
-+ domain += 1;
-+ dns_status = dns_lookup(domain, type, 0, &server_list,
-+ (VSTRING *) 0, (VSTRING *) 0);
-+ if (dns_status != DNS_NOTFOUND || h_errno != NO_DATA)
-+ break;
-+ }
-+ }
-+ }
-+ if (dns_status != DNS_OK) {
-+ msg_warn("Unable to look up %s host for %s", dns_strtype(type),
-+ domain && domain[1] ? domain : reply_name);
-+ return (SMTPD_CHECK_DUNNO);
-+ }
-+
-+ /*
-+ * No bare returns after this point or we have a memory leak.
-+ */
-+ #define CHECK_SERVER_RETURN(x) { dns_rr_free(server_list); return(x); }
-+
-+ /*
-+ * Check the hostnames first, then the addresses.
-+ */
-+ for (server = server_list; server != 0; server = server->next) {
-+ if ((hp = gethostbyname((char *) server->data)) == 0) {
-+ msg_warn("Unable to look up %s host %s for %s %s",
-+ dns_strtype(type), (char *) server->data,
-+ reply_class, reply_name);
-+ continue;
-+ }
-+ if (hp->h_addrtype != AF_INET || hp->h_length != sizeof(addr)) {
-+ if (msg_verbose)
-+ msg_warn("address type %d length %d for %s",
-+ hp->h_addrtype, hp->h_length, (char *) server->data);
-+ continue; /* XXX */
-+ }
-+ if (msg_verbose)
-+ msg_info("%s: %s hostname check: %s",
-+ myname, dns_strtype(type), (char *) server->data);
-+ if ((status = check_domain_access(state, table, (char *) server->data,
-+ FULL, &found, reply_name, reply_class,
-+ def_acl)) != 0 || found)
-+ CHECK_SERVER_RETURN(status);
-+ if (msg_verbose)
-+ msg_info("%s: %s host address check: %s",
-+ myname, dns_strtype(type), (char *) server->data);
-+ for (cpp = hp->h_addr_list; *cpp; cpp++) {
-+ memcpy((char *) &addr, *cpp, sizeof(addr));
-+ addr_string = mystrdup(inet_ntoa(addr));
-+ status = check_addr_access(state, table, addr_string, FULL,
-+ &found, reply_name, reply_class,
-+ def_acl);
-+ myfree(addr_string);
-+ if (status != 0 || found)
-+ CHECK_SERVER_RETURN(status);
-+ }
-+ }
-+ CHECK_SERVER_RETURN(SMTPD_CHECK_DUNNO);
-+ }
-+
- /* check_mail_access - OK/FAIL based on mail address lookup */
-
- static int check_mail_access(SMTPD_STATE *state, const char *table,
-***************
-*** 2568,2573 ****
---- 2709,2728 ----
- }
- }
-
-+ /* forbid_whitelist - disallow whitelisting */
-+
-+ static void forbid_whitelist(SMTPD_STATE *state, const char *name,
-+ int status, const char *target)
-+ {
-+ if (status == SMTPD_CHECK_OK) {
-+ msg_warn("restriction %s returns OK for %s", name, target);
-+ msg_warn("this is not allowed for security reasons");
-+ msg_warn("use DUNNO instead of OK if you want to make an exception");
-+ longjmp(smtpd_check_buf, smtpd_check_reject(state, MAIL_ERROR_SOFTWARE,
-+ "451 Server configuration error"));
-+ }
-+ }
-+
- /* generic_checks - generic restrictions */
-
- static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
-***************
-*** 2722,2727 ****
---- 2877,2896 ----
- state->helo_name, SMTPD_NAME_HELO)) == 0)
- status = SMTPD_CHECK_OK;
- }
-+ } else if (is_map_command(state, name, CHECK_HELO_NS_ACL, &cpp)) {
-+ if (state->helo_name) {
-+ status = check_server_access(state, *cpp, state->helo_name,
-+ T_NS, state->helo_name,
-+ SMTPD_NAME_HELO, def_acl);
-+ forbid_whitelist(state, name, status, state->helo_name);
-+ }
-+ } else if (is_map_command(state, name, CHECK_HELO_MX_ACL, &cpp)) {
-+ if (state->helo_name) {
-+ status = check_server_access(state, *cpp, state->helo_name,
-+ T_MX, state->helo_name,
-+ SMTPD_NAME_HELO, def_acl);
-+ forbid_whitelist(state, name, status, state->helo_name);
-+ }
- } else if (strcasecmp(name, REJECT_NON_FQDN_HOSTNAME) == 0) {
- if (state->helo_name) {
- if (*state->helo_name != '[')
-***************
-*** 2760,2765 ****
---- 2929,2948 ----
- } else if (strcasecmp(name, REJECT_SENDER_LOGIN_MISMATCH) == 0) {
- if (state->sender && *state->sender)
- status = reject_sender_login_mismatch(state, state->sender);
-+ } else if (is_map_command(state, name, CHECK_SENDER_NS_ACL, &cpp)) {
-+ if (state->sender && *state->sender) {
-+ status = check_server_access(state, *cpp, state->sender,
-+ T_NS, state->sender,
-+ SMTPD_NAME_SENDER, def_acl);
-+ forbid_whitelist(state, name, status, state->sender);
-+ }
-+ } else if (is_map_command(state, name, CHECK_SENDER_MX_ACL, &cpp)) {
-+ if (state->sender && *state->sender) {
-+ status = check_server_access(state, *cpp, state->sender,
-+ T_MX, state->sender,
-+ SMTPD_NAME_SENDER, def_acl);
-+ forbid_whitelist(state, name, status, state->sender);
-+ }
- } else if (strcasecmp(name, REJECT_RHSBL_SENDER) == 0) {
- if (cpp[1] == 0)
- msg_warn("restriction %s requires domain name argument", name);
-***************
-*** 2812,2817 ****
---- 2995,3014 ----
- if (state->recipient)
- status = reject_non_fqdn_address(state, state->recipient,
- state->recipient, SMTPD_NAME_RECIPIENT);
-+ } else if (is_map_command(state, name, CHECK_RECIP_NS_ACL, &cpp)) {
-+ if (state->recipient && *state->recipient) {
-+ status = check_server_access(state, *cpp, state->recipient,
-+ T_NS, state->recipient,
-+ SMTPD_NAME_RECIPIENT, def_acl);
-+ forbid_whitelist(state, name, status, state->recipient);
-+ }
-+ } else if (is_map_command(state, name, CHECK_RECIP_MX_ACL, &cpp)) {
-+ if (state->recipient && *state->recipient) {
-+ status = check_server_access(state, *cpp, state->recipient,
-+ T_MX, state->recipient,
-+ SMTPD_NAME_RECIPIENT, def_acl);
-+ forbid_whitelist(state, name, status, state->recipient);
-+ }
- } else if (strcasecmp(name, REJECT_RHSBL_RECIPIENT) == 0) {
- if (cpp[1] == 0)
- msg_warn("restriction %s requires domain name argument", name);
diff --git a/postfix-pgsql.patch b/postfix-pgsql.patch
deleted file mode 100644
index 596624c..0000000
--- a/postfix-pgsql.patch
+++ /dev/null
@@ -1,916 +0,0 @@
---- postfix-2.0.16.orig/PGSQL_README 1970-01-01 01:00:00.000000000 +0100
-+++ postfix-2.0.16/PGSQL_README 2003-11-08 20:11:44.000000000 +0100
-@@ -0,0 +1,88 @@
-+[Code contributed by Mathieu Arnold]
-+
-+We've written code to add a pgsql map type. It utilizes the pgsql
-+client library, which can be obtained from:
-+
-+ http://www.postgresql.org/
-+
-+In order to build postfix with pgsql map support, you will need to add
-+-DHAS_PGSQL and -I for the directory containing the postgres headers, and
-+the libpq library (and libcrypt) to AUXLIBS, for example:
-+
-+make -f Makefile.init makefiles \
-+ 'CCARGS=-DHAS_PGSQL -I/some/where/include/postgresql' \
-+ 'AUXLIBS=/some/where/lib/postgres/libpq.a -lcrypt'
-+
-+then, just run 'make'.
-+
-+Postfix installations which may benefit from using pgsql map types
-+include sites that have a need for instantaneous updates of
-+forwarding, and sites that may benefit from having mail exchangers
-+reference a networked database, possibly working in conjunction with a
-+customer database of sorts.
-+
-+Once postfix is built with pgsql support, you can specify a map type
-+in main.cf like this:
-+
-+alias_maps = pgsql:/etc/postfix/pgsql-aliases.cf
-+
-+The file /etc/postfix/pgsql-aliases.cf specifies lots of information
-+telling postfix how to reference the postgresql database. An example
-+postgresql map config file follows:
-+
-+#
-+# postgresql config file for alias lookups on postfix
-+# comments are ok.
-+#
-+
-+# the user name and password to log into the pgsql server
-+user = someone
-+password = some_passwordd
-+
-+# the database name on the servers
-+dbname = customer_database
-+
-+# the table name
-+table = mxaliases
-+
-+#
-+select_field = forw_addr
-+where_field = alias
-+
-+# you may specify additional_conditions here
-+additional_conditions = and status = 'paid'
-+
-+# the above variables will result in a query of
-+# the form:
-+# select forw_addr from mxaliases where alias = '$lookup' and status = 'paid'
-+# ($lookup is escaped so if it contains single quotes or other odd
-+# characters, it will not cause a parse error in the sql).
-+#
-+# the hosts that postfix will try to connect to
-+# and query from (in the order listed)
-+hosts = host1.some.domain host2.some.domain
-+
-+# end postgresql config file
-+
-+Some notes:
-+
-+This configuration interface setup allows for multiple postgresql
-+databases: you can use one for a virtual table, one for an access
-+table, and one for an aliases table if you want.
-+
-+Since sites that have a need for multiple mail exchangers may enjoy
-+the convenience of using a networked mailer database, but do not want
-+to introduce a single point of failure to their system, we've included
-+the ability to have postfix reference multiple hosts for access to a
-+single pgsql map. This will work if sites set up mirrored pgsql
-+databases on two or more hosts. Whenever queries fail with an error
-+at one host, the rest of the hosts will be tried in order. Each host
-+that is in an error state will undergo a reconnection attempt every so
-+often, and if no pgsql server hosts are reachable, then mail will be
-+deferred until atleast one of those hosts is reachable.
-+
-+Performance of postfix with pgsql has not been thoroughly tested,
-+however, we have found it to be stable. Busy mail servers using pgsql
-+maps will generate lots of concurrent pgsql clients, so the pgsql
-+server(s) should be run with this fact in mind. Any further
-+performance information, in addition to any feedback is most welcome.
---- postfix-2.0.16.orig/src/util/dict_open.c 2003-11-08 20:10:08.000000000 +0100
-+++ postfix-2.0.16/src/util/dict_open.c 2003-11-08 20:11:44.000000000 +0100
-@@ -178,6 +178,7 @@
- #include <dict_ni.h>
- #include <dict_ldap.h>
- #include <dict_mysql.h>
-+#include <dict_pgsql.h>
- #include <dict_pcre.h>
- #include <dict_regexp.h>
- #include <dict_static.h>
-@@ -230,6 +231,9 @@
- #ifdef HAS_MYSQL
- DICT_TYPE_MYSQL, dict_mysql_open,
- #endif
-+#ifdef HAS_PGSQL
-+ DICT_TYPE_PGSQL, dict_pgsql_open,
-+#endif
- #ifndef MAX_DYNAMIC_MAPS
- #ifdef HAS_PCRE
- DICT_TYPE_PCRE, dict_pcre_open,
---- postfix-2.0.16.orig/src/util/dict_pgsql.c 1970-01-01 01:00:00.000000000 +0100
-+++ postfix-2.0.16/src/util/dict_pgsql.c 2003-11-08 20:11:44.000000000 +0100
-@@ -0,0 +1,675 @@
-+
-+/*++
-+/* NAME
-+/* dict_pgsql 3
-+/* SUMMARY
-+/* dictionary manager interface to db files
-+/* SYNOPSIS
-+/* #include <dict.h>
-+/* #include <dict_pgsql.h>
-+/*
-+/* DICT *dict_pgsql_open(name, dummy, unused_dict_flags)
-+/* const char *name;
-+/* int dummy;
-+/* int unused_dict_flags;
-+/* DESCRIPTION
-+/* dict_pgsql_open() creates a dictionary of type 'pg'. This
-+/* dictionary is an interface for the postfix key->value mappings
-+/* to pgsql. The result is a pointer to the installed dictionary,
-+/* or a null pointer in case of problems.
-+/*
-+/* The pgsql dictionary can manage multiple connections to different
-+/* sql servers on different hosts. It assumes that the underlying data
-+/* on each host is identical (mirrored) and maintains one connection
-+/* at any given time. If any connection fails, any other available
-+/* ones will be opened and used. The intent of this feature is to eliminate
-+/* a single point of failure for mail systems that would otherwise rely
-+/* on a single pgsql server.
-+/*
-+/* Arguments:
-+/* .IP name
-+/* The path of the PostgreSQL configuration file. The file encodes a number of
-+/* pieces of information: username, password, databasename, table,
-+/* select_field, where_field, and hosts. For example, if you want the map to
-+/* reference databases of the name "your_db" and execute a query like this:
-+/* select forw_addr from aliases where alias like '<some username>' against
-+/* any database called "vmailer_info" located on hosts host1.some.domain and
-+/* host2.some.domain, logging in as user "vmailer" and password "passwd" then
-+/* the configuration file should read:
-+/*
-+/* user = vmailer
-+/* password = passwd
-+/* DBname = vmailer_info
-+/* table = aliases
-+/* select_field = forw_addr
-+/* where_field = alias
-+/* hosts = host1.some.domain host2.some.domain
-+/*
-+/* .IP other_name
-+/* reference for outside use.
-+/* .IP unusued_flags
-+/* unused flags
-+/* SEE ALSO
-+/* dict(3) generic dictionary manager
-+/* AUTHOR(S)
-+/* Mathieu Arnold
-+/* Absolight
-+/* mat@absolight.com
-+/*
-+/* based on dict_mysql by
-+/*
-+/* Scott Cotton
-+/* IC Group, Inc.
-+/* scott@icgroup.com
-+/*
-+/* Joshua Marcus
-+/* IC Group, Inc.
-+/* josh@icgroup.com
-+/*--*/
-+
-+/* System library. */
-+#include "sys_defs.h"
-+
-+#ifdef HAS_PGSQL
-+#include <sys/socket.h>
-+#include <netinet/in.h>
-+#include <arpa/inet.h>
-+#include <netdb.h>
-+#include <stdio.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <syslog.h>
-+#include <time.h>
-+#include <libpq-fe.h>
-+
-+/* Utility library. */
-+#include "dict.h"
-+#include "msg.h"
-+#include "mymalloc.h"
-+#include "dict_pgsql.h"
-+#include "argv.h"
-+#include "vstring.h"
-+#include "split_at.h"
-+#include "find_inet.h"
-+
-+/* need some structs to help organize things */
-+typedef struct
-+{
-+ PGconn *db;
-+ char *hostname;
-+ int stat; /* STATUNTRIED | STATFAIL | STATCUR */
-+ time_t ts; /* used for attempting reconnection
-+ * every so often if a host is down */
-+} HOST;
-+
-+typedef struct
-+{
-+ int len_hosts; /* number of hosts */
-+ HOST *db_hosts; /* the hosts on which the databases
-+ * reside */
-+} PLPGSQL;
-+
-+typedef struct
-+{
-+ char *username;
-+ char *password;
-+ char *dbname;
-+ char *table;
-+ char *select_field;
-+ char *where_field;
-+ char *additional_conditions;
-+ char **hostnames;
-+ int len_hosts;
-+} PGSQL_NAME;
-+
-+typedef struct
-+{
-+ DICT dict;
-+ PLPGSQL *pldb;
-+ PGSQL_NAME *name;
-+} DICT_PGSQL;
-+
-+#define STATACTIVE 0
-+#define STATFAIL 1
-+#define STATUNTRIED 2
-+#define RETRY_CONN_INTV 60 /* 1 minute */
-+
-+/* internal function declarations */
-+static PLPGSQL *plpgsql_init (char *hostnames[], int);
-+static PGresult *plpgsql_query (PLPGSQL *, const char *, char *, char *,
-+
-+ char *);
-+static void plpgsql_dealloc (PLPGSQL *);
-+static void plpgsql_down_host (HOST *);
-+static void plpgsql_connect_single (HOST *, char *, char *, char *);
-+static int plpgsql_ready_reconn (HOST *);
-+static const char *dict_pgsql_lookup (DICT *, const char *);
-+DICT *dict_pgsql_open (const char *, int, int);
-+static void dict_pgsql_close (DICT *);
-+static PGSQL_NAME *pgsqlname_parse (const char *);
-+static HOST host_init (char *);
-+void pgsql_escape_string (char *escaped, const char *name, int len);
-+
-+
-+
-+/**********************************************************************
-+ * public interface dict_pgsql_lookup
-+ * find database entry return 0 if no alias found, set dict_errno
-+ * on errors to DICT_ERRBO_RETRY and set dict_errno to 0 on success
-+ *********************************************************************/
-+static const char *dict_pgsql_lookup (DICT *dict, const char *name)
-+{
-+ PGresult *query_res;
-+ char *field;
-+ DICT_PGSQL *dict_pgsql;
-+ PLPGSQL *pldb;
-+ static VSTRING *result;
-+ static VSTRING *query = 0;
-+ int i,
-+ j,
-+ numrows;
-+ char *name_escaped = 0;
-+
-+ dict_pgsql = (DICT_PGSQL *) dict;
-+ pldb = dict_pgsql->pldb;
-+ /* initialization for query */
-+ query = vstring_alloc (24);
-+ vstring_strcpy (query, "");
-+ if (
-+ (name_escaped =
-+ (char *) mymalloc ((sizeof (char) * (strlen (name) * 2) + 1))) ==
-+ NULL)
-+ {
-+ msg_fatal ("dict_pgsql_lookup: out of memory.");
-+ }
-+ /* prepare the query */
-+ pgsql_escape_string (name_escaped, name, (unsigned int) strlen (name));
-+ vstring_sprintf (query, "select %s from %s where %s = '%s' %s",
-+ dict_pgsql->name->select_field, dict_pgsql->name->table,
-+ dict_pgsql->name->where_field, name_escaped,
-+ dict_pgsql->name->additional_conditions);
-+ if (msg_verbose)
-+ msg_info ("dict_pgsql_lookup using sql query: %s",
-+ vstring_str (query));
-+ /* free mem associated with preparing the query */
-+ myfree (name_escaped);
-+ /* do the query - set dict_errno & cleanup if there's an error */
-+ if ((query_res = plpgsql_query (pldb,
-+ vstring_str (query),
-+ dict_pgsql->name->dbname,
-+ dict_pgsql->name->username,
-+ dict_pgsql->name->password)) == 0)
-+ {
-+ dict_errno = DICT_ERR_RETRY;
-+ vstring_free (query);
-+ return 0;
-+ }
-+ dict_errno = 0;
-+ /* free the vstring query */
-+ vstring_free (query);
-+ numrows = PQntuples (query_res);
-+ if (msg_verbose)
-+ msg_info ("dict_pgsql_lookup: retrieved %d rows", numrows);
-+ if (numrows == 0)
-+ {
-+ PQclear (query_res);
-+ return 0;
-+ }
-+ if (result == 0)
-+ result = vstring_alloc (10);
-+ vstring_strcpy (result, "");
-+ for (i = 0; i < numrows; i++)
-+ {
-+ if (i > 0)
-+ vstring_strcat (result, ",");
-+ for (j = 0; j < PQnfields (query_res); j++)
-+ {
-+ if (j > 0)
-+ vstring_strcat (result, ",");
-+ field = PQgetvalue (query_res, i, j);
-+ vstring_strcat (result, field);
-+ if (msg_verbose > 1)
-+ msg_info ("dict_pgsql_lookup: retrieved field: %d: %s", j,
-+ field);
-+ }
-+ }
-+ PQclear (query_res);
-+ return vstring_str (result);
-+}
-+
-+/*
-+ * plpgsql_query - process a PGSQL query. Return PGresult* on success.
-+ * On failure, log failure and try other db instances.
-+ * on failure of all db instances, return 0;
-+ * close unnecessary active connections
-+ */
-+
-+static PGresult *plpgsql_query (PLPGSQL * PLDB,
-+ const char *query,
-+ char *dbname, char *username, char *password)
-+{
-+ int i;
-+ HOST *host;
-+ PGresult *res = 0;
-+ ExecStatusType status;
-+
-+ for (i = 0; i < PLDB->len_hosts; i++)
-+ {
-+ /* can't deal with typing or reading PLDB->db_hosts[i] over & over */
-+ host = &(PLDB->db_hosts[i]);
-+ if (msg_verbose > 1)
-+ msg_info ("dict_pgsql: trying host %s stat %d, last res %p",
-+ host->hostname, host->stat, res);
-+
-+ /* answer already found */
-+ if (res != 0 && host->stat == STATACTIVE)
-+ {
-+ if (msg_verbose)
-+ msg_info
-+ ("dict_pgsql: closing unnessary connection to %s",
-+ host->hostname);
-+ plpgsql_down_host (host);
-+ }
-+ /* try to connect for the first time if we don't have a result yet */
-+ if (res == 0 && host->stat == STATUNTRIED)
-+ {
-+ if (msg_verbose)
-+ msg_info ("dict_pgsql: attempting to connect to host %s",
-+ host->hostname);
-+ plpgsql_connect_single (host, dbname, username, password);
-+ }
-+
-+ /*
-+ * try to reconnect if we don't have an answer and the host had a
-+ * prob in the past and it's time for it to reconnect
-+ */
-+ if (res == 0 && host->stat == STATFAIL
-+ && host->ts < time ((time_t *) 0))
-+ {
-+ if (msg_verbose)
-+ msg_info
-+ ("dict_pgsql: attempting to reconnect to host %s",
-+ host->hostname);
-+ plpgsql_connect_single (host, dbname, username, password);
-+ }
-+
-+ /*
-+ * if we don't have a result and the current host is marked active,
-+ * try the query. If the query fails, mark the host STATFAIL
-+ */
-+ if (res == 0 && host->stat == STATACTIVE)
-+ {
-+ res = PQexec (host->db, query);
-+ status = PQresultStatus (res);
-+ if (res
-+ && (status = PGRES_COMMAND_OK
-+ || status == PGRES_TUPLES_OK))
-+ {
-+ if (msg_verbose)
-+ msg_info
-+ ("dict_pgsql: successful query from host %s",
-+ host->hostname);
-+ }
-+ else
-+ {
-+ msg_warn ("%s", PQerrorMessage (host->db));
-+ plpgsql_down_host (host);
-+ }
-+ }
-+ }
-+ return res;
-+}
-+
-+/*
-+ * plpgsql_connect_single -
-+ * used to reconnect to a single database when one is down or none is
-+ * connected yet. Log all errors and set the stat field of host accordingly
-+ */
-+static void
-+plpgsql_connect_single (HOST *host, char *dbname, char *username,
-+ char *password)
-+{
-+ char *destination = host->hostname;
-+ char *hostname = 0;
-+ char *service;
-+ VSTRING *conninfo = vstring_alloc (100);
-+ char *conn;
-+ unsigned port = 0;
-+
-+ /*
-+ * Ad-hoc parsing code. Expect "unix:pathname" or "inet:host:port", where
-+ * both "inet:" and ":port" are optional.
-+ */
-+ if (strncmp (destination, "unix:", 5) == 0)
-+ {
-+ vstring_sprintf_append (conninfo, "host=%s ", destination + 5);
-+ }
-+ else
-+ {
-+ if (strncmp (destination, "inet:", 5) == 0)
-+ destination += 5;
-+ hostname = mystrdup (destination);
-+ if ((service = split_at (hostname, ':')) != 0)
-+ {
-+ port = ntohs (find_inet_port (service, "tcp"));
-+ vstring_sprintf_append (conninfo, "host='%s' port='%d'",
-+ hostname, port);
-+ }
-+ else
-+ {
-+ vstring_sprintf_append (conninfo, "host='%s'", hostname);
-+ }
-+ }
-+
-+ vstring_sprintf_append (conninfo, " dbname='%s' user='%s' password='%s'", dbname,
-+ username, password);
-+ conn = vstring_export (conninfo);
-+
-+ host->db = PQconnectdb (conn);
-+
-+ if ((host->db != NULL) && (PQstatus (host->db) == CONNECTION_OK))
-+ {
-+ if (msg_verbose)
-+ msg_info ("dict_pgsql: successful connection to host %s",
-+ host->hostname);
-+ host->stat = STATACTIVE;
-+ }
-+ else
-+ {
-+ msg_warn ("%s", PQerrorMessage (host->db));
-+ plpgsql_down_host (host);
-+ }
-+ if (hostname)
-+ myfree (hostname);
-+ myfree (conn);
-+}
-+
-+/*
-+ * plpgsql_down_host - mark a HOST down update ts if marked down
-+ * for the first time so that we'll know when to retry the connection
-+ */
-+static void plpgsql_down_host (HOST *host)
-+{
-+ if (host->stat != STATFAIL)
-+ {
-+ host->ts = time ((time_t *) 0) + RETRY_CONN_INTV;
-+ host->stat = STATFAIL;
-+ }
-+ PQfinish (host->db);
-+ host->db = 0;
-+}
-+
-+/**********************************************************************
-+ * public interface dict_pgsql_open
-+ * create association with database with appropriate values
-+ * parse the map's config file
-+ * allocate memory
-+ **********************************************************************/
-+DICT *dict_pgsql_open (const char *name, int unused_open_flags,
-+ int dict_flags)
-+{
-+ DICT_PGSQL *dict_pgsql;
-+ int connections;
-+
-+ dict_pgsql = (DICT_PGSQL *) dict_alloc (DICT_TYPE_PGSQL, name,
-+ sizeof (DICT_PGSQL));
-+ dict_pgsql->dict.lookup = dict_pgsql_lookup;
-+ dict_pgsql->dict.close = dict_pgsql_close;
-+ dict_pgsql->dict.flags = dict_flags | DICT_FLAG_FIXED;
-+ dict_pgsql->name = pgsqlname_parse (name);
-+ dict_pgsql->pldb = plpgsql_init (dict_pgsql->name->hostnames,
-+ dict_pgsql->name->len_hosts);
-+ if (dict_pgsql->pldb == NULL)
-+ msg_fatal ("couldn't intialize pldb!\n");
-+ dict_register (name, (DICT *) dict_pgsql);
-+ return (DICT_DEBUG (&dict_pgsql->dict));
-+}
-+
-+/* pgsqlname_parse - parse pgsql configuration file */
-+static PGSQL_NAME *pgsqlname_parse (const char *pgsqlcf_path)
-+{
-+ int i;
-+ char *nameval;
-+ char *hosts;
-+ PGSQL_NAME *name = (PGSQL_NAME *) mymalloc (sizeof (PGSQL_NAME));
-+ ARGV *hosts_argv;
-+ VSTRING *opt_dict_name;
-+
-+ /*
-+ * setup a dict containing info in the pgsql cf file. the dict has a
-+ * name, and a path. The name must be distinct from the path, or the
-+ * dict interface gets confused. The name must be distinct for two
-+ * different paths, or the configuration info will cache across different
-+ * pgsql maps, which can be confusing.
-+ */
-+ opt_dict_name = vstring_alloc (64);
-+ vstring_sprintf (opt_dict_name, "pgsql opt dict %s", pgsqlcf_path);
-+ dict_load_file (vstring_str (opt_dict_name), pgsqlcf_path);
-+ /* pgsql username lookup */
-+ if (
-+ (nameval =
-+ (char *) dict_lookup (vstring_str (opt_dict_name), "user")) == NULL)
-+ name->username = mystrdup ("");
-+ else
-+ name->username = mystrdup (nameval);
-+ if (msg_verbose)
-+ msg_info ("pgsqlname_parse(): set username to '%s'", name->username);
-+ /* password lookup */
-+ if (
-+ (nameval =
-+ (char *) dict_lookup (vstring_str (opt_dict_name),
-+ "password")) == NULL)
-+ name->password = mystrdup ("");
-+ else
-+ name->password = mystrdup (nameval);
-+ if (msg_verbose)
-+ msg_info ("pgsqlname_parse(): set password to '%s'", name->password);
-+
-+ /* database name lookup */
-+ if (
-+ (nameval =
-+ (char *) dict_lookup (vstring_str (opt_dict_name),
-+ "dbname")) == NULL)
-+
-+
-+
-+ msg_fatal ("%s: pgsql options file does not include database name",
-+ pgsqlcf_path);
-+ else
-+ name->dbname = mystrdup (nameval);
-+ if (msg_verbose)
-+ msg_info ("pgsqlname_parse(): set database name to '%s'",
-+ name->dbname);
-+
-+ /* table lookup */
-+ if (
-+ (nameval =
-+ (char *) dict_lookup (vstring_str (opt_dict_name), "table")) == NULL)
-+ msg_fatal ("%s: pgsql options file does not include table name",
-+ pgsqlcf_path);
-+ else
-+ name->table = mystrdup (nameval);
-+ if (msg_verbose)
-+ msg_info ("pgsqlname_parse(): set table name to '%s'", name->table);
-+
-+ /* select field lookup */
-+ if (
-+ (nameval =
-+ (char *) dict_lookup (vstring_str (opt_dict_name),
-+ "select_field")) == NULL)
-+
-+
-+
-+ msg_fatal ("%s: pgsql options file does not include select field",
-+ pgsqlcf_path);
-+ else
-+ name->select_field = mystrdup (nameval);
-+ if (msg_verbose)
-+ msg_info ("pgsqlname_parse(): set select_field to '%s'",
-+ name->select_field);
-+
-+ /* where field lookup */
-+ if (
-+ (nameval =
-+ (char *) dict_lookup (vstring_str (opt_dict_name),
-+ "where_field")) == NULL)
-+ msg_fatal ("%s: pgsql options file does not include where field",
-+ pgsqlcf_path);
-+ else
-+ name->where_field = mystrdup (nameval);
-+ if (msg_verbose)
-+ msg_info ("pgsqlname_parse(): set where_field to '%s'",
-+ name->where_field);
-+
-+ /* additional conditions */
-+ if (
-+ (nameval =
-+ (char *) dict_lookup (vstring_str (opt_dict_name),
-+ "additional_conditions")) == NULL)
-+ name->additional_conditions = mystrdup ("");
-+ else
-+ name->additional_conditions = mystrdup (nameval);
-+ if (msg_verbose)
-+ msg_info ("pgsqlname_parse(): set additional_conditions to '%s'",
-+ name->additional_conditions);
-+
-+ /* pgsql server hosts */
-+ if (
-+ (nameval =
-+ (char *) dict_lookup (vstring_str (opt_dict_name), "hosts")) == NULL)
-+ hosts = mystrdup ("");
-+ else
-+ hosts = mystrdup (nameval);
-+ /* coo argv interface */
-+ hosts_argv = argv_split (hosts, " ,\t\r\n");
-+
-+ if (hosts_argv->argc == 0)
-+ { /* no hosts specified,
-+ * default to 'localhost' */
-+ if (msg_verbose)
-+ msg_info
-+ ("pgsqlname_parse(): no hostnames specified, defaulting to 'localhost'");
-+ argv_add (hosts_argv, "localhost", ARGV_END);
-+ argv_terminate (hosts_argv);
-+ }
-+ name->len_hosts = hosts_argv->argc;
-+ name->hostnames =
-+
-+ (char **) mymalloc ((sizeof (char *)) * name->len_hosts);
-+ i = 0;
-+ for (i = 0; hosts_argv->argv[i] != NULL; i++)
-+ {
-+ name->hostnames[i] = mystrdup (hosts_argv->argv[i]);
-+ if (msg_verbose)
-+ msg_info
-+ ("pgsqlname_parse(): adding host '%s' to list of pgsql server hosts",
-+ name->hostnames[i]);
-+ }
-+ myfree (hosts);
-+ vstring_free (opt_dict_name);
-+ argv_free (hosts_argv);
-+ return name;
-+}
-+
-+
-+/*
-+ * plpgsql_init - initalize a PGSQL database.
-+ * Return NULL on failure, or a PLPGSQL * on success.
-+ */
-+static PLPGSQL *plpgsql_init (char *hostnames[], int len_hosts)
-+{
-+ PLPGSQL *PLDB;
-+ int i;
-+ HOST host;
-+
-+ if ((PLDB = (PLPGSQL *) mymalloc (sizeof (PLPGSQL))) == NULL)
-+ {
-+ msg_fatal ("mymalloc of pldb failed");
-+ }
-+ PLDB->len_hosts = len_hosts;
-+ if ((PLDB->db_hosts = (HOST *) mymalloc (sizeof (HOST) * len_hosts))
-+ == NULL)
-+ return NULL;
-+
-+ for (i = 0; i < len_hosts; i++)
-+ {
-+ PLDB->db_hosts[i] = host_init (hostnames[i]);
-+ }
-+ return PLDB;
-+}
-+
-+
-+/* host_init - initialize HOST structure */
-+static HOST host_init (char *hostname)
-+{
-+ HOST host;
-+
-+ host.stat = STATUNTRIED;
-+ host.hostname = mystrdup (hostname);
-+ host.db = 0;
-+ host.ts = 0;
-+ return host;
-+}
-+
-+/**********************************************************************
-+ * public interface dict_pgsql_close
-+ * unregister, disassociate from database, freeing appropriate memory
-+ **********************************************************************/
-+static void dict_pgsql_close (DICT *dict)
-+{
-+ int i;
-+ DICT_PGSQL *dict_pgsql = (DICT_PGSQL *) dict;
-+
-+ plpgsql_dealloc (dict_pgsql->pldb);
-+ myfree (dict_pgsql->name->username);
-+ myfree (dict_pgsql->name->password);
-+ myfree (dict_pgsql->name->dbname);
-+ myfree (dict_pgsql->name->table);
-+ myfree (dict_pgsql->name->select_field);
-+ myfree (dict_pgsql->name->where_field);
-+ myfree (dict_pgsql->name->additional_conditions);
-+ for (i = 0; i < dict_pgsql->name->len_hosts; i++)
-+ {
-+ myfree (dict_pgsql->name->hostnames[i]);
-+ }
-+ myfree ((char *) dict_pgsql->name->hostnames);
-+ myfree ((char *) dict_pgsql->name);
-+ dict_free (dict);
-+}
-+
-+/* plpgsql_dealloc - free memory associated with PLPGSQL close databases */
-+static void plpgsql_dealloc (PLPGSQL * PLDB)
-+{
-+ int i;
-+
-+ for (i = 0; i < PLDB->len_hosts; i++)
-+ {
-+ if (PLDB->db_hosts[i].db)
-+ PQfinish (PLDB->db_hosts[i].db);
-+ myfree (PLDB->db_hosts[i].hostname);
-+ }
-+ myfree ((char *) PLDB->db_hosts);
-+ myfree ((char *) (PLDB));
-+}
-+
-+/* pgsql_escape_string - replace mysql_escape_string */
-+void pgsql_escape_string (char *escaped, const char *name, int len)
-+{
-+ int i,
-+ j;
-+
-+ for (i = 0, j = 0; i <= len; i++, j++)
-+ {
-+ if ((name[i] == '\'') || (name[i] == '\\'))
-+ {
-+ escaped[j] = '\\';
-+ j++;
-+ }
-+ escaped[j] = name[i];
-+ }
-+}
-+
-+
-+
-+#endif
-+
---- postfix-2.0.16.orig/src/util/dict_pgsql.h 1970-01-01 01:00:00.000000000 +0100
-+++ postfix-2.0.16/src/util/dict_pgsql.h 2003-11-08 20:11:44.000000000 +0100
-@@ -0,0 +1,41 @@
-+#ifndef _DICT_PGSQL_H_INCLUDED_
-+#define _DICT_PGSQL_H_INCLUDED_
-+
-+/*++
-+/* NAME
-+/* dict_pgsql 3h
-+/* SUMMARY
-+/* dictionary manager interface to pgsql databases
-+/* SYNOPSIS
-+/* #include <dict_pgsql.h>
-+/* DESCRIPTION
-+/* .nf
-+
-+ /*
-+ * Utility library.
-+ */
-+#include <dict.h>
-+
-+ /*
-+ * External interface.
-+ */
-+#define DICT_TYPE_PGSQL "pgsql"
-+
-+extern DICT *dict_pgsql_open (const char *, int, int);
-+
-+/* LICENSE
-+/* .ad
-+/* .fi
-+/* The Secure Mailer license must be distributed with this software.
-+/* AUTHOR(S)
-+/* Scott Cotton
-+/* IC Group, Inc.
-+/* scott@icgroup.com
-+/*
-+/* Joshua Marcus
-+/* IC Group, Inc.
-+/* josh@icgroup.com
-+/*--*/
-+
-+#endif
-+
---- postfix-2.0.16.orig/src/util/Makefile.in 2003-11-08 20:10:08.000000000 +0100
-+++ postfix-2.0.16/src/util/Makefile.in 2003-11-08 20:12:29.000000000 +0100
-@@ -4,7 +4,7 @@
- chroot_uid.c clean_env.c close_on_exec.c concatenate.c ctable.c \
- dict.c dict_alloc.c dict_db.c dict_dbm.c dict_debug.c dict_env.c \
- dict_ht.c dict_mysql.c dict_ni.c dict_nis.c \
-- dict_nisplus.c dict_open.c dict_pcre.c dict_regexp.c dict_static.c \
-+ dict_nisplus.c dict_open.c dict_pcre.c dict_pgsql.c dict_regexp.c dict_static.c \
- dict_tcp.c dict_unix.c dir_forest.c doze.c duplex_pipe.c \
- environ.c events.c exec_command.c fifo_listen.c fifo_trigger.c \
- file_limit.c find_inet.c fsspace.c fullname.c get_domainname.c \
-@@ -60,7 +60,7 @@
- HDRS = argv.h attr.h base64_code.h binhash.h chroot_uid.h clean_env.h \
- connect.h ctable.h dict.h dict_db.h dict_dbm.h dict_env.h \
- dict_ht.h dict_ldap.h dict_mysql.h dict_ni.h dict_nis.h \
-- dict_nisplus.h dict_pcre.h dict_regexp.h dict_static.h dict_tcp.h \
-+ dict_nisplus.h dict_pcre.h dict_pgsql.h dict_regexp.h dict_static.h dict_tcp.h \
- dict_unix.h dir_forest.h events.h exec_command.h find_inet.h \
- fsspace.h fullname.h get_domainname.h get_hostname.h hex_quote.h \
- htable.h inet_addr_host.h inet_addr_list.h inet_addr_local.h \
-@@ -86,6 +86,7 @@
- INCL =
- PCRESO = dict_pcre.so
- MYSQLSO = dict_mysql.so
-+PGSQLSO = dict_pgsql.so
- LIB = libutil.a
- TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \
- fifo_rdonly_bug fifo_rdwr_bug fifo_trigger fsspace fullname \
-@@ -98,7 +99,7 @@
-
- LIB_DIR = ../../lib
- INC_DIR = ../../include
--LIBS = $(LIB_DIR)/$(LIB) $(LIB_DIR)/$(PCRESO) $(LIB_DIR)/$(MYSQLSO)
-+LIBS = $(LIB_DIR)/$(LIB) $(LIB_DIR)/$(PCRESO) $(LIB_DIR)/$(MYSQLSO) $(LIB_DIR)/$(PGSQLSO)
-
- .c.o:; $(CC) -fPIC $(CFLAGS) -c $*.c
-
-@@ -115,6 +116,9 @@
- $(MYSQLSO): dict_mysql.o
- gcc -shared -Wl,-soname,dict_mysql.so -o $@ $? -lmysqlclient -L. -lutil
-
-+$(PGSQLSO): dict_pgsql.o
-+ gcc -shared -Wl,-soname,dict_pgsql.so -o $@ $? -lpq -lcrypt -L. -lutil
-+
- $(LIB): $(OBJS)
- gcc -shared -Wl,-soname,libpostfix-util.so.1 -o $(LIB) $(OBJS) -ldl
-
-@@ -127,6 +131,9 @@
- $(LIB_DIR)/$(MYSQLSO): $(MYSQLSO)
- cp $(MYSQLSO) $(LIB_DIR)
-
-+$(LIB_DIR)/$(PGSQLSO): $(PGSQLSO)
-+ cp $(PGSQLSO) $(LIB_DIR)
-+
- update: $(LIBS) $(HDRS)
- -for i in $(HDRS); \
- do \
-@@ -149,7 +156,7 @@
- lint $(SRCS)
-
- clean:
-- rm -f *.o $(LIB) $(PCRESO) $(MYSQLSO) *core $(TESTPROG) \
-+ rm -f *.o $(LIB) $(PCRESO) $(MYSQLSO) $(PGSQLSO) *core $(TESTPROG) \
- junk $(MAKES) *.tmp
- rm -rf printfck
-
-@@ -591,6 +598,8 @@
- dict_ldap.o: sys_defs.h
- dict_mysql.o: dict_mysql.c
- dict_mysql.o: sys_defs.h
-+dict_pgsql.o: dict_pgsql.c
-+dict_pgsql.o: sys_defs.h
- dict_ni.o: dict_ni.c
- dict_ni.o: sys_defs.h
- dict_nis.o: dict_nis.c
-@@ -632,6 +641,7 @@
- dict_open.o: dict_ni.h
- dict_open.o: dict_ldap.h
- dict_open.o: dict_mysql.h
-+dict_open.o: dict_pgsql.h
- dict_open.o: dict_pcre.h
- dict_open.o: dict_regexp.h
- dict_open.o: dict_static.h
diff --git a/postfix-pl.patch b/postfix-pl.patch
deleted file mode 100644
index 50a1448..0000000
--- a/postfix-pl.patch
+++ /dev/null
@@ -1,386 +0,0 @@
-diff -Nur postfix-1.1.2.orig/src/bounce/bounce_notify_util.c postfix-1.1.2/src/bounce/bounce_notify_util.c
---- postfix-1.1.2.orig/src/bounce/bounce_notify_util.c Mon Nov 26 22:47:05 2001
-+++ postfix-1.1.2/src/bounce/bounce_notify_util.c Mon Jan 28 12:33:52 2002
-@@ -275,7 +275,7 @@
- post_mail_fputs(bounce, dest == var_bounce_rcpt
- || dest == var_2bounce_rcpt || dest == var_delay_rcpt ?
- "Subject: Postmaster Copy: Undelivered Mail" :
-- "Subject: Undelivered Mail Returned to Sender");
-+ "Subject: Zwrot niedostarczonej poczty / Undelivered Mail Returned to Sender");
- }
-
- /*
-@@ -285,7 +285,7 @@
- post_mail_fputs(bounce, dest == var_bounce_rcpt
- || dest == var_2bounce_rcpt || dest == var_delay_rcpt ?
- "Subject: Postmaster Warning: Delayed Mail" :
-- "Subject: Delayed Mail (still being retried)");
-+ "Subject: Opoznienie wyslania / Delayed Mail (still being retried)");
- }
- post_mail_fprintf(bounce, "To: %s",
- STR(quote_822_local(bounce_info->buf, dest)));
-@@ -300,15 +300,6 @@
- post_mail_fputs(bounce, "");
- post_mail_fputs(bounce, "This is a MIME-encapsulated message.");
-
-- /*
-- * MIME header.
-- */
-- post_mail_fputs(bounce, "");
-- post_mail_fprintf(bounce, "--%s", bounce_info->mime_boundary);
-- post_mail_fprintf(bounce, "Content-Description: %s", "Notification");
-- post_mail_fprintf(bounce, "Content-Type: %s", "text/plain");
-- post_mail_fputs(bounce, "");
--
- return (vstream_ferror(bounce));
- }
-
-@@ -324,6 +315,73 @@
- * word wrapping to make the text look nicer. No matter how hard we would
- * try, receiving bounced mail will always suck.
- */
-+
-+
-+ /* teraz po polsku */
-+ post_mail_fputs(bounce, "");
-+ post_mail_fprintf(bounce, "--%s", bounce_info->mime_boundary);
-+ post_mail_fprintf(bounce, "Content-Description: %s", "Informacja");
-+ post_mail_fprintf(bounce, "Content-Type: %s", "text/plain; charset=iso-8859-2");
-+ post_mail_fprintf(bounce, "Content-Transfer-Encoding: %s", "8bit");
-+ post_mail_fputs(bounce, "");
-+
-+ post_mail_fprintf(bounce, "Informacja od systemu pocztowego %s.",
-+ var_myhostname);
-+ post_mail_fputs(bounce, "");
-+ if (bounce_info->flush) {
-+ post_mail_fputs(bounce,
-+ "Twój list nie mógł być dostarczony do jednego");
-+ post_mail_fputs(bounce,
-+ "lub większej liczby odbiorców.");
-+ } else {
-+ post_mail_fputs(bounce,
-+ "########################################################################");
-+ post_mail_fputs(bounce,
-+ "# TO JEST TYLKO OSTRZEŻENIE. NIE MUSISZ PONOWNIE WYSYŁAĆ SWOJEGO LISTU #");
-+ post_mail_fputs(bounce,
-+ "########################################################################");
-+ post_mail_fputs(bounce, "");
-+ post_mail_fprintf(bounce,
-+ "Twój list nie mógł być dostarczony przez %.1f godzin.",
-+ var_delay_warn_time);
-+ post_mail_fprintf(bounce,
-+ "Będą podejmowane próby wysłania jeszcze przez %.1f dni.",
-+ var_max_queue_time);
-+ }
-+
-+ post_mail_fputs(bounce, "");
-+
-+ /* FIXME */
-+#if 0
-+ post_mail_fprintf(bounce,
-+ "For further assistance, please contact <%s>",
-+ STR(canon_addr_external(buf, MAIL_ADDR_POSTMASTER)));
-+ if (flush) {
-+ post_mail_fputs(bounce, "");
-+ post_mail_fprintf(bounce,
-+ "If you do so, please include this problem report. You can");
-+ post_mail_fprintf(bounce,
-+ "delete your own text from the message returned below.");
-+ post_mail_fprintf(bounce,
-+ "If you do so, please include this problem report. You can");
-+ post_mail_fprintf(bounce,
-+ "delete your own text from the message returned below.");
-+ }
-+ /* FIXME */
-+ post_mail_fputs(bounce, "");
-+ post_mail_fprintf(bounce, "\t\t\tProgram %s", var_mail_name);
-+ post_mail_fputs(bounce, "");
-+#endif
-+
-+ /*
-+ * MIME header.
-+ */
-+ post_mail_fputs(bounce, "");
-+ post_mail_fprintf(bounce, "--%s", bounce_info->mime_boundary);
-+ post_mail_fprintf(bounce, "Content-Description: %s", "Notification");
-+ post_mail_fprintf(bounce, "Content-Type: %s", "text/plain");
-+ post_mail_fputs(bounce, "");
-+
- post_mail_fprintf(bounce, "This is the %s program at host %s.",
- var_mail_name, var_myhostname);
- post_mail_fputs(bounce, "");
-@@ -347,7 +405,7 @@
- "It will be retried until it is %.1f days old.",
- var_max_queue_time / 86400.0);
- }
--
-+#if 0
- post_mail_fputs(bounce, "");
- post_mail_fprintf(bounce,
- "For further assistance, please send mail to <%s>",
-@@ -359,6 +417,7 @@
- post_mail_fprintf(bounce,
- "delete your own text from the message returned below.");
- }
-+#endif
- post_mail_fputs(bounce, "");
- post_mail_fprintf(bounce, "\t\t\tThe %s program", var_mail_name);
- return (vstream_ferror(bounce));
-@@ -420,6 +479,7 @@
- if (bounce_info->log_handle == 0
- || bounce_log_rewind(bounce_info->log_handle)) {
- post_mail_fputs(bounce, "\t--- Delivery error report unavailable ---");
-+ post_mail_fputs(bounce, "\t--- Raport dostarczenia niedostepny ---");
- } else {
- while (bounce_log_read(bounce_info->log_handle) != 0)
- if (bounce_recipient_log(bounce, bounce_info) != 0)
-@@ -440,7 +500,8 @@
- post_mail_fprintf(bounce, "--%s", bounce_info->mime_boundary);
- post_mail_fprintf(bounce, "Content-Description: %s",
- "Delivery error report");
-- post_mail_fprintf(bounce, "Content-Type: %s", "message/delivery-status");
-+ post_mail_fprintf(bounce, "Content-Type: %s", "message/delivery-status; charset=iso-8859-2");
-+ post_mail_fprintf(bounce, "Content-Transfer-Encoding: %s", "8bit");
-
- /*
- * According to RFC 1894: The body of a message/delivery-status consists
-@@ -529,6 +590,7 @@
- if (bounce_info->orig_offs == 0 || vstream_fseek(bounce_info->orig_fp,
- bounce_info->orig_offs, SEEK_SET) < 0) {
- post_mail_fputs(bounce, "\t--- Undelivered message unavailable ---");
-+ post_mail_fputs(bounce, "\t--- Niedostepna kopia niedostarczonego listu ---");
- return (vstream_ferror(bounce));
- }
-
-diff -Nur postfix-1.1.2.orig/src/global/pipe_command.c postfix-1.1.2/src/global/pipe_command.c
---- postfix-1.1.2.orig/src/global/pipe_command.c Tue Nov 27 02:02:17 2001
-+++ postfix-1.1.2/src/global/pipe_command.c Mon Jan 28 12:33:52 2002
-@@ -482,9 +482,9 @@
- if (pipe_command_wait_or_kill(pid, &wait_status, SIGKILL) < 0)
- msg_fatal("wait: %m");
- if (pipe_command_timeout) {
-- vstring_sprintf(why, "Command time limit exceeded: \"%s\"%s%s",
-+ vstring_sprintf(why, "Przekroczony czas wykonania polecania / Command time limit exceeded: \"%s\"%s%s",
- args.command,
-- log_len ? ". Command output: " : "", log_buf);
-+ log_len ? ". Wyniki polecenia / Command output: " : "", log_buf);
- return (PIPE_STAT_BOUNCE);
- }
-
-@@ -494,28 +494,28 @@
- */
- if (!NORMAL_EXIT_STATUS(wait_status)) {
- if (WIFSIGNALED(wait_status)) {
-- vstring_sprintf(why, "Command died with signal %d: \"%s\"%s%s",
-+ vstring_sprintf(why, "Polecenia zakonczone blendem / Command died with signal %d: \"%s\"%s%s",
- WTERMSIG(wait_status),
- args.command,
-- log_len ? ". Command output: " : "", log_buf);
-+ log_len ? ". Wynik polecenia / Command output: " : "", log_buf);
- return (PIPE_STAT_DEFER);
- } else if (SYS_EXITS_CODE(WEXITSTATUS(wait_status))) {
- vstring_sprintf(why, "%s%s%s",
- sys_exits_strerror(WEXITSTATUS(wait_status)),
-- log_len ? ". Command output: " : "", log_buf);
-+ log_len ? ". Wynik polecenia / Command output: " : "", log_buf);
- return (sys_exits_softerror(WEXITSTATUS(wait_status)) ?
- PIPE_STAT_DEFER : PIPE_STAT_BOUNCE);
- } else {
-- vstring_sprintf(why, "Command died with status %d: \"%s\"%s%s",
-+ vstring_sprintf(why, "Polecenie zakonczone bledem / Command died with status %d: \"%s\"%s%s",
- WEXITSTATUS(wait_status),
- args.command,
-- log_len ? ". Command output: " : "", log_buf);
-+ log_len ? ". Wynik polecenia / Command output: " : "", log_buf);
- return (PIPE_STAT_BOUNCE);
- }
- } else if (write_status & MAIL_COPY_STAT_CORRUPT) {
- return (PIPE_STAT_CORRUPT);
- } else if (write_status && errno != EPIPE) {
-- vstring_sprintf(why, "Command failed: %m: \"%s\"", args.command);
-+ vstring_sprintf(why, "Polecenie niepowiodlo sie / Command failed: %m: \"%s\"", args.command);
- return (PIPE_STAT_DEFER);
- } else {
- return (PIPE_STAT_OK);
-diff -Nur postfix-1.1.2.orig/src/global/sys_exits.c postfix-1.1.2/src/global/sys_exits.c
---- postfix-1.1.2.orig/src/global/sys_exits.c Fri Dec 11 19:55:25 1998
-+++ postfix-1.1.2/src/global/sys_exits.c Mon Jan 28 12:33:52 2002
-@@ -60,21 +60,21 @@
- } SYS_EXITS_TABLE;
-
- static SYS_EXITS_TABLE sys_exits_table[] = {
-- 0, EX_USAGE, "command line usage error",
-- 0, EX_DATAERR, "data format error",
-+ 0, EX_USAGE, "bledne wywylanie polecanie / command line usage error",
-+ 0, EX_DATAERR, "blad formatu danych / data format error",
- 0, EX_NOINPUT, "cannot open input",
-- 0, EX_NOUSER, "user unknown",
-+ 0, EX_NOUSER, "nieznany uzytkownik / user unknown",
- 0, EX_NOHOST, "host name unknown",
-- 0, EX_UNAVAILABLE, "service unavailable",
-- 0, EX_SOFTWARE, "internal software error",
-+ 0, EX_UNAVAILABLE, "niedostepny serwis / service unavailable",
-+ 0, EX_SOFTWARE, "wewnetrzny blad oprogramowania / internal software error",
- 1, EX_OSERR, "system resource problem",
- 0, EX_OSFILE, "critical OS file missing",
- 0, EX_CANTCREAT, "can't create user output file",
- 0, EX_IOERR, "input/output error",
-- 1, EX_TEMPFAIL, "temporary failure",
-+ 1, EX_TEMPFAIL, "chwilowe niepowodzenie / temporary failure",
- 0, EX_PROTOCOL, "remote error in protocol",
-- 0, EX_NOPERM, "permission denied",
-- 0, EX_CONFIG, "local configuration error",
-+ 0, EX_NOPERM, "brak dostępu / permission denied",
-+ 0, EX_CONFIG, "blad lokalnej konfiguracji / local configuration error",
- };
-
- /* sys_exits_strerror - map exit status to error string */
-
---- postfix-2.0.10/src/smtpd/smtpd_check.c.orig Sun Jun 1 12:38:56 2003
-+++ postfix-2.0.10/src/smtpd/smtpd_check.c Sun Jun 1 12:57:27 2003
-@@ -988,7 +988,7 @@
- */
- if (!valid_hostaddr(test_addr, DONT_GRIPE))
- stat = smtpd_check_reject(state, MAIL_ERROR_POLICY,
-- "%d <%s>: %s rejected: invalid ip address",
-+ "%d <%s>: %s odrzucony/rejected: niepoprawny adres IP/invalid IP address",
- var_bad_name_code, reply_name, reply_class);
- else
- stat = SMTPD_CHECK_DUNNO;
-@@ -1024,7 +1024,7 @@
- */
- if (!valid_hostname(test_name, DONT_GRIPE))
- stat = smtpd_check_reject(state, MAIL_ERROR_POLICY,
-- "%d <%s>: %s rejected: Invalid name",
-+ "%d <%s>: %s odrzucony/rejected: Niepoprawna nazwa / Invalid name",
- var_bad_name_code, reply_name, reply_class);
- else
- stat = SMTPD_CHECK_DUNNO;
-@@ -1060,7 +1060,7 @@
- */
- if (!valid_hostname(test_name, DONT_GRIPE) || !strchr(test_name, '.'))
- stat = smtpd_check_reject(state, MAIL_ERROR_POLICY,
-- "%d <%s>: %s rejected: need fully-qualified hostname",
-+ "%d <%s>: %s odrzucowny/rejected: need fully-qualified hostname",
- var_non_fqdn_code, reply_name, reply_class);
- else
- stat = SMTPD_CHECK_DUNNO;
-@@ -1095,7 +1095,7 @@
- (VSTRING *) 0, RR_ADDR_TYPES, T_MX, 0);
- if (dns_status == DNS_NOTFOUND)
- return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
-- "%d <%s>: %s rejected: Host not found",
-+ "%d <%s>: %s odrzucony/rejected: Host not found",
- var_unk_name_code,
- reply_name, reply_class));
- else if (dns_status != DNS_OK)
-@@ -1120,7 +1120,7 @@
- (VSTRING *) 0, RR_ADDR_TYPES, T_MX, 0);
- if (dns_status == DNS_NOTFOUND)
- return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
-- "%d <%s>: %s rejected: Domain not found",
-+ "%d <%s>: %s odrzucony/rejected: Domain not found",
- var_unk_addr_code,
- reply_name, reply_class));
- else if (dns_status != DNS_OK)
-@@ -1201,7 +1201,8 @@
- vstring_strcat(reply_msg, "%d <%s>: %s ");
- vstring_strcat(reply_msg, var_reject_reply_msg_access_denied);
- return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
-- vstring_export(reply_msg), var_relay_code, reply_name, reply_class));
-+ "%d <%s>: %s odrzucony/rejected: Relay access denied",
-+ var_relay_code, reply_name, reply_class));
- }
-
- /* permit_auth_destination - OK for message relaying */
-@@ -1650,7 +1651,7 @@
- */
- if (!*test_dom || !valid_hostname(test_dom, DONT_GRIPE) || !strchr(test_dom, '.'))
- stat = smtpd_check_reject(state, MAIL_ERROR_POLICY,
-- "%d <%s>: %s rejected: need fully-qualified address",
-+ "%d <%s>: %s odrzucony/rejected: need fully-qualified address",
- var_non_fqdn_code, reply_name, reply_class);
- else
- stat = SMTPD_CHECK_DUNNO;
-@@ -1766,9 +1767,9 @@
- */
- if (STREQUAL(value, "REJECT", cmd_len)) {
- return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
-- "%d <%s>: %s rejected: %s",
-+ "%d <%s>: %s odrzucony/rejected: %s",
- var_access_map_code, reply_name, reply_class,
-- *cmd_text ? cmd_text : "Access denied"));
-+ *cmd_text ? cmd_text : "Brak dostepu / Access denied"));
- }
-
- /*
-@@ -1858,7 +1859,7 @@
- && ISDIGIT(value[0]) && ISDIGIT(value[1]) && ISDIGIT(value[2])) {
- code = atoi(value);
- return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
-- "%d <%s>: %s rejected: %s",
-+ "%d <%s>: %s odrzucony/rejected: %s",
- code, reply_name, reply_class, cmd_text));
- }
-
-@@ -2743,14 +2744,14 @@
- cpp[1], PERMIT_ALL);
- } else if (strcasecmp(name, DEFER_ALL) == 0) {
- status = smtpd_check_reject(state, MAIL_ERROR_POLICY,
-- "%d <%s>: %s rejected: Try again later",
-+ "%d <%s>: %s odrzucony/rejected: Sprobuj pozniej / Try again later",
- var_defer_code, reply_name, reply_class);
- if (cpp[1] != 0 && state->warn_if_reject == 0)
- msg_warn("restriction `%s' after `%s' is ignored",
- cpp[1], DEFER_ALL);
- } else if (strcasecmp(name, REJECT_ALL) == 0) {
- status = smtpd_check_reject(state, MAIL_ERROR_POLICY,
-- "%d <%s>: %s rejected: Access denied",
-+ "%d <%s>: %s odrzucony/rejected: Brak dostepu / Access denied",
- var_reject_code, reply_name, reply_class);
- if (cpp[1] != 0 && state->warn_if_reject == 0)
- msg_warn("restriction `%s' after `%s' is ignored",
-@@ -3356,10 +3357,10 @@
- strlen(MAIL_ADDR_MAIL_DAEMON))
- && NOMATCH(local_rcpt_maps, CONST_STR(reply->recipient)))
- return (smtpd_check_reject(state, MAIL_ERROR_BOUNCE,
-- "%d <%s>: User unknown%s",
-+ "%d <%s>: Nieznany uzytkownik / User unknown%s",
- var_local_rcpt_code, recipient,
- var_show_unk_rcpt_table ?
-- " in local recipient table" : ""));
-+ " in local recipient table" : ""));
-
- /*
- * Reject mail to unknown addresses in virtual mailbox domains.
-@@ -3368,10 +3369,10 @@
- && *var_virt_mailbox_maps
- && NOMATCHV8(virt_mailbox_maps, CONST_STR(reply->recipient)))
- return (smtpd_check_reject(state, MAIL_ERROR_BOUNCE,
-- "%d <%s>: User unknown%s",
-+ "%d <%s>: Nieznany uzytkownik / User unknown%s",
- var_virt_mailbox_code, recipient,
- var_show_unk_rcpt_table ?
-- " in virtual mailbox table" : ""));
-+ " in virtual mailbox table" : ""));
-
- /*
- * Reject mail to unknown addresses in relay domains.
-@@ -3380,7 +3381,7 @@
- && *var_relay_rcpt_maps
- && NOMATCH(relay_rcpt_maps, CONST_STR(reply->recipient)))
- return (smtpd_check_reject(state, MAIL_ERROR_BOUNCE,
-- "%d <%s>: User unknown%s",
-+ "%d <%s>: Nieznany uzytkownik / User unknown%s",
- var_relay_rcpt_code, recipient,
- var_show_unk_rcpt_table ?
- " in relay recipient table" : ""));
-@@ -3415,7 +3416,7 @@
-
- if (var_message_limit > 0 && size > var_message_limit) {
- (void) smtpd_check_reject(state, MAIL_ERROR_POLICY,
-- "552 Message size exceeds fixed limit");
-+ "552 Przekroczony rozmiar wiadomosci / Message size exceeds fixed limit");
- return (STR(error_text));
- }
- fsspace(".", &fsbuf);
diff --git a/postfix-sasl2.patch b/postfix-sasl2.patch
deleted file mode 100644
index 4b745d4..0000000
--- a/postfix-sasl2.patch
+++ /dev/null
@@ -1,298 +0,0 @@
-diff -durN postfix-1.1.11.orig/src/lmtp/lmtp.h postfix-1.1.11/src/lmtp/lmtp.h
---- postfix-1.1.11.orig/src/lmtp/lmtp.h Tue May 22 20:37:14 2001
-+++ postfix-1.1.11/src/lmtp/lmtp.h Mon Jan 13 12:27:52 2003
-@@ -12,8 +12,8 @@
- * SASL library.
- */
- #ifdef USE_SASL_AUTH
--#include <sasl.h>
--#include <saslutil.h>
-+#include <sasl/sasl.h>
-+#include <sasl/saslutil.h>
- #endif
-
- /*
-diff -durN postfix-1.1.11.orig/src/lmtp/lmtp_sasl_glue.c postfix-1.1.11/src/lmtp/lmtp_sasl_glue.c
---- postfix-1.1.11.orig/src/lmtp/lmtp_sasl_glue.c Fri Jan 19 22:46:44 2001
-+++ postfix-1.1.11/src/lmtp/lmtp_sasl_glue.c Mon Jan 13 12:31:32 2003
-@@ -138,10 +138,10 @@
- {
- switch (priority) {
- case SASL_LOG_ERR:
-- case SASL_LOG_WARNING:
-+ case SASL_LOG_WARN:
- msg_warn("%s", message);
- break;
-- case SASL_LOG_INFO:
-+ case SASL_LOG_NOTE:
- if (msg_verbose)
- msg_info("%s", message);
- break;
-@@ -318,6 +318,7 @@
- for (cp = state->sasl_callbacks; cp->id != SASL_CB_LIST_END; cp++)
- cp->context = (void *) state;
- if (sasl_client_new("smtp", state->session->host,
-+ NULL, NULL,
- state->sasl_callbacks, NULL_SECFLAGS,
- (sasl_conn_t **) &state->sasl_conn) != SASL_OK)
- msg_fatal("per-session SASL client initialization");
-@@ -354,7 +355,7 @@
- char *myname = "lmtp_sasl_authenticate";
- unsigned enc_length;
- unsigned enc_length_out;
-- char *clientout;
-+ const char *clientout;
- unsigned clientoutlen;
- unsigned serverinlen;
- LMTP_RESP *resp;
-@@ -376,7 +377,7 @@
- */
- result = sasl_client_start((sasl_conn_t *) state->sasl_conn,
- state->sasl_mechanism_list,
-- NO_SASL_SECRET, NO_SASL_INTERACTION,
-+ NO_SASL_INTERACTION,
- &clientout, &clientoutlen, &mechanism);
- if (result != SASL_OK && result != SASL_CONTINUE) {
- vstring_sprintf(why, "cannot SASL authenticate to server %s: %s",
-@@ -404,7 +405,6 @@
- STR(state->sasl_encoded), enc_length,
- &enc_length_out) != SASL_OK)
- msg_panic("%s: sasl_encode64 botch", myname);
-- free(clientout);
- lmtp_chat_cmd(state, "AUTH %s %s", mechanism, STR(state->sasl_encoded));
- } else {
- lmtp_chat_cmd(state, "AUTH %s", mechanism);
-@@ -424,7 +424,7 @@
- serverinlen = strlen(line);
- VSTRING_SPACE(state->sasl_decoded, serverinlen);
- if (sasl_decode64(line, serverinlen,
-- STR(state->sasl_decoded), &enc_length) != SASL_OK) {
-+ STR(state->sasl_decoded), serverinlen, &enc_length) != SASL_OK) {
- vstring_sprintf(why, "malformed SASL challenge from server %s",
- state->session->namaddr);
- return (-1);
-@@ -456,7 +456,6 @@
- STR(state->sasl_encoded), enc_length,
- &enc_length_out) != SASL_OK)
- msg_panic("%s: sasl_encode64 botch", myname);
-- free(clientout);
- } else {
- vstring_strcat(state->sasl_encoded, "");
- }
-diff -durN postfix-1.1.11.orig/src/smtp/smtp.h postfix-1.1.11/src/smtp/smtp.h
---- postfix-1.1.11.orig/src/smtp/smtp.h Mon Jan 13 12:33:43 2003
-+++ postfix-1.1.11/src/smtp/smtp.h Mon Jan 13 12:10:16 2003
-@@ -12,8 +12,8 @@
- * SASL library.
- */
- #ifdef USE_SASL_AUTH
--#include <sasl.h>
--#include <saslutil.h>
-+#include <sasl/sasl.h>
-+#include <sasl/saslutil.h>
- #endif
-
- /*
-diff -durN postfix-1.1.11.orig/src/smtp/smtp_sasl_glue.c postfix-1.1.11/src/smtp/smtp_sasl_glue.c
---- postfix-1.1.11.orig/src/smtp/smtp_sasl_glue.c Mon Jul 2 21:12:54 2001
-+++ postfix-1.1.11/src/smtp/smtp_sasl_glue.c Mon Jan 13 12:17:57 2003
-@@ -138,10 +138,10 @@
- {
- switch (priority) {
- case SASL_LOG_ERR:
-- case SASL_LOG_WARNING:
-+ case SASL_LOG_WARN:
- msg_warn("SASL authentication problem: %s", message);
- break;
-- case SASL_LOG_INFO:
-+ case SASL_LOG_NOTE:
- if (msg_verbose)
- msg_info("SASL authentication info: %s", message);
- break;
-@@ -317,9 +317,10 @@
- memcpy((char *) state->sasl_callbacks, callbacks, sizeof(callbacks));
- for (cp = state->sasl_callbacks; cp->id != SASL_CB_LIST_END; cp++)
- cp->context = (void *) state;
-- if (sasl_client_new("smtp", state->session->host,
-+ if (sasl_client_new("smtp", state->session->host, NULL, NULL,
- state->sasl_callbacks, NULL_SECFLAGS,
- (sasl_conn_t **) &state->sasl_conn) != SASL_OK)
-+
- msg_fatal("per-session SASL client initialization");
-
- /*
-@@ -354,7 +355,7 @@
- char *myname = "smtp_sasl_authenticate";
- unsigned enc_length;
- unsigned enc_length_out;
-- char *clientout;
-+ const char *clientout;
- unsigned clientoutlen;
- unsigned serverinlen;
- SMTP_RESP *resp;
-@@ -362,8 +363,7 @@
- int result;
- char *line;
-
--#define NO_SASL_SECRET 0
--#define NO_SASL_INTERACTION 0
-+#define NO_SASL_INTERACTION NULL
- #define NO_SASL_LANGLIST ((const char *) 0)
- #define NO_SASL_OUTLANG ((const char **) 0)
-
-@@ -376,7 +376,7 @@
- */
- result = sasl_client_start((sasl_conn_t *) state->sasl_conn,
- state->sasl_mechanism_list,
-- NO_SASL_SECRET, NO_SASL_INTERACTION,
-+ NO_SASL_INTERACTION,
- &clientout, &clientoutlen, &mechanism);
- if (result != SASL_OK && result != SASL_CONTINUE) {
- vstring_sprintf(why, "cannot SASL authenticate to server %s: %s",
-@@ -404,7 +404,6 @@
- STR(state->sasl_encoded), enc_length,
- &enc_length_out) != SASL_OK)
- msg_panic("%s: sasl_encode64 botch", myname);
-- free(clientout);
- smtp_chat_cmd(state, "AUTH %s %s", mechanism, STR(state->sasl_encoded));
- } else {
- smtp_chat_cmd(state, "AUTH %s", mechanism);
-@@ -424,7 +423,7 @@
- serverinlen = strlen(line);
- VSTRING_SPACE(state->sasl_decoded, serverinlen);
- if (sasl_decode64(line, serverinlen,
-- STR(state->sasl_decoded), &enc_length) != SASL_OK) {
-+ STR(state->sasl_decoded), serverinlen, &enc_length) != SASL_OK) {
- vstring_sprintf(why, "malformed SASL challenge from server %s",
- state->session->namaddr);
- return (-1);
-diff -durN postfix-1.1.11.orig/src/smtpd/smtpd.h postfix-1.1.11/src/smtpd/smtpd.h
---- postfix-1.1.11.orig/src/smtpd/smtpd.h Mon Jan 13 12:33:43 2003
-+++ postfix-1.1.11/src/smtpd/smtpd.h Mon Jan 13 12:26:29 2003
-@@ -17,8 +17,8 @@
- * SASL library.
- */
- #ifdef USE_SASL_AUTH
--#include <sasl.h>
--#include <saslutil.h>
-+#include <sasl/sasl.h>
-+#include <sasl/saslutil.h>
- #endif
-
- /*
-@@ -69,7 +69,7 @@
- off_t msg_size;
- int junk_cmds;
- #ifdef USE_SASL_AUTH
-- char *sasl_mechanism_list;
-+ const char *sasl_mechanism_list;
- char *sasl_method;
- char *sasl_username;
- char *sasl_sender;
-diff -durN postfix-1.1.11.orig/src/smtpd/smtpd_sasl_glue.c postfix-1.1.11/src/smtpd/smtpd_sasl_glue.c
---- postfix-1.1.11.orig/src/smtpd/smtpd_sasl_glue.c Mon Nov 26 01:14:01 2001
-+++ postfix-1.1.11/src/smtpd/smtpd_sasl_glue.c Mon Jan 13 12:27:15 2003
-@@ -117,10 +117,10 @@
- {
- switch (priority) {
- case SASL_LOG_ERR:
-- case SASL_LOG_WARNING:
-+ case SASL_LOG_WARN:
- msg_warn("SASL authentication problem: %s", message);
- break;
-- case SASL_LOG_INFO:
-+ case SASL_LOG_NOTE:
- if (msg_verbose)
- msg_info("SASL authentication info: %s", message);
- break;
-@@ -196,6 +196,7 @@
- #define NO_SESSION_CALLBACKS ((sasl_callback_t *) 0)
-
- if (sasl_server_new("smtp", var_myhostname, var_smtpd_sasl_realm,
-+ NULL, NULL,
- NO_SESSION_CALLBACKS, NO_SECURITY_LAYERS,
- &state->sasl_conn) != SASL_OK)
- msg_fatal("SASL per-connection server initialization");
-@@ -238,10 +239,6 @@
-
- void smtpd_sasl_disconnect(SMTPD_STATE *state)
- {
-- if (state->sasl_mechanism_list) {
-- free(state->sasl_mechanism_list);
-- state->sasl_mechanism_list = 0;
-- }
- if (state->sasl_conn) {
- sasl_dispose(&state->sasl_conn);
- state->sasl_conn = 0;
-@@ -262,10 +259,9 @@
- unsigned enc_length;
- unsigned enc_length_out;
- unsigned reply_len;
-- char *serverout = 0;
-+ const char *serverout = 0;
- unsigned serveroutlen;
- int result;
-- const char *errstr = 0;
-
- #define IFELSE(e1,e2,e3) ((e1) ? (e2) : (e3))
-
-@@ -289,7 +285,7 @@
- VSTRING_SPACE(state->sasl_decoded, reply_len);
- dec_buffer = STR(state->sasl_decoded);
- if (sasl_decode64(init_response, reply_len,
-- dec_buffer, &dec_length) != SASL_OK)
-+ dec_buffer, reply_len, &dec_length) != SASL_OK)
- return ("501 Authentication failed: malformed initial response");
- if (msg_verbose)
- msg_info("%s: decoded initial response %s", myname, dec_buffer);
-@@ -298,7 +294,7 @@
- dec_length = 0;
- }
- result = sasl_server_start(state->sasl_conn, sasl_method, dec_buffer,
-- dec_length, &serverout, &serveroutlen, &errstr);
-+ dec_length, &serverout, &serveroutlen);
-
- /*
- * Repeat until done or until the client gives up.
-@@ -327,7 +323,6 @@
- if (sasl_encode64(serverout, serveroutlen, STR(state->sasl_encoded),
- enc_length, &enc_length_out) != SASL_OK)
- msg_panic("%s: sasl_encode64 botch", myname);
-- free(serverout);
- serverout = 0;
- smtpd_chat_reply(state, "334 %s", STR(state->sasl_encoded));
-
-@@ -343,22 +338,16 @@
- reply_len = VSTRING_LEN(state->buffer);
- VSTRING_SPACE(state->sasl_decoded, reply_len);
- if (sasl_decode64(vstring_str(state->buffer), reply_len,
-- STR(state->sasl_decoded), &dec_length) != SASL_OK)
-+ STR(state->sasl_decoded), reply_len, &dec_length) != SASL_OK)
- return ("501 Error: malformed authentication response");
- if (msg_verbose)
- msg_info("%s: decoded response: %.*s",
- myname, (int) dec_length, STR(state->sasl_decoded));
- result = sasl_server_step(state->sasl_conn, STR(state->sasl_decoded),
-- dec_length, &serverout, &serveroutlen, &errstr);
-+ dec_length, &serverout, &serveroutlen);
- }
-
- /*
-- * Cleanup. What an awful interface.
-- */
-- if (serverout)
-- free(serverout);
--
-- /*
- * The authentication protocol was completed.
- */
- if (result != SASL_OK)
-@@ -370,7 +359,7 @@
- * authentication method that was used. XXX Do not free(serverout).
- */
- result = sasl_getprop(state->sasl_conn, SASL_USERNAME,
-- (void **) &serverout);
-+ (const void **) &serverout);
- if (result != SASL_OK || serverout == 0)
- msg_panic("%s: sasl_getprop SASL_USERNAME botch", myname);
- state->sasl_username = mystrdup(serverout);