-TNAME_MASK
-TNBBIO
-TPC_DBMS_INFO
+-TPC_EVAL_CTX
-TPC_MASTER_ENT
-TPC_PARAM_NODE
-TPC_SERVICE_DEF
This part of the code is not documented and had escaped
testing. Files: util/ip_match.c, util/ip_match.in,
util/ip_match.ref.
+
+20121215
+
+ Bugfix (introduced: 19980218, when recipient_delimiter
+ support was added): The error message for unknown local
+ users (or missing required aliases) should report the user
+ name instead of the full localpart which may contain an
+ address extension. Problem reported by Christian Holler.
+ File: local/unknown.c.
+
+20121221
+
+ Feature: "postconf -x" support to expand $nama in parameter
+ values. Files: postconf/postconf_main.c, postconf/postconf.h,
+ postconf/postconf_node.c, postconf/postconf.c.
<b>SYNOPSIS</b>
<b>Managing <a href="postconf.5.html">main.cf</a>:</b>
- <b>postconf</b> [<b>-dfhnv</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<b>-C</b> <i>class,...</i>] [<i>parame-</i>
+ <b>postconf</b> [<b>-dfhnvx</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<b>-C</b> <i>class,...</i>] [<i>parame-</i>
<i>ter ...</i>]
<b>postconf</b> [<b>-ev</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<i>parameter=value ...</i>]
tiple <b>-v</b> options make the software increasingly
verbose.
+ <b>-x</b> Expand <i>$name</i> in parameter values. The expansion is
+ recursive.
+
<b>-X</b> Edit the <a href="postconf.5.html"><b>main.cf</b></a> configuration file, and remove the
- parameters named on the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line.
+ parameters named on the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line.
The file is copied to a temporary file then renamed
into place. Specify a list of parameter names, not
- "<i>name</i>=<i>value</i>" pairs. There is no <a href="postconf.1.html"><b>postconf</b>(1)</a> com-
+ "<i>name</i>=<i>value</i>" pairs. There is no <a href="postconf.1.html"><b>postconf</b>(1)</a> com-
mand to perform the reverse operation.
- This feature is available with Postfix 2.10 and
+ This feature is available with Postfix 2.10 and
later.
- <b>-#</b> Edit the <a href="postconf.5.html"><b>main.cf</b></a> configuration file, and comment
+ <b>-#</b> Edit the <a href="postconf.5.html"><b>main.cf</b></a> configuration file, and comment
out the parameters named on the <a href="postconf.1.html"><b>postconf</b>(1)</a> command
- line, so that those parameters revert to their
- default values. The file is copied to a temporary
- file then renamed into place. Specify a list of
- parameter names, not "<i>name</i>=<i>value</i>" pairs. There is
+ line, so that those parameters revert to their
+ default values. The file is copied to a temporary
+ file then renamed into place. Specify a list of
+ parameter names, not "<i>name</i>=<i>value</i>" pairs. There is
no <a href="postconf.1.html"><b>postconf</b>(1)</a> command to perform the reverse oper-
ation.
- This feature is available with Postfix 2.6 and
+ This feature is available with Postfix 2.6 and
later.
<b>DIAGNOSTICS</b>
Directory with Postfix configuration files.
<b>CONFIGURATION PARAMETERS</b>
- The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant
+ The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant
to this program.
- The text below provides only a parameter summary. See
+ The text below provides only a parameter summary. See
<a href="postconf.5.html"><b>postconf</b>(5)</a> for more details including examples.
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and
<a href="master.5.html">master.cf</a> configuration files.
<b><a href="postconf.5.html#bounce_template_file">bounce_template_file</a> (empty)</b>
- Pathname of a configuration file with bounce mes-
+ Pathname of a configuration file with bounce mes-
sage templates.
<b>FILES</b>
<a href="DATABASE_README.html">DATABASE_README</a>, Postfix lookup table overview
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
.fi
\fBManaging main.cf:\fR
-\fBpostconf\fR [\fB-dfhnv\fR] [\fB-c \fIconfig_dir\fR]
+\fBpostconf\fR [\fB-dfhnvx\fR] [\fB-c \fIconfig_dir\fR]
[\fB-C \fIclass,...\fR] [\fIparameter ...\fR]
\fBpostconf\fR [\fB-ev\fR] [\fB-c \fIconfig_dir\fR]
.IP \fB-v\fR
Enable verbose logging for debugging purposes. Multiple \fB-v\fR
options make the software increasingly verbose.
+.IP \fB-x\fR
+Expand \fI$name\fR in parameter values. The expansion is
+recursive.
.IP \fB-X\fR
Edit the \fBmain.cf\fR configuration file, and remove
the parameters named on the \fBpostconf\fR(1) command line.
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20121210"
+#define MAIL_RELEASE_DATE "20121221"
#define MAIL_VERSION_NUMBER "2.10"
#ifdef SNAPSHOT
*/
#define STREQ(x,y) (strcasecmp(x,y) == 0)
- if (STREQ(state.msg_attr.local, MAIL_ADDR_MAIL_DAEMON)
- || STREQ(state.msg_attr.local, MAIL_ADDR_POSTMASTER)) {
- msg_warn("required alias not found: %s", state.msg_attr.local);
+ if (STREQ(state.msg_attr.user, MAIL_ADDR_MAIL_DAEMON)
+ || STREQ(state.msg_attr.user, MAIL_ADDR_POSTMASTER)) {
+ msg_warn("required alias not found: %s", state.msg_attr.user);
dsb_simple(state.msg_attr.why, "2.0.0", "discarded");
return (sent(BOUNCE_FLAGS(state.request), SENT_ATTR(state.msg_attr)));
}
* Bounce the message when no luser relay is specified.
*/
dsb_simple(state.msg_attr.why, "5.1.1",
- "unknown user: \"%s\"", state.msg_attr.local);
+ "unknown user: \"%s\"", state.msg_attr.user);
return (bounce_append(BOUNCE_FLAGS(state.request),
BOUNCE_ATTR(state.msg_attr)));
}
tests: test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 \
test12 test13 test14 test15 test16 test17 test18 test19 test20 test21 \
- test22 test23 test24 test25 test26 test27 test28 test29 test30 test4b
+ test22 test23 test24 test25 test26 test27 test28 test29 test30 test4b \
+ test31 test32 test33
root_tests:
diff test30.ref test30.tmp
rm -f main.cf master.cf test30.tmp
+# Does a non-default setting propagate to a non-default value?
+
+test31: $(PROG) test31.ref
+ rm -f main.cf master.cf
+ touch main.cf master.cf
+ echo 'smtpd_helo_restrictions=whatever' >> main.cf
+ echo 'smtpd_sender_restrictions=$$smtpd_helo_restrictions' >> main.cf
+ ./$(PROG) -nxc . >test31.tmp 2>&1
+ diff test31.ref test31.tmp
+ rm -f main.cf master.cf test31.tmp
+
+# Does a non-default setting propagate to a default value?
+
+test32: $(PROG) test32.ref
+ rm -f main.cf master.cf
+ touch main.cf master.cf
+ echo 'relay_domains=whatever' >> main.cf
+ ./$(PROG) -xc . fast_flush_domains >test32.tmp 2>&1
+ diff test32.ref test32.tmp
+ rm -f main.cf master.cf test32.tmp
+
+# Does a default setting propagate to a non-default value?
+
+test33: $(PROG) test33.ref
+ rm -f main.cf master.cf
+ touch main.cf master.cf
+ echo 'mydestination=whatever' >> main.cf
+ echo 'always_bcc=$$relay_domains' >> main.cf
+ ./$(PROG) -xc . always_bcc >test33.tmp 2>&1
+ diff test33.ref test33.tmp
+ rm -f main.cf master.cf test33.tmp
+
printfck: $(OBJS) $(PROG)
rm -rf printfck
mkdir printfck
postconf_main.o: ../../include/argv.h
postconf_main.o: ../../include/dict.h
postconf_main.o: ../../include/htable.h
+postconf_main.o: ../../include/mac_expand.h
+postconf_main.o: ../../include/mac_parse.h
postconf_main.o: ../../include/mail_conf.h
postconf_main.o: ../../include/mail_params.h
postconf_main.o: ../../include/msg.h
/* .fi
/* \fBManaging main.cf:\fR
/*
-/* \fBpostconf\fR [\fB-dfhnv\fR] [\fB-c \fIconfig_dir\fR]
+/* \fBpostconf\fR [\fB-dfhnvx\fR] [\fB-c \fIconfig_dir\fR]
/* [\fB-C \fIclass,...\fR] [\fIparameter ...\fR]
/*
/* \fBpostconf\fR [\fB-ev\fR] [\fB-c \fIconfig_dir\fR]
/* .IP \fB-v\fR
/* Enable verbose logging for debugging purposes. Multiple \fB-v\fR
/* options make the software increasingly verbose.
+/* .IP \fB-x\fR
+/* Expand \fI$name\fR in parameter values. The expansion is
+/* recursive.
/* .IP \fB-X\fR
/* Edit the \fBmain.cf\fR configuration file, and remove
/* the parameters named on the \fBpostconf\fR(1) command line.
/*
* Parse JCL.
*/
- while ((ch = GETOPT(argc, argv, "aAbc:C:deEf#hlmMntvX")) > 0) {
+ while ((ch = GETOPT(argc, argv, "aAbc:C:deEf#hlmMntvxX")) > 0) {
switch (ch) {
case 'a':
cmd_mode |= SHOW_SASL_SERV;
cmd_mode |= FOLD_LINE;
break;
- /*
- * People, this does not work unless you properly handle default
- * settings. For example, fast_flush_domains = $relay_domains
- * must not evaluate to the empty string when relay_domains is
- * left at its default setting of $mydestination.
- */
-#if 0
- case 'E':
- cmd_mode |= SHOW_EVAL;
- break;
-#endif
case '#':
cmd_mode = COMMENT_OUT;
break;
ext_argv = argv_alloc(2);
argv_add(ext_argv, "bounce", "-SVndump_templates", (char *) 0);
break;
+ case 'x':
+ cmd_mode |= SHOW_EVAL;
+ break;
case 'X':
/* This is irreversible, therefore require two-finger action. */
cmd_mode = EDIT_EXCL;
&& junk != EDIT_EXCL)
|| ext_argv != 0))
msg_fatal("specify one of -a, -A, -b, -d, -e, -#, -l, -m, -M, -n, and -X");
+ if ((cmd_mode & SHOW_EVAL) != 0 && junk != 0 && junk != SHOW_DEFS && junk != SHOW_NONDEF)
+ msg_fatal("do not specify -x with -a, -A, -b, -e, -#, -l, -m, -M, or -X");
/*
* Display bounce template information and exit.
else {
if ((cmd_mode & SHOW_DEFS) == 0) {
read_parameters();
- set_parameters();
}
register_builtin_parameters();
int flags; /* see below */
char *param_data; /* mostly, the default value */
const char *(*convert_fn) (char *); /* value to string */
+ const char *cached_defval; /* cached default value */
} PC_PARAM_NODE;
/* Values for flags. See the postconf_node module for narrative text. */
/*
/* void read_parameters()
/*
-/* void set_parameters()
-/*
/* void show_parameters(mode, param_class, names)
/* int mode;
/* int param_class;
/* DESCRIPTION
/* read_parameters() reads parameters from main.cf.
/*
-/* set_parameters() does nothing. It is a place holder for
-/* code that assigns actual or default parameter values, which
-/* could be needed to implement "postconf -e" parameter value
-/* expansion.
-/*
/* show_parameters() writes main.cf parameters to the standard
/* output stream.
/*
/* .IP SHOW_NAME
/* Output the parameter as "name = value".
/* .IP SHOW_EVAL
-/* Expand parameter values (not implemented).
+/* Expand $name in parameter values.
/* .RE
/* .IP param_class
/* Bit-wise OR of one or more of the following:
#include <dict.h>
#include <stringops.h>
#include <htable.h>
+#include <mac_expand.h>
/* Global library. */
myfree(path);
}
-/* set_parameters - set parameter values from default or explicit setting */
-
-void set_parameters(void)
-{
-
- /*
- * The proposal below describes some of the steps needed to expand
- * parameter values. It has a problem: it updates the configuration
- * parameter dictionary, and in doing so breaks the "postconf -d"
- * implementation. This makes "-d" and "-e" mutually exclusive.
- *
- * Populate the configuration parameter dictionary with default settings or
- * with actual settings.
- *
- * Iterate over each entry in str_fn_table, str_fn_table_2, time_table,
- * bool_table, int_table, str_table, and raw_table. Look up each
- * parameter name in the configuration parameter dictionary. If the
- * parameter is not set, take the default value, or take the value from
- * main.cf, without doing $name expansions. This includes converting
- * default values from numeric/boolean internal forms to external string
- * form.
- *
- * Once the configuration parameter dictionary is populated, printing a
- * parameter setting is a matter of querying the configuration parameter
- * dictionary, optionally expanding of $name values, and printing the
- * result.
- */
-}
-
/* print_line - show line possibly folded, and with normalized whitespace */
static void print_line(int mode, const char *fmt,...)
vstream_fputs("\n", VSTREAM_OUT);
}
+/* lookup_parameter_value - look up specific parameter value */
+
+static const char *lookup_parameter_value(int mode, const char *name,
+ PC_PARAM_NODE *node)
+{
+ const char *value;
+
+ /*
+ * Use the actual or built-in default parameter value. Some default
+ * values are computed by functions that have side effects, and those
+ * functions should be invoked only once. Therefore, when expanding $name
+ * in parameter values, we cache the default values.
+ */
+ if ((mode & SHOW_DEFS) != 0
+ || ((value = dict_lookup(CONFIG_DICT, name)) == 0
+ && (mode & SHOW_NONDEF) == 0)) {
+ if ((value = node->cached_defval) == 0
+ && (value = convert_param_node(SHOW_DEFS, name, node)) != 0
+ && (mode & SHOW_EVAL) != 0)
+ node->cached_defval = value = mystrdup(value);
+ }
+ return (value);
+}
+
+ /*
+ * Data structure to pass private state while recursively expanding $name in
+ * parameter values.
+ */
+typedef struct {
+ int mode;
+} PC_EVAL_CTX;
+
+/* expand_parameter_value_helper - macro parser call-back routine */
+
+static const char *expand_parameter_value_helper(const char *key,
+ int unused_type,
+ char *context)
+{
+ PC_PARAM_NODE *node;
+ PC_EVAL_CTX *cp = (PC_EVAL_CTX *) context;
+
+ /*
+ * XXX Do not spam the user with warnings about legacy parameter names in
+ * backwards-compatible default settings.
+ */
+ if ((node = PC_PARAM_TABLE_FIND(param_table, key)) != 0) {
+ return (lookup_parameter_value(cp->mode, key, node));
+ } else {
+ /* msg_warn("%s: unknown parameter", key); */
+ return (0);
+ }
+}
+
+/* expand_parameter_value - expand $name in parameter value */
+
+static const char *expand_parameter_value(int mode, const char *value,
+ PC_PARAM_NODE *node)
+{
+ const char *myname = "expand_parameter_value";
+ static VSTRING *buf;
+ int status;
+ PC_EVAL_CTX eval_ctx;
+
+ /*
+ * Initialize.
+ */
+ if (buf == 0)
+ buf = vstring_alloc(10);
+
+ /*
+ * Expand macros recursively.
+ *
+ * When expanding $name in "postconf -n" parameter values, don't limit the
+ * search to only non-default parameter values.
+ *
+ * When expanding $name in "postconf -d" parameter values, do limit the
+ * search to only default parameter values.
+ */
+#define DONT_FILTER (char *) 0
+
+ eval_ctx.mode = mode & ~SHOW_NONDEF;
+ status = mac_expand(buf, value, MAC_EXP_FLAG_RECURSE, DONT_FILTER,
+ expand_parameter_value_helper, (char *) &eval_ctx);
+ if (status & MAC_PARSE_ERROR)
+ msg_fatal("macro processing error");
+ if (msg_verbose > 1) {
+ if (strcmp(value, STR(buf)) != 0)
+ msg_info("%s: expand %s -> %s", myname, value, STR(buf));
+ else
+ msg_info("%s: const %s", myname, value);
+ }
+ return (STR(buf));
+}
+
/* print_parameter - show specific parameter */
static void print_parameter(int mode, const char *name,
/*
* Use the default or actual value.
*/
- if ((mode & SHOW_DEFS) != 0
- || ((value = dict_lookup(CONFIG_DICT, name)) == 0
- && (mode & SHOW_NONDEF) == 0))
- value = convert_param_node(SHOW_DEFS, name, node);
+ value = lookup_parameter_value(mode, name, node);
/*
- * Print with or without the name= prefix.
+ * Optionally expand $name in the parameter value. Print the result with
+ * or without the name= prefix.
*/
if (value != 0) {
+ if ((mode & SHOW_EVAL) != 0 && PC_RAW_PARAMETER(node) == 0)
+ value = expand_parameter_value(mode, value, node);
if (mode & SHOW_NAME) {
print_line(mode, "%s = %s\n", name, value);
} else {
node->flags = flags;
node->param_data = param_data;
node->convert_fn = convert_fn;
+ node->cached_defval = 0;
return (node);
}
-/* convert_param_node - get actual or default parameter value */
+/* convert_param_node - get default parameter value */
const char *convert_param_node(int mode, const char *name, PC_PARAM_NODE *node)
{
--- /dev/null
+config_directory = .
+smtpd_helo_restrictions = whatever
+smtpd_sender_restrictions = whatever
--- /dev/null
+fast_flush_domains = whatever
--- /dev/null
+always_bcc = whatever
1.2.[3;5;7;9;11].5 1.2.3.5 1.2.2.5 1.2.4.5 1.2.11.5 1.2.12.5 1.2.11.6
[1;2].3.4.5 1.3.4.5 2.3.4.5 3.3.4.5
[[1;2].3.4.5] 1.3.4.5 2.3.4.5 3.3.4.5
+[[1;2].3.4.5
+1;2].3.4.5
Match 1.3.4.5: yes
Match 2.3.4.5: yes
Match 3.3.4.5: no
+> [[1;2].3.4.5
+Error: missing "]" character
+> 1;2].3.4.5
+Error: need "." at "1>;<2].3.4.5"