diff --git a/postfix/.indent.pro b/postfix/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/.indent.pro
+++ b/postfix/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/HISTORY b/postfix/HISTORY
index 27c6d153e..54133a830 100644
--- a/postfix/HISTORY
+++ b/postfix/HISTORY
@@ -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.
diff --git a/postfix/LDAP_README b/postfix/LDAP_README
index e07308c30..76d26eb05 100644
--- a/postfix/LDAP_README
+++ b/postfix/LDAP_README
@@ -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
=======
diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES
index 0211dafb9..784b74480 100644
--- a/postfix/RELEASE_NOTES
+++ b/postfix/RELEASE_NOTES
@@ -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,
diff --git a/postfix/bounce/.indent.pro b/postfix/bounce/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/bounce/.indent.pro
+++ b/postfix/bounce/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/cleanup/.indent.pro b/postfix/cleanup/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/cleanup/.indent.pro
+++ b/postfix/cleanup/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/conf/main.cf.default b/postfix/conf/main.cf.default
index 90ca4fb21..e12daa656 100644
--- a/postfix/conf/main.cf.default
+++ b/postfix/conf/main.cf.default
@@ -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 =
diff --git a/postfix/dns/.indent.pro b/postfix/dns/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/dns/.indent.pro
+++ b/postfix/dns/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/fsstone/.indent.pro b/postfix/fsstone/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/fsstone/.indent.pro
+++ b/postfix/fsstone/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/global/.indent.pro b/postfix/global/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/global/.indent.pro
+++ b/postfix/global/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/global/Makefile.in b/postfix/global/Makefile.in
index ccf259c53..bb618ef14 100644
--- a/postfix/global/Makefile.in
+++ b/postfix/global/Makefile.in
@@ -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
diff --git a/postfix/global/mail_params.c b/postfix/global/mail_params.c
index 5731a1c97..f7388814c 100644
--- a/postfix/global/mail_params.c
+++ b/postfix/global/mail_params.c
@@ -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);
}
diff --git a/postfix/global/mail_params.h b/postfix/global/mail_params.h
index 2c4a5280c..9fef329bf 100644
--- a/postfix/global/mail_params.h
+++ b/postfix/global/mail_params.h
@@ -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"
diff --git a/postfix/global/mail_version.h b/postfix/global/mail_version.h
index 5ed04d7c7..d2702bd0d 100644
--- a/postfix/global/mail_version.h
+++ b/postfix/global/mail_version.h
@@ -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
diff --git a/postfix/html/uce.html b/postfix/html/uce.html
index 4fd756000..1f206e176 100644
--- a/postfix/html/uce.html
+++ b/postfix/html/uce.html
@@ -188,7 +188,7 @@ significant octets. Reject the request if the result is REJECT
or "[45]XX text". Permit the request if the result
is anything else. The access_map_reject_code parameter
specifies the response code for REJECT results (default:
-550).
+554).
@@ -198,7 +198,7 @@ specifies the response code for REJECT results (default:
network address is listed under any of the domains listed in $maps_rbl_domains. The
maps_rbl_reject_code parameter specifies the response code for
-rejected requests (default: 550).
+rejected requests (default: 554).
@@ -333,7 +333,7 @@ or parent domains in the specified table. Reject the request if
the result is REJECT or "[45]XX text". Permit
the request when the result is anything else. The
access_map_reject_code parameter specifies the response
-code for REJECT results (default: 550).
+code for REJECT results (default: 554).
@@ -420,7 +420,7 @@ parent domain, or localpart@. Reject the request if the
result is REJECT or "[45]XX text". Permit the
request if the result is anything else. The access_map_reject_code
parameter specifies the result code for rejected requests
-(default: 550).
+(default: 554).
@@ -519,7 +519,7 @@ client hostname matches $relay_domains,
or when the resolved destination address matches
$relay_domains, otherwise reject. The relay_domains_reject_code
parameter specifies the response code for rejected requests (default:
-550).
+554).
@@ -542,7 +542,7 @@ address, parent domain, or localpart@. Reject the request
if the result is REJECT or "[45]XX text".
Permit the request if the result is anything else. The
access_map_reject_code parameter specifies the result code
-for rejected requests (default: 550).
+for rejected requests (default: 554).
@@ -661,7 +661,7 @@ in the ETRN command, or its parent domains. Reject the request if
the result is REJECT or "[45]XX text". Permit
the request if the result is anything else. The access_map_reject_code
parameter specifies the result code for rejected requests
-(default: 550).
+(default: 554).
@@ -727,7 +727,7 @@ policy explicit.
is useful at the end of a restriction list, to make the default
policy explicit. The reject_code configuration parameter
specifies the response code to rejected requests (default:
-550).
+554).
diff --git a/postfix/local/.indent.pro b/postfix/local/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/local/.indent.pro
+++ b/postfix/local/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/master/.indent.pro b/postfix/master/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/master/.indent.pro
+++ b/postfix/master/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/pickup/.indent.pro b/postfix/pickup/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/pickup/.indent.pro
+++ b/postfix/pickup/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/pipe/.indent.pro b/postfix/pipe/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/pipe/.indent.pro
+++ b/postfix/pipe/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/postalias/.indent.pro b/postfix/postalias/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/postalias/.indent.pro
+++ b/postfix/postalias/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/postcat/.indent.pro b/postfix/postcat/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/postcat/.indent.pro
+++ b/postfix/postcat/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/postconf/.indent.pro b/postfix/postconf/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/postconf/.indent.pro
+++ b/postfix/postconf/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/postconf/postconf.c b/postfix/postconf/postconf.c
index d6ec2e3cc..70df435fb 100644
--- a/postfix/postconf/postconf.c
+++ b/postfix/postconf/postconf.c
@@ -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);
}
diff --git a/postfix/postdrop/.indent.pro b/postfix/postdrop/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/postdrop/.indent.pro
+++ b/postfix/postdrop/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/postfix/.indent.pro b/postfix/postfix/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/postfix/.indent.pro
+++ b/postfix/postfix/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/postkick/.indent.pro b/postfix/postkick/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/postkick/.indent.pro
+++ b/postfix/postkick/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/postlock/.indent.pro b/postfix/postlock/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/postlock/.indent.pro
+++ b/postfix/postlock/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/postlog/.indent.pro b/postfix/postlog/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/postlog/.indent.pro
+++ b/postfix/postlog/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/postmap/.indent.pro b/postfix/postmap/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/postmap/.indent.pro
+++ b/postfix/postmap/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/postsuper/.indent.pro b/postfix/postsuper/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/postsuper/.indent.pro
+++ b/postfix/postsuper/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/qmgr/.indent.pro b/postfix/qmgr/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/qmgr/.indent.pro
+++ b/postfix/qmgr/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/sendmail/.indent.pro b/postfix/sendmail/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/sendmail/.indent.pro
+++ b/postfix/sendmail/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/showq/.indent.pro b/postfix/showq/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/showq/.indent.pro
+++ b/postfix/showq/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/smtp/.indent.pro b/postfix/smtp/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/smtp/.indent.pro
+++ b/postfix/smtp/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/smtpd/.indent.pro b/postfix/smtpd/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/smtpd/.indent.pro
+++ b/postfix/smtpd/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/smtpd/smtpd_check.c b/postfix/smtpd/smtpd_check.c
index 570b15e94..976a8dfcd 100644
--- a/postfix/smtpd/smtpd_check.c
+++ b/postfix/smtpd/smtpd_check.c
@@ -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.
@@ -123,7 +123,7 @@
/* 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
diff --git a/postfix/smtpstone/.indent.pro b/postfix/smtpstone/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/smtpstone/.indent.pro
+++ b/postfix/smtpstone/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/trivial-rewrite/.indent.pro b/postfix/trivial-rewrite/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/trivial-rewrite/.indent.pro
+++ b/postfix/trivial-rewrite/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/util/.indent.pro b/postfix/util/.indent.pro
index 7dd2776b0..88212c9ce 100644
--- a/postfix/util/.indent.pro
+++ b/postfix/util/.indent.pro
@@ -97,6 +97,7 @@
-TUSER_ATTR
-TVBUF
-TVSTREAM
+-TVSTREAM_POPEN_ARGS
-TVSTRING
-TWAIT_STATUS_T
-TWATCH_FD
diff --git a/postfix/util/Makefile.in b/postfix/util/Makefile.in
index 74de770ad..8a75f3f50 100644
--- a/postfix/util/Makefile.in
+++ b/postfix/util/Makefile.in
@@ -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
diff --git a/postfix/global/clean_env.c b/postfix/util/clean_env.c
similarity index 96%
rename from postfix/global/clean_env.c
rename to postfix/util/clean_env.c
index 3086680c8..8549332d3 100644
--- a/postfix/global/clean_env.c
+++ b/postfix/util/clean_env.c
@@ -31,10 +31,7 @@
/* Utility library. */
#include
-
-/* Global library. */
-
-#include "clean_env.h"
+#include
/* clean_env - clean up the environment */
diff --git a/postfix/global/clean_env.h b/postfix/util/clean_env.h
similarity index 100%
rename from postfix/global/clean_env.h
rename to postfix/util/clean_env.h
diff --git a/postfix/util/dict_ldap.c b/postfix/util/dict_ldap.c
index 10dcc6cc9..32f1fa997 100644
--- a/postfix/util/dict_ldap.c
+++ b/postfix/util/dict_ldap.c
@@ -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
@@ -97,23 +97,23 @@
* 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);
+ 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);
+ 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);
+ 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 (signal(SIGALRM, saved_alarm) == SIG_ERR)
+ msg_fatal("%s: signal: %m", myname);
- if (msg_verbose)
- msg_info("%s: after ldap_open", 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);
+ if (dict_ldap->ld == 0) {
+ msg_fatal("%s: Unable to contact LDAP server %s",
+ myname, dict_ldap->server_host);
+ } else {
- 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);
+ }
}
/*
@@ -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));
+ 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) {
+ 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;
+ 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);
diff --git a/postfix/util/vstream.h b/postfix/util/vstream.h
index 68c4fbe20..d67ee2377 100644
--- a/postfix/util/vstream.h
+++ b/postfix/util/vstream.h
@@ -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 *);
diff --git a/postfix/util/vstream_popen.c b/postfix/util/vstream_popen.c
index d6cf60f37..46116a19e 100644
--- a/postfix/util/vstream_popen.c
+++ b/postfix/util/vstream_popen.c
@@ -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
@@ -19,6 +22,41 @@
/* 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.
@@ -55,27 +93,119 @@
#include
#include
#include
+#include
#include
+#ifdef USE_PATHS_H
+#include
+#endif
+#include
/* Utility library. */
#include
-#include
#include
#include
+#include
+#include
+#include
/* 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));