]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
snapshot-19990423
authorWietse Venema <wietse@porcupine.org>
Fri, 23 Apr 1999 05:00:00 +0000 (00:00 -0500)
committerWietse Venema <wietse@porcupine.org>
Thu, 17 Jan 2013 03:34:13 +0000 (22:34 -0500)
45 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/LDAP_README
postfix/RELEASE_NOTES
postfix/bounce/.indent.pro
postfix/cleanup/.indent.pro
postfix/conf/main.cf.default
postfix/dns/.indent.pro
postfix/fsstone/.indent.pro
postfix/global/.indent.pro
postfix/global/Makefile.in
postfix/global/mail_params.c
postfix/global/mail_params.h
postfix/global/mail_version.h
postfix/html/uce.html
postfix/local/.indent.pro
postfix/master/.indent.pro
postfix/pickup/.indent.pro
postfix/pipe/.indent.pro
postfix/postalias/.indent.pro
postfix/postcat/.indent.pro
postfix/postconf/.indent.pro
postfix/postconf/postconf.c
postfix/postdrop/.indent.pro
postfix/postfix/.indent.pro
postfix/postkick/.indent.pro
postfix/postlock/.indent.pro
postfix/postlog/.indent.pro
postfix/postmap/.indent.pro
postfix/postsuper/.indent.pro
postfix/qmgr/.indent.pro
postfix/sendmail/.indent.pro
postfix/showq/.indent.pro
postfix/smtp/.indent.pro
postfix/smtpd/.indent.pro
postfix/smtpd/smtpd_check.c
postfix/smtpstone/.indent.pro
postfix/trivial-rewrite/.indent.pro
postfix/util/.indent.pro
postfix/util/Makefile.in
postfix/util/clean_env.c [moved from postfix/global/clean_env.c with 96% similarity]
postfix/util/clean_env.h [moved from postfix/global/clean_env.h with 100% similarity]
postfix/util/dict_ldap.c
postfix/util/vstream.h
postfix/util/vstream_popen.c

index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 27c6d153e9fe3d513192bc898734f56548f5dbda..54133a830d8575302880754b8992a8e9bc8c6bb3 100644 (file)
@@ -2651,3 +2651,16 @@ Apologies for any names omitted.
        report as part of the first message segment, because users
        had trouble extracting the delivery error report from the
        attachment.
+
+19990423
+
+       Cleanup: the default junk mail reject code is now 554
+       (service unavailable) rather than 550 (user unknown).
+
+       Folded in the updated dict_ldap.c module by John Hensley,
+       Merit Network, USA.
+
+       Folded in the vstream_popen.c updates by Philip A.
+       Prindeville, Mirapoint, Inc., USA.  This copies a lot of
+       code from pipe_command(); the next step is to trim that
+       module.
index e07308c305d488993797134ed957c14d3003cb10..76d26eb0550b45c11a29d19aca239e53ebb985d6 100644 (file)
@@ -70,7 +70,7 @@ Defaults are given in parentheses:
     result_attribute (maildrop)
        The attribute Postfix will read from any directory entries
        returned by the lookup, to be resolved to an email address.
-               ldapsource_result = mailbox
+               ldapsource_result_attribute = mailbox
 
     bind (yes)
        Whether or not to bind to the LDAP server. Newer LDAP
@@ -185,6 +185,12 @@ NOTES AND THINGS TO THINK ABOUT
   Any performance reports will be much appreciated on the postfix-users
   list.
 
+  UPDATE: At Merit, I've seen over 150000 deliveries per day with no
+  noticeable delay from our OpenLDAP server. I'd now recommend not
+  resorting to the above unless you anticipate much more traffic than
+  that. It makes management of your directory less intuitive, which is
+  probably not worth the reduction in lookups.
+
 CREDITS
 =======
 
index 0211dafb98e6614601f1561135dbd11bd482b5e9..784b74480bc981455dba1b43a8cdd82ca6590bb4 100644 (file)
@@ -1,4 +1,4 @@
-Incompatible changes with snapshot-19990422:
+Incompatible changes with snapshot-19990423:
 ===========================================
 
 - If an address extension (+foo) matches a user's .forward+foo file
@@ -6,7 +6,7 @@ name, the +foo extension is no longer appended to recipient addresses
 listed in the .forward+foo file. This is more consistent with the
 way Postfix expands aliases.
 
-Major changes with snapshot-19990422:
+Major changes with snapshot-19990423:
 =====================================
 
 In addition to several little bugfixes, none related to security,
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 90ca4fb21b5d4f8c15cbf1c6cfeaf5b4b004a8fa..e12daa65607272e2e69a0b854d444e562c80d7b4 100644 (file)
@@ -1,5 +1,5 @@
 2bounce_notice_recipient = postmaster
-access_map_reject_code = 550
+access_map_reject_code = 554
 alias_database = hash:/etc/aliases
 alias_maps = hash:/etc/aliases
 allow_mail_to_commands = alias,forward
@@ -61,11 +61,11 @@ luser_relay =
 mail_name = Postfix
 mail_owner = postfix
 mail_spool_directory = /var/mail
-mail_version = Snapshot-19990422
+mail_version = Snapshot-19990423
 mailbox_command = 
 mailbox_transport = 
 maps_rbl_domains = rbl.maps.vix.com
-maps_rbl_reject_code = 550
+maps_rbl_reject_code = 554
 masquerade_domains = 
 masquerade_exceptions = 
 max_idle = 100
@@ -89,9 +89,9 @@ queue_run_delay = 1000
 recipient_canonical_maps = 
 recipient_delimiter = 
 recipient_feature_delimiter = 
-reject_code = 550
+reject_code = 554
 relay_domains = $mydestination, $virtual_maps
-relay_domains_reject_code = 550
+relay_domains_reject_code = 554
 relayhost = 
 relocated_maps = 
 sender_canonical_maps = 
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index ccf259c53280708bcef0331bb096738bbc61be33..bb618ef14b2087f9a1ed88175ec7d1fe5604adf9 100644 (file)
@@ -1,5 +1,5 @@
 SHELL  = /bin/sh
-SRCS   = been_here.c bounce.c canon_addr.c clean_env.c cleanup_strerror.c \
+SRCS   = been_here.c bounce.c canon_addr.c cleanup_strerror.c \
        config.c config_bool.c config_int.c config_str.c debug_peer.c \
        debug_process.c defer.c deliver_completed.c deliver_flock.c \
        deliver_request.c domain_list.c dot_lockfile.c file_id.c \
@@ -17,7 +17,7 @@ SRCS  = been_here.c bounce.c canon_addr.c clean_env.c cleanup_strerror.c \
        split_addr.c string_list.c sys_exits.c timed_ipc.c tok822_find.c \
        tok822_node.c tok822_parse.c tok822_resolve.c tok822_rewrite.c \
        tok822_tree.c clnt_stream.c deliver_pass.c config_raw.c
-OBJS   = been_here.o bounce.o canon_addr.o clean_env.o cleanup_strerror.o \
+OBJS   = been_here.o bounce.o canon_addr.o cleanup_strerror.o \
        config.o config_bool.o config_int.o config_str.o debug_peer.o \
        debug_process.o defer.o deliver_completed.o deliver_flock.o \
        deliver_request.o domain_list.o dot_lockfile.o file_id.o \
@@ -35,7 +35,7 @@ OBJS  = been_here.o bounce.o canon_addr.o clean_env.o cleanup_strerror.o \
        split_addr.o string_list.o sys_exits.o timed_ipc.o tok822_find.o \
        tok822_node.o tok822_parse.o tok822_resolve.o tok822_rewrite.o \
        tok822_tree.o clnt_stream.o deliver_pass.o config_raw.o
-HDRS   = been_here.h bounce.h canon_addr.h clean_env.h cleanup_user.h \
+HDRS   = been_here.h bounce.h canon_addr.h cleanup_user.h \
        config.h debug_peer.h debug_process.h defer.h deliver_completed.h \
        deliver_flock.h deliver_request.h domain_list.h dot_lockfile.h \
        file_id.h header_opts.h is_header.h mail_addr.h mail_addr_crunch.h \
@@ -238,10 +238,6 @@ canon_addr.o: ../include/vbuf.h
 canon_addr.o: ../include/mymalloc.h
 canon_addr.o: rewrite_clnt.h
 canon_addr.o: canon_addr.h
-clean_env.o: clean_env.c
-clean_env.o: ../include/sys_defs.h
-clean_env.o: ../include/msg.h
-clean_env.o: clean_env.h
 cleanup_strerror.o: cleanup_strerror.c
 cleanup_strerror.o: ../include/sys_defs.h
 cleanup_strerror.o: ../include/vstring.h
@@ -499,6 +495,7 @@ mail_params.o: ../include/sys_defs.h
 mail_params.o: ../include/msg.h
 mail_params.o: ../include/get_hostname.h
 mail_params.o: ../include/valid_hostname.h
+mail_params.o: ../include/stringops.h
 mail_params.o: mynetworks.h
 mail_params.o: config.h
 mail_params.o: mail_version.h
@@ -694,7 +691,7 @@ pipe_command.o: ../include/set_ugid.h
 pipe_command.o: ../include/argv.h
 pipe_command.o: mail_params.h
 pipe_command.o: mail_copy.h
-pipe_command.o: clean_env.h
+pipe_command.o: ../include/clean_env.h
 pipe_command.o: pipe_command.h
 pipe_command.o: ../include/exec_command.h
 pipe_command.o: sys_exits.h
index 5731a1c978af64631246a1a6597247ae282c388a..f7388814c2562d8ad03b5956db66a5c40fa8c491 100644 (file)
@@ -177,8 +177,7 @@ static const char *check_myhostname(void)
     name = get_hostname();
     if ((dot = strchr(name, '.')) == 0) {
        if ((domain = config_lookup_eval(VAR_MYDOMAIN)) == 0)
-           msg_fatal("My hostname %s is not a fully qualified name - "
-                     "set %s or %s in %s/main.cf",
+           msg_fatal("My hostname %s is not a fully qualified name - set %s or %s in %s/main.cf",
                      name, VAR_MYHOSTNAME, VAR_MYDOMAIN, var_config_dir);
        name = concatenate(name, ".", domain, (char *) 0);
     }
index 2c4a5280c5cc1fbdc09c6d35aef2b198e034ab87..9fef329bf530f436f56c4b0bff31178ab6fa6cb5 100644 (file)
@@ -706,7 +706,7 @@ extern char *var_etrn_checks;
 #define PERMIT_ALL             "permit"
 #define REJECT_ALL             "reject"
 #define VAR_REJECT_CODE                "reject_code"
-#define DEF_REJECT_CODE                550
+#define DEF_REJECT_CODE                554
 extern int var_reject_code;
 
 #define REJECT_UNKNOWN_CLIENT  "reject_unknown_client"
@@ -744,13 +744,13 @@ extern int var_unk_addr_code;
 
 #define CHECK_RELAY_DOMAINS    "check_relay_domains"
 #define VAR_RELAY_CODE         "relay_domains_reject_code"
-#define DEF_RELAY_CODE         550
+#define DEF_RELAY_CODE         554
 extern int var_relay_code;
 
 #define PERMIT_MX_BACKUP       "permit_mx_backup"
 
 #define VAR_ACCESS_MAP_CODE    "access_map_reject_code"
-#define DEF_ACCESS_MAP_CODE    550
+#define DEF_ACCESS_MAP_CODE    554
 extern int var_access_map_code;
 
 #define CHECK_CLIENT_ACL       "check_client_access"
@@ -761,7 +761,7 @@ extern int var_access_map_code;
 
 #define REJECT_MAPS_RBL                "reject_maps_rbl"
 #define VAR_MAPS_RBL_CODE      "maps_rbl_reject_code"
-#define DEF_MAPS_RBL_CODE      550
+#define DEF_MAPS_RBL_CODE      554
 extern int var_maps_rbl_code;
 
 #define VAR_MAPS_RBL_DOMAINS   "maps_rbl_domains"
index 5ed04d7c79cf23bc803d78424844cd18975de87c..d2702bd0d283fe83dcdd3763355ac21ddf2cee09 100644 (file)
@@ -15,7 +15,7 @@
   * Version of this program.
   */
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "Snapshot-19990422"
+#define DEF_MAIL_VERSION       "Snapshot-19990423"
 extern char *var_mail_version;
 
 /* LICENSE
index 4fd7560001543a0beee744a6cba588492edfe519..1f206e176551df99f2f8104e46641eb73627ebcb 100644 (file)
@@ -188,7 +188,7 @@ significant octets.  Reject the request if the result is <b>REJECT</b>
 or "[<b>45</b>]<i>XX text</i>". Permit the request if the result
 is anything else.  The <b>access_map_reject_code</b> parameter
 specifies the response code for <b>REJECT</b> results (default:
-<b>550</b>).
+<b>554</b>).
 
 <p>
 
@@ -198,7 +198,7 @@ specifies the response code for <b>REJECT</b> results (default:
 network address is listed under any of the domains listed in <a
 href="#maps_rbl_domains">$maps_rbl_domains</a>. The <b>
 maps_rbl_reject_code</b> parameter specifies the response code for
-rejected requests (default: <b>550</b>).
+rejected requests (default: <b>554</b>).
 
 <p>
 
@@ -333,7 +333,7 @@ or parent domains in the specified table.  Reject the request if
 the result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>". Permit
 the request when the result is anything else.  The
 <b>access_map_reject_code </b> parameter specifies the response
-code for <b>REJECT</b> results (default:  <b>550</b>).
+code for <b>REJECT</b> results (default:  <b>554</b>).
 
 <p>
 
@@ -420,7 +420,7 @@ parent domain, or <i>localpart</i>@. Reject the request if the
 result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>". Permit the
 request if the result is anything else.  The <b>access_map_reject_code
 </b> parameter specifies the result code for rejected requests
-(default: <b>550</b>).
+(default: <b>554</b>).
 
 <p>
 
@@ -519,7 +519,7 @@ client hostname matches <a href="#relay_domains">$relay_domains</a>,
 or when the resolved destination address matches <a href="#relay_domains">
 $relay_domains</a>, otherwise reject.  The <b>relay_domains_reject_code</b>
 parameter specifies the response code for rejected requests (default:
-<b>550</b>).
+<b>554</b>).
 
 <p>
 
@@ -542,7 +542,7 @@ address, parent domain, or <i>localpart</i>@. Reject the request
 if the result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>".
 Permit the request if the result is anything else.  The
 <b>access_map_reject_code </b> parameter specifies the result code
-for rejected requests (default: <b>550</b>).
+for rejected requests (default: <b>554</b>).
 
 <p>
 
@@ -661,7 +661,7 @@ in the ETRN command, or its parent domains. Reject the request if
 the result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>".  Permit
 the request if the result is anything else.  The <b>access_map_reject_code
 </b> parameter specifies the result code for rejected requests
-(default: <b>550</b>).
+(default: <b>554</b>).
 
 <p>
 
@@ -727,7 +727,7 @@ policy explicit.
 is useful at the end of a restriction list, to make the default
 policy explicit. The <b>reject_code</b> configuration parameter
 specifies the response code to rejected requests (default:
-<b>550</b>).
+<b>554</b>).
 
 </dl>
 
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index d6ec2e3cc0247327a615f4174dd70fb3e9681807..70df435fb2c776c396607a97ca61720d18400990 100644 (file)
@@ -168,8 +168,7 @@ static const char *check_myhostname(void)
     name = get_hostname();
     if ((mode & SHOW_DEFS) == 0 && (dot = strchr(name, '.')) == 0) {
        if ((domain = config_lookup_eval(VAR_MYDOMAIN)) == 0)
-           msg_fatal("My hostname %s is not a fully qualified name - "
-                     "set %s or %s in %s/main.cf",
+           msg_fatal("My hostname %s is not a fully qualified name - set %s or %s in %s/main.cf",
                      name, VAR_MYHOSTNAME, VAR_MYDOMAIN, var_config_dir);
        name = concatenate(name, ".", domain, (char *) 0);
     }
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 570b15e94e1f7ee539b856ba21fb2df92f05887a..976a8dfcdd805ac9f9b221a024439537cdb98dc6 100644 (file)
@@ -68,7 +68,7 @@
 /*     4xx or 5xx status code. Other numerical status codes are not
 /*     permitted. Allow the request otherwise. The
 /*     \fIaccess_map_reject_code\fR configuration parameter specifies the
-/*     reject status code (default: 550).
+/*     reject status code (default: 554).
 /* .IP "check_client_access maptype:mapname"
 /*     Look up the client host name or any of its parent domains, or
 /*     the client address or any network obtained by stripping octets
@@ -86,7 +86,7 @@
 /*     DNS zones below the domains listed in the "maps_rbl_domains"
 /*     configuration parameter. The \fImaps_rbl_reject_code\fR
 /*     configuration parameter specifies the reject status code
-/*     (default: 550).
+/*     (default: 554).
 /* .IP permit_naked_ip_address
 /*     Permit the use of a naked IP address (without enclosing [])
 /*     in HELO/EHLO commands.
 /*     recipient domain matches the \fIrelay_domains\fR configuration
 /*     parameter.  Reject the request otherwise.
 /*     The \fIrelay_domains_reject_code\fR configuration parameter specifies
-/*     the reject status code (default: 550).
+/*     the reject status code (default: 554).
 /* .IP permit_mx_backup
 /*     Allow the request when the local mail system is mail exchanger
 /*     for the recipient domain (this includes the case where the local
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 7dd2776b00e928040cdd6cd35cdb3cc113d90787..88212c9ce1891606672f7dbda7043f821be8ab57 100644 (file)
@@ -97,6 +97,7 @@
 -TUSER_ATTR
 -TVBUF
 -TVSTREAM
+-TVSTREAM_POPEN_ARGS
 -TVSTRING
 -TWAIT_STATUS_T
 -TWATCH_FD
index 74de770ad640569eb0f048cf3c890299ff39f34e..8a75f3f503d4a3dbab5dccfa1b6b6fdef21da160 100644 (file)
@@ -19,7 +19,8 @@ SRCS  = argv.c argv_split.c attr.c basename.c binhash.c chroot_uid.c \
        unsafe.c username.c valid_hostname.c vbuf.c vbuf_print.c \
        vstream.c vstream_popen.c vstring.c vstring_vstream.c writable.c \
        write_buf.c write_wait.c dict_unix.c dict_pcre.c stream_listen.c \
-       stream_connect.c stream_trigger.c dict_regexp.c watch_fd.c
+       stream_connect.c stream_trigger.c dict_regexp.c watch_fd.c \
+       clean_env.c
 OBJS   = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
        close_on_exec.o concatenate.o dict.o dict_db.o dict_dbm.o \
        dict_env.o dict_ht.o dict_ldap.o dict_ni.o dict_nis.o \
@@ -40,7 +41,8 @@ OBJS  = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
        unsafe.o username.o valid_hostname.o vbuf.o vbuf_print.o \
        vstream.o vstream_popen.o vstring.o vstring_vstream.o writable.o \
        write_buf.o write_wait.o dict_unix.o dict_pcre.o stream_listen.o \
-       stream_connect.o stream_trigger.o dict_regexp.o watch_fd.o
+       stream_connect.o stream_trigger.o dict_regexp.o watch_fd.o \
+       clean_env.o
 HDRS   = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \
        dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_ni.h dict_nis.h \
        dict_nisplus.h dir_forest.h events.h exec_command.h find_inet.h \
@@ -54,7 +56,7 @@ HDRS  = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \
        sigdelay.h 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 \
-       dict_unix.h dict_pcre.h dict_regexp.h watch_fd.h
+       dict_unix.h dict_pcre.h dict_regexp.h watch_fd.h clean_env.h
 TESTSRC        = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
        stream_test.c
 WARN   = -W -Wformat -Wimplicit -Wmissing-prototypes \
@@ -274,6 +276,10 @@ chroot_uid.o: chroot_uid.c
 chroot_uid.o: sys_defs.h
 chroot_uid.o: msg.h
 chroot_uid.o: chroot_uid.h
+clean_env.o: clean_env.c
+clean_env.o: sys_defs.h
+clean_env.o: msg.h
+clean_env.o: clean_env.h
 close_on_exec.o: close_on_exec.c
 close_on_exec.o: sys_defs.h
 close_on_exec.o: msg.h
@@ -802,10 +808,12 @@ vstream.o: vstream.h
 vstream_popen.o: vstream_popen.c
 vstream_popen.o: sys_defs.h
 vstream_popen.o: msg.h
-vstream_popen.o: binhash.h
 vstream_popen.o: exec_command.h
 vstream_popen.o: vstream.h
 vstream_popen.o: vbuf.h
+vstream_popen.o: argv.h
+vstream_popen.o: set_ugid.h
+vstream_popen.o: clean_env.h
 vstring.o: vstring.c
 vstring.o: sys_defs.h
 vstring.o: mymalloc.h
similarity index 96%
rename from postfix/global/clean_env.c
rename to postfix/util/clean_env.c
index 3086680c84dff764b63a70d4255443902115545f..8549332d38e1176de0de83268d28803da6962b9b 100644 (file)
 /* Utility library. */
 
 #include <msg.h>
-
-/* Global library. */
-
-#include "clean_env.h"
+#include <clean_env.h>
 
 /* clean_env - clean up the environment */
 
index 10dcc6cc9ee5b98ed773ad0813935d308ee4361d..32f1fa99736b12a3bdd6ccd952af2796521a3b27 100644 (file)
@@ -17,7 +17,7 @@
 /*     Arguments:
 /* .IP ldapsource
 /*     The prefix which will be used to obtain configuration parameters
-/*     for this search. If it's 'ldapone', the configuration variables below 
+/*     for this search. If it's 'ldapone', the configuration variables below
 /*     would look like 'ldapone_server_host', 'ldapone_search_base', and so
 /*     on in main.cf.
 /* .IP dummy
@@ -61,7 +61,7 @@
 /*     IBM T.J. Watson Research
 /*     P.O. Box 704
 /*     Yorktown Heights, NY 10532, USA
-/* 
+/*
 /*     John Hensley
 /*     Merit Network, Inc.
 /*     hensley@merit.edu
   * themselves, including their configuration file parameters.
   */
 
-/* 
+/*
  * structure containing all the configuration parameters for a given
  * LDAP source, plus its connection handle
  */
 typedef struct {
-    DICT    dict;                        /* generic member */
-    char    *ldapsource;
-    char    *server_host;
+    DICT    dict;                      /* generic member */
+    char   *ldapsource;
+    char   *server_host;
     int     server_port;
-    char    *search_base;
-    char    *query_filter;
-    char    *result_attribute;
+    char   *search_base;
+    char   *query_filter;
+    char   *result_attribute;
     int     bind;
-    char    *bind_dn;
-    char    *bind_pw;
+    char   *bind_dn;
+    char   *bind_pw;
     int     timeout;
-    LDAP    *ld;
+    LDAP   *ld;
 } DICT_LDAP;
 
  /*
@@ -133,14 +133,13 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
     char   *myname = "dict_ldap_lookup";
     DICT_LDAP *dict_ldap = (DICT_LDAP *) dict;
     static VSTRING *result;
-    int LDAP_UNBIND = 0;
-    LDAPMessage *res = 0; 
-    LDAPMessage *entry = 0; 
+    LDAPMessage *res = 0;
+    LDAPMessage *entry = 0;
     struct timeval tv;
     VSTRING *filter_buf = 0;
     char  **attr_values;
-    long i = 0, j = 0;
-    int rc = 0;
+    long    i = 0;
+    int     rc = 0;
     void    (*saved_alarm) (int);
 
     dict_errno = 0;
@@ -149,60 +148,61 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
      * Initialize.
      */
     if (result == 0)
-        result = vstring_alloc(2);
+       result = vstring_alloc(2);
 
-    vstring_strcpy(result,"");
+    vstring_strcpy(result, "");
 
     if (msg_verbose)
-        msg_info("%s: In dict_ldap_lookup", myname);
+       msg_info("%s: In dict_ldap_lookup", myname);
 
     if (dict_ldap->ld == 0) {
-        msg_warn("%s: no existing connection for ldapsource %s, reopening", 
-                 myname, dict_ldap->ldapsource);
-        if (msg_verbose)
-            msg_info("%s: connecting to server %s", myname, 
-                     dict_ldap->server_host);
-
-        if ((saved_alarm = signal(SIGALRM, dict_ldap_timeout)) == SIG_ERR)
-            msg_fatal("%s: signal: %m", myname);
-
-        alarm(dict_ldap->timeout);
-        if (setjmp(env) == 0)
-            dict_ldap->ld = ldap_open(dict_ldap->server_host, 
-                           (int) dict_ldap->server_port);
-        alarm(0);
-
-        if (signal(SIGALRM, saved_alarm) == SIG_ERR)
-            msg_fatal("%s: signal: %m", myname);
-
-        if (msg_verbose)
-            msg_info("%s: after ldap_open", myname);
-
-        if (dict_ldap->ld == 0) {
-            msg_fatal("%s: Unable to contact LDAP server %s",
-                     myname, dict_ldap->server_host);
-        } else {
-            /*
-             * If this server requires us to bind, do so.
-             */
-            if (dict_ldap->bind) {
-                if (msg_verbose)
-                    msg_info("%s: about to bind: server %s, base %s", myname, 
-                         dict_ldap->server_host, dict_ldap->search_base);
-
-                rc = ldap_bind_s(dict_ldap->ld, dict_ldap->search_base, NULL, 
-                                 LDAP_AUTH_SIMPLE);
-                if (rc != LDAP_SUCCESS) {
-                    msg_fatal("%s: Unable to bind with search base %s at server %s (%d -- %s): ", myname, dict_ldap->search_base, dict_ldap->server_host, rc, ldap_err2string(rc));
-                } else {
-                    if (msg_verbose)
-                        msg_info("%s: Successful bind to server %s with search base %s(%d -- %s): ", myname, dict_ldap->search_base, dict_ldap->server_host, rc, ldap_err2string(rc));
-                }
-            }
-            if (msg_verbose)
-                msg_info("%s: cached connection handle for LDAP source %s",
-                         myname, dict_ldap->ldapsource);
-        }
+       msg_warn("%s: no existing connection for ldapsource %s, reopening",
+                myname, dict_ldap->ldapsource);
+       if (msg_verbose)
+           msg_info("%s: connecting to server %s", myname,
+                    dict_ldap->server_host);
+
+       if ((saved_alarm = signal(SIGALRM, dict_ldap_timeout)) == SIG_ERR)
+           msg_fatal("%s: signal: %m", myname);
+
+       alarm(dict_ldap->timeout);
+       if (setjmp(env) == 0)
+           dict_ldap->ld = ldap_open(dict_ldap->server_host,
+                                     (int) dict_ldap->server_port);
+       alarm(0);
+
+       if (signal(SIGALRM, saved_alarm) == SIG_ERR)
+           msg_fatal("%s: signal: %m", myname);
+
+       if (msg_verbose)
+           msg_info("%s: after ldap_open", myname);
+
+       if (dict_ldap->ld == 0) {
+           msg_fatal("%s: Unable to contact LDAP server %s",
+                     myname, dict_ldap->server_host);
+       } else {
+
+           /*
+            * If this server requires us to bind, do so.
+            */
+           if (dict_ldap->bind) {
+               if (msg_verbose)
+                   msg_info("%s: about to bind: server %s, base %s", myname,
+                            dict_ldap->server_host, dict_ldap->search_base);
+
+               rc = ldap_bind_s(dict_ldap->ld, dict_ldap->search_base, NULL,
+                                LDAP_AUTH_SIMPLE);
+               if (rc != LDAP_SUCCESS) {
+                   msg_fatal("%s: Unable to bind with search base %s at server %s (%d -- %s): ", myname, dict_ldap->search_base, dict_ldap->server_host, rc, ldap_err2string(rc));
+               } else {
+                   if (msg_verbose)
+                       msg_info("%s: Successful bind to server %s with search base %s(%d -- %s): ", myname, dict_ldap->search_base, dict_ldap->server_host, rc, ldap_err2string(rc));
+               }
+           }
+           if (msg_verbose)
+               msg_info("%s: cached connection handle for LDAP source %s",
+                        myname, dict_ldap->ldapsource);
+       }
     }
 
     /*
@@ -214,47 +214,51 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
     vstring_sprintf(filter_buf, dict_ldap->query_filter, name);
 
     if (msg_verbose)
-        msg_info("%s: searching with filter %s", myname, 
-                 vstring_str(filter_buf));
-
-    if ((rc=ldap_search_st(dict_ldap->ld, dict_ldap->search_base, 
-                           LDAP_SCOPE_SUBTREE,
-                           vstring_str(filter_buf), 
-                           0, 0, &tv, &res)) != LDAP_SUCCESS) {
-
-        msg_info("%s: right after search", myname);
-
-        msg_warn("%s: Unable to search base %s at server %s (%d -- %s): ", 
-                 myname, dict_ldap->search_base, dict_ldap->server_host, rc, 
-                 ldap_err2string(rc));
-        LDAP_UNBIND = 1;
+       msg_info("%s: searching with filter %s", myname,
+                vstring_str(filter_buf));
+
+    if ((rc = ldap_search_st(dict_ldap->ld, dict_ldap->search_base,
+                            LDAP_SCOPE_SUBTREE,
+                            vstring_str(filter_buf),
+                            0, 0, &tv, &res)) != LDAP_SUCCESS) {
+
+       ldap_unbind(dict_ldap->ld);
+       dict_ldap->ld = 0;
+       if (msg_verbose)
+           msg_info("%s: freed connection handle for LDAP source %s", myname, dict_ldap->ldapsource);
+       msg_fatal("%s: Unable to search base %s at server %s (%d -- %s): ",
+                 myname, dict_ldap->search_base, dict_ldap->server_host, rc,
+                 ldap_err2string(rc));
 
     } else {
-        /*
-         * Extract the requested result_attribute.
-         */
-        if (msg_verbose)
-            msg_info("%s: search completed", myname);
-
-        if ((entry = ldap_first_entry(dict_ldap->ld, res)) != 0) {
-            attr_values = ldap_get_values(dict_ldap->ld, entry, 
-                                          dict_ldap->result_attribute);
-            /*
-             * Append each returned address to the result list.
-             */
-            while (attr_values[i]) {
-                if (VSTRING_LEN(result) > 0)
-                    vstring_strcat(result, ",");
-                vstring_strcat(result, attr_values[i]);
-                i++;
-            }
-            ldap_value_free(attr_values);
-            if (msg_verbose)
-                msg_info("%s: search returned: %s", myname, vstring_str(result));
-        } else {
-            if (msg_verbose)
-                msg_info("%s: search returned nothing", myname);
-        }
+
+       /*
+        * Extract the requested result_attribute.
+        */
+       if (msg_verbose)
+           msg_info("%s: search found %d", myname,
+                    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)) {
+           attr_values = ldap_get_values(dict_ldap->ld, entry,
+                                         dict_ldap->result_attribute);
+           if (attr_values == NULL) {
+               msg_warn("%s: entry doesn't have any values for %s", myname, dict_ldap->result_attribute);
+               continue;
+           }
+
+           /*
+            * Append each returned address to the result list.
+            */
+           for (i = 0; attr_values[i] != NULL; i++) {
+               if (VSTRING_LEN(result) > 0)
+                   vstring_strcat(result, ",");
+               vstring_strcat(result, attr_values[i]);
+           }
+           ldap_value_free(attr_values);
+       }
+       if (msg_verbose)
+           msg_info("%s: search returned: %s", myname, vstring_str(result));
     }
 
     /*
@@ -262,28 +266,18 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
      * perform the query.
      */
     if (res != 0)
-        ldap_msgfree(res);
+       ldap_msgfree(res);
     else
-        dict_errno = 1;
-    if (LDAP_UNBIND == 1) {
-        /* 
-         * there was an LDAP problem; free the handle
-         */
-        ldap_unbind(dict_ldap->ld);
-        dict_ldap->ld = 0;
-        if (msg_verbose)
-            msg_info("%s: freed connection handle for LDAP source %s", 
-                     myname, dict_ldap->ldapsource);
-    }
+       dict_errno = 1;
     if (filter_buf != 0)
-        vstring_free(filter_buf);
-    return (entry != 0 ? vstring_str(result) : 0);
+       vstring_free(filter_buf);
+    return (VSTRING_LEN(result) > 0 ? vstring_str(result) : 0);
 }
 
 /* dict_ldap_update - add or update database entry */
 
 static void dict_ldap_update(DICT *dict, const char *unused_name,
-                                     const char *unused_value)
+                                    const char *unused_value)
 {
     msg_fatal("dict_ldap_update: operation not implemented");
 }
@@ -296,7 +290,7 @@ static void dict_ldap_close(DICT *dict)
     DICT_LDAP *dict_ldap = (DICT_LDAP *) dict;
 
     if (dict_ldap->ld)
-        ldap_unbind(dict_ldap->ld);
+       ldap_unbind(dict_ldap->ld);
 
     myfree(dict_ldap->ldapsource);
     myfree(dict_ldap->server_host);
@@ -305,7 +299,7 @@ static void dict_ldap_close(DICT *dict)
     myfree(dict_ldap->result_attribute);
     myfree(dict_ldap->bind_dn);
     myfree(dict_ldap->bind_pw);
-    myfree((char *)dict_ldap);
+    myfree((char *) dict_ldap);
 }
 
 /* dict_ldap_open - create association with data base */
@@ -315,7 +309,7 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
     char   *myname = "dict_ldap_open";
     DICT_LDAP *dict_ldap;
     VSTRING *config_param;
-    int rc = 0;
+    int     rc = 0;
     void    (*saved_alarm) (int);
 
     dict_ldap = (DICT_LDAP *) mymalloc(sizeof(*dict_ldap));
@@ -326,129 +320,132 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
     dict_ldap->dict.flags = dict_flags | DICT_FLAG_FIXED;
 
     if (msg_verbose)
-        msg_info("%s: using LDAP source %s", myname, ldapsource);
+       msg_info("%s: using LDAP source %s", myname, ldapsource);
 
     dict_ldap->ldapsource = mystrdup(ldapsource);
 
     config_param = vstring_alloc(15);
     vstring_sprintf(config_param, "%s_server_host", ldapsource);
 
-    dict_ldap->server_host = 
-        mystrdup((char *)get_config_str(vstring_str(config_param), 
-                 "localhost",0,0));
+    dict_ldap->server_host =
+       mystrdup((char *) get_config_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);
+       msg_info("%s: %s is %s", myname, vstring_str(config_param),
+                dict_ldap->server_host);
 
-    /* get configured value of "ldapsource_server_port"; default to 
-    /* LDAP_PORT (389) */
+    /*
+     * get configured value of "ldapsource_server_port"; default to LDAP_PORT
+     * (389)
+     */
     vstring_sprintf(config_param, "%s_server_port", ldapsource);
-    dict_ldap->server_port = 
-        get_config_int(vstring_str(config_param),LDAP_PORT,0,0);
+    dict_ldap->server_port =
+       get_config_int(vstring_str(config_param), LDAP_PORT, 0, 0);
     if (msg_verbose)
-        msg_info("%s: %s is %d", myname, vstring_str(config_param), 
-                 dict_ldap->server_port);
+       msg_info("%s: %s is %d", myname, vstring_str(config_param),
+                dict_ldap->server_port);
 
     vstring_sprintf(config_param, "%s_search_base", ldapsource);
-    dict_ldap->search_base = 
-        mystrdup((char *)get_config_str(vstring_str(config_param),"",0,0));
+    dict_ldap->search_base =
+       mystrdup((char *) get_config_str(vstring_str(config_param), "", 0, 0));
     if (msg_verbose)
-        msg_info("%s: %s is %s", myname, vstring_str(config_param), 
-                 dict_ldap->search_base);
+       msg_info("%s: %s is %s", myname, vstring_str(config_param),
+                dict_ldap->search_base);
 
     /* get configured value of "ldapsource_timeout"; default to 10 */
     vstring_sprintf(config_param, "%s_timeout", ldapsource);
-    dict_ldap->timeout = get_config_int(config_param,10,0,0);
+    dict_ldap->timeout = get_config_int(config_param, 10, 0, 0);
     if (msg_verbose)
-        msg_info("%s: %s is %d", myname, vstring_str(config_param), 
-                 dict_ldap->timeout);
+       msg_info("%s: %s is %d", myname, vstring_str(config_param),
+                dict_ldap->timeout);
 
     vstring_sprintf(config_param, "%s_query_filter", ldapsource);
-    dict_ldap->query_filter = 
-        mystrdup((char *)get_config_str(vstring_str(config_param),
-                 "(mailacceptinggeneralid=%s)",0,0));
+    dict_ldap->query_filter =
+       mystrdup((char *) get_config_str(vstring_str(config_param),
+                                     "(mailacceptinggeneralid=%s)", 0, 0));
     if (msg_verbose)
-        msg_info("%s: %s is %s", myname, vstring_str(config_param), 
-                 dict_ldap->query_filter);
+       msg_info("%s: %s is %s", myname, vstring_str(config_param),
+                dict_ldap->query_filter);
 
     vstring_sprintf(config_param, "%s_result_attribute", ldapsource);
-    dict_ldap->result_attribute = 
-        mystrdup((char *)get_config_str(vstring_str(config_param),
-                                        "maildrop",0,0));
+    dict_ldap->result_attribute =
+       mystrdup((char *) get_config_str(vstring_str(config_param),
+                                        "maildrop", 0, 0));
     if (msg_verbose)
-        msg_info("%s: %s is %s", myname, vstring_str(config_param), 
-                 dict_ldap->result_attribute);
+       msg_info("%s: %s is %s", myname, vstring_str(config_param),
+                dict_ldap->result_attribute);
 
     /* get configured value of "ldapsource_bind"; default to true */
     vstring_sprintf(config_param, "%s_bind", ldapsource);
     dict_ldap->bind = get_config_bool(vstring_str(config_param), 1);
     if (msg_verbose)
-        msg_info("%s: %s is %d", myname, vstring_str(config_param), 
-                 dict_ldap->bind);
+       msg_info("%s: %s is %d", myname, vstring_str(config_param),
+                dict_ldap->bind);
 
     /* get configured value of "ldapsource_bind_dn"; default to "" */
     vstring_sprintf(config_param, "%s_bind_dn", ldapsource);
-    dict_ldap->bind_dn = 
-        mystrdup((char *)get_config_str(vstring_str(config_param),"",0,0));
+    dict_ldap->bind_dn =
+       mystrdup((char *) get_config_str(vstring_str(config_param), "", 0, 0));
     if (msg_verbose)
-        msg_info("%s: %s is %s", myname, vstring_str(config_param), 
-                 dict_ldap->bind_dn);
+       msg_info("%s: %s is %s", myname, vstring_str(config_param),
+                dict_ldap->bind_dn);
 
     /* get configured value of "ldapsource_bind_pw"; default to "" */
     vstring_sprintf(config_param, "%s_bind_pw", ldapsource);
-    dict_ldap->bind_pw = 
-        mystrdup((char *)get_config_str(vstring_str(config_param),"",0,0));
+    dict_ldap->bind_pw =
+       mystrdup((char *) get_config_str(vstring_str(config_param), "", 0, 0));
     if (msg_verbose)
-        msg_info("%s: %s is %s", myname, vstring_str(config_param), 
-                 dict_ldap->bind_pw);
+       msg_info("%s: %s is %s", myname, vstring_str(config_param),
+                dict_ldap->bind_pw);
 
-    /* 
+    /*
      * establish the connection to the LDAP server
      */
 
     if (msg_verbose)
-        msg_info("%s: connecting to server %s", myname, 
-                 dict_ldap->server_host);
+       msg_info("%s: connecting to server %s", myname,
+                dict_ldap->server_host);
 
     if ((saved_alarm = signal(SIGALRM, dict_ldap_timeout)) == SIG_ERR)
-        msg_fatal("%s: signal: %m", myname);
+       msg_fatal("%s: signal: %m", myname);
 
     alarm(dict_ldap->timeout);
     if (setjmp(env) == 0)
-        dict_ldap->ld = ldap_open(dict_ldap->server_host, 
-                       (int) dict_ldap->server_port);
+       dict_ldap->ld = ldap_open(dict_ldap->server_host,
+                                 (int) dict_ldap->server_port);
     alarm(0);
 
     if (signal(SIGALRM, saved_alarm) == SIG_ERR)
-        msg_fatal("%s: signal: %m", myname);
+       msg_fatal("%s: signal: %m", myname);
 
     if (msg_verbose)
-        msg_info("%s: after ldap_open", myname);
+       msg_info("%s: after ldap_open", myname);
 
     if (dict_ldap->ld == 0) {
-        msg_fatal("%s: Unable to contact LDAP server %s",
-                 myname, dict_ldap->server_host);
+       msg_fatal("%s: Unable to contact LDAP server %s",
+                 myname, dict_ldap->server_host);
     } else {
-        /*
-         * If this server requires us to bind, do so.
-         */
-        if (dict_ldap->bind) {
-            if (msg_verbose)
-                msg_info("%s: about to bind: server %s, base %s", myname, 
-                     dict_ldap->server_host, dict_ldap->search_base);
-
-            rc = ldap_bind_s(dict_ldap->ld, dict_ldap->search_base, NULL, 
-                             LDAP_AUTH_SIMPLE);
-            if (rc != LDAP_SUCCESS) {
-                msg_fatal("%s: Unable to bind with search base %s at server %s (%d -- %s): ", myname, dict_ldap->search_base, dict_ldap->server_host, rc, ldap_err2string(rc));
-            } else {
-                if (msg_verbose)
-                    msg_info("%s: Successful bind to server %s with search base %s(%d -- %s): ", myname, dict_ldap->search_base, dict_ldap->server_host, rc, ldap_err2string(rc));
-            }
-        }
-        if (msg_verbose)
-            msg_info("%s: cached connection handle for LDAP source %s",
-                     myname, dict_ldap->ldapsource);
+
+       /*
+        * If this server requires us to bind, do so.
+        */
+       if (dict_ldap->bind) {
+           if (msg_verbose)
+               msg_info("%s: about to bind: server %s, base %s", myname,
+                        dict_ldap->server_host, dict_ldap->search_base);
+
+           rc = ldap_bind_s(dict_ldap->ld, dict_ldap->search_base, NULL,
+                            LDAP_AUTH_SIMPLE);
+           if (rc != LDAP_SUCCESS) {
+               msg_fatal("%s: Unable to bind with search base %s at server %s (%d -- %s): ", myname, dict_ldap->search_base, dict_ldap->server_host, rc, ldap_err2string(rc));
+           } else {
+               if (msg_verbose)
+                   msg_info("%s: Successful bind to server %s with search base %s(%d -- %s): ", myname, dict_ldap->search_base, dict_ldap->server_host, rc, ldap_err2string(rc));
+           }
+       }
+       if (msg_verbose)
+           msg_info("%s: cached connection handle for LDAP source %s",
+                    myname, dict_ldap->ldapsource);
     }
 
     return (&dict_ldap->dict);
index 68c4fbe200a848d798b664ef6fe5aa3a3ecd1230..d67ee237731e31d527e1888535aa93c8e6bab0c5 100644 (file)
@@ -103,8 +103,20 @@ extern VSTREAM *vstream_printf(const char *,...);
 extern VSTREAM *vstream_fprintf(VSTREAM *, const char *,...);
 
 extern VSTREAM *vstream_popen(const char *, int);
+extern VSTREAM *vstream_popen_vargs(int,...);
 extern int vstream_pclose(VSTREAM *);
 
+#define vstream_ispipe(vp)     ((vp)->pid != 0)
+
+#define VSTREAM_POPEN_END      0       /* terminator */
+#define VSTREAM_POPEN_COMMAND  1       /* command is string */
+#define VSTREAM_POPEN_ARGV     2       /* command is array */
+#define VSTREAM_POPEN_UID      3       /* privileges */
+#define VSTREAM_POPEN_GID      4       /* privileges */
+#define VSTREAM_POPEN_ENV      5       /* extra environment */
+#define VSTREAM_POPEN_SHELL    6       /* alternative shell */
+#define VSTREAM_POPEN_WAITPID_FN 7     /* child catcher, waitpid() compat. */
+
 extern VSTREAM *vstream_vfprintf(VSTREAM *, const char *, va_list);
 
 extern int vstream_peek(VSTREAM *);
index d6cf60f3789c697298553ce197d4cab49539d84e..46116a19ea4ced36c2cb94e9ae360fd063c24674 100644 (file)
@@ -12,6 +12,9 @@
 /*
 /*     int     vstream_pclose(stream)
 /*     VSTREAM *stream;
+/*
+/*     VSTREAM *vstream_popen_vargs(key, value, ...)
+/*     int     key;
 /* DESCRIPTION
 /*     vstream_popen() opens a one-way or two-way stream to the specified
 /*     \fIcommand\fR, which is executed by a child process. The \fIflags\fR
 /*     standard output are redirected to the stream, which is based on a
 /*     socketpair.
 /*
+/*     vstream_popen_vargs() offers the user more control over the
+/*     child process and over how it is managed. The key argument
+/*     specifies what value will follow. pipe_command() takes a list
+/*     of (key, value) arguments, terminated by VSTREAM_POPEN_END. The
+/*     following is a listing of key codes together with the expected
+/*     value type.
+/* .RS
+/* .IP "VSTREAM_POPEN_COMMAND (char *)"
+/*     Specifies the command to execute as a string. The string is
+/*     passed to the shell when it contains shell meta characters
+/*     or when it appears to be a shell built-in command, otherwise
+/*     the command is executed without invoking a shell.
+/*     One of VSTREAM_POPEN_COMMAND or VSTREAM_POPEN_ARGV must be specified.
+/* .IP "VSTREAM_POPEN_ARGV (char **)"
+/*     The command is specified as an argument vector. This vector is
+/*     passed without further inspection to the \fIexecvp\fR() routine.
+/*     One of VSTREAM_POPEN_COMMAND or VSTREAM_POPEN_ARGV must be specified.
+/*     See also the VSTREAM_POPEN_SHELL attribute below.
+/* .IP "VSTREAM_POPEN_ENV (char **)"
+/*     Additional environment information, in the form of a null-terminated
+/*     list of name, value, name, value, ... elements. By default only the
+/*     command search path is initialized to _PATH_DEFPATH.
+/* .IP "VSTREAM_POPEN_UID (int)"
+/*     The user ID to execute the command as. The user ID must be non-zero.
+/* .IP "VSTREAM_POPEN_GID (int)"
+/*     The group ID to execute the command as. The group ID must be non-zero.
+/* .IP "VSTREAM_POPEN_SHELL (char *)"
+/*     The shell to use when executing the command specified with
+/*     VSTREAM_POPEN_COMMAND. This shell is invoked regardless of the
+/*     command content.
+/* .IP "VSTREAM_POPEN_WAITPID_FN ((*)(pid_t, WAIT_STATUS_T *, int))"
+/*     waitpid()-like function to reap the child exit status when
+/*     vstream_pclose() is called.
+/* .RE
+/* .PP
 /*     vstream_pclose() closes the named stream and returns the child
 /*     exit status. It is an error to specify a stream that was not
 /*     returned by vstream_popen() or that is no longer open.
 #include <sys/socket.h>
 #include <sys/wait.h>
 #include <unistd.h>
+#include <stdlib.h>
 #include <errno.h>
+#ifdef USE_PATHS_H
+#include <paths.h>
+#endif
+#include <syslog.h>
 
 /* Utility library. */
 
 #include <msg.h>
-#include <binhash.h>
 #include <exec_command.h>
 #include <vstream.h>
+#include <argv.h>
+#include <set_ugid.h>
+#include <clean_env.h>
 
 /* Application-specific. */
 
-static BINHASH *vstream_popen_table = 0;
+typedef struct VSTREAM_POPEN_ARGS {
+    char  **argv;
+    char   *command;
+    uid_t   uid;
+    gid_t   gid;
+    int     privileged;
+    char  **env;
+    char   *shell;
+    VSTREAM_WAITPID_FN waitpid_fn;
+} VSTREAM_POPEN_ARGS;
 
-/* vstream_popen - open stream to child process */
+/* vstream_parse_args - get arguments from variadic list */
 
-VSTREAM *vstream_popen(const char *command, int flags)
+static VSTREAM *vstream_parse_args(VSTREAM_POPEN_ARGS *args, va_list ap)
+{
+    char   *myname = "vstream_parse_args";
+    int     key;
+
+    /*
+     * First, set the default values (on all non-zero entries)
+     */
+    args->argv = 0;
+    args->command = 0;
+    args->uid = 0;
+    args->gid = 0;
+    args->privileged = 0;
+    args->env = 0;
+    args->shell = 0;
+    args->waitpid_fn = 0;
+
+    /*
+     * Then, override the defaults with user-supplied inputs.
+     */
+    while ((key = va_arg(ap, int)) != VSTREAM_POPEN_END) {
+       switch (key) {
+       case VSTREAM_POPEN_ARGV:
+           if (args->command != 0)
+               msg_panic("%s: got VSTREAM_POPEN_ARGV and VSTREAM_POPEN_COMMAND", myname);
+           args->argv = va_arg(ap, char **);
+           break;
+       case VSTREAM_POPEN_COMMAND:
+           if (args->argv != 0)
+               msg_panic("%s: got VSTREAM_POPEN_ARGV and VSTREAM_POPEN_COMMAND", myname);
+           args->command = va_arg(ap, char *);
+           break;
+       case VSTREAM_POPEN_UID:
+           args->privileged = 1;
+           args->uid = va_arg(ap, int);
+           break;
+       case VSTREAM_POPEN_GID:
+           args->privileged = 1;
+           args->gid = va_arg(ap, int);
+           break;
+       case VSTREAM_POPEN_ENV:
+           args->env = va_arg(ap, char **);
+           break;
+       case VSTREAM_POPEN_SHELL:
+           args->shell = va_arg(ap, char *);
+           break;
+       case VSTREAM_POPEN_WAITPID_FN:
+           args->waitpid_fn = va_arg(ap, VSTREAM_WAITPID_FN);
+           break;
+       default:
+           msg_panic("%s: unknown key: %d", myname, key);
+       }
+    }
+
+    if (args->command == 0 && args->argv == 0)
+       msg_panic("%s: missing VSTREAM_POPEN_ARGV or VSTREAM_POPEN_COMMAND", myname);
+    if (args->privileged != 0 && args->uid == 0)
+       msg_panic("%s: privileged uid", myname);
+    if (args->privileged != 0 && args->gid == 0)
+       msg_panic("%s: privileged gid", myname);
+}
+
+/* vstream_popen_vargs - open stream to child process */
+
+VSTREAM *vstream_popen_vargs(int flags,...)
 {
+    char   *myname = "vstream_popen_vargs";
+    VSTREAM_POPEN_ARGS args;
+    va_list ap;
     VSTREAM *stream;
     int     sockfd[2];
-    pid_t   pid;
+    int     pid;
     int     fd;
+    ARGV   *argv;
+    char  **cpp;
+
+    va_start(ap, flags);
+    vstream_parse_args(&args, ap);
+    va_end(ap);
+
+    if (args.command == 0)
+       args.command = args.argv[0];
 
     if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) < 0)
        return (0);
@@ -92,48 +222,87 @@ VSTREAM *vstream_popen(const char *command, int flags)
                    msg_fatal("dup2: %m");
        if (sockfd[0] >= 2 && close(sockfd[0]))
            msg_warn("close: %m");
-       exec_command(command);
+
+       /*
+        * Don't try to become someone else unless the user specified it.
+        */
+       if (args.privileged)
+           set_ugid(args.uid, args.gid);
+
+       /*
+        * Environment plumbing. Always reset the command search path. XXX
+        * That should probably be done by clean_env().
+        */
+       clean_env();
+       if (setenv("PATH", _PATH_DEFPATH, 1))
+           msg_fatal("%s: setenv: %m", myname);
+       if (args.env)
+           for (cpp = args.env; *cpp; cpp += 2)
+               if (setenv(cpp[0], cpp[1], 1))
+                   msg_fatal("setenv: %m");
+
+       /*
+        * Process plumbing. If possible, avoid running a shell.
+        */
+       closelog();
+       if (args.argv) {
+           execvp(args.argv[0], args.argv);
+           msg_fatal("%s: execvp %s: %m", myname, args.argv[0]);
+       } else if (args.shell && *args.shell) {
+           argv = argv_split(args.shell, " \t\r\n");
+           argv_add(argv, args.command, (char *) 0);
+           argv_terminate(argv);
+           execvp(argv->argv[0], argv->argv);
+           msg_fatal("%s: execvp %s: %m", myname, argv->argv[0]);
+       } else {
+           exec_command(args.command);
+       }
        /* NOTREACHED */
     default:                                   /* parent */
        if (close(sockfd[0]))
            msg_warn("close: %m");
        stream = vstream_fdopen(sockfd[1], flags);
-       if (vstream_popen_table == 0)
-           vstream_popen_table = binhash_create(10);
-       binhash_enter(vstream_popen_table, (char *) &stream,
-                     sizeof(stream), (char *) pid);
+       stream->waitpid_fn = args.waitpid_fn;
+       stream->pid = pid;
        return (stream);
     }
 }
 
+/* vstream_popen - retro-compatible wrapper for new interface */
+
+VSTREAM *vstream_popen(const char *command, int flags)
+{
+    return (vstream_popen_vargs(flags,
+                               VSTREAM_POPEN_COMMAND, command,
+                               VSTREAM_POPEN_END));
+}
+
 /* vstream_pclose - close stream to child process */
 
 int     vstream_pclose(VSTREAM *stream)
 {
-    char   *myname = "vstream_pclose";
-    BINHASH_INFO *info;
-    int     pid;
+    pid_t   saved_pid = stream->pid;
+    VSTREAM_WAITPID_FN saved_waitpid_fn = stream->waitpid_fn;
+    pid_t   pid;
     WAIT_STATUS_T wait_status;
 
     /*
-     * Sanity check.
+     * Close the pipe. Don't trigger an alarm in vstream_fclose().
      */
-    if (vstream_popen_table == 0
-       || (info = binhash_locate(vstream_popen_table, (char *) &stream,
-                                 sizeof(stream))) == 0)
-       msg_panic("%s: spurious stream %p", myname, (char *) stream);
+    if (saved_pid == 0)
+       msg_panic("vstream_pclose: stream has no process");
+    stream->pid = 0;
+    vstream_fclose(stream);
 
     /*
-     * Close the stream and reap the child exit status. Ignore errors while
-     * flushing the stream. The child might already have terminated.
+     * Reap the child exit status.
      */
-    (void) vstream_fclose(stream);
     do {
-       pid = waitpid((pid_t) info->value, &wait_status, 0);
+       if (saved_waitpid_fn != 0)
+           pid = saved_waitpid_fn(saved_pid, &wait_status, 0);
+       else
+           pid = waitpid(saved_pid, &wait_status, 0);
     } while (pid == -1 && errno == EINTR);
-    binhash_delete(vstream_popen_table, (char *) &stream, sizeof(stream),
-                  (void (*) (char *)) 0);
-
     return (pid == -1 ? -1 :
            WIFSIGNALED(wait_status) ? WTERMSIG(wait_status) :
            WEXITSTATUS(wait_status));