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