2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 05:38:06 +00:00

postfix-2.8.8

This commit is contained in:
Wietse Venema 2012-02-01 00:00:00 -05:00 committed by Viktor Dukhovni
parent fa39a469ca
commit a3e9b5d9c2
11 changed files with 151 additions and 42 deletions

View File

@ -16695,3 +16695,55 @@ Apologies for any names omitted.
Portability: OpenBSD 5.x is supported. Files: makedefs, Portability: OpenBSD 5.x is supported. Files: makedefs,
util/sys_defs.h. util/sys_defs.h.
Portability: Dovecot now officially supports more socket
types for its authentication server. File:
xsasl/xsasl_dovecot_server.c.
20111126
Bitrot: changes in error reporting to the under-documented
OpenLDAP API. Problem reported by Quanah Gibson-Mount. Fix
by Viktor Dukhovni. File: global/dict_ldap.c.
20111205
Bugfix: tlsproxy(8) stored TLS sessions with a serverID of
"tlsproxy" instead of "smtpd", wasting an opportunity for
session reuse. File: tlsproxy/tlsproxy.c.
20111211
Bugfix: missing lookup table entry and terminator, causing
proxymap server segfault when postscreen(8) or verify(8)
attempted to access their cache via the proxymap server.
This could never have worked anyway, because the Postfix
2.8 proxymap protocol does not support cache cleanup. File
util/dict.c.
20111226
Bugfix (introduced 20110426): after lookup error with
mailbox_transport_maps, mailbox_command_maps or
fallback_transport_maps, the local delivery agent did not
log the problem before deferring mail, and produced no defer
logfile record. Files: local/mailbox.c, local/unknown.c.
20120127
Bugfix (introduced: Postfix 2.8): the Postfix client sqlite
quoting routine returned the unquoted result instead of the
quoted text. The opportunities for misuse are limited,
because Postfix sqlite files are usually owned by root, and
Postfix daemons usually run with non-root privileges so
they can't corrupt the database. Problem reported by Rob
McGee (rob0). File: global/dict_sqlite.c.
20120130
Bugfix (introduced: Postfix 2.3): the trace service did not
distinguish between notifications for a non-bounce or a
bounce message. This code pre-dates DSN support and should
have been updated when it was re-purposed to handle DSN
SUCCESS notifications. Problem reported by Sabahattin
Gucukoglu. File: bounce/bounce_trace_service.c.

View File

@ -83,8 +83,39 @@ int bounce_trace_service(int flags, char *service, char *queue_name,
BOUNCE_INFO *bounce_info; BOUNCE_INFO *bounce_info;
int bounce_status = 1; int bounce_status = 1;
VSTREAM *bounce; VSTREAM *bounce;
VSTRING *new_id = vstring_alloc(10); int notify_mask = name_mask(VAR_NOTIFY_CLASSES, mail_error_masks,
var_notify_classes);
VSTRING *new_id;
int count; int count;
const char *sender;
/*
* For consistency with fail/delay notifications, send notification for a
* non-bounce message as a single-bounce message, send notification for a
* single-bounce message as a double-bounce message, and drop requests to
* send notification for a double-bounce message.
*/
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
if (strcasecmp(recipient, mail_addr_double_bounce()) == 0) {
msg_info("%s: not sending trace/success notification for "
"double-bounce message", queue_id);
return (0);
} else if (*recipient == 0) {
if ((notify_mask & MAIL_ERROR_2BOUNCE) != 0) {
recipient = var_2bounce_rcpt;
sender = mail_addr_double_bounce();
} else {
msg_info("%s: not sending trace/success notification "
"for single-bounce message", queue_id);
if (mail_queue_remove(service, queue_id) && errno != ENOENT)
msg_fatal("remove %s %s: %m", service, queue_id);
return (0);
}
} else {
/* Always send notification for non-bounce message. */
sender = NULL_SENDER;
}
/* /*
* Initialize. Open queue file, bounce log, etc. * Initialize. Open queue file, bounce log, etc.
@ -126,7 +157,6 @@ int bounce_trace_service(int flags, char *service, char *queue_name,
bounce_mail_free(bounce_info); bounce_mail_free(bounce_info);
return (0); return (0);
} }
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
#define NULL_TRACE_FLAGS 0 #define NULL_TRACE_FLAGS 0
/* /*
@ -139,7 +169,8 @@ int bounce_trace_service(int flags, char *service, char *queue_name,
* there are fewer potential left-over files to remove up when we create * there are fewer potential left-over files to remove up when we create
* a new queue file. * a new queue file.
*/ */
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, recipient, new_id = vstring_alloc(10);
if ((bounce = post_mail_fopen_nowait(sender, recipient,
INT_FILT_MASK_BOUNCE, INT_FILT_MASK_BOUNCE,
NULL_TRACE_FLAGS, NULL_TRACE_FLAGS,
new_id)) != 0) { new_id)) != 0) {

View File

@ -225,6 +225,7 @@
#include "mail_conf.h" #include "mail_conf.h"
#if defined(USE_LDAP_SASL) && defined(LDAP_API_FEATURE_X_OPENLDAP) #if defined(USE_LDAP_SASL) && defined(LDAP_API_FEATURE_X_OPENLDAP)
/* /*
* SASL headers, for sasl_interact_t. Either SASL v1 or v2 should be fine. * SASL headers, for sasl_interact_t. Either SASL v1 or v2 should be fine.
*/ */
@ -242,13 +243,13 @@
#define DICT_LDAP_DO_SASL(d) ((d)->bind == DICT_LDAP_BIND_SASL) #define DICT_LDAP_DO_SASL(d) ((d)->bind == DICT_LDAP_BIND_SASL)
static const NAME_CODE bindopt_table[] = { static const NAME_CODE bindopt_table[] = {
CONFIG_BOOL_NO, DICT_LDAP_BIND_NONE, CONFIG_BOOL_NO, DICT_LDAP_BIND_NONE,
"none", DICT_LDAP_BIND_NONE, "none", DICT_LDAP_BIND_NONE,
CONFIG_BOOL_YES, DICT_LDAP_BIND_SIMPLE, CONFIG_BOOL_YES, DICT_LDAP_BIND_SIMPLE,
"simple", DICT_LDAP_BIND_SIMPLE, "simple", DICT_LDAP_BIND_SIMPLE,
#ifdef LDAP_API_FEATURE_X_OPENLDAP #ifdef LDAP_API_FEATURE_X_OPENLDAP
#if defined(USE_LDAP_SASL) #if defined(USE_LDAP_SASL)
"sasl", DICT_LDAP_BIND_SASL, "sasl", DICT_LDAP_BIND_SASL,
#endif #endif
#endif #endif
0, -1, 0, -1,
@ -292,9 +293,9 @@ typedef struct {
#ifdef LDAP_API_FEATURE_X_OPENLDAP #ifdef LDAP_API_FEATURE_X_OPENLDAP
#if defined(USE_LDAP_SASL) #if defined(USE_LDAP_SASL)
int sasl; int sasl;
char *sasl_mechs; char *sasl_mechs;
char *sasl_realm; char *sasl_realm;
char *sasl_authz; char *sasl_authz;
int sasl_minssf; int sasl_minssf;
#endif #endif
int ldap_ssl; int ldap_ssl;
@ -451,28 +452,26 @@ static int dict_ldap_set_errno(LDAP *ld, int rc)
} }
#if defined(USE_LDAP_SASL) && defined(LDAP_API_FEATURE_X_OPENLDAP) #if defined(USE_LDAP_SASL) && defined(LDAP_API_FEATURE_X_OPENLDAP)
/* /*
* Context structure for SASL property callback. * Context structure for SASL property callback.
*/ */
typedef struct bind_props { typedef struct bind_props {
char *authcid; char *authcid;
char *passwd; char *passwd;
char *realm; char *realm;
char *authzid; char *authzid;
} bind_props; } bind_props;
static int static int ldap_b2_interact(LDAP *ld, unsigned flags, void *props, void *inter)
ldap_b2_interact(LDAP *ld, unsigned flags, void *props, void *inter)
{ {
sasl_interact_t *in; sasl_interact_t *in;
bind_props *ctx = (bind_props *)props; bind_props *ctx = (bind_props *) props;
for (in = inter; in->id != SASL_CB_LIST_END; in++) for (in = inter; in->id != SASL_CB_LIST_END; in++) {
{
in->result = NULL; in->result = NULL;
switch(in->id) switch (in->id) {
{
case SASL_CB_GETREALM: case SASL_CB_GETREALM:
in->result = ctx->realm; in->result = ctx->realm;
break; break;
@ -491,6 +490,7 @@ ldap_b2_interact(LDAP *ld, unsigned flags, void *props, void *inter)
} }
return LDAP_SUCCESS; return LDAP_SUCCESS;
} }
#endif #endif
/* dict_ldap_result - Read and parse LDAP result */ /* dict_ldap_result - Read and parse LDAP result */
@ -498,6 +498,7 @@ ldap_b2_interact(LDAP *ld, unsigned flags, void *props, void *inter)
static int dict_ldap_result(LDAP *ld, int msgid, int timeout, LDAPMessage **res) static int dict_ldap_result(LDAP *ld, int msgid, int timeout, LDAPMessage **res)
{ {
struct timeval mytimeval; struct timeval mytimeval;
int err;
mytimeval.tv_sec = timeout; mytimeval.tv_sec = timeout;
mytimeval.tv_usec = 0; mytimeval.tv_usec = 0;
@ -506,9 +507,12 @@ static int dict_ldap_result(LDAP *ld, int msgid, int timeout, LDAPMessage **res)
if (ldap_result(ld, msgid, GET_ALL, &mytimeval, res) == -1) if (ldap_result(ld, msgid, GET_ALL, &mytimeval, res) == -1)
return (dict_ldap_get_errno(ld)); return (dict_ldap_get_errno(ld));
if (dict_ldap_get_errno(ld) == LDAP_TIMEOUT) { if ((err = dict_ldap_get_errno(ld)) != LDAP_SUCCESS) {
(void) dict_ldap_abandon(ld, msgid); if (err == LDAP_TIMEOUT) {
return (dict_ldap_set_errno(ld, LDAP_TIMEOUT)); (void) dict_ldap_abandon(ld, msgid);
return (dict_ldap_set_errno(ld, LDAP_TIMEOUT));
}
return err;
} }
return LDAP_SUCCESS; return LDAP_SUCCESS;
} }
@ -529,7 +533,7 @@ static int dict_ldap_bind_sasl(DICT_LDAP *dict_ldap)
vstring_sprintf(minssf, "minssf=%d", dict_ldap->sasl_minssf); vstring_sprintf(minssf, "minssf=%d", dict_ldap->sasl_minssf);
if ((rc = ldap_set_option(dict_ldap->ld, LDAP_OPT_X_SASL_SECPROPS, if ((rc = ldap_set_option(dict_ldap->ld, LDAP_OPT_X_SASL_SECPROPS,
(char *) minssf)) != LDAP_OPT_SUCCESS) (char *) minssf)) != LDAP_OPT_SUCCESS)
return (rc); return (rc);
props.authcid = dict_ldap->bind_dn; props.authcid = dict_ldap->bind_dn;
@ -538,13 +542,14 @@ static int dict_ldap_bind_sasl(DICT_LDAP *dict_ldap)
props.authzid = dict_ldap->sasl_authz; props.authzid = dict_ldap->sasl_authz;
if ((rc = ldap_sasl_interactive_bind_s(dict_ldap->ld, NULL, if ((rc = ldap_sasl_interactive_bind_s(dict_ldap->ld, NULL,
dict_ldap->sasl_mechs, NULL, NULL, dict_ldap->sasl_mechs, NULL, NULL,
LDAP_SASL_QUIET, ldap_b2_interact, LDAP_SASL_QUIET, ldap_b2_interact,
&props)) != LDAP_SUCCESS) &props)) != LDAP_SUCCESS)
return (rc); return (rc);
return (LDAP_SUCCESS); return (LDAP_SUCCESS);
} }
#endif #endif
/* dict_ldap_bind_st - Synchronous simple auth with timeout */ /* dict_ldap_bind_st - Synchronous simple auth with timeout */
@ -552,6 +557,7 @@ static int dict_ldap_bind_sasl(DICT_LDAP *dict_ldap)
static int dict_ldap_bind_st(DICT_LDAP *dict_ldap) static int dict_ldap_bind_st(DICT_LDAP *dict_ldap)
{ {
int rc; int rc;
int err = LDAP_SUCCESS;
int msgid; int msgid;
LDAPMessage *res; LDAPMessage *res;
struct berval cred; struct berval cred;
@ -567,7 +573,8 @@ static int dict_ldap_bind_st(DICT_LDAP *dict_ldap)
return (rc); return (rc);
#define FREE_RESULT 1 #define FREE_RESULT 1
return (ldap_parse_sasl_bind_result(dict_ldap->ld, res, 0, FREE_RESULT)); rc = ldap_parse_result(dict_ldap->ld, res, &err, 0, 0, 0, 0, FREE_RESULT);
return (rc == LDAP_SUCCESS ? err : rc);
} }
/* search_st - Synchronous search with timeout */ /* search_st - Synchronous search with timeout */
@ -868,6 +875,7 @@ static int dict_ldap_connect(DICT_LDAP *dict_ldap)
#define DN_LOG_VAL(dict_ldap) \ #define DN_LOG_VAL(dict_ldap) \
((dict_ldap)->bind_dn[0] ? (dict_ldap)->bind_dn : "empty or implicit") ((dict_ldap)->bind_dn[0] ? (dict_ldap)->bind_dn : "empty or implicit")
/* /*
* If this server requires a bind, do so. Thanks to Sam Tardieu for * If this server requires a bind, do so. Thanks to Sam Tardieu for
* noticing that the original bind call was broken. * noticing that the original bind call was broken.
@ -1873,6 +1881,7 @@ DICT *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
#ifdef LDAP_API_FEATURE_X_OPENLDAP #ifdef LDAP_API_FEATURE_X_OPENLDAP
#if defined(USE_LDAP_SASL) #if defined(USE_LDAP_SASL)
/* /*
* SASL options * SASL options
*/ */

View File

@ -57,6 +57,12 @@
/* AUTHOR(S) /* AUTHOR(S)
/* Axel Steiner /* Axel Steiner
/* ast@treibsand.com /* ast@treibsand.com
/*
/* Adopted and updated by:
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/ /*--*/
/* System library. */ /* System library. */
@ -109,7 +115,7 @@ static void dict_sqlite_quote(DICT *dict, const char *raw_text, VSTRING *result)
/* Fix 20100616 */ /* Fix 20100616 */
if (quoted_text == 0) if (quoted_text == 0)
msg_fatal("dict_sqlite_quote: out of memory"); msg_fatal("dict_sqlite_quote: out of memory");
vstring_strcat(result, raw_text); vstring_strcat(result, quoted_text);
sqlite3_free(quoted_text); sqlite3_free(quoted_text);
} }
@ -150,6 +156,11 @@ static const char *dict_sqlite_lookup(DICT *dict, const char *name)
int expansion = 0; int expansion = 0;
int status; int status;
/*
* In case of return without lookup (skipped key, etc.).
*/
dict_errno = 0;
/* /*
* Don't frustrate future attempts to make Postfix UTF-8 transparent. * Don't frustrate future attempts to make Postfix UTF-8 transparent.
*/ */

View File

@ -20,8 +20,8 @@
* Patches change both the patchlevel and the release date. Snapshots have no * Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only. * patchlevel; they change the release date only.
*/ */
#define MAIL_RELEASE_DATE "20111105" #define MAIL_RELEASE_DATE "20120201"
#define MAIL_VERSION_NUMBER "2.8.7" #define MAIL_VERSION_NUMBER "2.8.8"
#ifdef SNAPSHOT #ifdef SNAPSHOT
# define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE # define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE

View File

@ -163,6 +163,11 @@ const char *maps_find(MAPS *maps, const char *name, int flags)
const char *expansion; const char *expansion;
DICT *dict; DICT *dict;
/*
* In case of return without map lookup (empty name or no maps).
*/
dict_errno = 0;
/* /*
* Temp. workaround, for buggy callers that pass zero-length keys when * Temp. workaround, for buggy callers that pass zero-length keys when
* given partial addresses. * given partial addresses.
@ -189,6 +194,7 @@ const char *maps_find(MAPS *maps, const char *name, int flags)
*map_name, name, expansion); *map_name, name, expansion);
return (expansion); return (expansion);
} else if (dict_errno != 0) { } else if (dict_errno != 0) {
msg_warn("%s:%s lookup of %s failed", dict->type, dict->name, name);
break; break;
} }
} }

View File

@ -289,7 +289,8 @@ int deliver_mailbox(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp)
} else if (dict_errno != 0) { } else if (dict_errno != 0) {
/* Details in the logfile. */ /* Details in the logfile. */
dsb_simple(state.msg_attr.why, "4.3.0", "table lookup failure"); dsb_simple(state.msg_attr.why, "4.3.0", "table lookup failure");
*statusp = DEL_STAT_DEFER; *statusp = defer_append(BOUNCE_FLAGS(state.request),
BOUNCE_ATTR(state.msg_attr));
return (YES); return (YES);
} }
if (*var_mailbox_transport) { if (*var_mailbox_transport) {
@ -333,7 +334,8 @@ int deliver_mailbox(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp)
} else if (dict_errno != 0) { } else if (dict_errno != 0) {
/* Details in the logfile. */ /* Details in the logfile. */
dsb_simple(state.msg_attr.why, "4.3.0", "table lookup failure"); dsb_simple(state.msg_attr.why, "4.3.0", "table lookup failure");
status = DEL_STAT_DEFER; status = defer_append(BOUNCE_FLAGS(state.request),
BOUNCE_ATTR(state.msg_attr));
} else if (*var_mailbox_command) { } else if (*var_mailbox_command) {
status = deliver_command(state, usr_attr, var_mailbox_command); status = deliver_command(state, usr_attr, var_mailbox_command);
} else if (*var_home_mailbox && LAST_CHAR(var_home_mailbox) == '/') { } else if (*var_home_mailbox && LAST_CHAR(var_home_mailbox) == '/') {

View File

@ -120,7 +120,8 @@ int deliver_unknown(LOCAL_STATE state, USER_ATTR usr_attr)
} else if (dict_errno != 0) { } else if (dict_errno != 0) {
/* Details in the logfile. */ /* Details in the logfile. */
dsb_simple(state.msg_attr.why, "4.3.0", "table lookup failure"); dsb_simple(state.msg_attr.why, "4.3.0", "table lookup failure");
return (DEL_STAT_DEFER); return (defer_append(BOUNCE_FLAGS(state.request),
BOUNCE_ATTR(state.msg_attr)));
} }
if (*var_fallback_transport) { if (*var_fallback_transport) {
state.msg_attr.rcpt.offset = -1L; state.msg_attr.rcpt.offset = -1L;

View File

@ -692,7 +692,7 @@ static void tlsp_start_tls(TLSP_STATE *state)
timeout = 0, /* unused */ timeout = 0, /* unused */
requirecert = (var_tlsp_tls_req_ccert requirecert = (var_tlsp_tls_req_ccert
&& var_tlsp_enforce_tls), && var_tlsp_enforce_tls),
serverid = state->service, serverid = MAIL_SERVICE_SMTPD, /* XXX */
namaddr = state->remote_endpt, namaddr = state->remote_endpt,
cipher_grade = cipher_grade, cipher_grade = cipher_grade,
cipher_exclusions = STR(cipher_exclusions), cipher_exclusions = STR(cipher_exclusions),

View File

@ -536,6 +536,8 @@ static const NAME_MASK dict_mask[] = {
"no_unauth", (1 << 13), /* disallow unauthenticated data */ "no_unauth", (1 << 13), /* disallow unauthenticated data */
"fold_fix", (1 << 14), /* case-fold with fixed-case key map */ "fold_fix", (1 << 14), /* case-fold with fixed-case key map */
"fold_mul", (1 << 15), /* case-fold with multi-case key map */ "fold_mul", (1 << 15), /* case-fold with multi-case key map */
"open_lock", (1 << 16), /* permanent lock upon open */
0,
}; };
/* dict_flags_str - convert mask to string for debugging purposes */ /* dict_flags_str - convert mask to string for debugging purposes */

View File

@ -371,11 +371,6 @@ XSASL_SERVER_IMPL *xsasl_dovecot_server_init(const char *server_type,
{ {
XSASL_DOVECOT_SERVER_IMPL *xp; XSASL_DOVECOT_SERVER_IMPL *xp;
if (strchr(path_info, '/') == 0)
msg_warn("when SASL type is \"%s\", SASL path \"%s\" "
"should be a socket pathname",
server_type, path_info);
xp = (XSASL_DOVECOT_SERVER_IMPL *) mymalloc(sizeof(*xp)); xp = (XSASL_DOVECOT_SERVER_IMPL *) mymalloc(sizeof(*xp));
xp->xsasl.create = xsasl_dovecot_server_create; xp->xsasl.create = xsasl_dovecot_server_create;
xp->xsasl.done = xsasl_dovecot_server_done; xp->xsasl.done = xsasl_dovecot_server_done;