20211022
- Bugfix: the known_tcp_ports setting had no effect. Reported
- by Peter. It also wasn't fully implemented. Files:
- config_known_tcp_ports.c, mail_params.c,
+ Bugfix (introduced: Postfix 3.6): the known_tcp_ports setting
+ had no effect. Reported by Peter. It also wasn't fully
+ implemented. Files: config_known_tcp_ports.c, mail_params.c,
posttls-finger/posttls-finger.c, smtp/smtp_connect.c,
util/find_inet.c, util/myaddrinfo.c.
Documentation: fixed a jq example in the postsuper manpage, to
delete the quotes around a queue ID. File: postsuper/postsuper.c.
- Cleanup: with "smtputf8_nable = yes" (the default), the
+ Cleanup: with "smtputf8_enable = yes" (the default), the
postscreen(8) dummy SMTP engine will no longer log a "non-UTF-8
key" warning when a remote SMTP client sends garbage. Instead,
postscreen(8) will reject the command with the same server
repsonse as smtpd(8). File: postscreen/p[ostscreen_smtpd.c.
+
+20211025
+
+ Bugfix (introduced: Postfix 3.6): mangled warning where a
+ hostname and warning message ran together. Viktor Dukhovni.
+ File: tls/tls_dane.c.
+
+20211026
+
+ Feature: with "smtp_bind_address_enforce = yes" the Postfix
+ SMTP client will defer delivery when it is unable to apply
+ the smtp_bind_address or smtp_bind_address6 setting. By
+ default, the Postfix SMTP client continues with delivery,
+ after logging a warning. File: src/smtp/smtp_connect.c.
+
+20211027
+
+ Documentation: readability fix for the text about automatic
+ or explicit daemon restart (postfix reload) after LMDB table
+ change. raj. File: proto/lmdb_table.
+
+ Safety: the postqueue command now sanitizes strings before they
+ are formatted as json output or legacy output. These outputs are
+ piped into other programs that are run by administrative
+ users. This closes a hypothetical opportunity for privilege
+ escalation. Files: util/attr.h, util/attr_scan*.c,
+ postqueue/showq_json.c, postqueue/showq_compat.c.
+
+20211030
+
+ Bugfix: check_ccert_access worked as expected, but produced
+ a spurious warning when Postfix is built without SASL
+ support. Fix by Brad Barden. File: smtpd/smtpd_check.c.
part, address extension or domain portion. This behavior is also found
with, for example, <a href="DATABASE_README.html#types">btree</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="ldap_table.5.html">ldap</a>: tables.
- Unlike other flat-file Postfix databases, changes to an LMDB database
- do not trigger automatic daemon program restart, and do not require
- "<b>postfix reload</b>".
+ Changes to an LMDB database do not trigger an automatic daemon restart,
+ and do not require a daemon restart with "<b>postfix reload</b>".
<b>RELIABILITY</b>
LMDB's copy-on-write architecture provides safe updates, at the cost of
- using more space than some other flat-file databases. Read operations
+ using more space than some other flat-file databases. Read operations
are memory-mapped for speed. Write operations are not memory-mapped to
avoid silent corruption due to stray pointer bugs.
as a shared cache for <a href="verify.8.html">verify(8)</a> or <a href="postscreen.8.html">postscreen(8)</a> services.
<b>SYNCHRONIZATION</b>
- The Postfix LMDB adapter does not use LMDB's built-in locking scheme,
- because that would require world-writable lockfiles and would violate
- the Postfix security model. Instead, Postfix uses fcntl(2) locks with
+ The Postfix LMDB adapter does not use LMDB's built-in locking scheme,
+ because that would require world-writable lockfiles and would violate
+ the Postfix security model. Instead, Postfix uses fcntl(2) locks with
whole-file granularity. Programs that use LMDB's built-in locking pro-
tocol will corrupt a Postfix LMDB database or will read garbage.
Every Postfix LMDB database read or write transaction must be protected
- from start to end with a shared or exclusive fcntl(2) lock. A writer
- may atomically downgrade an exclusive lock to a shared lock, but it
+ from start to end with a shared or exclusive fcntl(2) lock. A writer
+ may atomically downgrade an exclusive lock to a shared lock, but it
must hold an exclusive lock while opening another write transaction.
- Note that fcntl(2) locks do not protect transactions within the same
- process against each other. If a program cannot avoid making simulta-
- neous database requests, then it must protect its transactions with
+ Note that fcntl(2) locks do not protect transactions within the same
+ process against each other. If a program cannot avoid making simulta-
+ neous database requests, then it must protect its transactions with
in-process locks, in addition to the per-process fcntl(2) locks.
<b>CONFIGURATION PARAMETERS</b>
- Short-lived programs automatically pick up changes to <a href="postconf.5.html">main.cf</a>. With
- long-running daemon programs, Use the command "<b>postfix reload</b>" after a
+ Short-lived programs automatically pick up changes to <a href="postconf.5.html">main.cf</a>. With
+ long-running daemon programs, Use the command "<b>postfix reload</b>" after a
configuration change.
- <b><a href="postconf.5.html#lmdb_map_size">lmdb_map_size</a> (default: 16777216)</b>
- The initial LMDB database size limit in bytes.
+ <b><a href="postconf.5.html#lmdb_map_size">lmdb_map_size</a> (16777216)</b>
+ The initial OpenLDAP LMDB database size limit in bytes.
<b>SEE ALSO</b>
<a href="postconf.1.html">postconf(1)</a>, Postfix supported lookup tables
<b><a href="postconf.5.html#service_name">service_name</a> (read-only)</b>
The <a href="master.5.html">master.cf</a> service name of a Postfix daemon process.
+ Available in Postfix 3.7 and later:
+
+ <b><a href="postconf.5.html#smtp_bind_address_enforce">smtp_bind_address_enforce</a> (no)</b>
+ Defer delivery when the Postfix SMTP client cannot apply the
+ <a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> or <a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a> setting.
+
<b>SEE ALSO</b>
<a href="generic.5.html">generic(5)</a>, output address rewriting
<a href="header_checks.5.html">header_checks(5)</a>, message header content inspection
<p> This feature is available in Postfix 2.3 and later. </p>
+</DD>
+
+<DT><b><a name="lmtp_bind_address_enforce">lmtp_bind_address_enforce</a>
+(default: empty)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_bind_address_enforce">smtp_bind_address_enforce</a>
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 3.7 and later. </p>
+
+
</DD>
<DT><b><a name="lmtp_body_checks">lmtp_body_checks</a>
</pre>
</blockquote>
+<p> See <a href="postconf.5.html#smtp_bind_address_enforce">smtp_bind_address_enforce</a> for how Postfix should handle
+errors (Postfix 3.7 and later). </p>
+
<p> Note 1: when <a href="postconf.5.html#inet_interfaces">inet_interfaces</a> specifies no more than one IPv4
address, and that address is a non-loopback address, it is
automatically used as the <a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a>. This supports virtual
</pre>
</blockquote>
+<p> See <a href="postconf.5.html#smtp_bind_address_enforce">smtp_bind_address_enforce</a> for how Postfix should handle
+errors (Postfix 3.7 and later). </p>
+
<p> Note 1: when <a href="postconf.5.html#inet_interfaces">inet_interfaces</a> specifies no more than one IPv6
address, and that address is a non-loopback address, it is
automatically used as the <a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a>. This supports virtual
but this form is not recommended here. </p>
+</DD>
+
+<DT><b><a name="smtp_bind_address_enforce">smtp_bind_address_enforce</a>
+(default: no)</b></DT><DD>
+
+<p> Defer delivery when the Postfix SMTP client cannot apply the
+<a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> or <a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a> setting. By default, the
+Postfix SMTP client will continue delivery after logging a warning.
+</p>
+
+<p> This feature is available in Postfix 3.7 and later. </p>
+
+
</DD>
<DT><b><a name="smtp_body_checks">smtp_body_checks</a>
input. For example, to delete all mail with exactly one recipi-
ent <b>user@example.com</b>:
- postqueue -j | jq '
+ postqueue -j | jq -r '
# See JSON OBJECT FORMAT section in the <a href="postqueue.1.html">postqueue(1)</a> manpage
select(.recipients[0].address == "user@example.com")
| select(.recipients[1].address == null)
| .queue_id
- ' | tr -d '"' | postsuper -d -
+ ' | postsuper -d -
- Or the historical form:
+ (note the "jq -r" option), or the historical form:
mailq | tail -n +2 | grep -v '^ *(' | awk 'BEGIN { RS = "" }
# $7=sender, $8=recipient1, $9=recipient2
<b><a href="postconf.5.html#service_name">service_name</a> (read-only)</b>
The <a href="master.5.html">master.cf</a> service name of a Postfix daemon process.
+ Available in Postfix 3.7 and later:
+
+ <b><a href="postconf.5.html#smtp_bind_address_enforce">smtp_bind_address_enforce</a> (no)</b>
+ Defer delivery when the Postfix SMTP client cannot apply the
+ <a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> or <a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a> setting.
+
<b>SEE ALSO</b>
<a href="generic.5.html">generic(5)</a>, output address rewriting
<a href="header_checks.5.html">header_checks(5)</a>, message header content inspection
with exactly one recipient \fBuser@example.com\fR:
.sp
.nf
-postqueue \-j | jq '
+postqueue \-j | jq -r '
# See JSON OBJECT FORMAT section in the postqueue(1) manpage
select(.recipients[0].address == "user@example.com")
| select(.recipients[1].address == null)
| .queue_id
- ' | tr \-d '"' | postsuper \-d \-
+ ' | postsuper \-d \-
.fi
.sp
-Or the historical form:
+(note the "jq -r" option), or the historical form:
.sp
.nf
mailq | tail \-n +2 | grep \-v '^ *(' | awk 'BEGIN { RS = "" }
or domain portion. This behavior is also found with, for
example, btree:, hash:, or ldap: tables.
-Unlike other flat\-file Postfix databases, changes to
-an LMDB database do not trigger automatic daemon program
-restart, and do not require "\fBpostfix reload\fR".
+Changes to an LMDB database do not trigger an automatic
+daemon restart, and do not require a daemon restart with
+"\fBpostfix reload\fR".
.SH "RELIABILITY"
.na
.nf
Short\-lived programs automatically pick up changes to
main.cf. With long\-running daemon programs, Use the command
"\fBpostfix reload\fR" after a configuration change.
-.IP "\fBlmdb_map_size (default: 16777216)\fR"
-The initial LMDB database size limit in bytes.
+.IP "\fBlmdb_map_size (16777216)\fR"
+The initial OpenLDAP LMDB database size limit in bytes.
.SH "SEE ALSO"
.na
.nf
parameter. See there for details.
.PP
This feature is available in Postfix 2.3 and later.
+.SH lmtp_bind_address_enforce (default: empty)
+The LMTP\-specific version of the smtp_bind_address_enforce
+configuration parameter. See there for details.
+.PP
+This feature is available in Postfix 3.7 and later.
.SH lmtp_body_checks (default: empty)
The LMTP\-specific version of the smtp_body_checks configuration
parameter. See there for details.
.ft R
.in -4
.PP
+See smtp_bind_address_enforce for how Postfix should handle
+errors (Postfix 3.7 and later).
+.PP
Note 1: when inet_interfaces specifies no more than one IPv4
address, and that address is a non\-loopback address, it is
automatically used as the smtp_bind_address. This supports virtual
.ft R
.in -4
.PP
+See smtp_bind_address_enforce for how Postfix should handle
+errors (Postfix 3.7 and later).
+.PP
Note 1: when inet_interfaces specifies no more than one IPv6
address, and that address is a non\-loopback address, it is
automatically used as the smtp_bind_address6. This supports virtual
.PP
Note 2: address information may be enclosed inside [],
but this form is not recommended here.
+.SH smtp_bind_address_enforce (default: no)
+Defer delivery when the Postfix SMTP client cannot apply the
+smtp_bind_address or smtp_bind_address6 setting. By default, the
+Postfix SMTP client will continue delivery after logging a warning.
+.PP
+This feature is available in Postfix 3.7 and later.
.SH smtp_body_checks (default: empty)
Restricted \fBbody_checks\fR(5) tables for the Postfix SMTP client.
These tables are searched while mail is being delivered. Actions
Available in Postfix 3.3 and later:
.IP "\fBservice_name (read\-only)\fR"
The master.cf service name of a Postfix daemon process.
+.PP
+Available in Postfix 3.7 and later:
+.IP "\fBsmtp_bind_address_enforce (no)\fR"
+Defer delivery when the Postfix SMTP client cannot apply the
+smtp_bind_address or smtp_bind_address6 setting.
.SH "SEE ALSO"
.na
.nf
s;\bsmtp_always_send_ehlo\b;<a href="postconf.5.html#smtp_always_send_ehlo">$&</a>;g;
s;\bsmtp_bind_address\b;<a href="postconf.5.html#smtp_bind_address">$&</a>;g;
s;\bsmtp_bind_address6\b;<a href="postconf.5.html#smtp_bind_address6">$&</a>;g;
+ s;\bsmtp_bind_address_enforce\b;<a href="postconf.5.html#smtp_bind_address_enforce">$&</a>;g;
s;\bsmtp_cname_overrides_servername\b;<a href="postconf.5.html#smtp_cname_overrides_servername">$&</a>;g;
s;\bsmtp_connect_timeout\b;<a href="postconf.5.html#smtp_connect_timeout">$&</a>;g;
# or domain portion. This behavior is also found with, for
# example, btree:, hash:, or ldap: tables.
#
-# Unlike other flat-file Postfix databases, changes to
-# an LMDB database do not trigger automatic daemon program
-# restart, and do not require "\fBpostfix reload\fR".
+# Changes to an LMDB database do not trigger an automatic
+# daemon restart, and do not require a daemon restart with
+# "\fBpostfix reload\fR".
# RELIABILITY
# .ad
# .fi
# Short-lived programs automatically pick up changes to
# main.cf. With long-running daemon programs, Use the command
# "\fBpostfix reload\fR" after a configuration change.
-# .IP "\fBlmdb_map_size (default: 16777216)\fR"
-# The initial LMDB database size limit in bytes.
+# .IP "\fBlmdb_map_size (16777216)\fR"
+# The initial OpenLDAP LMDB database size limit in bytes.
# SEE ALSO
# postconf(1), Postfix supported lookup tables
# postmap(1), Postfix lookup table maintenance
</pre>
</blockquote>
+<p> See smtp_bind_address_enforce for how Postfix should handle
+errors (Postfix 3.7 and later). </p>
+
<p> Note 1: when inet_interfaces specifies no more than one IPv4
address, and that address is a non-loopback address, it is
automatically used as the smtp_bind_address. This supports virtual
</pre>
</blockquote>
+<p> See smtp_bind_address_enforce for how Postfix should handle
+errors (Postfix 3.7 and later). </p>
+
<p> Note 1: when inet_interfaces specifies no more than one IPv6
address, and that address is a non-loopback address, it is
automatically used as the smtp_bind_address6. This supports virtual
2.9-3.6. </p>
<p> This feature is available in Postfix 3.7 and later. </p>
+
+%PARAM smtp_bind_address_enforce no
+
+<p> Defer delivery when the Postfix SMTP client cannot apply the
+smtp_bind_address or smtp_bind_address6 setting. By default, the
+Postfix SMTP client will continue delivery after logging a warning.
+</p>
+
+<p> This feature is available in Postfix 3.7 and later. </p>
+
+%PARAM lmtp_bind_address_enforce
+
+<p> The LMTP-specific version of the smtp_bind_address_enforce
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 3.7 and later. </p>
#define DEF_LMTP_BIND_ADDR6 ""
extern char *var_smtp_bind_addr6;
+#define VAR_SMTP_BIND_ADDR_ENFORCE "smtp_bind_address_enforce"
+#define DEF_SMTP_BIND_ADDR_ENFORCE 0
+#define VAR_LMTP_BIND_ADDR_ENFORCE "lmtp_bind_address_enforce"
+#define DEF_LMTP_BIND_ADDR_ENFORCE 0
+extern bool var_smtp_bind_addr_enforce;
+
#define VAR_SMTP_HELO_NAME "smtp_helo_name"
#define DEF_SMTP_HELO_NAME "$myhostname"
#define VAR_LMTP_HELO_NAME "lmtp_lhlo_name"
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20211023"
+#define MAIL_RELEASE_DATE "20211030"
#define MAIL_VERSION_NUMBER "3.7"
#ifdef SNAPSHOT
/*
* Read the message properties and sender address.
*/
- if (attr_scan(showq_stream, ATTR_FLAG_MORE | ATTR_FLAG_STRICT,
+ if (attr_scan(showq_stream, ATTR_FLAG_MORE | ATTR_FLAG_STRICT
+ | ATTR_FLAG_PRINTABLE,
RECV_ATTR_STR(MAIL_ATTR_QUEUE, queue_name),
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
RECV_ATTR_LONG(MAIL_ATTR_TIME, &arrival_time),
* resynchronize.
*/
while ((showq_status = attr_scan_more(showq_stream)) > 0) {
- if (attr_scan(showq_stream, ATTR_FLAG_MORE | ATTR_FLAG_STRICT,
+ if (attr_scan(showq_stream, ATTR_FLAG_MORE | ATTR_FLAG_STRICT
+ | ATTR_FLAG_PRINTABLE,
RECV_ATTR_STR(MAIL_ATTR_RECIP, addr),
RECV_ATTR_STR(MAIL_ATTR_WHY, why),
ATTR_TYPE_END) != 2)
/*
* Read the message properties and sender address.
*/
- if (attr_scan(showq_stream, ATTR_FLAG_MORE | ATTR_FLAG_STRICT,
+ if (attr_scan(showq_stream, ATTR_FLAG_MORE | ATTR_FLAG_STRICT
+ | ATTR_FLAG_PRINTABLE,
RECV_ATTR_STR(MAIL_ATTR_QUEUE, queue_name),
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
RECV_ATTR_LONG(MAIL_ATTR_TIME, &arrival_time),
if (rcpt_count > 0)
vstream_printf(", ");
vstream_printf("{");
- if (attr_scan(showq_stream, ATTR_FLAG_MORE | ATTR_FLAG_STRICT,
+ if (attr_scan(showq_stream, ATTR_FLAG_MORE | ATTR_FLAG_STRICT
+ | ATTR_FLAG_PRINTABLE,
RECV_ATTR_STR(MAIL_ATTR_RECIP, addr),
RECV_ATTR_STR(MAIL_ATTR_WHY, why),
ATTR_TYPE_END) != 2)
/* with exactly one recipient \fBuser@example.com\fR:
/* .sp
/* .nf
-/* postqueue -j | jq '
+/* postqueue -j | jq -r '
/* # See JSON OBJECT FORMAT section in the postqueue(1) manpage
/* select(.recipients[0].address == "user@example.com")
/* | select(.recipients[1].address == null)
/* | .queue_id
-/* ' | tr -d '"' | postsuper -d -
+/* ' | postsuper -d -
/* .fi
/* .sp
-/* Or the historical form:
+/* (note the "jq -r" option), or the historical form:
/* .sp
/* .nf
/* mailq | tail -n +2 | grep -v '^ *(' | awk 'BEGIN { RS = "" }
VAR_LMTP_ASSUME_FINAL, DEF_LMTP_ASSUME_FINAL, &var_lmtp_assume_final,
VAR_LMTP_DUMMY_MAIL_AUTH, DEF_LMTP_DUMMY_MAIL_AUTH, &var_smtp_dummy_mail_auth,
VAR_LMTP_BALANCE_INET_PROTO, DEF_LMTP_BALANCE_INET_PROTO, &var_smtp_balance_inet_proto,
+ VAR_LMTP_BIND_ADDR_ENFORCE, DEF_LMTP_BIND_ADDR_ENFORCE, &var_smtp_bind_addr_enforce,
0,
};
static const CONFIG_NBOOL_TABLE lmtp_nbool_table[] = {
/* Available in Postfix 3.3 and later:
/* .IP "\fBservice_name (read-only)\fR"
/* The master.cf service name of a Postfix daemon process.
+/* .PP
+/* Available in Postfix 3.7 and later:
+/* .IP "\fBsmtp_bind_address_enforce (no)\fR"
+/* Defer delivery when the Postfix SMTP client cannot apply the
+/* smtp_bind_address or smtp_bind_address6 setting.
/* SEE ALSO
/* generic(5), output address rewriting
/* header_checks(5), message header content inspection
bool var_smtp_sasl_auth_soft_bounce;
char *var_hfrom_format;
+bool var_smtp_bind_addr_enforce;
/*
* Global variables.
if ((aierr = hostaddr_to_sockaddr(bind_addr, (char *) 0, 0, &res0)) != 0)
msg_fatal("%s: bad %s parameter: %s: %s",
myname, bind_var, bind_addr, MAI_STRERROR(aierr));
- if (bind(sock, res0->ai_addr, res0->ai_addrlen) < 0)
+ if (bind(sock, res0->ai_addr, res0->ai_addrlen) < 0) {
msg_warn("%s: bind %s: %m", myname, bind_addr);
- else if (msg_verbose)
+ if (var_smtp_bind_addr_enforce) {
+ freeaddrinfo(res0);
+ dsb_simple(why, "4.4.0", "server configuration error");
+ return (0);
+ }
+ } else if (msg_verbose)
msg_info("%s: bind %s", myname, bind_addr);
freeaddrinfo(res0);
}
VAR_LMTP_ASSUME_FINAL, DEF_LMTP_ASSUME_FINAL, &var_lmtp_assume_final,
VAR_SMTP_DUMMY_MAIL_AUTH, DEF_SMTP_DUMMY_MAIL_AUTH, &var_smtp_dummy_mail_auth,
VAR_SMTP_BALANCE_INET_PROTO, DEF_SMTP_BALANCE_INET_PROTO, &var_smtp_balance_inet_proto,
+ VAR_SMTP_BIND_ADDR_ENFORCE, DEF_SMTP_BIND_ADDR_ENFORCE, &var_smtp_bind_addr_enforce,
0,
};
static const CONFIG_NBOOL_TABLE smtp_nbool_table[] = {
}
} else if (is_map_command(state, name, CHECK_CCERT_ACL, &cpp)) {
status = check_ccert_access(state, *cpp, def_acl);
-#ifdef USE_SASL_AUTH
} else if (is_map_command(state, name, CHECK_SASL_ACL, &cpp)) {
+#ifdef USE_SASL_AUTH
if (var_smtpd_sasl_enable) {
if (state->sasl_username && state->sasl_username[0])
status = check_sasl_access(state, *cpp, def_acl);
vstring_sprintf(top, "...");
}
- msg_warn("%s%s%s%s: %u %u %u %s%s%s", s1, s2, s3, s4, u, s, m, STR(top),
+ msg_warn("%s%s%s %s: %u %u %u %s%s%s", s1, s2, s3, s4, u, s, m, STR(top),
dlen > MAX_DUMP_BYTES ? "..." : "",
dlen > MAX_DUMP_BYTES ? STR(bot) : "");
}
continue;
}
if (ret == 0) {
- tlsa_carp(TLScontext->namaddr, ": ", "", "unusable TLSA RR",
+ tlsa_carp(TLScontext->namaddr, ":", "", "unusable TLSA RR",
tp->usage, tp->selector, tp->mtype, tp->data,
tp->length);
continue;
}
/* Internal problem in OpenSSL */
- tlsa_carp(TLScontext->namaddr, ": ", "", "error loading trust settings",
+ tlsa_carp(TLScontext->namaddr, ":", "", "error loading trust settings",
tp->usage, tp->selector, tp->mtype, tp->data, tp->length);
tls_print_errors();
return (-1);
#define ATTR_FLAG_MISSING (1<<0) /* Flag missing attribute */
#define ATTR_FLAG_EXTRA (1<<1) /* Flag spurious attribute */
#define ATTR_FLAG_MORE (1<<2) /* Don't skip or terminate */
+#define ATTR_FLAG_PRINTABLE (1<<3) /* Sanitize received strings */
#define ATTR_FLAG_STRICT (ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA)
-#define ATTR_FLAG_ALL (07)
+#define ATTR_FLAG_ALL (017)
/*
* Default to null-terminated, as opposed to base64-encoded.
/* same input attribute list.
/* By default, attr_scan0() skips forward past the input attribute list
/* terminator.
+/* .IP ATTR_FLAG_PRINTABLE
+/* Santize received string values with printable(_, '?').
/* .IP ATTR_FLAG_STRICT
/* For convenience, this value combines both ATTR_FLAG_MISSING and
/* ATTR_FLAG_EXTRA.
#include <vstring_vstream.h>
#include <htable.h>
#include <base64_code.h>
+#include <stringops.h>
#include <attr.h>
/* Application specific. */
if ((ch = attr_scan0_string(fp, string,
"input attribute value")) < 0)
return (-1);
+ if (flags & ATTR_FLAG_PRINTABLE)
+ (void) printable(STR(string), '?');
break;
case ATTR_TYPE_DATA:
string = va_arg(ap, VSTRING *);
if ((ch = attr_scan0_string(fp, str_buf,
"input attribute value")) < 0)
return (-1);
+ if (flags & ATTR_FLAG_PRINTABLE) {
+ (void) printable(STR(name_buf), '?');
+ (void) printable(STR(str_buf), '?');
+ }
if (htable_locate(hash_table, STR(name_buf)) != 0) {
if ((flags & ATTR_FLAG_EXTRA) != 0) {
msg_warn("duplicate attribute %s in input from %s",
/* same input attribute list.
/* By default, attr_scan64() skips forward past the input attribute list
/* terminator.
+/* .IP ATTR_FLAG_PRINTABLE
+/* Santize received string values with printable(_, '?').
/* .IP ATTR_FLAG_STRICT
/* For convenience, this value combines both ATTR_FLAG_MISSING and
/* ATTR_FLAG_EXTRA.
#include <vstring.h>
#include <htable.h>
#include <base64_code.h>
+#include <stringops.h>
#include <attr.h>
/* Application specific. */
STR(name_buf), VSTREAM_PATH(fp));
return (-1);
}
+ if (flags & ATTR_FLAG_PRINTABLE)
+ (void) printable(STR(string), '?');
break;
case ATTR_TYPE_DATA:
if (ch != ':') {
STR(name_buf), VSTREAM_PATH(fp));
return (-1);
}
+ if (flags & ATTR_FLAG_PRINTABLE) {
+ (void) printable(STR(name_buf), '?');
+ (void) printable(STR(str_buf), '?');
+ }
if (htable_locate(hash_table, STR(name_buf)) != 0) {
if ((flags & ATTR_FLAG_EXTRA) != 0) {
msg_warn("duplicate attribute %s in input from %s",
/* from the same input attribute list.
/* By default, attr_scan_plain() skips forward past the input attribute
/* list terminator.
+/* .IP ATTR_FLAG_PRINTABLE
+/* Santize received string values with printable(_, '?').
/* .IP ATTR_FLAG_STRICT
/* For convenience, this value combines both ATTR_FLAG_MISSING and
/* ATTR_FLAG_EXTRA.
#include <vstring.h>
#include <htable.h>
#include <base64_code.h>
+#include <stringops.h>
#include <attr.h>
/* Application specific. */
if ((ch = attr_scan_plain_string(fp, string, 0,
"input attribute value")) < 0)
return (-1);
+ if (flags & ATTR_FLAG_PRINTABLE)
+ (void) printable(STR(string), '?');
break;
case ATTR_TYPE_DATA:
if (ch != '=') {
if ((ch = attr_scan_plain_string(fp, str_buf, 0,
"input attribute value")) < 0)
return (-1);
+ if (flags & ATTR_FLAG_PRINTABLE) {
+ (void) printable(STR(name_buf), '?');
+ (void) printable(STR(str_buf), '?');
+ }
if (htable_locate(hash_table, STR(name_buf)) != 0) {
if ((flags & ATTR_FLAG_EXTRA) != 0) {
msg_warn("duplicate attribute %s in input from %s",