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));