]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.5-20080107
authorWietse Venema <wietse@porcupine.org>
Mon, 7 Jan 2008 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:33:48 +0000 (06:33 +0000)
23 files changed:
postfix/HISTORY
postfix/RELEASE_NOTES
postfix/WISHLIST
postfix/html/master.5.html
postfix/man/man5/master.5
postfix/proto/master
postfix/src/cleanup/cleanup.h
postfix/src/cleanup/cleanup_milter.c
postfix/src/cleanup/cleanup_state.c
postfix/src/global/mail_version.h
postfix/src/master/master.h
postfix/src/master/master_listen.c
postfix/src/master/master_proto.h
postfix/src/master/master_wakeup.c
postfix/src/util/Makefile.in
postfix/src/util/connect.h
postfix/src/util/listen.h
postfix/src/util/sys_defs.h
postfix/src/util/trigger.h
postfix/src/util/unix_connect.c
postfix/src/util/upass_connect.c [new file with mode: 0644]
postfix/src/util/upass_trigger.c [new file with mode: 0644]
postfix/src/xsasl/xsasl_dovecot_server.c

index d30cc79946939309db915f764fbced377c3fbb46..b0787657c5175e7365bb5b1712fa54a7d3467125 100644 (file)
@@ -14083,3 +14083,23 @@ Apologies for any names omitted.
        Bugfix: the Milter client did not replace the Postfix-specific
        form for unknown host names by the Sendmail-specific form.
        File: milter/milter8.c.
+
+       Cleanup: when a cleanup milter reports a problem don't log
+       generic "4.3.0 Sevice unavailable", but log the text for
+       the actual error. File: cleanup/cleanup_milter.c.
+
+20080104
+
+       Workaround: minor change to the Dovecot AUTH request to
+       prevent dovecot-auth memory wastage. Timo Sirainen.  File:
+       xsasl/xsasl_dovecot_server.c.
+
+20070807
+
+       Feature (experimental release only): new "pass" service
+       type (in addition to "inet", "unix" and "fifo").  The "pass"
+       service type supports front-end daemons that accept all
+       inbound connections and that permit only well-behaved clients
+       to talk to the MTA. This service type had been sitting in
+       the master daemon for years but was disabled by default.
+       Files: util/upass_connect.c, util/upass_trigger.c.
index c953a33dd79c6d8a4110b5326cfd434235f56fb4..cc1d9e95dac126d422817b4e26a1bed033fcf078 100644 (file)
@@ -11,6 +11,16 @@ instead, a new snapshot is released.
 The mail_release_date configuration parameter (format: yyyymmdd)
 specifies the release date of a stable release or snapshot release.
 
+Major changes with Postfix snapshot 20080107
+============================================
+
+New "pass" service type in master.cf.  Written years ago, this
+allows a front-end daemon to accept all connections from the network,
+and forward only those from well-behaved clients to Postfix. Since
+this uses file descriptor passing, it imposes no overhead once a
+connection is handed over to Postfix. This is available in the
+experimental release only. See master(5) for a few details.
+
 Incompatibility with Postfix snapshot 20071224
 ==============================================
 
index 3302948b55c5eface84eaea0b5e226d873546d2b..179fbcba1cf0aeb3cebc067273058817e9b2dc22 100644 (file)
@@ -1,9 +1,6 @@
 Wish list:
 
-       Milter client: send [ipaddress] instead of "unknown".
-
-       The cleanup server should report "file too large" milter
-       errors as permanent errors.
+       Consolidate duplicated code in {inet,unix,upass}_trigger.c.
 
        In the SMTP client, handle 421 replies in smtp_loop() by
        having the input function raise a flag after detecting 421
index a527cc44f442e65109f4addedd2259eabb6748f7..68fe8dc191acadc0f6d8bb79e7f5e24db6c32393 100644 (file)
@@ -109,44 +109,57 @@ MASTER(5)                                                            MASTER(5)
                      trolled with the <b><a href="postconf.5.html#queue_directory">queue_directory</a></b>  configura-
                      tion parameter in <a href="postconf.5.html">main.cf</a>).
 
+              <b>pass</b>   The service listens on a UNIX-domain socket,
+                     receives one open connection (file  descrip-
+                     tor  passing) per connection request, and is
+                     accessible to local clients only.
+
+                     This feature is not part of the stable Post-
+                     fix release.
+
+                     The  service  name is a pathname relative to
+                     the Postfix queue directory  (pathname  con-
+                     trolled  with the <b><a href="postconf.5.html#queue_directory">queue_directory</a></b> configura-
+                     tion parameter in <a href="postconf.5.html">main.cf</a>).
+
        <b>Private (default: y)</b>
-              Whether  or  not  access  is restricted to the mail
-              system.  Internet (type  <b>inet</b>)  services  can't  be
+              Whether or not access is  restricted  to  the  mail
+              system.   Internet  (type  <b>inet</b>)  services can't be
               private.
 
        <b>Unprivileged (default: y)</b>
               Whether the service runs with root privileges or as
-              the owner of the Postfix system (the owner name  is
+              the  owner of the Postfix system (the owner name is
               controlled by the <b><a href="postconf.5.html#mail_owner">mail_owner</a></b> configuration variable
               in the <a href="postconf.5.html">main.cf</a> file).
 
-              The <a href="local.8.html"><b>local</b>(8)</a>,  <a href="pipe.8.html"><b>pipe</b>(8)</a>,  <a href="spawn.8.html"><b>spawn</b>(8)</a>,  and  <a href="virtual.8.html"><b>virtual</b>(8)</a>
+              The  <a href="local.8.html"><b>local</b>(8)</a>,  <a href="pipe.8.html"><b>pipe</b>(8)</a>,  <a href="spawn.8.html"><b>spawn</b>(8)</a>,  and <a href="virtual.8.html"><b>virtual</b>(8)</a>
               daemons require privileges.
 
        <b>Chroot (default: y)</b>
-              Whether  or  not  the  service runs chrooted to the
+              Whether or not the service  runs  chrooted  to  the
               mail queue directory (pathname is controlled by the
-              <b><a href="postconf.5.html#queue_directory">queue_directory</a></b>   configuration   variable  in  the
+              <b><a href="postconf.5.html#queue_directory">queue_directory</a></b>  configuration  variable   in   the
               <a href="postconf.5.html">main.cf</a> file).
 
               Chroot  should  not  be  used  with  the  <a href="local.8.html"><b>local</b>(8)</a>,
-              <a href="pipe.8.html"><b>pipe</b>(8)</a>,    <a href="spawn.8.html"><b>spawn</b>(8)</a>,   and   <a href="virtual.8.html"><b>virtual</b>(8)</a>   daemons.
-              Although the <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server can  run  chrooted,
+              <a href="pipe.8.html"><b>pipe</b>(8)</a>,   <a href="spawn.8.html"><b>spawn</b>(8)</a>,   and   <a href="virtual.8.html"><b>virtual</b>(8)</a>    daemons.
+              Although  the  <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server can run chrooted,
               doing so defeats most of the purpose of having that
               service in the first place.
 
               The files in the examples/chroot-setup subdirectory
               of the Postfix source archive show set up a Postfix
-              chroot environment on a  variety  of  systems.  See
-              also  <a href="BASIC_CONFIGURATION_README.html">BASIC_CONFIGURATION_README</a> for issues related
+              chroot  environment  on  a  variety of systems. See
+              also <a href="BASIC_CONFIGURATION_README.html">BASIC_CONFIGURATION_README</a> for issues  related
               to running daemons chrooted.
 
        <b>Wake up time (default: 0)</b>
-              Automatically wake up the named service  after  the
-              specified  number of seconds. The wake up is imple-
-              mented by connecting to the service and  sending  a
-              wake  up  request.   A  ? at the end of the wake-up
-              time field requests that no wake up events be  sent
+              Automatically  wake  up the named service after the
+              specified number of seconds. The wake up is  imple-
+              mented  by  connecting to the service and sending a
+              wake up request.  A ? at the  end  of  the  wake-up
+              time  field requests that no wake up events be sent
               before the first time a service is used.  Specify 0
               for no automatic wake up.
 
@@ -154,59 +167,59 @@ MASTER(5)                                                            MASTER(5)
               a wake up timer.
 
        <b>Process limit (default: $<a href="postconf.5.html#default_process_limit">default_process_limit</a>)</b>
-              The  maximum  number  of processes that may execute
+              The maximum number of processes  that  may  execute
               this  service  simultaneously.  Specify  0  for  no
               process count limit.
 
               NOTE: Some Postfix services must be configured as a
-              single-process service (for example,  <a href="qmgr.8.html"><b>qmgr</b>(8)</a>)  and
-              some  services  must  be configured with no process
+              single-process  service  (for example, <a href="qmgr.8.html"><b>qmgr</b>(8)</a>) and
+              some services must be configured  with  no  process
               limit (for example, <a href="cleanup.8.html"><b>cleanup</b>(8)</a>).  These limits must
               not be changed.
 
        <b>Command name + arguments</b>
-              The  command  to  be executed.  Characters that are
-              special to the shell such as "&gt;"  or  "|"  have  no
-              special  meaning here, and quotes cannot be used to
+              The command to be executed.   Characters  that  are
+              special  to  the  shell  such as "&gt;" or "|" have no
+              special meaning here, and quotes cannot be used  to
               protect arguments containing whitespace.
 
-              The command name is relative to the Postfix  daemon
+              The  command name is relative to the Postfix daemon
               directory  (pathname  is  controlled  by  the  <b><a href="postconf.5.html#daemon_directory">dae</a>-</b>
               <b><a href="postconf.5.html#daemon_directory">mon_directory</a></b> configuration variable).
 
-              The command argument syntax for  specific  commands
-              is  specified in the respective daemon manual page.
+              The  command  argument syntax for specific commands
+              is specified in the respective daemon manual  page.
 
-              The following command-line options  have  the  same
+              The  following  command-line  options have the same
               effect for all daemon programs:
 
-              <b>-D</b>     Run  the daemon under control by the command
+              <b>-D</b>     Run the daemon under control by the  command
                      specified with the <b><a href="postconf.5.html#debugger_command">debugger_command</a></b> variable
                      in  the  <a href="postconf.5.html">main.cf</a>  configuration  file.   See
                      <a href="DEBUG_README.html">DEBUG_README</a> for hints and tips.
 
               <b>-o</b> <i>name</i>=<i>value</i>
                      Override  the  named  <a href="postconf.5.html">main.cf</a>  configuration
-                     parameter.  The parameter value can refer to
+                     parameter. The parameter value can refer  to
                      other parameters as <i>$name</i> etc., just like in
                      <a href="postconf.5.html">main.cf</a>.  See <a href="postconf.5.html"><b>postconf</b>(5)</a> for syntax.
 
                      NOTE 1: do not specify whitespace around the
-                     "=".  In  parameter  values,  either   avoid
+                     "=".   In  parameter  values,  either  avoid
                      whitespace altogether, use commas instead of
-                     spaces,  or  consider  overrides  like   "-o
-                     name=$override_parameter"     with    $over-
+                     spaces,   or  consider  overrides  like  "-o
+                     name=$override_parameter"    with     $over-
                      ride_parameter set in <a href="postconf.5.html">main.cf</a>.
 
-                     NOTE 2: Over-zealous use of parameter  over-
-                     rides  makes  the Postfix configuration hard
-                     to understand and maintain.   At  a  certain
-                     point,  it might be easier to configure mul-
-                     tiple instances of Postfix, instead of  con-
+                     NOTE  2: Over-zealous use of parameter over-
+                     rides makes the Postfix  configuration  hard
+                     to  understand  and  maintain.  At a certain
+                     point, it might be easier to configure  mul-
+                     tiple  instances of Postfix, instead of con-
                      figuring  multiple  personalities  via  mas-
                      ter.cf.
 
-              <b>-v</b>     Increase the verbose logging level.  Specify
+              <b>-v</b>     Increase  the verbose logging level. Specify
                      multiple <b>-v</b> options to make a Postfix daemon
                      process increasingly verbose.
 
@@ -219,7 +232,7 @@ MASTER(5)                                                            MASTER(5)
        <a href="DEBUG_README.html">DEBUG_README</a>, Postfix debugging
 
 <b>LICENSE</b>
-       The  Secure  Mailer  license must be distributed with this
+       The Secure Mailer license must be  distributed  with  this
        software.
 
 <b>AUTHOR(S)</b>
index 7be2b2e8c72b5e7ae62caf1b808d440d5b29ba1a..2a787a23a4bab00c9b66b4c3f7ad6d58a44d3b1b 100644 (file)
@@ -98,6 +98,16 @@ streams sockets.
 The service listens on a FIFO (named pipe) and is accessible
 for local clients only.
 
+The service name is a pathname relative to the Postfix
+queue directory (pathname controlled with the \fBqueue_directory\fR
+configuration parameter in main.cf).
+.IP \fBpass\fR
+The service listens on a UNIX-domain socket, receives one
+open connection (file descriptor passing) per connection
+request, and is accessible to local clients only.
+
+This feature is not part of the stable Postfix release.
+
 The service name is a pathname relative to the Postfix
 queue directory (pathname controlled with the \fBqueue_directory\fR
 configuration parameter in main.cf).
index 5ee1c8079f5041c7d96b16daa6e8052252701db7..11f407933b959b0fc13cdb06348ab23203d0365f 100644 (file)
 #      The service name is a pathname relative to the Postfix
 #      queue directory (pathname controlled with the \fBqueue_directory\fR
 #      configuration parameter in main.cf).
+# .IP \fBpass\fR
+#      The service listens on a UNIX-domain socket, receives one
+#      open connection (file descriptor passing) per connection
+#      request, and is accessible to local clients only.
+#
+#      This feature is not part of the stable Postfix release.
+#
+#      The service name is a pathname relative to the Postfix
+#      queue directory (pathname controlled with the \fBqueue_directory\fR
+#      configuration parameter in main.cf).
 # .RE
 # .IP "\fBPrivate (default: y)\fR"
 #      Whether or not access is restricted to the mail system.
index d73058a8c6db1a2b2f1b966f628009a9eab9e6fa..500d31f5c009f4964ae396a7a265b4cfe084b925 100644 (file)
@@ -104,6 +104,7 @@ typedef struct CLEANUP_STATE {
     const char *client_port;           /* real or ersatz client */
     VSTRING *milter_ext_from;          /* externalized sender */
     VSTRING *milter_ext_rcpt;          /* externalized recipient */
+    VSTRING *milter_err_text;          /* milter call-back reply */
 
     /*
      * Support for Milter body replacement requests.
index 9a060326b7e677acaee7f68da95b553a0f55fe44..ed1adb8ff785f3286f5a2c42eb134804819257b6 100644 (file)
@@ -234,6 +234,7 @@ static void cleanup_milter_set_error(CLEANUP_STATE *state, int err)
 static const char *cleanup_milter_error(CLEANUP_STATE *state, int err)
 {
     const char *myname = "cleanup_milter_error";
+    CLEANUP_STAT_DETAIL *dp;
 
     /*
      * For consistency with error reporting within the milter infrastructure,
@@ -251,7 +252,11 @@ static const char *cleanup_milter_error(CLEANUP_STATE *state, int err)
        cleanup_milter_set_error(state, err);
     else if (CLEANUP_OUT_OK(state))
        msg_panic("%s: missing errno to error flag mapping", myname);
-    return ("451 4.3.0 Server internal error");
+    if (state->milter_err_text == 0)
+       state->milter_err_text = vstring_alloc(50);
+    dp = cleanup_stat_detail(state->errs);
+    return (STR(vstring_sprintf(state->milter_err_text,
+                               "%d %s %s", dp->smtp, dp->dsn, dp->text)));
 }
 
 /* cleanup_add_header - append message header */
index a69f9f7aa709e91b1063ad45a93e1a831cd4ce78..9e584a66078bad8e5a1b93162603bd8eccd2bed7 100644 (file)
@@ -117,6 +117,7 @@ CLEANUP_STATE *cleanup_state_alloc(VSTREAM *src)
     state->client_port = 0;
     state->milter_ext_from = 0;
     state->milter_ext_rcpt = 0;
+    state->milter_err_text = 0;
     state->free_regions = state->body_regions = state->curr_body_region = 0;
     return (state);
 }
@@ -168,6 +169,8 @@ void    cleanup_state_free(CLEANUP_STATE *state)
        vstring_free(state->milter_ext_from);
     if (state->milter_ext_rcpt)
        vstring_free(state->milter_ext_rcpt);
+    if (state->milter_err_text)
+       vstring_free(state->milter_err_text);
     cleanup_region_done(state);
     myfree((char *) state);
 }
index 89a103c265e918949abb9900352d73e469c59610..1d9229222faf63f1f301be311eff4fd885783f7c 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20071229"
+#define MAIL_RELEASE_DATE      "20080107"
 #define MAIL_VERSION_NUMBER    "2.5"
 
 #ifdef SNAPSHOT
index 0ed354d284f6e0677c61463deecb6b4a79f72e03..f1dcdda4ff904c068aec0e9fc3d107717028c8ae 100644 (file)
@@ -33,9 +33,6 @@ typedef struct MASTER_SERV {
     int     wakeup_time;               /* wakeup interval */
     int    *listen_fd;                 /* incoming requests */
     int     listen_fd_count;           /* nr of descriptors */
-#ifdef MASTER_SERV_TYPE_PASS
-    struct PASS_INFO *pass_info;       /* descriptor passing state */
-#endif
     union {
        struct {
            char   *port;               /* inet listen port */
@@ -78,7 +75,9 @@ typedef struct MASTER_SERV {
 #define MASTER_SERV_TYPE_UNIX  1       /* AF_UNIX domain socket */
 #define MASTER_SERV_TYPE_INET  2       /* AF_INET domain socket */
 #define MASTER_SERV_TYPE_FIFO  3       /* fifo (named pipe) */
-/*#define MASTER_SERV_TYPE_PASS        4       /* AF_UNIX domain socket */
+#ifdef SNAPSHOT                                /* see also master_proto.h */
+#define MASTER_SERV_TYPE_PASS  4       /* AF_UNIX domain socket */
+#endif
 
  /*
   * Default process management policy values. This is only the bare minimum.
index 984b5dc057b7e6e649d35957d422ade7933c8b78..50b9721775576a72caedd2b8532844d5720c7418 100644 (file)
@@ -136,8 +136,7 @@ void    master_listen_init(MASTER_SERV *serv)
        set_eugid(var_owner_uid, var_owner_gid);
        serv->listen_fd[0] =
            PASS_LISTEN(serv->name, serv->max_proc > var_proc_limit ?
-                       serv->max_proc : var_proc_limit, NON_BLOCKING,
-                       &(serv->pass_info));
+                       serv->max_proc : var_proc_limit, NON_BLOCKING);
        close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
        set_ugid(getuid(), getgid());
        break;
@@ -161,10 +160,6 @@ void    master_listen_cleanup(MASTER_SERV *serv)
      * listener. The 4.4BSD shutdown(2) man page promises an ENOTCONN error
      * when shutdown(2) is applied to a socket that is not connected.
      */
-#ifdef MASTER_SERV_TYPE_PASS
-    if (serv->type == MASTER_SERV_TYPE_PASS)
-       PASS_SHUTDOWN(&(serv->pass_info));
-#endif
     for (n = 0; n < serv->listen_fd_count; n++) {
        if (close(serv->listen_fd[n]) < 0)
            msg_warn("%s: close listener socket %d: %m",
index ca6fe0b241fb8ead045736feb11a0cfcd1e86067..a017b5a2649e17dc1eeb9af3c40fe3b1733e91c5 100644 (file)
@@ -15,7 +15,9 @@
 #define MASTER_XPORT_NAME_UNIX "unix"  /* local IPC */
 #define MASTER_XPORT_NAME_FIFO "fifo"  /* local IPC */
 #define MASTER_XPORT_NAME_INET "inet"  /* non-local IPC */
-/*#define MASTER_XPORT_NAME_PASS       "pass"  /* local IPC */
+#ifdef SNAPSHOT                                /* see also master.h */
+#define MASTER_XPORT_NAME_PASS "pass"  /* local IPC */
+#endif
 
  /*
   * Format of a status message sent by a child process to the process
index 8a431001f024bfaa5933b2b5f85d366d58ff7a5a..306514ede4c8ebb82bf0c7de7e82377d47a86dae 100644 (file)
@@ -106,8 +106,7 @@ static void master_wakeup_timer_event(int unused_event, char *context)
            break;
 #ifdef MASTER_SERV_TYPE_PASS
        case MASTER_SERV_TYPE_PASS:
-           /* Can't send data to a service that expects descriptors. */
-           status = 0;
+           status = PASS_TRIGGER(serv->name, &wakeup, sizeof(wakeup), BRIEFLY);
            break;
 #endif
 
index 5e8a6c47e73b299db06f7b6bf9faeba4fb853e05..475bcf749a2979660e5377e750ccda408dd09183 100644 (file)
@@ -30,7 +30,8 @@ SRCS  = alldig.c allprint.c argv.c argv_split.c attr_clnt.c attr_print0.c \
        username.c valid_hostname.c vbuf.c vbuf_print.c vstream.c \
        vstream_popen.c vstring.c vstring_vstream.c watchdog.c writable.c \
        write_buf.c write_wait.c sane_basename.c format_tv.c allspace.c \
-       allascii.c load_file.c killme_after.c vstream_tweak.c
+       allascii.c load_file.c killme_after.c vstream_tweak.c upass_connect.c \
+       upass_listen.c upass_trigger.c
 OBJS   = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
        attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
        attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
@@ -62,7 +63,8 @@ OBJS  = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
        username.o valid_hostname.o vbuf.o vbuf_print.o vstream.o \
        vstream_popen.o vstring.o vstring_vstream.o watchdog.o writable.o \
        write_buf.o write_wait.o sane_basename.o format_tv.o allspace.o \
-       allascii.o load_file.o killme_after.o vstream_tweak.o
+       allascii.o load_file.o killme_after.o vstream_tweak.o upass_connect.o \
+       upass_listen.o upass_trigger.o
 HDRS   = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
        chroot_uid.h cidr_match.h clean_env.h connect.h ctable.h dict.h \
        dict_cdb.h dict_cidr.h dict_db.h dict_dbm.h dict_env.h dict_ht.h \
@@ -1550,12 +1552,30 @@ unix_trigger.o: unix_trigger.c
 unsafe.o: safe.h
 unsafe.o: sys_defs.h
 unsafe.o: unsafe.c
+upass_connect.o: connect.h
+upass_connect.o: events.h
+upass_connect.o: iostuff.h
+upass_connect.o: msg.h
+upass_connect.o: mymalloc.h
+upass_connect.o: sane_connect.h
+upass_connect.o: sane_socketpair.h
+upass_connect.o: sys_defs.h
+upass_connect.o: timed_connect.h
+upass_connect.o: upass_connect.c
 upass_listen.o: iostuff.h
 upass_listen.o: listen.h
 upass_listen.o: msg.h
 upass_listen.o: sane_accept.h
 upass_listen.o: sys_defs.h
 upass_listen.o: upass_listen.c
+upass_trigger.o: connect.h
+upass_trigger.o: events.h
+upass_trigger.o: iostuff.h
+upass_trigger.o: msg.h
+upass_trigger.o: mymalloc.h
+upass_trigger.o: sys_defs.h
+upass_trigger.o: trigger.h
+upass_trigger.o: upass_trigger.c
 uppercase.o: stringops.h
 uppercase.o: sys_defs.h
 uppercase.o: uppercase.c
index 080b99c064a37826cb6ada39bb5ea36479889da8..40987dc727aeff5f03c8c74d1269f670458c3d70 100644 (file)
@@ -22,6 +22,7 @@
 extern int unix_connect(const char *, int, int);
 extern int inet_connect(const char *, int, int);
 extern int stream_connect(const char *, int, int);
+extern int upass_connect(const char *, int, int);
 
 /* LICENSE
 /* .ad
index f7e70db4c2441a494d84aab5ff865bdab81c91f1..8a9041547a36f9018fe4fcb3007cc71dee016c57 100644 (file)
@@ -24,7 +24,7 @@ extern int inet_listen(const char *, int, int);
 extern int fifo_listen(const char *, int, int);
 extern int stream_listen(const char *, int, int);
 
-#define upass_listen(path, mode, log) fifo_listen((path), (mode), (log))
+#define upass_listen(path, mode, log) unix_listen((path), (mode), (log))
 
 extern int inet_accept(int);
 extern int unix_accept(int);
index af3b1fd176ffaf48d4121e3a26685b897937c8f4..a43098de3e45c132f339bec5aa2021d89d623aa4 100644 (file)
@@ -1301,6 +1301,12 @@ extern int inet_pton(int, const char *, void *);
 #define LOCAL_RECV_FD  unix_recv_fd
 #endif
 
+#ifndef PASS_LISTEN
+#define PASS_LISTEN    upass_listen
+#define PASS_ACCEPT    upass_accept
+#define PASS_TRIGGER   upass_trigger
+#endif
+
 #if !defined (HAVE_SYS_NDIR_H) && !defined (HAVE_SYS_DIR_H) \
        && !defined (HAVE_NDIR_H)
 #define HAVE_DIRENT_H
index 1f15482298f7002d19df55214a4ee13f1d691788..bd3e45d4f3b3eecddaf2625a2344264a5450f72d 100644 (file)
@@ -18,6 +18,7 @@ extern int unix_trigger(const char *, const char *, ssize_t, int);
 extern int inet_trigger(const char *, const char *, ssize_t, int);
 extern int fifo_trigger(const char *, const char *, ssize_t, int);
 extern int stream_trigger(const char *, const char *, ssize_t, int);
+extern int upass_trigger(const char *, const char *, ssize_t, int);
 
 /* LICENSE
 /* .ad
index 402befb9085086beea2899f297681af51c6d20ef..68de86d32700ef8fe39872e153bab3c5cce77819 100644 (file)
@@ -79,7 +79,7 @@ int     unix_connect(const char *addr, int block_mode, int timeout)
      * Create a client socket.
      */
     if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
-       msg_fatal("socket: %m");
+       return (-1);
 
     /*
      * Timed connect.
diff --git a/postfix/src/util/upass_connect.c b/postfix/src/util/upass_connect.c
new file mode 100644 (file)
index 0000000..4efd837
--- /dev/null
@@ -0,0 +1,141 @@
+/*++
+/* NAME
+/*     upass_connect 3
+/* SUMMARY
+/*     connect to UNIX-domain file descriptor listener
+/* SYNOPSIS
+/*     #include <connect.h>
+/*
+/*     int     upass_connect(addr, block_mode, timeout)
+/*     const char *addr;
+/*     int     block_mode;
+/*     int     timeout;
+/* DESCRIPTION
+/*     upass_connect() connects to a file descriptor listener in
+/*     the UNIX domain at the specified address, sends one half
+/*     of a socketpair to the listener, and returns the other half
+/*     to the caller.
+/*
+/*     The file descriptor transporting connection is closed by
+/*     a background thread. Some kernels might otherwise discard
+/*     the descriptor before the server has received it.
+/*
+/*     Arguments:
+/* .IP addr
+/*     Null-terminated string with connection destination.
+/* .IP block_mode
+/*     Either NON_BLOCKING for a non-blocking socket, or BLOCKING for
+/*     blocking mode. This setting has no effect on the connection
+/*     establishment process.
+/* .IP timeout
+/*     Bounds the number of seconds that the operation may take. Specify
+/*     a value <= 0 to disable the time limit.
+/* DIAGNOSTICS
+/*     The result is -1 in case the connection could not be made.
+/*     Fatal errors: other system call failures.
+/* 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 interfaces. */
+
+#include <sys_defs.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <iostuff.h>
+#include <sane_connect.h>
+#include <connect.h>
+#include <timed_connect.h>
+#include <events.h>
+#include <mymalloc.h>
+#include <sane_socketpair.h>
+
+ /*
+  * Workaround for hostile kernels that don't support graceful shutdown.
+  */
+struct upass_connect {
+    int     fd;
+    char   *service;
+};
+
+/* upass_connect_event - disconnect from peer */
+
+static void upass_connect_event(int event, char *context)
+{
+    struct upass_connect *up = (struct upass_connect *) context;
+    static const char *myname = "upass_connect_event";
+
+    /*
+     * Disconnect.
+     */
+    if (event == EVENT_TIME)
+       msg_warn("%s: read timeout for service %s", myname, up->service);
+    event_disable_readwrite(up->fd);
+    event_cancel_timer(upass_connect_event, context);
+    if (close(up->fd) < 0)
+       msg_warn("%s: close %s: %m", myname, up->service);
+    myfree(up->service);
+    myfree((char *) up);
+}
+
+/* upass_connect - connect to UNIX-domain file descriptor listener */
+
+int     upass_connect(const char *addr, int block_mode, int timeout)
+{
+    struct upass_connect *up;
+    int     pair[2];
+    int     sock;
+
+    /*
+     * Connect.
+     */
+    if ((sock = unix_connect(addr, BLOCKING, timeout)) < 0)
+       return (-1);
+
+    /*
+     * Send one socket pair half to the server.
+     */
+#define OUR_HALF       0
+#define THEIR_HALF     1
+
+    if (sane_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) < 0) {
+       close(sock);
+       return (-1);
+    }
+    if (unix_send_fd(sock, pair[THEIR_HALF]) < 0) {
+       close(pair[THEIR_HALF]);
+       close(pair[OUR_HALF]);
+       close(sock);
+       return (-1);
+    }
+    close(pair[THEIR_HALF]);
+
+    /*
+     * Return the other socket pair half to the caller. Don't close the
+     * control socket just yet, but wait until the receiver closes it first.
+     * Otherwise, some hostile kernel might discard the socket that we just
+     * sent.
+     */
+    up = (struct upass_connect *) mymalloc(sizeof(*up));
+    up->fd = sock;
+    up->service = mystrdup(addr);
+    if (timeout > 0)
+       event_request_timer(upass_connect_event, (char *) up, timeout + 100);
+    event_enable_read(sock, upass_connect_event, (char *) up);
+    non_blocking(pair[OUR_HALF], block_mode);
+    return (pair[OUR_HALF]);
+}
diff --git a/postfix/src/util/upass_trigger.c b/postfix/src/util/upass_trigger.c
new file mode 100644 (file)
index 0000000..2532f2b
--- /dev/null
@@ -0,0 +1,131 @@
+/*++
+/* NAME
+/*     upass_trigger 3
+/* SUMMARY
+/*     wakeup UNIX-domain file descriptor listener
+/* SYNOPSIS
+/*     #include <trigger.h>
+/*
+/*     int     upass_trigger(service, buf, len, timeout)
+/*     const char *service;
+/*     const char *buf;
+/*     ssize_t len;
+/*     int     timeout;
+/* DESCRIPTION
+/*     upass_trigger() wakes up the named UNIX-domain server by sending
+/*     a brief connection to it and writing the named buffer.
+/*
+/*     The connection is closed by a background thread. Some kernels
+/*     cannot handle client-side disconnect before the server has
+/*     received the message.
+/*
+/*     Arguments:
+/* .IP service
+/*     Name of the communication endpoint.
+/* .IP buf
+/*     Address of data to be written.
+/* .IP len
+/*     Amount of data to be written.
+/* .IP timeout
+/*     Deadline in seconds. Specify a value <= 0 to disable
+/*     the time limit.
+/* DIAGNOSTICS
+/*     The result is zero in case of success, -1 in case of problems.
+/* SEE ALSO
+/*     upass_connect(3), UNIX-domain client
+/* 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 <sys/socket.h>
+#include <unistd.h>
+#include <string.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <connect.h>
+#include <iostuff.h>
+#include <mymalloc.h>
+#include <events.h>
+#include <trigger.h>
+
+struct upass_trigger {
+    int     fd;
+    char   *service;
+};
+
+/* upass_trigger_event - disconnect from peer */
+
+static void upass_trigger_event(int event, char *context)
+{
+    struct upass_trigger *up = (struct upass_trigger *) context;
+    static const char *myname = "upass_trigger_event";
+
+    /*
+     * Disconnect.
+     */
+    if (event == EVENT_TIME)
+       msg_warn("%s: read timeout for service %s", myname, up->service);
+    event_disable_readwrite(up->fd);
+    event_cancel_timer(upass_trigger_event, context);
+    if (close(up->fd) < 0)
+       msg_warn("%s: close %s: %m", myname, up->service);
+    myfree(up->service);
+    myfree((char *) up);
+}
+
+/* upass_trigger - wakeup UNIX-domain server */
+
+int     upass_trigger(const char *service, const char *buf, ssize_t len, int timeout)
+{
+    const char *myname = "upass_trigger";
+    struct upass_trigger *up;
+    int     fd;
+
+    if (msg_verbose > 1)
+       msg_info("%s: service %s", myname, service);
+
+    /*
+     * Connect...
+     */
+    if ((fd = upass_connect(service, BLOCKING, timeout)) < 0) {
+       if (msg_verbose)
+           msg_warn("%s: connect to %s: %m", myname, service);
+       return (-1);
+    }
+    close_on_exec(fd, CLOSE_ON_EXEC);
+
+    /*
+     * Stash away context.
+     */
+    up = (struct upass_trigger *) mymalloc(sizeof(*up));
+    up->fd = fd;
+    up->service = mystrdup(service);
+
+    /*
+     * Write the request...
+     */
+    if (write_buf(fd, buf, len, timeout) < 0
+       || write_buf(fd, "", 1, timeout) < 0)
+       if (msg_verbose)
+           msg_warn("%s: write to %s: %m", myname, service);
+
+    /*
+     * Wakeup when the peer disconnects, or when we lose patience.
+     */
+    if (timeout > 0)
+       event_request_timer(upass_trigger_event, (char *) up, timeout + 100);
+    event_enable_read(fd, upass_trigger_event, (char *) up);
+    return (0);
+}
index fa59fa7227d0adafe3cfb3e64d2f97bff7bab150..2e382f24a0e365a65a14118b94be61fe8e538a4b 100644 (file)
@@ -579,7 +579,7 @@ int     xsasl_dovecot_server_first(XSASL_SERVER *xp, const char *sasl_method,
        /* send the request */
        server->last_request_id = ++server->impl->request_id_counter;
        vstream_fprintf(server->impl->sasl_stream,
-                       "AUTH\t%u\t%s\tservice=%s",
+                       "AUTH\t%u\t%s\tservice=%s\tnologin",
                        server->last_request_id, sasl_method,
                        server->service);
        if (init_response) {