The attached patch should work for postfix-2.1.4 on Release 2.1
and CURRENT.  The older patch fails in several places.

I've forwarded this patch to the maintainer, Laurent Wacrenier
<[EMAIL PROTECTED]> as well.

Bill
--
INTERNET:   [EMAIL PROTECTED]  Bill Campbell; Celestial Systems, Inc.
UUCP:               camco!bill  PO Box 820; 6641 E. Mercer Way
FAX:            (206) 232-9186  Mercer Island, WA 98040-0820; (206) 236-1676
URL: http://www.celestial.com/

Giving money and power to government is like giving whiskey and car keys to
teenage boys -- P.J. O'Rourke
diff -uNr ../postfix-2.1.4.orig/src/util/Makefile.in ./src/util/Makefile.in
--- ../postfix-2.1.4.orig/src/util/Makefile.in  2004-07-24 16:28:33.231640208 -0700
+++ ./src/util/Makefile.in      2004-07-24 16:33:05.139303960 -0700
@@ -28,7 +28,8 @@
        vstream_popen.c vstring.c vstring_vstream.c watchdog.c writable.c \
        write_buf.c write_wait.c auto_clnt.c attr_clnt.c attr_scan_plain.c \
        attr_print_plain.c sane_connect.c neuter.c name_code.c \
-       uppercase.c dict_sdbm.c sdbm.c
+       uppercase.c dict_sdbm.c sdbm.c dict_whoson.c
+
 OBJS   = alldig.o argv.o argv_split.o attr_print0.o attr_print64.o \
        attr_scan0.o attr_scan64.o base64_code.o basename.o binhash.o \
        chroot_uid.o clean_env.o close_on_exec.o concatenate.o ctable.o \
@@ -58,7 +59,8 @@
        vstream_popen.o vstring.o vstring_vstream.o watchdog.o writable.o \
        write_buf.o write_wait.o auto_clnt.o attr_clnt.o attr_scan_plain.o \
        attr_print_plain.o sane_connect.o $(STRCASE) neuter.o name_code.o \
-       uppercase.o dict_sdbm.o sdbm.o
+       uppercase.o dict_sdbm.o sdbm.o dict_whoson.o
+
 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_cidr.h dict_ht.h dict_ni.h dict_nis.h \
@@ -77,7 +79,9 @@
        split_at.h stat_as.h stringops.h sys_defs.h timed_connect.h \
        timed_wait.h trigger.h username.h valid_hostname.h vbuf.h \
        vbuf_print.h vstream.h vstring.h vstring_vstream.h watchdog.h \
-       auto_clnt.h attr_clnt.h sane_connect.h name_code.h dict_sdbm.h sdbm.h
+       auto_clnt.h attr_clnt.h sane_connect.h name_code.h dict_sdbm.h sdbm.h \
+       dict_whoson.h
+
 TESTSRC        = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
        stream_test.c dup2_pass_on_exec.c
 DEFS   = -I. -D$(SYSTYPE)
diff -uNr ../postfix-2.1.4.orig/src/util/dict_open.c ./src/util/dict_open.c
--- ../postfix-2.1.4.orig/src/util/dict_open.c  2004-07-24 16:28:33.232640056 -0700
+++ ./src/util/dict_open.c      2004-07-24 16:34:47.640721376 -0700
@@ -180,6 +180,7 @@
 #include <stringops.h>
 #include <split_at.h>
 #include <htable.h>
+#include <dict_whoson.h>
 
  /*
   * lookup table for available map types.
@@ -220,6 +221,7 @@
 #endif
     DICT_TYPE_STATIC, dict_static_open,
     DICT_TYPE_CIDR, dict_cidr_open,
+    DICT_TYPE_WHOSON, dict_whoson_open,
     0,
 };
 
diff -uNr ../postfix-2.1.4.orig/src/util/dict_whoson.c ./src/util/dict_whoson.c
--- ../postfix-2.1.4.orig/src/util/dict_whoson.c        1969-12-31 16:00:00.000000000 
-0800
+++ ./src/util/dict_whoson.c    2004-07-24 16:29:21.654278848 -0700
@@ -0,0 +1,269 @@
+/*++
+/* NAME
+/*     dict_whoson 3
+/* SUMMARY
+/*     dictionary manager interface to whoson lookup tables
+/* SYNOPSIS
+/*     #include <dict_whoson.h>
+/*
+/*     DICT    *dict_whoson_open(map, dummy, dict_flags)
+/*     const char *map;
+/*     int     dummy;
+/*     int     dict_flags;
+/* DESCRIPTION
+/*      dict_whoson_open() make a WHOSON server accessible
+/*      via the generic dictionary operations described in 
+/*      dict_open(3).
+/*     The \fIdummy\fR argument is not used. The only implemented
+/*     operation is dictionary lookup. 
+/*
+/*      Map names have the form host:port in case of a TCP
+/*      whoson server or /path/to/socket in case of a Unix domain
+/*      server.
+/*
+/*      WHOSON protocol is designed to allow mail relay to
+/*      a given IP adress on a smtpd server without requiring
+/*      an SMTP authentication. Authentication has to be trusted
+/*      from another source (for example, a POP server)
+/*
+/*      Keys have to be full IP addresses. If a value is found
+/*      for a key, lookup reply will be the constant string "OK",
+/*      the IP address key and the whoson server answer are logged.
+/*
+/* SEE ALSO
+/*     dict(3) generic dictionary manager
+/* DIAGNOSTICS
+/*     Fatal errors: out of memory, unknown host or service name,
+/*     attempt to update or iterate over map.
+/*      Warnings: unable to connect to whoson server, connection
+/*      close, whoson server error.
+/* BUGS
+/*     Only the lookup method is currently implemented.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include "sys_defs.h"
+#include <unistd.h>
+#include <string.h>
+
+#include "msg.h"
+#include "mymalloc.h"
+#include "vstring.h"
+#include "vstream.h"
+#include "vstring_vstream.h"
+#include "valid_hostname.h"
+#include "connect.h"
+#include "stringops.h"
+#include "dict_whoson.h"
+#include "dict.h"
+
+
+typedef struct {
+  DICT    dict;                       /* generic members */
+  VSTRING *input;                     /* raw I/O buffer */
+  VSTRING *dummy;                     /* raw I/O buffer to skip empty lines */
+  VSTREAM *fp;                        /* I/O stream */
+} DICT_WHOSON;
+
+#define DICT_WHOSON_TMOUT  100
+
+/*
+ * Does the server stop when the whoson server fails ?
+ *
+ * According the nature of the map, it should be a bad thing
+ * exepted on a dedicaced SMTP after POP server.
+ */
+
+#undef DICT_WHOSON_INSISTS
+
+#ifdef DICT_WHOSON_INSISTS
+#  define DICT_WHOSON_MAXTRY 10
+#  define DICT_WHOSON_ERROR  DICT_ERR_RETRY
+#else
+#  define DICT_WHOSON_MAXTRY 10
+#  define DICT_WHOSON_ERROR  DICT_ERR_NONE
+#endif
+
+
+#define STR(x)         vstring_str(x)
+
+/* dict_whoson_connect - connect to whoson server */
+
+static int dict_whoson_connect(DICT_WHOSON *dict_whoson)
+{
+  int fd;
+  if (dict_whoson->dict.name[0] == '/') { /* unix domain socket */
+    fd = unix_connect(dict_whoson->dict.name, BLOCKING, 0);
+  } else {
+    fd = inet_connect(dict_whoson->dict.name, BLOCKING, 0);
+  }
+  if (fd < 0) {
+    msg_warn("connect to WHOSON map %s: %m", dict_whoson->dict.name);
+    return -1;
+  }
+
+  dict_whoson->fp = vstream_fdopen(fd, O_RDWR);
+
+  vstream_control(dict_whoson->fp,
+                 VSTREAM_CTL_TIMEOUT, DICT_WHOSON_TMOUT,
+                 VSTREAM_CTL_END);
+
+  dict_whoson->fp = vstream_fdopen(fd, O_RDWR);
+
+  if (dict_whoson->input == 0) {
+    dict_whoson->input = vstring_alloc(10);
+    dict_whoson->dummy = vstring_alloc(10);
+  }
+  return 0;
+  
+}
+
+/* dict_whoson_disconnect - disconnect from whoson server */
+
+static void dict_whoson_disconnect(DICT_WHOSON *dict_whoson)
+{
+  (void) vstream_fclose(dict_whoson->fp);
+  dict_whoson->fp = 0;
+}
+
+/* dict_whoson_lookup - request whoson server */
+
+
+static const char *dict_whoson_lookup(DICT *dict, const char *key)
+{
+  DICT_WHOSON *dict_whoson = (DICT_WHOSON *) dict;
+  char   *myname = "dict_whoson_lookup";
+  char   *reply;
+  char   *end_of_reply;
+  char   *dummy;
+  int    tries;
+  
+#define RETURN(errval, result) { dict_errno = errval; return (result); }
+
+  if (msg_verbose)
+    msg_info("%s: key %s", myname, key);
+
+  if (valid_hostaddr(key, 0) == 0) {
+    if (msg_verbose)
+      msg_info("%s: %s is not a host address, dont send it to whoson server",
+              myname, key);
+    RETURN(DICT_ERR_NONE, 0);
+  }
+
+  for (tries = 0; /* see below */ ; /* see below */ ) {
+
+    /*
+     * Connect to the server, or use an existing connection.
+     */
+    if (dict_whoson->fp != 0 || dict_whoson_connect(dict_whoson) == 0) {
+
+      vstream_fprintf(dict_whoson->fp, "QUERY %s\r\n\r\n", key);
+      if (vstring_get_nonl(dict_whoson->input, dict_whoson->fp) > 0) {
+       
+       reply = STR(dict_whoson->input);
+
+       /*
+        *  wait for an empty line
+        */
+       while(vstring_get_nonl(dict_whoson->dummy, dict_whoson->fp)>0) {
+         dummy = STR(dict_whoson->dummy);
+         if (dummy[0] == '\r')  dummy ++;
+         if (dummy[0] == '\0')  break;
+       }
+
+       end_of_reply=reply + strlen(reply);
+       if (reply != end_of_reply && end_of_reply[-1] == '\r') 
+         end_of_reply[-1]='\0';
+
+       /*
+        *  Parse the answer
+        */ 
+
+       if (reply[0] == '+') {
+         /*
+          *  send the anwser in log file
+          */
+         msg_info("%s: user found '%.100s' for [%s] from %s", myname,
+                  reply+1, key, dict_whoson->dict.name);
+
+         RETURN(DICT_ERR_NONE, "OK");
+
+       } else if (reply[0] == '-') {
+         if (msg_verbose) {
+           msg_info("%s: user not found for [%s] from %s", myname,
+                    key, dict_whoson->dict.name);
+         }
+         RETURN(DICT_ERR_NONE, 0);
+
+       } else if (reply[0] == '*') {
+         msg_warn("%s: read whoson map reply from %s: %.100s", myname,
+                  dict_whoson->dict.name, printable(reply, '?'));
+         RETURN(DICT_WHOSON_ERROR, 0);
+       } else {
+         msg_warn("%s: read whoson map reply from %s: bad sequence",
+                  myname, dict_whoson->dict.name);
+         dict_whoson_disconnect(dict_whoson);
+         RETURN(DICT_WHOSON_ERROR, 0);
+       }
+      } else {
+       msg_warn("%s: read whoson map reply from %s: unexpected EOF (%m)",
+                myname, dict_whoson->dict.name);
+       dict_whoson_disconnect(dict_whoson);
+      }
+
+    }
+
+      /*
+       * Try to connect a limited number of times before giving up.
+       */
+      if (++tries >= DICT_WHOSON_MAXTRY)
+       RETURN(DICT_WHOSON_ERROR, 0);
+      
+      /*
+       * Sleep between attempts, instead of hammering the server.
+       */
+      sleep(1);
+
+  }
+  
+}
+
+/* dict_whoson_close - close whoson MAP */
+
+static void dict_whoson_close(DICT *dict) {
+  DICT_WHOSON *dict_whoson = (DICT_WHOSON *) dict;
+
+  if (dict_whoson->fp)
+    (void) vstream_fclose(dict_whoson->fp);
+  if (dict_whoson->input)
+    vstring_free(dict_whoson->input);
+  if (dict_whoson->dummy)
+    vstring_free(dict_whoson->dummy);
+  dict_free(dict);
+}
+
+/* dict_whoson_open - open whoson MAP */
+
+DICT    *dict_whoson_open(const char *map, int unused_flags, int dict_flags)
+{
+  DICT_WHOSON *dict_whoson;
+  dict_errno = 0;
+  dict_whoson = (DICT_WHOSON *) dict_alloc(DICT_TYPE_WHOSON, map,
+                                       sizeof(*dict_whoson));
+  dict_whoson->dict.lookup = dict_whoson_lookup;
+  dict_whoson->input = dict_whoson->dummy = 0;
+  dict_whoson->dict.flags = dict_flags & ~DICT_FLAG_FIXED;
+  dict_whoson->dict.close = dict_whoson_close;
+  dict_whoson->fp = 0;
+  return (DICT_DEBUG(&dict_whoson->dict));
+}
diff -uNr ../postfix-2.1.4.orig/src/util/dict_whoson.h ./src/util/dict_whoson.h
--- ../postfix-2.1.4.orig/src/util/dict_whoson.h        1969-12-31 16:00:00.000000000 
-0800
+++ ./src/util/dict_whoson.h    2004-07-24 16:29:21.654278848 -0700
@@ -0,0 +1,37 @@
+#ifndef _DICT_WHOSON_H_INCLUDED_
+#define _DICT_WHOSON_H_INCLUDED_
+
+/*++
+/* NAME
+/*     dict_whoson 3h
+/* SUMMARY
+/*     dictionary manager interface to whoson-based lookup tables
+/* SYNOPSIS
+/*     #include <dict_whoson.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <dict.h>
+
+ /*
+  * External interface.
+  */
+#define DICT_TYPE_WHOSON       "whoson"
+
+extern DICT *dict_whoson_open(const char *, int, int);
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif

Reply via email to