From: Wietse Venema Date: Sun, 8 Oct 2023 05:00:00 +0000 (-0500) Subject: postfix-3.9-20231008 X-Git-Tag: v3.9.0~38 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5389836142cbb377e9170ed67a6c9d2688062a0d;p=thirdparty%2Fpostfix.git postfix-3.9-20231008 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 4471f993e..4205d93c6 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -27431,3 +27431,26 @@ Apologies for any names omitted. Documentation: added smtp_balance_inet_protocols to the text with smtp_address_preference caveats. File: proto/postconf.proto. + +20230926 + + Documentation: added a section to smtp_balance_inet_protocols + to address the problem that servers may flag mail received + over IPv6 as more spammy. File: proto/postconf.proto. + +20231006 + + Cleanup: attempt to log the SASL username after authentication + failure. This appends ", sasl_username=xxx" to SASL authentication + failure logging. Based on code by Jozsef Kadlecsik. Files: + xsasl/xsasl_server.c, xsasl/xsasl_cyrus_server.c, + smtpd/smtpd_sasl_glue.c. + +20231008 + + Cleanup: enforce stricter UTF8 checks in printable(). Factor + out the UTF8 parser, so that it can be shared between + valid_utf8_string() and printable(). Wietse Venema, with + tests by Viktor Dukhovni. Files: util/valid_utf8_string.c, + util/printable.c, util/parse_utf8_char.c, util/printable.in, + util/printable.ref. diff --git a/postfix/README_FILES/POSTSCREEN_README b/postfix/README_FILES/POSTSCREEN_README index 9467e68f6..420f5a08c 100644 --- a/postfix/README_FILES/POSTSCREEN_README +++ b/postfix/README_FILES/POSTSCREEN_README @@ -78,7 +78,7 @@ Zombies have challenges too: they have only a limited amount of time to deliver spam before their IP address becomes denylisted. To speed up spam deliveries, zombies make compromises in their SMTP protocol implementation. For example, they speak before their turn, or they ignore responses from SMTP servers and -continue sending mail even when the server tells them to go away. +continue sending commands even when the server tells them to go away. postscreen(8) uses a variety of measurements to recognize zombies. First, postscreen(8) determines if the remote SMTP client IP address is denylisted. diff --git a/postfix/html/POSTSCREEN_README.html b/postfix/html/POSTSCREEN_README.html index bca2ef098..328131f77 100644 --- a/postfix/html/POSTSCREEN_README.html +++ b/postfix/html/POSTSCREEN_README.html @@ -120,7 +120,7 @@ of time to deliver spam before their IP address becomes denylisted. To speed up spam deliveries, zombies make compromises in their SMTP protocol implementation. For example, they speak before their turn, or they ignore responses from SMTP servers and continue sending -mail even when the server tells them to go away.

+commands even when the server tells them to go away.

postscreen(8) uses a variety of measurements to recognize zombies. First, postscreen(8) determines if the remote SMTP client diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index e3954b467..8159fb710 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -10949,7 +10949,7 @@ IPv6 connectivity:

This feature is available in Postfix 2.8 and later.

diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index 0f25fdd2d..f61b8a143 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -6966,7 +6966,7 @@ Notes for mail delivery between sites that have both IPv4 and IPv6 connectivity: .IP \(bu The setting "smtp_address_preference = ipv6" is unsafe. -All deliveries will suffer delays when IPv6 is not available even +All deliveries will suffer delays during an IPv6 outage, even while the destination is still reachable over IPv4. Mail may be stuck in the queue with Postfix versions < 3.3 that do not implement "smtp_balance_inet_protocols". For similar reasons, the @@ -6976,6 +6976,35 @@ The setting "smtp_address_preference = any" is safe. With this, and "smtp_balance_inet_protocols = yes" (the default), only half of deliveries will suffer delays if there is an outage that affects IPv6 or IPv4, as long as it does not affect both. +.IP \(bu +The setting "smtp_address_preference = ipv4" is not a +solution for remote servers that flag email received over IPv6 as +more 'spammy' (the client IPv6 address has a bad or missing PTR or +AAAA record, bad network neighbors, etc.). Instead, configure Postfix +to receive mail over both IPv4 and IPv6, and to deliver mail over +only IPv4. +.sp +.in +4 +.nf +.na +.ft C +/etc/postfix/main.cf: + inet_protocols = all +.fi +.ad +.ft R +.in -4 +.sp +.in +4 +.nf +.na +.ft C +/etc/postfix/master.cf + smtp ...other fields... smtp \-o inet_protocols=ipv4 +.fi +.ad +.ft R +.in -4 .br .PP This feature is available in Postfix 2.8 and later. diff --git a/postfix/proto/POSTSCREEN_README.html b/postfix/proto/POSTSCREEN_README.html index eb9c9f5d4..b2d412df3 100644 --- a/postfix/proto/POSTSCREEN_README.html +++ b/postfix/proto/POSTSCREEN_README.html @@ -120,7 +120,7 @@ of time to deliver spam before their IP address becomes denylisted. To speed up spam deliveries, zombies make compromises in their SMTP protocol implementation. For example, they speak before their turn, or they ignore responses from SMTP servers and continue sending -mail even when the server tells them to go away.

+commands even when the server tells them to go away.

postscreen(8) uses a variety of measurements to recognize zombies. First, postscreen(8) determines if the remote SMTP client diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index ce17251c6..31a96bc1f 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -15023,7 +15023,7 @@ IPv6 connectivity:

This feature is available in Postfix 2.8 and later.

diff --git a/postfix/proto/stop b/postfix/proto/stop index ae0f37b8b..2c5d841bd 100644 --- a/postfix/proto/stop +++ b/postfix/proto/stop @@ -1585,3 +1585,4 @@ certificate's pubout rpk sni +Amawalk diff --git a/postfix/proto/stop.spell-history b/postfix/proto/stop.spell-history index dcd003cfc..acecbce8b 100644 --- a/postfix/proto/stop.spell-history +++ b/postfix/proto/stop.spell-history @@ -62,3 +62,4 @@ INI Serg Kinzler smtpstone +spammy diff --git a/postfix/proto/stop.spell-proto-html b/postfix/proto/stop.spell-proto-html index c4f4c845b..6baa193e5 100644 --- a/postfix/proto/stop.spell-proto-html +++ b/postfix/proto/stop.spell-proto-html @@ -358,3 +358,4 @@ srv wraptls api MinProtocol +spammy diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index c667582b4..2191f3bcf 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20230924" +#define MAIL_RELEASE_DATE "20231008" #define MAIL_VERSION_NUMBER "3.9" #ifdef SNAPSHOT diff --git a/postfix/src/smtpd/smtpd_sasl_glue.c b/postfix/src/smtpd/smtpd_sasl_glue.c index 2c5271916..6586e005b 100644 --- a/postfix/src/smtpd/smtpd_sasl_glue.c +++ b/postfix/src/smtpd/smtpd_sasl_glue.c @@ -120,6 +120,10 @@ /* Google, Inc. /* 111 8th Avenue /* New York, NY 10011, USA +/* +/* Wietse Venema +/* porcupine.org +/* Amawalk, NY 10501, USA /*--*/ /* System library. */ @@ -340,9 +344,11 @@ int smtpd_sasl_authenticate(SMTPD_STATE *state, } } if (status != XSASL_AUTH_DONE) { - msg_warn("%s: SASL %s authentication failed: %s", + sasl_username = xsasl_server_get_username(state->sasl_server); + msg_warn("%s: SASL %s authentication failed: %s, sasl_username=%s", state->namaddr, sasl_method, - STR(state->sasl_reply)); + STR(state->sasl_reply), + sasl_username ? sasl_username : "(unavailable)"); /* RFC 4954 Section 6. */ if (status == XSASL_AUTH_TEMP) smtpd_chat_reply(state, "454 4.7.0 Temporary authentication failure: %s", diff --git a/postfix/src/util/.gitattributes b/postfix/src/util/.gitattributes new file mode 100644 index 000000000..8d63819a9 --- /dev/null +++ b/postfix/src/util/.gitattributes @@ -0,0 +1 @@ +printable.in binary diff --git a/postfix/src/util/Makefile.in b/postfix/src/util/Makefile.in index d795f69d6..2c4d09b3e 100644 --- a/postfix/src/util/Makefile.in +++ b/postfix/src/util/Makefile.in @@ -145,7 +145,7 @@ TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \ vstream timecmp dict_cache midna_domain casefold strcasecmp_utf8 \ vbuf_print split_qnameval vstream msg_logger byte_mask \ known_tcp_ports dict_stream find_inet binhash hash_fnv argv \ - clean_env inet_prefix_top + clean_env inet_prefix_top printable PLUGIN_MAP_SO = $(LIB_PREFIX)pcre$(LIB_SUFFIX) $(LIB_PREFIX)lmdb$(LIB_SUFFIX) \ $(LIB_PREFIX)cdb$(LIB_SUFFIX) $(LIB_PREFIX)sdbm$(LIB_SUFFIX) HTABLE_FIX = NORANDOMIZE=1 @@ -365,6 +365,11 @@ unescape: $(LIB) $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o +printable: $(LIB) + mv $@.o junk + $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) + mv junk $@.o + hex_quote: $(LIB) mv $@.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) @@ -618,7 +623,7 @@ tests: all valid_hostname_test mac_expand_test dict_test unescape_test \ strcasecmp_utf8_test vbuf_print_test miss_endif_cidr_test \ miss_endif_regexp_test split_qnameval_test vstring_test \ vstream_test byte_mask_tests mystrtok_test known_tcp_ports_test \ - binhash_test argv_test inet_prefix_top_test + binhash_test argv_test inet_prefix_top_test printable_test dict_tests: all dict_test \ dict_pcre_tests dict_cidr_test dict_thash_test dict_static_test \ @@ -650,6 +655,11 @@ unescape_test: unescape unescape.in unescape.ref # diff unescape.in unescape.tmp rm -f unescape.tmp +printable_test: printable printable.in + $(SHLIB_ENV) ${VALGRIND} ./printable printable.tmp + diff -b printable.ref printable.tmp + rm -f printable.tmp + hex_quote_test: hex_quote $(SHLIB_ENV) ${VALGRIND} ./hex_quote hex_quote.tmp od -cb hex_quote.ref @@ -2526,6 +2536,7 @@ posix_signals.o: posix_signals.c posix_signals.o: posix_signals.h posix_signals.o: sys_defs.h printable.o: check_arg.h +printable.o: parse_utf8_char.h printable.o: printable.c printable.o: stringops.h printable.o: sys_defs.h @@ -2849,6 +2860,7 @@ valid_utf8_hostname.o: valid_utf8_hostname.h valid_utf8_hostname.o: vbuf.h valid_utf8_hostname.o: vstring.h valid_utf8_string.o: check_arg.h +valid_utf8_string.o: parse_utf8_char.h valid_utf8_string.o: stringops.h valid_utf8_string.o: sys_defs.h valid_utf8_string.o: valid_utf8_string.c diff --git a/postfix/src/util/parse_utf8_char.h b/postfix/src/util/parse_utf8_char.h new file mode 100644 index 000000000..318ed232f --- /dev/null +++ b/postfix/src/util/parse_utf8_char.h @@ -0,0 +1,109 @@ +/*++ +/* NAME +/* parse_utf8_char 3h +/* SUMMARY +/* parse one UTF-8 multibyte character +/* SYNOPSIS +/* #include +/* +/* char *parse_utf8_char(str, len) +/* const char *str; +/* ssize_t len; +/* DESCRIPTION +/* parse_utf8_char() determines if the \fBlen\fR bytes starting +/* at \fBstr\fR begin with a complete UTF-8 multi-byte character +/* as defined in RFC 3629. That is, it contains a proper +/* encoding of code points U+0000..U+10FFFF, excluding over-long +/* encodings and excluding U+D800..U+DFFF surrogates. +/* +/* When the \fBlen\fR bytes starting at \fBstr\fR begin with +/* a complete UTF-8 multi-byte character, this function returns +/* a pointer to the last byte in that character. Otherwise, +/* it returns a null pointer. +/* BUGS +/* Code points in the range U+FDD0..U+FDEF and ending in FFFE +/* or FFFF are non-characters in UNICODE. This function does +/* not reject these. +/* 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 +/* +/* Wietse Venema +/* porcupine.org +/* Amawalk, NY 10501, USA +/*--*/ + + /* + * System library. + */ +#include + +#ifdef NO_INLINE +#define inline /* */ +#endif + +/* parse_utf8_char - parse and validate one UTF8 multibyte sequence */ + +static inline char *parse_utf8_char(const char *str, const char *end) +{ + const unsigned char *cp = (const unsigned char *) str; + const unsigned char *ep = (const unsigned char *) end; + unsigned char c0, ch; + + /* + * Optimized for correct input, time, space, and for CPUs that have a + * decent number of registers. + */ + /* Single-byte encodings. */ + if (EXPECTED((c0 = *cp) <= 0x7f) /* we know that c0 >= 0x0 */ ) { + return ((char *) cp); + } + /* Two-byte encodings. */ + else if (EXPECTED(c0 <= 0xdf) /* we know that c0 >= 0x80 */ ) { + /* Exclude over-long encodings. */ + if (UNEXPECTED(c0 < 0xc2) + || UNEXPECTED(cp + 1 >= ep) + /* Require UTF-8 tail byte. */ + || UNEXPECTED(((ch = *++cp) & 0xc0) != 0x80)) + return (0); + return ((char *) cp); + } + /* Three-byte encodings. */ + else if (EXPECTED(c0 <= 0xef) /* we know that c0 >= 0xe0 */ ) { + if (UNEXPECTED(cp + 2 >= ep) + /* Exclude over-long encodings. */ + || UNEXPECTED((ch = *++cp) < (c0 == 0xe0 ? 0xa0 : 0x80)) + /* Exclude U+D800..U+DFFF. */ + || UNEXPECTED(ch > (c0 == 0xed ? 0x9f : 0xbf)) + /* Require UTF-8 tail byte. */ + || UNEXPECTED(((ch = *++cp) & 0xc0) != 0x80)) + return (0); + return ((char *) cp); + } + /* Four-byte encodings. */ + else if (EXPECTED(c0 <= 0xf4) /* we know that c0 >= 0xf0 */ ) { + if (UNEXPECTED(cp + 3 >= ep) + /* Exclude over-long encodings. */ + || UNEXPECTED((ch = *++cp) < (c0 == 0xf0 ? 0x90 : 0x80)) + /* Exclude code points above U+10FFFF. */ + || UNEXPECTED(ch > (c0 == 0xf4 ? 0x8f : 0xbf)) + /* Require UTF-8 tail byte. */ + || UNEXPECTED(((ch = *++cp) & 0xc0) != 0x80) + /* Require UTF-8 tail byte. */ + || UNEXPECTED(((ch = *++cp) & 0xc0) != 0x80)) + return (0); + return ((char *) cp); + } + /* Invalid: c0 >= 0xf5 */ + else { + return (0); + } +} + +#undef inline diff --git a/postfix/src/util/printable.c b/postfix/src/util/printable.c index 6c148fd00..5091a3cfc 100644 --- a/postfix/src/util/printable.c +++ b/postfix/src/util/printable.c @@ -45,6 +45,10 @@ /* Google, Inc. /* 111 8th Avenue /* New York, NY 10011, USA +/* +/* Wietse Venema +/* porcupine.org +/* Amawalk, NY 10501, USA /*--*/ /* System library. */ @@ -56,6 +60,7 @@ /* Utility library. */ #include "stringops.h" +#include "parse_utf8_char.h" int util_utf8_enable = 0; @@ -74,27 +79,54 @@ char *printable(char *string, int replacement) char *printable_except(char *string, int replacement, const char *except) { - unsigned char *cp; + char *cp; + char *ep = string + strlen(string); + char *last; int ch; /* - * XXX Replace invalid UTF8 sequences (too short, over-long encodings, - * out-of-range code points, etc). See valid_utf8_string.c. + * In case of a non-UTF8 sequence (bad leader byte, bad non-leader byte, + * over-long encodings, out-of-range code points, etc), replace the first + * byte, and try to resynchronize at the next byte. */ - cp = (unsigned char *) string; - while ((ch = *cp) != 0) { - if (ISASCII(ch) && (ISPRINT(ch) || (except && strchr(except, ch)))) { - /* ok */ - } else if (util_utf8_enable && ch >= 194 && ch <= 254 - && cp[1] >= 128 && cp[1] < 192) { - /* UTF8; skip the rest of the bytes in the character. */ - while (cp[1] >= 128 && cp[1] < 192) - cp++; - } else { - /* Not ASCII and not UTF8. */ - *cp = replacement; +#define PRINT_OR_EXCEPT(ch) (ISPRINT(ch) || (except && strchr(except, ch))) + + for (cp = string; (ch = *(unsigned char *) cp) != 0; cp++) { + if (util_utf8_enable == 0) { + if (ISASCII(ch) && PRINT_OR_EXCEPT(ch)) + continue; + } else if ((last = parse_utf8_char(cp, ep)) == cp) { /* ASCII */ + if (PRINT_OR_EXCEPT(ch)) + continue; + } else if (last > cp) { /* Other UTF8 */ + cp = last; + continue; } - cp++; + *cp = replacement; } return (string); } + +#ifdef TEST + +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + VSTRING *in = vstring_alloc(10); + + util_utf8_enable = 1; + + while (vstring_fgets_nonl(in, VSTREAM_IN)) { + printable(vstring_str(in), '?'); + vstream_fwrite(VSTREAM_OUT, vstring_str(in), VSTRING_LEN(in)); + VSTREAM_PUTC('\n', VSTREAM_OUT); + } + vstream_fflush(VSTREAM_OUT); + exit(0); +} + +#endif diff --git a/postfix/src/util/printable.in b/postfix/src/util/printable.in new file mode 100644 index 000000000..21e0acdd1 --- /dev/null +++ b/postfix/src/util/printable.in @@ -0,0 +1,10 @@ +printable +nonn-printable +naïve +naÃve +виктор +вÐкºÑ‚ор +ויקטוּר +ו™×§×˜×•ּר +中国互联网络发展状况统计报告 +中å互è”网络发展状况统计报å diff --git a/postfix/src/util/printable.ref b/postfix/src/util/printable.ref new file mode 100644 index 000000000..a85f3405a --- /dev/null +++ b/postfix/src/util/printable.ref @@ -0,0 +1,10 @@ +printable +non?n-printable +naïve +na?ve +виктор +в?к?тор +ויקטוּר +ו?קטוּר +中国互联网络发展状况统计报告 +中?互??网络发展状况统计报? diff --git a/postfix/src/util/valid_utf8_string.c b/postfix/src/util/valid_utf8_string.c index 96b5b4db8..bc84fdd3f 100644 --- a/postfix/src/util/valid_utf8_string.c +++ b/postfix/src/util/valid_utf8_string.c @@ -10,23 +10,16 @@ /* const char *str; /* ssize_t len; /* DESCRIPTION -/* valid_utf8_string() determines if a string satisfies the UTF-8 -/* definition in RFC 3629. That is, it contains proper encodings -/* of code points U+0000..U+10FFFF, excluding over-long encodings -/* and excluding U+D800..U+DFFF surrogates. +/* valid_utf8_string() determines if all bytes in a string +/* satisfy parse_utf8_char(3h) checks. See there for any +/* implementation limitations. /* /* A zero-length string is considered valid. /* DIAGNOSTICS /* The result value is zero when the caller specifies a negative -/* length, or a string that violates RFC 3629, for example a -/* string that is truncated in the middle of a multi-byte -/* sequence. -/* BUGS -/* But wait, there is more. Code points in the range U+FDD0..U+FDEF -/* and ending in FFFE or FFFF are non-characters in UNICODE. This -/* function does not block these. +/* length, or a string that does not pass parse_utf8_char(3h) checks. /* SEE ALSO -/* RFC 3629 +/* parse_utf8_char(3h), parse one UTF-8 multibyte character /* LICENSE /* .ad /* .fi @@ -36,6 +29,10 @@ /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA +/* +/* Wietse Venema +/* porcupine.org +/* Amawalk, NY 10501, USA /*--*/ /* System library. */ @@ -45,14 +42,15 @@ /* Utility library. */ #include +#include /* valid_utf8_string - validate string according to RFC 3629 */ int valid_utf8_string(const char *str, ssize_t len) { - const unsigned char *end = (const unsigned char *) str + len; - const unsigned char *cp; - unsigned char c0, ch; + const char *ep = str + len; + const char *cp; + const char *last; if (len < 0) return (0); @@ -60,51 +58,13 @@ int valid_utf8_string(const char *str, ssize_t len) return (1); /* - * Optimized for correct input, time, space, and for CPUs that have a - * decent number of registers. + * Ideally, the compiler will inline parse_utf8_char(). */ - for (cp = (const unsigned char *) str; cp < end; cp++) { - /* Single-byte encodings. */ - if (EXPECTED((c0 = *cp) <= 0x7f) /* we know that c0 >= 0x0 */ ) { - /* void */ ; - } - /* Two-byte encodings. */ - else if (EXPECTED(c0 <= 0xdf) /* we know that c0 >= 0x80 */ ) { - /* Exclude over-long encodings. */ - if (UNEXPECTED(c0 < 0xc2) - || UNEXPECTED(cp + 1 >= end) - /* Require UTF-8 tail byte. */ - || UNEXPECTED(((ch = *++cp) & 0xc0) != 0x80)) - return (0); - } - /* Three-byte encodings. */ - else if (EXPECTED(c0 <= 0xef) /* we know that c0 >= 0xe0 */ ) { - if (UNEXPECTED(cp + 2 >= end) - /* Exclude over-long encodings. */ - || UNEXPECTED((ch = *++cp) < (c0 == 0xe0 ? 0xa0 : 0x80)) - /* Exclude U+D800..U+DFFF. */ - || UNEXPECTED(ch > (c0 == 0xed ? 0x9f : 0xbf)) - /* Require UTF-8 tail byte. */ - || UNEXPECTED(((ch = *++cp) & 0xc0) != 0x80)) - return (0); - } - /* Four-byte encodings. */ - else if (EXPECTED(c0 <= 0xf4) /* we know that c0 >= 0xf0 */ ) { - if (UNEXPECTED(cp + 3 >= end) - /* Exclude over-long encodings. */ - || UNEXPECTED((ch = *++cp) < (c0 == 0xf0 ? 0x90 : 0x80)) - /* Exclude code points above U+10FFFF. */ - || UNEXPECTED(ch > (c0 == 0xf4 ? 0x8f : 0xbf)) - /* Require UTF-8 tail byte. */ - || UNEXPECTED(((ch = *++cp) & 0xc0) != 0x80) - /* Require UTF-8 tail byte. */ - || UNEXPECTED(((ch = *++cp) & 0xc0) != 0x80)) - return (0); - } - /* Invalid: c0 >= 0xf5 */ - else { + for (cp = str; cp < ep; cp++) { + if ((last = parse_utf8_char(cp, ep)) != 0) + cp = last; + else return (0); - } } return (1); } diff --git a/postfix/src/xsasl/xsasl_cyrus_server.c b/postfix/src/xsasl/xsasl_cyrus_server.c index 89e1fc9a0..e9032892f 100644 --- a/postfix/src/xsasl/xsasl_cyrus_server.c +++ b/postfix/src/xsasl/xsasl_cyrus_server.c @@ -52,6 +52,10 @@ /* Google, Inc. /* 111 8th Avenue /* New York, NY 10011, USA +/* +/* Wietse Venema +/* porcupine.org +/* Amawalk, NY 10501, USA /*--*/ /* System library. */ @@ -625,16 +629,15 @@ static const char *xsasl_cyrus_server_get_username(XSASL_SERVER *xp) /* * XXX Do not free(serverout). */ + if (server->username) + myfree(server->username); sasl_status = sasl_getprop(server->sasl_conn, SASL_USERNAME, &serverout); if (sasl_status != SASL_OK || serverout == 0) { - msg_warn("%s: sasl_getprop SASL_USERNAME botch: %s", - myname, xsasl_cyrus_strerror(sasl_status)); - return (0); + server->username = 0; + } else { + server->username = mystrdup(serverout); + printable(server->username, '?'); } - if (server->username) - myfree(server->username); - server->username = mystrdup(serverout); - printable(server->username, '?'); return (server->username); } diff --git a/postfix/src/xsasl/xsasl_server.c b/postfix/src/xsasl/xsasl_server.c index e8d7e1694..c50486476 100644 --- a/postfix/src/xsasl/xsasl_server.c +++ b/postfix/src/xsasl/xsasl_server.c @@ -123,7 +123,10 @@ /* reply. /* /* xsasl_server_get_username() returns the stored username -/* after successful authentication. +/* after successful authentication. The username may be null +/* after authentication failure, depending on the kind of +/* failure and on authentication backend implementation +/* details. A non-null result is converted to printable text. /* /* Arguments: /* .IP addr_family @@ -207,6 +210,10 @@ /* Google, Inc. /* 111 8th Avenue /* New York, NY 10011, USA +/* +/* Wietse Venema +/* porcupine.org +/* Amawalk, NY 10501, USA /*--*/ /* System library. */