2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 21:55:20 +00:00

snapshot-19990423

This commit is contained in:
Wietse Venema
1999-04-23 00:00:00 -05:00
parent 5f740cf9e5
commit 54996be828
45 changed files with 476 additions and 251 deletions

1
postfix/.indent.pro vendored
View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -2651,3 +2651,16 @@ Apologies for any names omitted.
report as part of the first message segment, because users report as part of the first message segment, because users
had trouble extracting the delivery error report from the had trouble extracting the delivery error report from the
attachment. 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.

View File

@@ -70,7 +70,7 @@ Defaults are given in parentheses:
result_attribute (maildrop) result_attribute (maildrop)
The attribute Postfix will read from any directory entries The attribute Postfix will read from any directory entries
returned by the lookup, to be resolved to an email address. returned by the lookup, to be resolved to an email address.
ldapsource_result = mailbox ldapsource_result_attribute = mailbox
bind (yes) bind (yes)
Whether or not to bind to the LDAP server. Newer LDAP 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 Any performance reports will be much appreciated on the postfix-users
list. 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 CREDITS
======= =======

View File

@@ -1,4 +1,4 @@
Incompatible changes with snapshot-19990422: Incompatible changes with snapshot-19990423:
=========================================== ===========================================
- If an address extension (+foo) matches a user's .forward+foo file - 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 listed in the .forward+foo file. This is more consistent with the
way Postfix expands aliases. way Postfix expands aliases.
Major changes with snapshot-19990422: Major changes with snapshot-19990423:
===================================== =====================================
In addition to several little bugfixes, none related to security, In addition to several little bugfixes, none related to security,

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -1,5 +1,5 @@
2bounce_notice_recipient = postmaster 2bounce_notice_recipient = postmaster
access_map_reject_code = 550 access_map_reject_code = 554
alias_database = hash:/etc/aliases alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases alias_maps = hash:/etc/aliases
allow_mail_to_commands = alias,forward allow_mail_to_commands = alias,forward
@@ -61,11 +61,11 @@ luser_relay =
mail_name = Postfix mail_name = Postfix
mail_owner = postfix mail_owner = postfix
mail_spool_directory = /var/mail mail_spool_directory = /var/mail
mail_version = Snapshot-19990422 mail_version = Snapshot-19990423
mailbox_command = mailbox_command =
mailbox_transport = mailbox_transport =
maps_rbl_domains = rbl.maps.vix.com maps_rbl_domains = rbl.maps.vix.com
maps_rbl_reject_code = 550 maps_rbl_reject_code = 554
masquerade_domains = masquerade_domains =
masquerade_exceptions = masquerade_exceptions =
max_idle = 100 max_idle = 100
@@ -89,9 +89,9 @@ queue_run_delay = 1000
recipient_canonical_maps = recipient_canonical_maps =
recipient_delimiter = recipient_delimiter =
recipient_feature_delimiter = recipient_feature_delimiter =
reject_code = 550 reject_code = 554
relay_domains = $mydestination, $virtual_maps relay_domains = $mydestination, $virtual_maps
relay_domains_reject_code = 550 relay_domains_reject_code = 554
relayhost = relayhost =
relocated_maps = relocated_maps =
sender_canonical_maps = sender_canonical_maps =

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -1,5 +1,5 @@
SHELL = /bin/sh 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 \ 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 \ debug_process.c defer.c deliver_completed.c deliver_flock.c \
deliver_request.c domain_list.c dot_lockfile.c file_id.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 \ 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_node.c tok822_parse.c tok822_resolve.c tok822_rewrite.c \
tok822_tree.c clnt_stream.c deliver_pass.c config_raw.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 \ 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 \ debug_process.o defer.o deliver_completed.o deliver_flock.o \
deliver_request.o domain_list.o dot_lockfile.o file_id.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 \ 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_node.o tok822_parse.o tok822_resolve.o tok822_rewrite.o \
tok822_tree.o clnt_stream.o deliver_pass.o config_raw.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 \ 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 \ 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 \ 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: ../include/mymalloc.h
canon_addr.o: rewrite_clnt.h canon_addr.o: rewrite_clnt.h
canon_addr.o: canon_addr.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: cleanup_strerror.c
cleanup_strerror.o: ../include/sys_defs.h cleanup_strerror.o: ../include/sys_defs.h
cleanup_strerror.o: ../include/vstring.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/msg.h
mail_params.o: ../include/get_hostname.h mail_params.o: ../include/get_hostname.h
mail_params.o: ../include/valid_hostname.h mail_params.o: ../include/valid_hostname.h
mail_params.o: ../include/stringops.h
mail_params.o: mynetworks.h mail_params.o: mynetworks.h
mail_params.o: config.h mail_params.o: config.h
mail_params.o: mail_version.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: ../include/argv.h
pipe_command.o: mail_params.h pipe_command.o: mail_params.h
pipe_command.o: mail_copy.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: pipe_command.h
pipe_command.o: ../include/exec_command.h pipe_command.o: ../include/exec_command.h
pipe_command.o: sys_exits.h pipe_command.o: sys_exits.h

View File

@@ -177,8 +177,7 @@ static const char *check_myhostname(void)
name = get_hostname(); name = get_hostname();
if ((dot = strchr(name, '.')) == 0) { if ((dot = strchr(name, '.')) == 0) {
if ((domain = config_lookup_eval(VAR_MYDOMAIN)) == 0) if ((domain = config_lookup_eval(VAR_MYDOMAIN)) == 0)
msg_fatal("My hostname %s is not a fully qualified name - " msg_fatal("My hostname %s is not a fully qualified name - set %s or %s in %s/main.cf",
"set %s or %s in %s/main.cf",
name, VAR_MYHOSTNAME, VAR_MYDOMAIN, var_config_dir); name, VAR_MYHOSTNAME, VAR_MYDOMAIN, var_config_dir);
name = concatenate(name, ".", domain, (char *) 0); name = concatenate(name, ".", domain, (char *) 0);
} }

View File

@@ -706,7 +706,7 @@ extern char *var_etrn_checks;
#define PERMIT_ALL "permit" #define PERMIT_ALL "permit"
#define REJECT_ALL "reject" #define REJECT_ALL "reject"
#define VAR_REJECT_CODE "reject_code" #define VAR_REJECT_CODE "reject_code"
#define DEF_REJECT_CODE 550 #define DEF_REJECT_CODE 554
extern int var_reject_code; extern int var_reject_code;
#define REJECT_UNKNOWN_CLIENT "reject_unknown_client" #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 CHECK_RELAY_DOMAINS "check_relay_domains"
#define VAR_RELAY_CODE "relay_domains_reject_code" #define VAR_RELAY_CODE "relay_domains_reject_code"
#define DEF_RELAY_CODE 550 #define DEF_RELAY_CODE 554
extern int var_relay_code; extern int var_relay_code;
#define PERMIT_MX_BACKUP "permit_mx_backup" #define PERMIT_MX_BACKUP "permit_mx_backup"
#define VAR_ACCESS_MAP_CODE "access_map_reject_code" #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; extern int var_access_map_code;
#define CHECK_CLIENT_ACL "check_client_access" #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 REJECT_MAPS_RBL "reject_maps_rbl"
#define VAR_MAPS_RBL_CODE "maps_rbl_reject_code" #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; extern int var_maps_rbl_code;
#define VAR_MAPS_RBL_DOMAINS "maps_rbl_domains" #define VAR_MAPS_RBL_DOMAINS "maps_rbl_domains"

View File

@@ -15,7 +15,7 @@
* Version of this program. * Version of this program.
*/ */
#define VAR_MAIL_VERSION "mail_version" #define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "Snapshot-19990422" #define DEF_MAIL_VERSION "Snapshot-19990423"
extern char *var_mail_version; extern char *var_mail_version;
/* LICENSE /* LICENSE

View File

@@ -188,7 +188,7 @@ significant octets. Reject the request if the result is <b>REJECT</b>
or "[<b>45</b>]<i>XX text</i>". Permit the request if the result or "[<b>45</b>]<i>XX text</i>". Permit the request if the result
is anything else. The <b>access_map_reject_code</b> parameter is anything else. The <b>access_map_reject_code</b> parameter
specifies the response code for <b>REJECT</b> results (default: specifies the response code for <b>REJECT</b> results (default:
<b>550</b>). <b>554</b>).
<p> <p>
@@ -198,7 +198,7 @@ specifies the response code for <b>REJECT</b> results (default:
network address is listed under any of the domains listed in <a network address is listed under any of the domains listed in <a
href="#maps_rbl_domains">$maps_rbl_domains</a>. The <b> href="#maps_rbl_domains">$maps_rbl_domains</a>. The <b>
maps_rbl_reject_code</b> parameter specifies the response code for maps_rbl_reject_code</b> parameter specifies the response code for
rejected requests (default: <b>550</b>). rejected requests (default: <b>554</b>).
<p> <p>
@@ -333,7 +333,7 @@ or parent domains in the specified table. Reject the request if
the result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>". Permit the result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>". Permit
the request when the result is anything else. The the request when the result is anything else. The
<b>access_map_reject_code </b> parameter specifies the response <b>access_map_reject_code </b> parameter specifies the response
code for <b>REJECT</b> results (default: <b>550</b>). code for <b>REJECT</b> results (default: <b>554</b>).
<p> <p>
@@ -420,7 +420,7 @@ parent domain, or <i>localpart</i>@. Reject the request if the
result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>". Permit the result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>". Permit the
request if the result is anything else. The <b>access_map_reject_code request if the result is anything else. The <b>access_map_reject_code
</b> parameter specifies the result code for rejected requests </b> parameter specifies the result code for rejected requests
(default: <b>550</b>). (default: <b>554</b>).
<p> <p>
@@ -519,7 +519,7 @@ client hostname matches <a href="#relay_domains">$relay_domains</a>,
or when the resolved destination address matches <a href="#relay_domains"> or when the resolved destination address matches <a href="#relay_domains">
$relay_domains</a>, otherwise reject. The <b>relay_domains_reject_code</b> $relay_domains</a>, otherwise reject. The <b>relay_domains_reject_code</b>
parameter specifies the response code for rejected requests (default: parameter specifies the response code for rejected requests (default:
<b>550</b>). <b>554</b>).
<p> <p>
@@ -542,7 +542,7 @@ address, parent domain, or <i>localpart</i>@. Reject the request
if the result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>". if the result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>".
Permit the request if the result is anything else. The Permit the request if the result is anything else. The
<b>access_map_reject_code </b> parameter specifies the result code <b>access_map_reject_code </b> parameter specifies the result code
for rejected requests (default: <b>550</b>). for rejected requests (default: <b>554</b>).
<p> <p>
@@ -661,7 +661,7 @@ in the ETRN command, or its parent domains. Reject the request if
the result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>". Permit the result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>". Permit
the request if the result is anything else. The <b>access_map_reject_code the request if the result is anything else. The <b>access_map_reject_code
</b> parameter specifies the result code for rejected requests </b> parameter specifies the result code for rejected requests
(default: <b>550</b>). (default: <b>554</b>).
<p> <p>
@@ -727,7 +727,7 @@ policy explicit.
is useful at the end of a restriction list, to make the default is useful at the end of a restriction list, to make the default
policy explicit. The <b>reject_code</b> configuration parameter policy explicit. The <b>reject_code</b> configuration parameter
specifies the response code to rejected requests (default: specifies the response code to rejected requests (default:
<b>550</b>). <b>554</b>).
</dl> </dl>

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -168,8 +168,7 @@ static const char *check_myhostname(void)
name = get_hostname(); name = get_hostname();
if ((mode & SHOW_DEFS) == 0 && (dot = strchr(name, '.')) == 0) { if ((mode & SHOW_DEFS) == 0 && (dot = strchr(name, '.')) == 0) {
if ((domain = config_lookup_eval(VAR_MYDOMAIN)) == 0) if ((domain = config_lookup_eval(VAR_MYDOMAIN)) == 0)
msg_fatal("My hostname %s is not a fully qualified name - " msg_fatal("My hostname %s is not a fully qualified name - set %s or %s in %s/main.cf",
"set %s or %s in %s/main.cf",
name, VAR_MYHOSTNAME, VAR_MYDOMAIN, var_config_dir); name, VAR_MYHOSTNAME, VAR_MYDOMAIN, var_config_dir);
name = concatenate(name, ".", domain, (char *) 0); name = concatenate(name, ".", domain, (char *) 0);
} }

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -68,7 +68,7 @@
/* 4xx or 5xx status code. Other numerical status codes are not /* 4xx or 5xx status code. Other numerical status codes are not
/* permitted. Allow the request otherwise. The /* permitted. Allow the request otherwise. The
/* \fIaccess_map_reject_code\fR configuration parameter specifies 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" /* .IP "check_client_access maptype:mapname"
/* Look up the client host name or any of its parent domains, or /* Look up the client host name or any of its parent domains, or
/* the client address or any network obtained by stripping octets /* 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" /* DNS zones below the domains listed in the "maps_rbl_domains"
/* configuration parameter. The \fImaps_rbl_reject_code\fR /* configuration parameter. The \fImaps_rbl_reject_code\fR
/* configuration parameter specifies the reject status code /* configuration parameter specifies the reject status code
/* (default: 550). /* (default: 554).
/* .IP permit_naked_ip_address /* .IP permit_naked_ip_address
/* Permit the use of a naked IP address (without enclosing []) /* Permit the use of a naked IP address (without enclosing [])
/* in HELO/EHLO commands. /* in HELO/EHLO commands.
@@ -123,7 +123,7 @@
/* recipient domain matches the \fIrelay_domains\fR configuration /* recipient domain matches the \fIrelay_domains\fR configuration
/* parameter. Reject the request otherwise. /* parameter. Reject the request otherwise.
/* The \fIrelay_domains_reject_code\fR configuration parameter specifies /* 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 /* .IP permit_mx_backup
/* Allow the request when the local mail system is mail exchanger /* Allow the request when the local mail system is mail exchanger
/* for the recipient domain (this includes the case where the local /* for the recipient domain (this includes the case where the local

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -97,6 +97,7 @@
-TUSER_ATTR -TUSER_ATTR
-TVBUF -TVBUF
-TVSTREAM -TVSTREAM
-TVSTREAM_POPEN_ARGS
-TVSTRING -TVSTRING
-TWAIT_STATUS_T -TWAIT_STATUS_T
-TWATCH_FD -TWATCH_FD

View File

@@ -19,7 +19,8 @@ SRCS = argv.c argv_split.c attr.c basename.c binhash.c chroot_uid.c \
unsafe.c username.c valid_hostname.c vbuf.c vbuf_print.c \ unsafe.c username.c valid_hostname.c vbuf.c vbuf_print.c \
vstream.c vstream_popen.c vstring.c vstring_vstream.c writable.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 \ 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 \ 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 \ 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 \ 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 \ unsafe.o username.o valid_hostname.o vbuf.o vbuf_print.o \
vstream.o vstream_popen.o vstring.o vstring_vstream.o writable.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 \ 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 \ 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_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 \ 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 \ 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 \ 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 \ 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 \ TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
stream_test.c stream_test.c
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \ 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: sys_defs.h
chroot_uid.o: msg.h chroot_uid.o: msg.h
chroot_uid.o: chroot_uid.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: close_on_exec.c
close_on_exec.o: sys_defs.h close_on_exec.o: sys_defs.h
close_on_exec.o: msg.h close_on_exec.o: msg.h
@@ -802,10 +808,12 @@ vstream.o: vstream.h
vstream_popen.o: vstream_popen.c vstream_popen.o: vstream_popen.c
vstream_popen.o: sys_defs.h vstream_popen.o: sys_defs.h
vstream_popen.o: msg.h vstream_popen.o: msg.h
vstream_popen.o: binhash.h
vstream_popen.o: exec_command.h vstream_popen.o: exec_command.h
vstream_popen.o: vstream.h vstream_popen.o: vstream.h
vstream_popen.o: vbuf.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: vstring.c
vstring.o: sys_defs.h vstring.o: sys_defs.h
vstring.o: mymalloc.h vstring.o: mymalloc.h

View File

@@ -31,10 +31,7 @@
/* Utility library. */ /* Utility library. */
#include <msg.h> #include <msg.h>
#include <clean_env.h>
/* Global library. */
#include "clean_env.h"
/* clean_env - clean up the environment */ /* clean_env - clean up the environment */

View File

@@ -17,7 +17,7 @@
/* Arguments: /* Arguments:
/* .IP ldapsource /* .IP ldapsource
/* The prefix which will be used to obtain configuration parameters /* 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 /* would look like 'ldapone_server_host', 'ldapone_search_base', and so
/* on in main.cf. /* on in main.cf.
/* .IP dummy /* .IP dummy
@@ -61,7 +61,7 @@
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10532, USA /* Yorktown Heights, NY 10532, USA
/* /*
/* John Hensley /* John Hensley
/* Merit Network, Inc. /* Merit Network, Inc.
/* hensley@merit.edu /* hensley@merit.edu
@@ -97,23 +97,23 @@
* themselves, including their configuration file parameters. * themselves, including their configuration file parameters.
*/ */
/* /*
* structure containing all the configuration parameters for a given * structure containing all the configuration parameters for a given
* LDAP source, plus its connection handle * LDAP source, plus its connection handle
*/ */
typedef struct { typedef struct {
DICT dict; /* generic member */ DICT dict; /* generic member */
char *ldapsource; char *ldapsource;
char *server_host; char *server_host;
int server_port; int server_port;
char *search_base; char *search_base;
char *query_filter; char *query_filter;
char *result_attribute; char *result_attribute;
int bind; int bind;
char *bind_dn; char *bind_dn;
char *bind_pw; char *bind_pw;
int timeout; int timeout;
LDAP *ld; LDAP *ld;
} DICT_LDAP; } DICT_LDAP;
/* /*
@@ -133,14 +133,13 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
char *myname = "dict_ldap_lookup"; char *myname = "dict_ldap_lookup";
DICT_LDAP *dict_ldap = (DICT_LDAP *) dict; DICT_LDAP *dict_ldap = (DICT_LDAP *) dict;
static VSTRING *result; static VSTRING *result;
int LDAP_UNBIND = 0; LDAPMessage *res = 0;
LDAPMessage *res = 0; LDAPMessage *entry = 0;
LDAPMessage *entry = 0;
struct timeval tv; struct timeval tv;
VSTRING *filter_buf = 0; VSTRING *filter_buf = 0;
char **attr_values; char **attr_values;
long i = 0, j = 0; long i = 0;
int rc = 0; int rc = 0;
void (*saved_alarm) (int); void (*saved_alarm) (int);
dict_errno = 0; dict_errno = 0;
@@ -149,60 +148,61 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
* Initialize. * Initialize.
*/ */
if (result == 0) if (result == 0)
result = vstring_alloc(2); result = vstring_alloc(2);
vstring_strcpy(result,""); vstring_strcpy(result, "");
if (msg_verbose) if (msg_verbose)
msg_info("%s: In dict_ldap_lookup", myname); msg_info("%s: In dict_ldap_lookup", myname);
if (dict_ldap->ld == 0) { if (dict_ldap->ld == 0) {
msg_warn("%s: no existing connection for ldapsource %s, reopening", msg_warn("%s: no existing connection for ldapsource %s, reopening",
myname, dict_ldap->ldapsource); myname, dict_ldap->ldapsource);
if (msg_verbose) if (msg_verbose)
msg_info("%s: connecting to server %s", myname, msg_info("%s: connecting to server %s", myname,
dict_ldap->server_host); dict_ldap->server_host);
if ((saved_alarm = signal(SIGALRM, dict_ldap_timeout)) == SIG_ERR) 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); alarm(dict_ldap->timeout);
if (setjmp(env) == 0) if (setjmp(env) == 0)
dict_ldap->ld = ldap_open(dict_ldap->server_host, dict_ldap->ld = ldap_open(dict_ldap->server_host,
(int) dict_ldap->server_port); (int) dict_ldap->server_port);
alarm(0); alarm(0);
if (signal(SIGALRM, saved_alarm) == SIG_ERR) if (signal(SIGALRM, saved_alarm) == SIG_ERR)
msg_fatal("%s: signal: %m", myname); msg_fatal("%s: signal: %m", myname);
if (msg_verbose) if (msg_verbose)
msg_info("%s: after ldap_open", myname); msg_info("%s: after ldap_open", myname);
if (dict_ldap->ld == 0) { if (dict_ldap->ld == 0) {
msg_fatal("%s: Unable to contact LDAP server %s", msg_fatal("%s: Unable to contact LDAP server %s",
myname, dict_ldap->server_host); myname, dict_ldap->server_host);
} else { } 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 this server requires us to bind, do so.
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)); if (dict_ldap->bind) {
} else { if (msg_verbose)
if (msg_verbose) msg_info("%s: about to bind: server %s, base %s", myname,
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)); dict_ldap->server_host, dict_ldap->search_base);
}
} rc = ldap_bind_s(dict_ldap->ld, dict_ldap->search_base, NULL,
if (msg_verbose) LDAP_AUTH_SIMPLE);
msg_info("%s: cached connection handle for LDAP source %s", if (rc != LDAP_SUCCESS) {
myname, dict_ldap->ldapsource); 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); vstring_sprintf(filter_buf, dict_ldap->query_filter, name);
if (msg_verbose) if (msg_verbose)
msg_info("%s: searching with filter %s", myname, msg_info("%s: searching with filter %s", myname,
vstring_str(filter_buf)); vstring_str(filter_buf));
if ((rc=ldap_search_st(dict_ldap->ld, dict_ldap->search_base, if ((rc = ldap_search_st(dict_ldap->ld, dict_ldap->search_base,
LDAP_SCOPE_SUBTREE, LDAP_SCOPE_SUBTREE,
vstring_str(filter_buf), vstring_str(filter_buf),
0, 0, &tv, &res)) != LDAP_SUCCESS) { 0, 0, &tv, &res)) != LDAP_SUCCESS) {
msg_info("%s: right after search", myname); ldap_unbind(dict_ldap->ld);
dict_ldap->ld = 0;
msg_warn("%s: Unable to search base %s at server %s (%d -- %s): ", if (msg_verbose)
myname, dict_ldap->search_base, dict_ldap->server_host, rc, msg_info("%s: freed connection handle for LDAP source %s", myname, dict_ldap->ldapsource);
ldap_err2string(rc)); msg_fatal("%s: Unable to search base %s at server %s (%d -- %s): ",
LDAP_UNBIND = 1; myname, dict_ldap->search_base, dict_ldap->server_host, rc,
ldap_err2string(rc));
} else { } 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, * Extract the requested result_attribute.
dict_ldap->result_attribute); */
/* if (msg_verbose)
* Append each returned address to the result list. msg_info("%s: search found %d", myname,
*/ ldap_count_entries(dict_ldap->ld, res));
while (attr_values[i]) {
if (VSTRING_LEN(result) > 0) for (entry = ldap_first_entry(dict_ldap->ld, res); entry != NULL; entry = ldap_next_entry(dict_ldap->ld, entry)) {
vstring_strcat(result, ","); attr_values = ldap_get_values(dict_ldap->ld, entry,
vstring_strcat(result, attr_values[i]); dict_ldap->result_attribute);
i++; if (attr_values == NULL) {
} msg_warn("%s: entry doesn't have any values for %s", myname, dict_ldap->result_attribute);
ldap_value_free(attr_values); continue;
if (msg_verbose) }
msg_info("%s: search returned: %s", myname, vstring_str(result));
} else { /*
if (msg_verbose) * Append each returned address to the result list.
msg_info("%s: search returned nothing", myname); */
} 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. * perform the query.
*/ */
if (res != 0) if (res != 0)
ldap_msgfree(res); ldap_msgfree(res);
else else
dict_errno = 1; 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);
}
if (filter_buf != 0) if (filter_buf != 0)
vstring_free(filter_buf); vstring_free(filter_buf);
return (entry != 0 ? vstring_str(result) : 0); return (VSTRING_LEN(result) > 0 ? vstring_str(result) : 0);
} }
/* dict_ldap_update - add or update database entry */ /* dict_ldap_update - add or update database entry */
static void dict_ldap_update(DICT *dict, const char *unused_name, 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"); 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; DICT_LDAP *dict_ldap = (DICT_LDAP *) dict;
if (dict_ldap->ld) if (dict_ldap->ld)
ldap_unbind(dict_ldap->ld); ldap_unbind(dict_ldap->ld);
myfree(dict_ldap->ldapsource); myfree(dict_ldap->ldapsource);
myfree(dict_ldap->server_host); myfree(dict_ldap->server_host);
@@ -305,7 +299,7 @@ static void dict_ldap_close(DICT *dict)
myfree(dict_ldap->result_attribute); myfree(dict_ldap->result_attribute);
myfree(dict_ldap->bind_dn); myfree(dict_ldap->bind_dn);
myfree(dict_ldap->bind_pw); myfree(dict_ldap->bind_pw);
myfree((char *)dict_ldap); myfree((char *) dict_ldap);
} }
/* dict_ldap_open - create association with data base */ /* 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"; char *myname = "dict_ldap_open";
DICT_LDAP *dict_ldap; DICT_LDAP *dict_ldap;
VSTRING *config_param; VSTRING *config_param;
int rc = 0; int rc = 0;
void (*saved_alarm) (int); void (*saved_alarm) (int);
dict_ldap = (DICT_LDAP *) mymalloc(sizeof(*dict_ldap)); 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; dict_ldap->dict.flags = dict_flags | DICT_FLAG_FIXED;
if (msg_verbose) 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); dict_ldap->ldapsource = mystrdup(ldapsource);
config_param = vstring_alloc(15); config_param = vstring_alloc(15);
vstring_sprintf(config_param, "%s_server_host", ldapsource); vstring_sprintf(config_param, "%s_server_host", ldapsource);
dict_ldap->server_host = dict_ldap->server_host =
mystrdup((char *)get_config_str(vstring_str(config_param), mystrdup((char *) get_config_str(vstring_str(config_param),
"localhost",0,0)); "localhost", 0, 0));
if (msg_verbose) if (msg_verbose)
msg_info("%s: %s is %s", myname, vstring_str(config_param), msg_info("%s: %s is %s", myname, vstring_str(config_param),
dict_ldap->server_host); 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); vstring_sprintf(config_param, "%s_server_port", ldapsource);
dict_ldap->server_port = dict_ldap->server_port =
get_config_int(vstring_str(config_param),LDAP_PORT,0,0); get_config_int(vstring_str(config_param), LDAP_PORT, 0, 0);
if (msg_verbose) if (msg_verbose)
msg_info("%s: %s is %d", myname, vstring_str(config_param), msg_info("%s: %s is %d", myname, vstring_str(config_param),
dict_ldap->server_port); dict_ldap->server_port);
vstring_sprintf(config_param, "%s_search_base", ldapsource); vstring_sprintf(config_param, "%s_search_base", ldapsource);
dict_ldap->search_base = dict_ldap->search_base =
mystrdup((char *)get_config_str(vstring_str(config_param),"",0,0)); mystrdup((char *) get_config_str(vstring_str(config_param), "", 0, 0));
if (msg_verbose) if (msg_verbose)
msg_info("%s: %s is %s", myname, vstring_str(config_param), msg_info("%s: %s is %s", myname, vstring_str(config_param),
dict_ldap->search_base); dict_ldap->search_base);
/* get configured value of "ldapsource_timeout"; default to 10 */ /* get configured value of "ldapsource_timeout"; default to 10 */
vstring_sprintf(config_param, "%s_timeout", ldapsource); 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) if (msg_verbose)
msg_info("%s: %s is %d", myname, vstring_str(config_param), msg_info("%s: %s is %d", myname, vstring_str(config_param),
dict_ldap->timeout); dict_ldap->timeout);
vstring_sprintf(config_param, "%s_query_filter", ldapsource); vstring_sprintf(config_param, "%s_query_filter", ldapsource);
dict_ldap->query_filter = dict_ldap->query_filter =
mystrdup((char *)get_config_str(vstring_str(config_param), mystrdup((char *) get_config_str(vstring_str(config_param),
"(mailacceptinggeneralid=%s)",0,0)); "(mailacceptinggeneralid=%s)", 0, 0));
if (msg_verbose) if (msg_verbose)
msg_info("%s: %s is %s", myname, vstring_str(config_param), msg_info("%s: %s is %s", myname, vstring_str(config_param),
dict_ldap->query_filter); dict_ldap->query_filter);
vstring_sprintf(config_param, "%s_result_attribute", ldapsource); vstring_sprintf(config_param, "%s_result_attribute", ldapsource);
dict_ldap->result_attribute = dict_ldap->result_attribute =
mystrdup((char *)get_config_str(vstring_str(config_param), mystrdup((char *) get_config_str(vstring_str(config_param),
"maildrop",0,0)); "maildrop", 0, 0));
if (msg_verbose) if (msg_verbose)
msg_info("%s: %s is %s", myname, vstring_str(config_param), msg_info("%s: %s is %s", myname, vstring_str(config_param),
dict_ldap->result_attribute); dict_ldap->result_attribute);
/* get configured value of "ldapsource_bind"; default to true */ /* get configured value of "ldapsource_bind"; default to true */
vstring_sprintf(config_param, "%s_bind", ldapsource); vstring_sprintf(config_param, "%s_bind", ldapsource);
dict_ldap->bind = get_config_bool(vstring_str(config_param), 1); dict_ldap->bind = get_config_bool(vstring_str(config_param), 1);
if (msg_verbose) if (msg_verbose)
msg_info("%s: %s is %d", myname, vstring_str(config_param), msg_info("%s: %s is %d", myname, vstring_str(config_param),
dict_ldap->bind); dict_ldap->bind);
/* get configured value of "ldapsource_bind_dn"; default to "" */ /* get configured value of "ldapsource_bind_dn"; default to "" */
vstring_sprintf(config_param, "%s_bind_dn", ldapsource); vstring_sprintf(config_param, "%s_bind_dn", ldapsource);
dict_ldap->bind_dn = dict_ldap->bind_dn =
mystrdup((char *)get_config_str(vstring_str(config_param),"",0,0)); mystrdup((char *) get_config_str(vstring_str(config_param), "", 0, 0));
if (msg_verbose) if (msg_verbose)
msg_info("%s: %s is %s", myname, vstring_str(config_param), msg_info("%s: %s is %s", myname, vstring_str(config_param),
dict_ldap->bind_dn); dict_ldap->bind_dn);
/* get configured value of "ldapsource_bind_pw"; default to "" */ /* get configured value of "ldapsource_bind_pw"; default to "" */
vstring_sprintf(config_param, "%s_bind_pw", ldapsource); vstring_sprintf(config_param, "%s_bind_pw", ldapsource);
dict_ldap->bind_pw = dict_ldap->bind_pw =
mystrdup((char *)get_config_str(vstring_str(config_param),"",0,0)); mystrdup((char *) get_config_str(vstring_str(config_param), "", 0, 0));
if (msg_verbose) if (msg_verbose)
msg_info("%s: %s is %s", myname, vstring_str(config_param), msg_info("%s: %s is %s", myname, vstring_str(config_param),
dict_ldap->bind_pw); dict_ldap->bind_pw);
/* /*
* establish the connection to the LDAP server * establish the connection to the LDAP server
*/ */
if (msg_verbose) if (msg_verbose)
msg_info("%s: connecting to server %s", myname, msg_info("%s: connecting to server %s", myname,
dict_ldap->server_host); dict_ldap->server_host);
if ((saved_alarm = signal(SIGALRM, dict_ldap_timeout)) == SIG_ERR) 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); alarm(dict_ldap->timeout);
if (setjmp(env) == 0) if (setjmp(env) == 0)
dict_ldap->ld = ldap_open(dict_ldap->server_host, dict_ldap->ld = ldap_open(dict_ldap->server_host,
(int) dict_ldap->server_port); (int) dict_ldap->server_port);
alarm(0); alarm(0);
if (signal(SIGALRM, saved_alarm) == SIG_ERR) if (signal(SIGALRM, saved_alarm) == SIG_ERR)
msg_fatal("%s: signal: %m", myname); msg_fatal("%s: signal: %m", myname);
if (msg_verbose) if (msg_verbose)
msg_info("%s: after ldap_open", myname); msg_info("%s: after ldap_open", myname);
if (dict_ldap->ld == 0) { if (dict_ldap->ld == 0) {
msg_fatal("%s: Unable to contact LDAP server %s", msg_fatal("%s: Unable to contact LDAP server %s",
myname, dict_ldap->server_host); myname, dict_ldap->server_host);
} else { } 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 this server requires us to bind, do so.
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)); if (dict_ldap->bind) {
} else { if (msg_verbose)
if (msg_verbose) msg_info("%s: about to bind: server %s, base %s", myname,
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)); dict_ldap->server_host, dict_ldap->search_base);
}
} rc = ldap_bind_s(dict_ldap->ld, dict_ldap->search_base, NULL,
if (msg_verbose) LDAP_AUTH_SIMPLE);
msg_info("%s: cached connection handle for LDAP source %s", if (rc != LDAP_SUCCESS) {
myname, dict_ldap->ldapsource); 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); return (&dict_ldap->dict);

View File

@@ -103,8 +103,20 @@ extern VSTREAM *vstream_printf(const char *,...);
extern VSTREAM *vstream_fprintf(VSTREAM *, const char *,...); extern VSTREAM *vstream_fprintf(VSTREAM *, const char *,...);
extern VSTREAM *vstream_popen(const char *, int); extern VSTREAM *vstream_popen(const char *, int);
extern VSTREAM *vstream_popen_vargs(int,...);
extern int vstream_pclose(VSTREAM *); 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 VSTREAM *vstream_vfprintf(VSTREAM *, const char *, va_list);
extern int vstream_peek(VSTREAM *); extern int vstream_peek(VSTREAM *);

View File

@@ -12,6 +12,9 @@
/* /*
/* int vstream_pclose(stream) /* int vstream_pclose(stream)
/* VSTREAM *stream; /* VSTREAM *stream;
/*
/* VSTREAM *vstream_popen_vargs(key, value, ...)
/* int key;
/* DESCRIPTION /* DESCRIPTION
/* vstream_popen() opens a one-way or two-way stream to the specified /* 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 /* \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 /* standard output are redirected to the stream, which is based on a
/* socketpair. /* 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 /* vstream_pclose() closes the named stream and returns the child
/* exit status. It is an error to specify a stream that was not /* exit status. It is an error to specify a stream that was not
/* returned by vstream_popen() or that is no longer open. /* returned by vstream_popen() or that is no longer open.
@@ -55,27 +93,119 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h> #include <unistd.h>
#include <stdlib.h>
#include <errno.h> #include <errno.h>
#ifdef USE_PATHS_H
#include <paths.h>
#endif
#include <syslog.h>
/* Utility library. */ /* Utility library. */
#include <msg.h> #include <msg.h>
#include <binhash.h>
#include <exec_command.h> #include <exec_command.h>
#include <vstream.h> #include <vstream.h>
#include <argv.h>
#include <set_ugid.h>
#include <clean_env.h>
/* Application-specific. */ /* 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; VSTREAM *stream;
int sockfd[2]; int sockfd[2];
pid_t pid; int pid;
int fd; 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) if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) < 0)
return (0); return (0);
@@ -92,48 +222,87 @@ VSTREAM *vstream_popen(const char *command, int flags)
msg_fatal("dup2: %m"); msg_fatal("dup2: %m");
if (sockfd[0] >= 2 && close(sockfd[0])) if (sockfd[0] >= 2 && close(sockfd[0]))
msg_warn("close: %m"); 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 */ /* NOTREACHED */
default: /* parent */ default: /* parent */
if (close(sockfd[0])) if (close(sockfd[0]))
msg_warn("close: %m"); msg_warn("close: %m");
stream = vstream_fdopen(sockfd[1], flags); stream = vstream_fdopen(sockfd[1], flags);
if (vstream_popen_table == 0) stream->waitpid_fn = args.waitpid_fn;
vstream_popen_table = binhash_create(10); stream->pid = pid;
binhash_enter(vstream_popen_table, (char *) &stream,
sizeof(stream), (char *) pid);
return (stream); 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 */ /* vstream_pclose - close stream to child process */
int vstream_pclose(VSTREAM *stream) int vstream_pclose(VSTREAM *stream)
{ {
char *myname = "vstream_pclose"; pid_t saved_pid = stream->pid;
BINHASH_INFO *info; VSTREAM_WAITPID_FN saved_waitpid_fn = stream->waitpid_fn;
int pid; pid_t pid;
WAIT_STATUS_T wait_status; WAIT_STATUS_T wait_status;
/* /*
* Sanity check. * Close the pipe. Don't trigger an alarm in vstream_fclose().
*/ */
if (vstream_popen_table == 0 if (saved_pid == 0)
|| (info = binhash_locate(vstream_popen_table, (char *) &stream, msg_panic("vstream_pclose: stream has no process");
sizeof(stream))) == 0) stream->pid = 0;
msg_panic("%s: spurious stream %p", myname, (char *) stream); vstream_fclose(stream);
/* /*
* Close the stream and reap the child exit status. Ignore errors while * Reap the child exit status.
* flushing the stream. The child might already have terminated.
*/ */
(void) vstream_fclose(stream);
do { 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); } while (pid == -1 && errno == EINTR);
binhash_delete(vstream_popen_table, (char *) &stream, sizeof(stream),
(void (*) (char *)) 0);
return (pid == -1 ? -1 : return (pid == -1 ? -1 :
WIFSIGNALED(wait_status) ? WTERMSIG(wait_status) : WIFSIGNALED(wait_status) ? WTERMSIG(wait_status) :
WEXITSTATUS(wait_status)); WEXITSTATUS(wait_status));