2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-29 13:18:12 +00:00

snapshot-20011119

This commit is contained in:
Wietse Venema 2001-11-19 00:00:00 -05:00 committed by Viktor Dukhovni
parent bf47bce10b
commit e36404ccca
32 changed files with 299 additions and 774 deletions

View File

@ -5600,7 +5600,7 @@ Apologies for any names omitted.
Feature: configurable parent domain matching for domain
and hostname/address match lists: either .domain or the
domain name itself.
domain name itself. Files: util/match_ops.c util/match_list.c
Feature: added pretend-to-be-behind-PIX mode to the smtp-sink
test program, in order to stress test some PIX bug workaround
@ -5620,6 +5620,11 @@ Apologies for any names omitted.
20011115
Feature: mailbox_command_maps no longer requires that every
user has an entry. If the user does not have a command
entry, the local delivery agent tries the other delivery
methods instead. File: local/mailbox.c.
Bugfix: reset the smtpd command transaction log between
non-deliveries. File: smtpd/smtpd.c.
@ -5629,6 +5634,31 @@ Apologies for any names omitted.
and eliminated one missing reset (Victor Duchovny, Morgan
Stanley). File: smtpd/smtpd.c.
20011118
Cleanup: replaced unnecessary wrapper code by macros. Files:
global/{string,domain,namadr}_list.[hc].
20011119
Feature: configurable parent domain matching strategy for
transport map lookups. File: trivial-rewrite/transport.c.
New parent_domain_matches_subdomains parameter. This lists
all the Postfix features where a domain name matches itself
and all its subdomains (instead of requiring ".domain.name"
for subdomain matches). Planning for future backwards
compatibility :-) File: global/match_parent_style.c.
Workaround: simplified the PIX ".<CR><LF>" bug to always
sleep for 10 seconds. File: smtp/smtp_proto.c.
20011120
Workaround: disable attribute string length restriction so
that trivial-rewrite does not refuse to rewrite broken mail
headers. Files: util/attr_scan*.c.
Open problems:
Medium: need in-process caching for map lookups. LDAP

View File

@ -1,7 +1,31 @@
Snapshot 20011103 introduces a negligible amount of features and
is all about revision of Postfix internals. With more than 70 pages
of context diffs compared to the previous snapshot, this release
is a baseline for upcoming feature changes.
Incompatible changes with snapshot-20011121
===========================================
The internal protocols have changed again, so you must "postfix
reload" if upgrading from a previous release. The change is from
base64 encoded strings to null-terminated strings.
Major changes with snapshot-20011121
====================================
With host/domain name wildcard matching, the parent domain matching
behavior is now configurable (that is, does "sub.domain.name" match
the pattern "domain.name" or does it match the pattern ".domain.name").
The new configuration parameter "parent_domain_matches_subdomains"
specifies what Postfix features use the "sub.domain.name matches
domain.name" approach. It is expected that eventually, all Postfix
features will use ".domain.name" subdomain matching.
New "warn_if_reject" smtpd pseudo restriction that only warns if
a restriction would reject mail.
Disgusting workaround for a well-known CISCO PIX firewall bug that
causes the .<CR>LF> at the end of mail to be lost. The workaround
has no effect for other mail deliveries.
mailbox_command_maps allows you to configure the external delivery
command per user (local delivery agent only). This feature has
precedence over mailbox_command and home_mailbox settings.
Major changes with snapshot-20011103
====================================

View File

@ -80,4 +80,5 @@ flush.o: ../../include/maps.h
flush.o: ../../include/domain_list.h
flush.o: ../../include/match_list.h
flush.o: ../../include/match_ops.h
flush.o: ../../include/match_parent_style.h
flush.o: ../../include/mail_server.h

View File

@ -160,6 +160,7 @@
#include <mail_scan_dir.h>
#include <maps.h>
#include <domain_list.h>
#include <match_parent_style.h>
/* Single server skeleton. */
@ -636,7 +637,8 @@ static void flush_service(VSTREAM *client_stream, char *unused_service,
static void pre_jail_init(char *unused_name, char **unused_argv)
{
flush_domains = domain_list_init(MATCH_FLAG_PARENT, var_fflush_domains);
flush_domains = domain_list_init(match_parent_style(VAR_FFLUSH_DOMAINS),
var_fflush_domains);
}
/* main - pass control to the single-threaded skeleton */

View File

@ -19,7 +19,7 @@ SRCS = been_here.c bounce.c canon_addr.c cleanup_strerror.c clnt_stream.c \
timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \
tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c \
flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c \
verp_sender.c
verp_sender.c match_parent_style.c
OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
debug_peer.o debug_process.o defer.o deliver_completed.o \
deliver_flock.o deliver_pass.o deliver_request.o domain_list.o \
@ -40,7 +40,7 @@ OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \
tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o \
flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o \
verp_sender.o
verp_sender.o match_parent_style.o
HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
config.h debug_peer.h debug_process.h defer.h deliver_completed.h \
deliver_flock.h deliver_pass.h deliver_request.h domain_list.h \
@ -56,7 +56,8 @@ HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
recipient_list.h record.h resolve_clnt.h resolve_local.h \
rewrite_clnt.h sent.h smtp_stream.h split_addr.h string_list.h \
sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h flush_clnt.h \
mbox_conf.h mbox_open.h abounce.h qmqp_proto.h verp_sender.h
mbox_conf.h mbox_open.h abounce.h qmqp_proto.h verp_sender.h \
match_parent_style.h
TESTSRC = rec2stream.c stream2rec.c recdump.c
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
-Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
@ -321,6 +322,7 @@ debug_peer.o: namadr_list.h
debug_peer.o: ../../include/match_list.h
debug_peer.o: ../../include/match_ops.h
debug_peer.o: debug_peer.h
debug_peer.o: match_parent_style.h
debug_process.o: debug_process.c
debug_process.o: ../../include/sys_defs.h
debug_process.o: ../../include/msg.h
@ -723,6 +725,13 @@ mark_corrupt.o: ../../include/vbuf.h
mark_corrupt.o: mail_queue.h
mark_corrupt.o: ../../include/vstring.h
mark_corrupt.o: mark_corrupt.h
match_parent_style.o: match_parent_style.c
match_parent_style.o: ../../include/sys_defs.h
match_parent_style.o: string_list.h
match_parent_style.o: ../../include/match_list.h
match_parent_style.o: ../../include/match_ops.h
match_parent_style.o: mail_params.h
match_parent_style.o: match_parent_style.h
mbox_conf.o: mbox_conf.c
mbox_conf.o: ../../include/sys_defs.h
mbox_conf.o: ../../include/name_mask.h
@ -942,6 +951,7 @@ resolve_local.o: ../../include/match_ops.h
resolve_local.o: mail_params.h
resolve_local.o: own_inet_addr.h
resolve_local.o: resolve_local.h
resolve_local.o: match_parent_style.h
rewrite_clnt.o: rewrite_clnt.c
rewrite_clnt.o: ../../include/sys_defs.h
rewrite_clnt.o: ../../include/msg.h

View File

@ -69,6 +69,7 @@
#include <mail_params.h>
#include <namadr_list.h>
#include <debug_peer.h>
#include <match_parent_style.h>
/* Application-specific. */
@ -97,8 +98,9 @@ void debug_peer_init(void)
* Finally.
*/
if (*var_debug_peer_list)
debug_peer_list = namadr_list_init(MATCH_FLAG_PARENT,
var_debug_peer_list);
debug_peer_list =
namadr_list_init(match_parent_style(VAR_DEBUG_PEER_LIST),
var_debug_peer_list);
}
/* debug_peer_check - see if this peer needs verbose logging */

View File

@ -38,11 +38,8 @@
/* .RS
/* .IP MATCH_FLAG_PARENT
/* The hostname pattern foo.com matches itself and any name below
/* the domain foo.com.
/* .IP MATCH_FLAG_DOTPARENT
/* The hostname pattern foo.com matches itself only.
/* The hostname pattern .foo.com matches any name below the domain
/* foo.com.
/* the domain foo.com. If this flag is cleared, foo.com matches itself
/* only, and .foo.com matches any name below the domain foo.com.
/* .RE
/* Specify MATCH_FLAG_NONE to request none of the above.
/* The second argument is a list of domain patterns, or the name of
@ -112,7 +109,7 @@ main(int argc, char **argv)
}
if (argc != optind + 2)
usage(argv[0]);
list = domain_list_init(argv[optind]);
list = domain_list_init(MATCH_FLAG_PARENT, argv[optind]);
host = argv[optind + 1];
vstream_printf("%s: %s\n", host, domain_list_match(list, host) ?
"YES" : "NO");

View File

@ -64,6 +64,7 @@
/* char *var_mynetworks_style;
/* char *var_verp_delims;
/* char *var_verp_filter;
/* char *var_par_dom_match;
/*
/* char *var_import_environ;
/* char *var_export_environ;
@ -187,6 +188,7 @@ char *var_mynetworks_style;
char *var_verp_delims;
char *var_verp_filter;
int var_in_flow_delay;
char *var_par_dom_match;
char *var_import_environ;
char *var_export_environ;
@ -312,6 +314,7 @@ void mail_params_init()
VAR_DEBUG_PEER_LIST, DEF_DEBUG_PEER_LIST, &var_debug_peer_list, 0, 0,
VAR_VERP_DELIMS, DEF_VERP_DELIMS, &var_verp_delims, 2, 2,
VAR_VERP_FILTER, DEF_VERP_FILTER, &var_verp_filter, 1, 0,
VAR_PAR_DOM_MATCH, DEF_PAR_DOM_MATCH, &var_par_dom_match, 0, 0,
0,
};
static CONFIG_STR_FN_TABLE function_str_defaults_2[] = {

View File

@ -1321,6 +1321,21 @@ extern bool var_verp_bounce_off;
#define DEF_IN_FLOW_DELAY "1s"
extern int var_in_flow_delay;
/*
* Backwards compatibility: foo.com matches itself and names below foo.com.
*/
#define VAR_PAR_DOM_MATCH "parent_domain_matches_subdomains"
#define DEF_PAR_DOM_MATCH VAR_DEBUG_PEER_LIST "," \
VAR_FFLUSH_DOMAINS "," \
VAR_MYNETWORKS "," \
VAR_PERM_MX_NETWORKS "," \
VAR_QMQPD_CLIENTS "," \
VAR_RELAY_DOMAINS "," \
SMTPD_ACCESS_MAPS
extern char *var_par_dom_match;
#define SMTPD_ACCESS_MAPS "smtpd_access_maps"
/* LICENSE
/* .ad
/* .fi

View File

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

View File

@ -0,0 +1,72 @@
/*++
/* NAME
/* match_parent_style 3
/* SUMMARY
/* parent domain matching control
/* SYNOPSIS
/* #include <match_parent_style.h>
/*
/* int match_parent_style(name)
/* const char *name;
/* DESCRIPTION
/* This module queries configuration parameters for the policy that
/* controls how wild-card parent domain names are used by various
/* postfix lookup mechanisms.
/*
/* match_parent_style() looks up "name" in the
/* parent_domain_matches_subdomain configuration parameter
/* and returns either MATCH_FLAG_PARENT or MATCH_PARENT_NONE.
/* DIAGNOSTICS
/* Fatal error: out of memory, name listed under both parent wild card
/* matching policies.
/* SEE ALSO
/* string_list(3) plain string matching
/* domain_list(3) match host name patterns
/* namadr_list(3) match host name/address patterns
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
/* Utility library. */
/* Global library. */
#include <string_list.h>
#include <mail_params.h>
#include <match_parent_style.h>
/* Application-specific. */
static STRING_LIST *match_par_dom_list;
int match_parent_style(const char *name)
{
int result;
/*
* Initialize on the fly.
*/
if (match_par_dom_list == 0)
match_par_dom_list =
string_list_init(MATCH_FLAG_NONE, var_par_dom_match);
/*
* Look up the parent domain matching policy.
*/
if (string_list_match(match_par_dom_list, name))
result = MATCH_FLAG_PARENT;
else
result = 0;
return (result);
}

View File

@ -0,0 +1,35 @@
#ifndef _MATCH_PARENT_STYLE_H_INCLUDED_
#define _MATCH_PARENT_STYLE_H_INCLUDED_
/*++
/* NAME
/* match_parent_style 3h
/* SUMMARY
/* parent domain matching control
/* SYNOPSIS
/* #include <match_parent_style.h>
/* DESCRIPTION
/* .nf
/*
* Utility library.
*/
#include <match_ops.h>
/*
* External interface.
*/
extern int match_parent_style(const char *);
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
#endif

View File

@ -39,16 +39,13 @@
/* pattern. The matching process is case insensitive.
/*
/* namadr_list_init() performs initializations. The first
/* argument is the bit-wise OR of zero or mor of the
/* argument is the bit-wise OR of zero or more of the
/* following:
/* .RS
/* .IP MATCH_FLAG_PARENT
/* The hostname pattern foo.com matches itself and any name below
/* the domain foo.com.
/* .IP MATCH_FLAG_DOTPARENT
/* The hostname pattern foo.com matches itself only.
/* The hostname pattern .foo.com matches any name below the domain
/* foo.com.
/* The hostname pattern foo.com matches itself and any name below
/* the domain foo.com. If this flag is cleared, foo.com matches itself
/* only, and .foo.com matches any name below the domain foo.com.
/* .RE
/* Specify MATCH_FLAG_NONE to request none of the above.
/* The second argument is a list of patterns, or the absolute
@ -109,22 +106,22 @@ main(int argc, char **argv)
msg_vstream_init(argv[0], VSTREAM_ERR);
while ((ch = GETOPT(argc, argv, "v")) > 0) {
switch (ch) {
case 'v':
msg_verbose++;
break;
default:
usage(argv[0]);
}
switch (ch) {
case 'v':
msg_verbose++;
break;
default:
usage(argv[0]);
}
}
if (argc != optind + 3)
usage(argv[0]);
list = namadr_list_init(argv[optind]);
usage(argv[0]);
list = namadr_list_init(MATCH_FLAG_PARENT, argv[optind]);
host = argv[optind + 1];
addr = argv[optind + 2];
vstream_printf("%s/%s: %s\n", host, addr,
namadr_list_match(list, host, addr) ?
"YES" : "NO");
namadr_list_match(list, host, addr) ?
"YES" : "NO");
vstream_fflush(VSTREAM_OUT);
namadr_list_free(list);
}

View File

@ -58,6 +58,7 @@
#include <mail_params.h>
#include <own_inet_addr.h>
#include <resolve_local.h>
#include <match_parent_style.h>
/* Application-specific */

View File

@ -98,7 +98,7 @@ main(int argc, char **argv)
}
if (argc != optind + 2)
usage(argv[0]);
list = string_list_init(argv[optind]);
list = string_list_init(MATCH_FLAG_NONE, argv[optind]);
string = argv[optind + 1];
vstream_printf("%s: %s\n", string, string_list_match(list, string) ?
"YES" : "NO");

View File

@ -92,6 +92,7 @@ qmqpd.o: ../../include/namadr_list.h
qmqpd.o: ../../include/match_list.h
qmqpd.o: ../../include/match_ops.h
qmqpd.o: ../../include/quote_822_local.h
qmqpd.o: ../../include/match_parent_style.h
qmqpd.o: ../../include/mail_server.h
qmqpd.o: qmqpd.h
qmqpd_peer.o: qmqpd_peer.c

View File

@ -135,6 +135,7 @@
#include <mail_stream.h>
#include <namadr_list.h>
#include <quote_822_local.h>
#include <match_parent_style.h>
/* Single-threaded server skeleton. */
@ -643,7 +644,9 @@ static void pre_accept(char *unused_name, char **unused_argv)
static void pre_jail_init(char *unused_name, char **unused_argv)
{
debug_peer_init();
qmqpd_clients = namadr_list_init(MATCH_FLAG_PARENT, var_qmqpd_clients);
qmqpd_clients =
namadr_list_init(match_parent_style(VAR_QMQPD_CLIENTS),
var_qmqpd_clients);
}
/* main - the main program */

View File

@ -663,8 +663,7 @@ int smtp_xfer(SMTP_STATE *state)
smtp_fputs("", 0, session->stream);
if ((state->features & SMTP_FEATURE_MAYBEPIX) != 0) {
vstream_fflush(session->stream);/* hurts performance */
sock_empty_wait(vstream_fileno(session->stream),
session->stream->timeout / 2);
sleep(10); /* not to mention this */
}
if (vstream_ferror(state->src))
msg_fatal("queue file read error");

View File

@ -189,6 +189,7 @@ smtpd_check.o: ../../include/own_inet_addr.h
smtpd_check.o: ../../include/mail_conf.h
smtpd_check.o: ../../include/maps.h
smtpd_check.o: ../../include/mail_addr_find.h
smtpd_check.o: ../../include/match_parent_style.h
smtpd_check.o: smtpd.h
smtpd_check.o: ../../include/mail_stream.h
smtpd_check.o: smtpd_sasl_glue.h

View File

@ -289,6 +289,7 @@
#include <mail_conf.h>
#include <maps.h>
#include <mail_addr_find.h>
#include <match_parent_style.h>
/* Application-specific. */
@ -339,6 +340,11 @@ static DOMAIN_LIST *relay_domains;
static NAMADR_LIST *mynetworks;
static NAMADR_LIST *perm_mx_networks;
/*
* How to do parent domain wildcard matching, if any.
*/
static int access_parent_style;
/*
* Pre-parsed restriction lists.
*/
@ -456,10 +462,9 @@ static int has_required(ARGV *restrictions, char **required)
rest += 1;
continue;
}
for (reqd = required; *reqd; reqd++) {
for (reqd = required; *reqd; reqd++)
if (strcmp(*rest, *reqd) == 0)
return (1);
}
if ((expansion = (ARGV *) htable_find(smtpd_rest_classes, *rest)) != 0)
if (has_required(expansion, required))
return (1);
@ -486,8 +491,8 @@ static void fail_required(char *name, char **required)
*/
example = vstring_alloc(10);
for (reqd = required; *reqd; reqd++)
vstring_sprintf_append(example, "%s%s", *reqd,
reqd[1] == 0 ? "" : reqd[2] == 0 ? " or " : ", ");
vstring_sprintf_append(example, "%s%s", *reqd,
reqd[1] == 0 ? "" : reqd[2] == 0 ? " or " : ", ");
msg_fatal("parameter \"%s\": specify at least one working instance of: %s",
name, STR(example));
}
@ -510,9 +515,15 @@ void smtpd_check_init(void)
/*
* Pre-open access control lists before going to jail.
*/
mynetworks = namadr_list_init(MATCH_FLAG_PARENT, var_mynetworks);
relay_domains = domain_list_init(MATCH_FLAG_PARENT, var_relay_domains);
perm_mx_networks = namadr_list_init(MATCH_FLAG_PARENT, var_perm_mx_networks);
mynetworks =
namadr_list_init(match_parent_style(VAR_MYNETWORKS),
var_mynetworks);
relay_domains =
domain_list_init(match_parent_style(VAR_RELAY_DOMAINS),
var_relay_domains);
perm_mx_networks =
namadr_list_init(match_parent_style(VAR_PERM_MX_NETWORKS),
var_perm_mx_networks);
/*
* Pre-parse and pre-open the recipient maps.
@ -530,6 +541,8 @@ void smtpd_check_init(void)
relocated_maps = maps_create(VAR_RELOCATED_MAPS, var_relocated_maps,
DICT_FLAG_LOCK);
access_parent_style = match_parent_style(SMTPD_ACCESS_MAPS);
/*
* error_text is used for returning error responses.
*/
@ -1562,7 +1575,7 @@ static int check_domain_access(SMTPD_STATE *state, const char *table,
if ((dict = dict_handle(table)) == 0)
msg_panic("%s: dictionary not found: %s", myname, table);
for (name = low_domain; /* void */ ; name = next + 1) {
for (name = low_domain; /* void */ ; name = next) {
if (flags == 0 || (flags & dict->flags) != 0) {
if ((value = dict_get(dict, name)) != 0)
CHK_DOMAIN_RETURN(check_table_result(state, table, value,
@ -1571,8 +1584,10 @@ static int check_domain_access(SMTPD_STATE *state, const char *table,
if (dict_errno != 0)
msg_fatal("%s: table lookup problem", table);
}
if ((next = strchr(name, '.')) == 0)
if ((next = strchr(name + 1, '.')) == 0)
break;
if (access_parent_style == MATCH_FLAG_PARENT)
next += 1;
flags = PARTIAL;
}
CHK_DOMAIN_RETURN(SMTPD_CHECK_DUNNO, MISSED);
@ -2456,6 +2471,7 @@ char *var_virt_mailbox_maps;
char *var_relocated_maps;
char *var_local_rcpt_maps;
char *var_perm_mx_networks;
char *var_par_dom_match;
typedef struct {
char *name;
@ -2477,7 +2493,8 @@ static STRING_TABLE string_table[] = {
VAR_VIRT_MAILBOX_MAPS, DEF_VIRT_MAILBOX_MAPS, &var_virt_mailbox_maps,
VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps,
VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps,
VAR_PERM_MX_NETWORKS, DEF_PERM_MX_NETWORKS, &var_perm_mx_networks, 0, 0,
VAR_PERM_MX_NETWORKS, DEF_PERM_MX_NETWORKS, &var_perm_mx_networks,
VAR_PAR_DOM_MATCH, DEF_PAR_DOM_MATCH, &var_par_dom_match,
0,
};
@ -2815,13 +2832,17 @@ int main(int argc, char **argv)
}
if (strcasecmp(args->argv[0], "mynetworks") == 0) {
namadr_list_free(mynetworks);
mynetworks = namadr_list_init(MATCH_FLAG_PARENT, args->argv[1]);
mynetworks =
namadr_list_init(match_parent_style(VAR_MYNETWORKS),
args->argv[1]);
resp = 0;
break;
}
if (strcasecmp(args->argv[0], "relay_domains") == 0) {
domain_list_free(relay_domains);
relay_domains = domain_list_init(MATCH_FLAG_PARENT, args->argv[1]);
relay_domains =
domain_list_init(match_parent_style(VAR_RELAY_DOMAINS),
args->argv[1]);
resp = 0;
break;
}

View File

@ -62,12 +62,14 @@
#include <mail_params.h>
#include <maps.h>
#include <match_parent_style.h>
/* Application-specific. */
#include "transport.h"
static MAPS *transport_path;
static int transport_match_parent_style;
/* transport_init - pre-jail initialization */
@ -77,6 +79,7 @@ void transport_init(void)
msg_panic("transport_init: repeated call");
transport_path = maps_create("transport", var_transport_maps,
DICT_FLAG_LOCK);
transport_match_parent_style = match_parent_style(VAR_TRANSPORT_MAPS);
}
/* transport_lookup - map a transport domain */
@ -85,6 +88,7 @@ int transport_lookup(const char *domain, VSTRING *channel, VSTRING *nexthop)
{
char *low_domain = lowercase(mystrdup(domain));
const char *name;
const char *next;
const char *value;
const char *host;
char *saved_value;
@ -113,7 +117,7 @@ int transport_lookup(const char *domain, VSTRING *channel, VSTRING *nexthop)
* Specify if a key is partial or full, to avoid matching partial keys with
* regular expressions.
*/
for (name = low_domain; name != 0; name = strchr(name + 1, '.')) {
for (name = low_domain; /* void */; name = next) {
if ((value = maps_find(transport_path, name, maps_flag)) != 0) {
saved_value = mystrdup(value);
if ((host = split_at(saved_value, ':')) == 0 || *host == 0)
@ -132,6 +136,10 @@ int transport_lookup(const char *domain, VSTRING *channel, VSTRING *nexthop)
} else if (dict_errno != 0) {
msg_fatal("transport table lookup problem");
}
if ((next = strchr(name + 1, '.')) == 0)
break;
if (transport_match_parent_style == MATCH_FLAG_PARENT)
next++;
maps_flag = PARTIAL;
}
myfree(low_domain);

View File

@ -1,227 +0,0 @@
/*++
/* NAME
/* attr_print 3
/* SUMMARY
/* send attributes over byte stream
/* SYNOPSIS
/* #include <attr.h>
/*
/* int attr_print(fp, flags, type, name, ...)
/* VSTREAM fp;
/* int flags;
/* int type;
/* char *name;
/*
/* int attr_vprint(fp, flags, ap)
/* VSTREAM fp;
/* int flags;
/* va_list ap;
/* DESCRIPTION
/* attr_print() takes zero or more (name, value) simple attributes
/* or (name, count, value) list attributes, and converts its input
/* to a byte stream that can be recovered with attr_scan(). The stream
/* is not flushed.
/*
/* attr_vprint() provides an alternate interface that is convenient
/* for calling from within variadoc functions.
/*
/* Attributes are sent in the requested order as specified with the
/* attr_print() argument list. This routine satisfies the formatting
/* rules as outlined in attr_scan(3).
/*
/* Arguments:
/* .IP fp
/* Stream to write the result to.
/* .IP flags
/* The bit-wise OR of zero or more of the following.
/* .RS
/* .IP ATTR_FLAG_MORE
/* After sending the requested attributes, leave the output stream in
/* a state that is usable for more attribute sending operations on
/* the same output attribute list.
/* By default, attr_print() automatically appends an attribute list
/* terminator when it has sent the last requested attribute.
/* .RE
/* .IP type
/* The type determines the arguments that follow.
/* .RS
/* .IP "ATTR_TYPE_NUM (char *, int)"
/* This argument is followed by an attribute name and an integer.
/* .IP "ATTR_TYPE_STR (char *, char *)"
/* This argument is followed by an attribute name and a null-terminated
/* string.
/* .IP "ATTR_TYPE_HASH (HTABLE *)"
/* The content of the hash table is sent as a sequence of string-valued
/* attributes with names equal to the hash table lookup key.
/* .IP ATTR_TYPE_END
/* This terminates the attribute list.
/* .RE
/* DIAGNOSTICS
/* The result value is 0 in case of success, VSTREAM_EOF in case
/* of trouble.
/*
/* Panic: interface violation. All system call errors are fatal.
/* SEE ALSO
/* attr_scan(3) recover attributes from byte stream
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
#include <stdarg.h>
/* Utility library. */
#include <msg.h>
#include <mymalloc.h>
#include <vstream.h>
#include <htable.h>
#include <base64_code.h>
#include <attr.h>
#define STR(x) vstring_str(x)
#define LEN(x) VSTRING_LEN(x)
/* attr_print_str - encode and send attribute information */
static void attr_print_str(VSTREAM *fp, const char *str, int len)
{
static VSTRING *base64_buf;
if (base64_buf == 0)
base64_buf = vstring_alloc(10);
base64_encode(base64_buf, str, len);
vstream_fputs(STR(base64_buf), fp);
}
static void attr_print_num(VSTREAM *fp, unsigned num)
{
static VSTRING *plain;
if (plain == 0)
plain = vstring_alloc(10);
vstring_sprintf(plain, "%u", num);
attr_print_str(fp, STR(plain), LEN(plain));
}
/* attr_vprint - send attribute list to stream */
int attr_vprint(VSTREAM *fp, int flags, va_list ap)
{
const char *myname = "attr_print";
int attr_type;
char *attr_name;
unsigned int_val;
char *str_val;
HTABLE_INFO **ht_info_list;
HTABLE_INFO **ht;
/*
* Sanity check.
*/
if (flags & ~ATTR_FLAG_ALL)
msg_panic("%s: bad flags: 0x%x", myname, flags);
/*
* Iterate over all (type, name, value) triples, and produce output on
* the fly.
*/
while ((attr_type = va_arg(ap, int)) != ATTR_TYPE_END) {
switch (attr_type) {
case ATTR_TYPE_NUM:
attr_name = va_arg(ap, char *);
attr_print_str(fp, attr_name, strlen(attr_name));
int_val = va_arg(ap, int);
VSTREAM_PUTC(':', fp);
attr_print_num(fp, (unsigned) int_val);
if (msg_verbose)
msg_info("send attr %s = %u", attr_name, int_val);
break;
case ATTR_TYPE_STR:
attr_name = va_arg(ap, char *);
attr_print_str(fp, attr_name, strlen(attr_name));
str_val = va_arg(ap, char *);
VSTREAM_PUTC(':', fp);
attr_print_str(fp, str_val, strlen(str_val));
if (msg_verbose)
msg_info("send attr %s = %s", attr_name, str_val);
break;
case ATTR_TYPE_HASH:
ht_info_list = htable_list(va_arg(ap, HTABLE *));
for (ht = ht_info_list; *ht; ht++) {
attr_print_str(fp, ht[0]->key, strlen(ht[0]->key));
VSTREAM_PUTC(':', fp);
attr_print_str(fp, ht[0]->value, strlen(ht[0]->value));
if (msg_verbose)
msg_info("send attr name %s value %s",
ht[0]->key, ht[0]->value);
if (ht[1] != 0)
VSTREAM_PUTC('\n', fp);
}
myfree((char *) ht_info_list);
break;
default:
msg_panic("%s: unknown type code: %d", myname, attr_type);
}
VSTREAM_PUTC('\n', fp);
}
if ((flags & ATTR_FLAG_MORE) == 0)
VSTREAM_PUTC('\n', fp);
return (vstream_ferror(fp));
}
int attr_print(VSTREAM *fp, int flags,...)
{
va_list ap;
int ret;
va_start(ap, flags);
ret = attr_vprint(fp, flags, ap);
va_end(ap);
return (ret);
}
#ifdef TEST
/*
* Proof of concept test program. Mirror image of the attr_scan test
* program.
*/
#include <msg_vstream.h>
int main(int unused_argc, char **argv)
{
HTABLE *table = htable_create(1);
msg_vstream_init(argv[0], VSTREAM_ERR);
msg_verbose = 1;
htable_enter(table, "foo-name", mystrdup("foo-value"));
htable_enter(table, "bar-name", mystrdup("bar-value"));
attr_print(VSTREAM_OUT, ATTR_FLAG_NONE,
ATTR_TYPE_NUM, ATTR_NAME_NUM, 4711,
ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee",
ATTR_TYPE_HASH, table,
ATTR_TYPE_END);
attr_print(VSTREAM_OUT, ATTR_FLAG_NONE,
ATTR_TYPE_NUM, ATTR_NAME_NUM, 4711,
ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee",
ATTR_TYPE_END);
if (vstream_fflush(VSTREAM_OUT) != 0)
msg_fatal("write error: %m");
htable_free(table, myfree);
return (0);
}
#endif

View File

@ -1,460 +0,0 @@
/*++
/* NAME
/* attr_scan 3
/* SUMMARY
/* recover attributes from byte stream
/* SYNOPSIS
/* #include <attr.h>
/*
/* int attr_scan(fp, flags, type, name, ...)
/* VSTREAM fp;
/* int flags;
/* int type;
/* char *name;
/*
/* int attr_vscan(fp, flags, ap)
/* VSTREAM fp;
/* int flags;
/* va_list ap;
/* DESCRIPTION
/* attr_scan() takes zero or more (name, value) request attributes
/* and recovers the attribute values from the byte stream that was
/* possibly generated by attr_print().
/*
/* attr_vscan() provides an alternative interface that is convenient
/* for calling from within a variadic function.
/*
/* The input stream is formatted as follows, where (item)* stands
/* for zero or more instances of the specified item, and where
/* (item1 | item2) stands for choice:
/*
/* .in +5
/* attr-list :== simple-attr* newline
/* .br
/* simple-attr :== attr-name colon attr-value newline
/* .br
/* attr-name :== any base64 encoded string
/* .br
/* attr-value :== any base64 encoded string
/* .br
/* colon :== the ASCII colon character
/* .br
/* newline :== the ASCII newline character
/* .in
/*
/* All attribute names and attribute values are sent as base64-encoded
/* strings. Each base64 encoding must be no longer than 2*var_line_limit
/* characters. The formatting rules aim to make implementations in PERL
/* and other languages easy.
/*
/* Normally, attributes must be received in the sequence as specified with
/* the attr_scan() argument list. The input stream may contain additional
/* attributes at any point in the input stream, including additional
/* instances of requested attributes.
/*
/* Additional input attributes or input attribute instances are silently
/* skipped over, unless the ATTR_FLAG_EXTRA processing flag is specified
/* (see below). This allows for some flexibility in the evolution of
/* protocols while still providing the option of being strict where
/* this is desirable.
/*
/* Arguments:
/* .IP fp
/* Stream to recover the input attributes from.
/* .IP flags
/* The bit-wise OR of zero or more of the following.
/* .RS
/* .IP ATTR_FLAG_MISSING
/* Log a warning when the input attribute list terminates before all
/* requested attributes are recovered. It is always an error when the
/* input stream ends without the newline attribute list terminator.
/* .IP ATTR_FLAG_EXTRA
/* Log a warning and stop attribute recovery when the input stream
/* contains an attribute that was not requested. This includes the
/* case of additional instances of a requested attribute.
/* .IP ATTR_FLAG_MORE
/* After recovering the requested attributes, leave the input stream
/* in a state that is usable for more attr_scan() operations from the
/* same input attribute list.
/* By default, attr_scan() skips forward past the input attribute list
/* terminator.
/* .IP ATTR_FLAG_STRICT
/* For convenience, this value combines both ATTR_FLAG_MISSING and
/* ATTR_FLAG_EXTRA.
/* .IP ATTR_FLAG_NONE
/* For convenience, this value requests none of the above.
/* .RE
/* .IP type
/* The type argument determines the arguments that follow.
/* .RS
/* .IP "ATTR_TYPE_NUM (char *, int *)"
/* This argument is followed by an attribute name and an integer pointer.
/* .IP "ATTR_TYPE_STR (char *, VSTRING *)"
/* This argument is followed by an attribute name and a VSTRING pointer.
/* .IP "ATTR_TYPE_HASH (HTABLE *)"
/* All further input attributes are processed as string attributes.
/* No specific attribute sequence is enforced.
/* All attributes up to the attribute list terminator are read,
/* but only the first instance of each attribute is stored.
/* .sp
/* The attribute string values are stored in the hash table under
/* keys equal to the attribute name (obtained from the input stream).
/* Values from the input stream are added to the hash table. Existing
/* hash table entries are not replaced.
/* .sp
/* N.B. This construct must be followed by an ATTR_TYPE_END argument.
/* .IP ATTR_TYPE_END
/* This argument terminates the requested attribute list.
/* .RE
/* BUGS
/* ATTR_TYPE_HASH accepts attributes with arbitrary names from possibly
/* untrusted sources. This is unsafe, unless the resulting table is
/* queried only with known to be good attribute names.
/* DIAGNOSTICS
/* attr_scan() and attr_vscan() return -1 when malformed input is
/* detected (string too long, incomplete line, missing end marker).
/* Otherwise, the result value is the number of attributes that were
/* successfully recovered from the input stream (a hash table counts
/* as the number of entries stored into the table).
/*
/* Panic: interface violation. All system call errors are fatal.
/* SEE ALSO
/* attr_print(3) send attributes over byte stream.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
#include <stdarg.h>
#include <stdio.h>
/* Utility library. */
#include <msg.h>
#include <mymalloc.h>
#include <vstream.h>
#include <vstring.h>
#include <htable.h>
#include <base64_code.h>
#include <attr.h>
/* Application specific. */
#define STR(x) vstring_str(x)
#define LEN(x) VSTRING_LEN(x)
/* attr_scan_string - pull a string from the input stream */
static int attr_scan_string(VSTREAM *fp, VSTRING *plain_buf, const char *context)
{
static VSTRING *base64_buf = 0;
extern int var_line_limit; /* XXX */
int limit = var_line_limit * 2;
int ch;
if (base64_buf == 0)
base64_buf = vstring_alloc(10);
VSTRING_RESET(base64_buf);
while ((ch = VSTREAM_GETC(fp)) != ':' && ch != '\n') {
if (ch == VSTREAM_EOF) {
msg_warn("premature end-of-input from %s while reading %s",
VSTREAM_PATH(fp), context);
return (-1);
}
VSTRING_ADDCH(base64_buf, ch);
if (LEN(base64_buf) > limit) {
msg_warn("string length > %d characters from %s while reading %s",
limit, VSTREAM_PATH(fp), context);
return (-1);
}
}
VSTRING_TERMINATE(base64_buf);
if (base64_decode(plain_buf, STR(base64_buf), LEN(base64_buf)) == 0) {
msg_warn("malformed base64 data from %s: %.100s",
VSTREAM_PATH(fp), STR(base64_buf));
return (-1);
}
if (msg_verbose)
msg_info("%s: %s", context, *STR(plain_buf) ? STR(plain_buf) : "(end)");
return (ch);
}
/* attr_scan_number - pull a number from the input stream */
static int attr_scan_number(VSTREAM *fp, unsigned *ptr, VSTRING *str_buf,
const char *context)
{
char junk = 0;
int ch;
if ((ch = attr_scan_string(fp, str_buf, context)) < 0)
return (-1);
if (sscanf(STR(str_buf), "%u%c", ptr, &junk) != 1 || junk != 0) {
msg_warn("malformed numerical data from %s while reading %s: %.100s",
VSTREAM_PATH(fp), context, STR(str_buf));
return (-1);
}
return (ch);
}
/* attr_vscan - receive attribute list from stream */
int attr_vscan(VSTREAM *fp, int flags, va_list ap)
{
const char *myname = "attr_scan";
static VSTRING *str_buf = 0;
static VSTRING *name_buf = 0;
int wanted_type = -1;
char *wanted_name;
unsigned int *number;
VSTRING *string;
HTABLE *hash_table;
int ch;
int conversions;
/*
* Sanity check.
*/
if (flags & ~ATTR_FLAG_ALL)
msg_panic("%s: bad flags: 0x%x", myname, flags);
/*
* Initialize.
*/
if (str_buf == 0) {
str_buf = vstring_alloc(10);
name_buf = vstring_alloc(10);
}
/*
* Iterate over all (type, name, value) triples.
*/
for (conversions = 0; /* void */ ; conversions++) {
/*
* Determine the next attribute type and attribute name on the
* caller's wish list.
*
* If we're reading into a hash table, we already know that the
* attribute value is string-valued, and we get the attribute name
* from the input stream instead. This is secure only when the
* resulting table is queried with known to be good attribute names.
*/
if (wanted_type != ATTR_TYPE_HASH) {
wanted_type = va_arg(ap, int);
if (wanted_type == ATTR_TYPE_END) {
if ((flags & ATTR_FLAG_MORE) != 0)
return (conversions);
wanted_name = "(list terminator)";
} else if (wanted_type == ATTR_TYPE_HASH) {
wanted_name = "(any attribute name or list terminator)";
hash_table = va_arg(ap, HTABLE *);
if (va_arg(ap, int) !=ATTR_TYPE_END)
msg_panic("%s: ATTR_TYPE_HASH not followed by ATTR_TYPE_END",
myname);
} else {
wanted_name = va_arg(ap, char *);
}
}
/*
* Locate the next attribute of interest in the input stream.
*/
for (;;) {
/*
* Get the name of the next attribute. Hitting EOF is always bad.
* Hitting the end-of-input early is OK if the caller is prepared
* to deal with missing inputs.
*/
if (msg_verbose)
msg_info("%s: wanted attribute: %s",
VSTREAM_PATH(fp), wanted_name);
if ((ch = attr_scan_string(fp, name_buf,
"input attribute name")) == VSTREAM_EOF)
return (-1);
if (ch == '\n' && LEN(name_buf) == 0) {
if (wanted_type == ATTR_TYPE_END
|| wanted_type == ATTR_TYPE_HASH)
return (conversions);
if ((flags & ATTR_FLAG_MISSING) != 0)
msg_warn("missing attribute %s in input from %s",
wanted_name, VSTREAM_PATH(fp));
return (conversions);
}
/*
* See if the caller asks for this attribute.
*/
if (wanted_type == ATTR_TYPE_HASH
|| (wanted_type != ATTR_TYPE_END
&& strcmp(wanted_name, STR(name_buf)) == 0))
break;
if ((flags & ATTR_FLAG_EXTRA) != 0) {
msg_warn("spurious attribute %s in input from %s",
STR(name_buf), VSTREAM_PATH(fp));
return (conversions);
}
/*
* Skip over this attribute. The caller does not ask for it.
*/
while ((ch = VSTREAM_GETC(fp)) != VSTREAM_EOF && ch != '\n')
/* void */ ;
}
/*
* Do the requested conversion. If the target attribute is a
* non-array type, disallow sending a multi-valued attribute, and
* disallow sending no value. If the target attribute is an array
* type, allow the sender to send a zero-element array (i.e. no value
* at all). XXX Need to impose a bound on the number of array
* elements.
*/
switch (wanted_type) {
case ATTR_TYPE_NUM:
if (ch != ':') {
msg_warn("missing value for number attribute %s from %s",
STR(name_buf), VSTREAM_PATH(fp));
return (-1);
}
number = va_arg(ap, unsigned int *);
if ((ch = attr_scan_number(fp, number, str_buf,
"input attribute value")) < 0)
return (-1);
if (ch != '\n') {
msg_warn("multiple values for attribute %s from %s",
STR(name_buf), VSTREAM_PATH(fp));
return (-1);
}
break;
case ATTR_TYPE_STR:
if (ch != ':') {
msg_warn("missing value for string attribute %s from %s",
STR(name_buf), VSTREAM_PATH(fp));
return (-1);
}
string = va_arg(ap, VSTRING *);
if ((ch = attr_scan_string(fp, string,
"input attribute value")) < 0)
return (-1);
if (ch != '\n') {
msg_warn("multiple values for attribute %s from %s",
STR(name_buf), VSTREAM_PATH(fp));
return (-1);
}
break;
case ATTR_TYPE_HASH:
if (ch != ':') {
msg_warn("missing value for string attribute %s from %s",
STR(name_buf), VSTREAM_PATH(fp));
return (-1);
}
if ((ch = attr_scan_string(fp, str_buf,
"input attribute value")) < 0)
return (-1);
if (ch != '\n') {
msg_warn("multiple values for attribute %s from %s",
STR(name_buf), VSTREAM_PATH(fp));
return (-1);
}
if (htable_locate(hash_table, STR(name_buf)) != 0) {
if ((flags & ATTR_FLAG_EXTRA) != 0) {
msg_warn("duplicate attribute %s in input from %s",
STR(name_buf), VSTREAM_PATH(fp));
return (conversions);
}
} else {
htable_enter(hash_table, STR(name_buf),
mystrdup(STR(str_buf)));
}
break;
default:
msg_panic("%s: unknown type code: %d", myname, wanted_type);
}
}
}
/* attr_scan - read attribute list from stream */
int attr_scan(VSTREAM *fp, int flags,...)
{
va_list ap;
int ret;
va_start(ap, flags);
ret = attr_vscan(fp, flags, ap);
va_end(ap);
return (ret);
}
#ifdef TEST
/*
* Proof of concept test program. Mirror image of the attr_scan test
* program.
*/
#include <msg_vstream.h>
int var_line_limit = 2048;
int main(int unused_argc, char **used_argv)
{
VSTRING *str_val = vstring_alloc(1);
HTABLE *table = htable_create(1);
HTABLE_INFO **ht_info_list;
HTABLE_INFO **ht;
int int_val;
int ret;
msg_verbose = 1;
msg_vstream_init(used_argv[0], VSTREAM_ERR);
if ((ret = attr_scan(VSTREAM_IN,
ATTR_FLAG_STRICT,
ATTR_TYPE_NUM, ATTR_NAME_NUM, &int_val,
ATTR_TYPE_STR, ATTR_NAME_STR, str_val,
ATTR_TYPE_HASH, table,
ATTR_TYPE_END)) > 2) {
vstream_printf("%s %d\n", ATTR_NAME_NUM, int_val);
vstream_printf("%s %s\n", ATTR_NAME_STR, STR(str_val));
ht_info_list = htable_list(table);
for (ht = ht_info_list; *ht; ht++)
vstream_printf("(hash) %s %s\n", ht[0]->key, ht[0]->value);
myfree((char *) ht_info_list);
} else {
vstream_printf("return: %d\n", ret);
}
if ((ret = attr_scan(VSTREAM_IN,
ATTR_FLAG_STRICT,
ATTR_TYPE_NUM, ATTR_NAME_NUM, &int_val,
ATTR_TYPE_STR, ATTR_NAME_STR, str_val,
ATTR_TYPE_END)) == 2) {
vstream_printf("%s %d\n", ATTR_NAME_NUM, int_val);
vstream_printf("%s %s\n", ATTR_NAME_STR, STR(str_val));
ht_info_list = htable_list(table);
for (ht = ht_info_list; *ht; ht++)
vstream_printf("(hash) %s %s\n", ht[0]->key, ht[0]->value);
myfree((char *) ht_info_list);
} else {
vstream_printf("return: %d\n", ret);
}
if (vstream_fflush(VSTREAM_OUT) != 0)
msg_fatal("write error: %m");
vstring_free(str_val);
htable_free(table, myfree);
return (0);
}
#endif

View File

@ -157,7 +157,7 @@ static int attr_scan0_string(VSTREAM *fp, VSTRING *plain_buf, const char *contex
int limit = var_line_limit * 2;
int ch;
if ((ch = vstring_get_null_bound(plain_buf, fp, limit)) == VSTREAM_EOF) {
if ((ch = vstring_get_null(plain_buf, fp)) == VSTREAM_EOF) {
msg_warn("premature end-of-input from %s while reading %s",
VSTREAM_PATH(fp), context);
return (-1);

View File

@ -172,11 +172,13 @@ static int attr_scan64_string(VSTREAM *fp, VSTRING *plain_buf, const char *conte
return (-1);
}
VSTRING_ADDCH(base64_buf, ch);
#if 0
if (LEN(base64_buf) > limit) {
msg_warn("string length > %d characters from %s while reading %s",
limit, VSTREAM_PATH(fp), context);
return (-1);
}
#endif
}
VSTRING_TERMINATE(base64_buf);
if (base64_decode(plain_buf, STR(base64_buf), LEN(base64_buf)) == 0) {

View File

@ -107,6 +107,7 @@ int inet_trigger(const char *service, const char *buf, int len, int timeout)
msg_warn("%s: connect to %s: %m", myname, service);
return (-1);
}
close_on_exec(fd, CLOSE_ON_EXEC);
ip = (struct inet_trigger *) mymalloc(sizeof(*ip));
ip->fd = fd;
ip->service = mystrdup(service);

View File

@ -54,7 +54,7 @@ int make_dirs(const char *path, int perms)
int saved_ch;
struct stat st;
int ret;
mode_t saved_mode;
mode_t saved_mode = 0;
/*
* Initialize. Make a copy of the path that we can safely clobber.

View File

@ -34,10 +34,8 @@
/* .RS
/* .IP MATCH_FLAG_PARENT
/* The hostname pattern foo.com matches any name within the domain
/* foo.com.
/* .IP MATCH_FLAG_DOTPARENT
/* The hostname pattern .foo.com matches any name under foo.com.
/* The pattern foo.com matches itself only.
/* foo.com. If this flag is cleared, foo.com matches itself
/* only, and .foo.com matches any name below the domain foo.com.
/* .RE
/* Specify MATCH_FLAG_NONE to request none of the above.
/* The pattern_list argument specifies a list of patterns. The third

View File

@ -34,10 +34,9 @@
/* of the named host. The flags argument specifies the bit-wise OR
/* of zero or more of the following:
/* .IP MATCH_FLAG_PARENT
/* The pattern foo.com matches any name within the domain foo.com.
/* .IP MATCH_FLAG_DOTPARENT
/* The pattern .foo.com matches any name under foo.com. The pattern
/* foo.com matches itself only.
/* The hostname pattern foo.com matches itself and any name below
/* the domain foo.com. If this flag is cleared, foo.com matches itself
/* only, and .foo.com matches any name below the domain foo.com.
/* .RE
/* Specify MATCH_FLAG_NONE to request none of the above.
/*
@ -140,25 +139,15 @@ int match_hostname(int flags, const char *name, const char *pattern)
if (strchr(pattern, ':') != 0) {
temp = lowercase(mystrdup(name));
match = 0;
if (flags & MATCH_FLAG_PARENT) {
for (entry = temp; /* void */ ; entry = next + 1) {
if ((match = (dict_lookup(pattern, entry) != 0)) != 0)
break;
if (dict_errno != 0)
msg_fatal("%s: table lookup problem", pattern);
if ((next = strchr(entry, '.')) == 0)
break;
}
}
if (flags & MATCH_FLAG_DOTPARENT) {
for (entry = temp; /* void */ ; entry = next) {
if ((match = (dict_lookup(pattern, entry) != 0)) != 0)
break;
if (dict_errno != 0)
msg_fatal("%s: table lookup problem", pattern);
if ((next = strchr(entry, '.')) == 0)
break;
}
for (entry = temp; /* void */ ; entry = next) {
if ((match = (dict_lookup(pattern, entry) != 0)) != 0)
break;
if (dict_errno != 0)
msg_fatal("%s: table lookup problem", pattern);
if ((next = strchr(entry + 1, '.')) == 0)
break;
if (flags & MATCH_FLAG_PARENT)
next += 1;
}
myfree(temp);
return (match);
@ -179,10 +168,9 @@ int match_hostname(int flags, const char *name, const char *pattern)
pd = name + strlen(name) - strlen(pattern);
if (pd > name && pd[-1] == '.' && strcasecmp(pd, pattern) == 0)
return (1);
}
if (flags & MATCH_FLAG_DOTPARENT) {
} else if (pattern[0] == '.') {
pd = name + strlen(name) - strlen(pattern);
if (pd > name && pd[-1] == '.' && strcasecmp(pd - 1, pattern) == 0)
if (pd > name && strcasecmp(pd, pattern) == 0)
return (1);
}
}

View File

@ -15,8 +15,7 @@
#define MATCH_FLAG_NONE 0
#define MATCH_FLAG_PARENT (1<<0)
#define MATCH_FLAG_DOTPARENT (1<<1)
#define MATCH_FLAG_ALL (MATCH_FLAG_PARENT|MATCH_FLAG_DOTPARENT)
#define MATCH_FLAG_ALL (MATCH_FLAG_PARENT)
extern int match_string(int, const char *, const char *);
extern int match_hostname(int, const char *, const char *);

View File

@ -103,6 +103,7 @@ int stream_trigger(const char *service, const char *buf, int len, int timeou
msg_warn("%s: connect to %s: %m", myname, service);
return (-1);
}
close_on_exec(fd, CLOSE_ON_EXEC);
/*
* Stash away context.

View File

@ -104,6 +104,7 @@ int unix_trigger(const char *service, const char *buf, int len, int timeout)
msg_warn("%s: connect to %s: %m", myname, service);
return (-1);
}
close_on_exec(fd, CLOSE_ON_EXEC);
/*
* Stash away context.