mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-28 20:57:56 +00:00
postfix-3.2-20170109-nonprod
This commit is contained in:
parent
990a60f79f
commit
6a78d6670f
@ -22785,3 +22785,10 @@ Apologies for any names omitted.
|
|||||||
relocated_maps). These features may be migrated later to
|
relocated_maps). These features may be migrated later to
|
||||||
enable quoted-form address lookup keys, for consistency
|
enable quoted-form address lookup keys, for consistency
|
||||||
with other Postfix features.
|
with other Postfix features.
|
||||||
|
|
||||||
|
20170109
|
||||||
|
|
||||||
|
Cleanup: reduce the number of modified files, to make a
|
||||||
|
back-port more feasible. This renames foo() to foo_opt(),
|
||||||
|
and renames the backwards_compatibility foo_noconv() to
|
||||||
|
their old name foo().
|
||||||
|
@ -6,7 +6,11 @@ Wish list:
|
|||||||
|
|
||||||
Disable -DSNAPSHOT and -DNONPROD in makedefs.
|
Disable -DSNAPSHOT and -DNONPROD in makedefs.
|
||||||
|
|
||||||
Document RFC5321 localpart quoting in DATABASE_README.
|
Document RFC5322 localpart quoting in DATABASE_README.
|
||||||
|
|
||||||
|
Add quote_822_local() flag to indicate if an address
|
||||||
|
is complete or localpart only. This avoids incorrect
|
||||||
|
results when a localpart-only input contains '@'.
|
||||||
|
|
||||||
In the bounce daemon, set util_utf8_enable if returning an
|
In the bounce daemon, set util_utf8_enable if returning an
|
||||||
SMTPUTF8 message.
|
SMTPUTF8 message.
|
||||||
|
@ -165,9 +165,8 @@ off_t cleanup_addr_sender(CLEANUP_STATE *state, const char *buf)
|
|||||||
if ((state->flags & CLEANUP_FLAG_BCC_OK)
|
if ((state->flags & CLEANUP_FLAG_BCC_OK)
|
||||||
&& *STR(clean_addr)
|
&& *STR(clean_addr)
|
||||||
&& cleanup_send_bcc_maps) {
|
&& cleanup_send_bcc_maps) {
|
||||||
if ((bcc = mail_addr_find_noconv(cleanup_send_bcc_maps,
|
if ((bcc = mail_addr_find(cleanup_send_bcc_maps, STR(clean_addr),
|
||||||
STR(clean_addr),
|
IGNORE_EXTENSION)) != 0) {
|
||||||
IGNORE_EXTENSION)) != 0) {
|
|
||||||
cleanup_addr_bcc(state, bcc);
|
cleanup_addr_bcc(state, bcc);
|
||||||
} else if (cleanup_send_bcc_maps->error) {
|
} else if (cleanup_send_bcc_maps->error) {
|
||||||
msg_warn("%s: %s map lookup problem -- "
|
msg_warn("%s: %s map lookup problem -- "
|
||||||
@ -229,9 +228,8 @@ void cleanup_addr_recipient(CLEANUP_STATE *state, const char *buf)
|
|||||||
if ((state->flags & CLEANUP_FLAG_BCC_OK)
|
if ((state->flags & CLEANUP_FLAG_BCC_OK)
|
||||||
&& *STR(clean_addr)
|
&& *STR(clean_addr)
|
||||||
&& cleanup_rcpt_bcc_maps) {
|
&& cleanup_rcpt_bcc_maps) {
|
||||||
if ((bcc = mail_addr_find_noconv(cleanup_rcpt_bcc_maps,
|
if ((bcc = mail_addr_find(cleanup_rcpt_bcc_maps, STR(clean_addr),
|
||||||
STR(clean_addr),
|
IGNORE_EXTENSION)) != 0) {
|
||||||
IGNORE_EXTENSION)) != 0) {
|
|
||||||
cleanup_addr_bcc(state, bcc);
|
cleanup_addr_bcc(state, bcc);
|
||||||
} else if (cleanup_rcpt_bcc_maps->error) {
|
} else if (cleanup_rcpt_bcc_maps->error) {
|
||||||
msg_warn("%s: %s map lookup problem -- "
|
msg_warn("%s: %s map lookup problem -- "
|
||||||
|
@ -104,9 +104,9 @@ int cleanup_map11_external(CLEANUP_STATE *state, VSTRING *addr,
|
|||||||
* the place.
|
* the place.
|
||||||
*/
|
*/
|
||||||
for (count = 0; count < MAX_RECURSION; count++) {
|
for (count = 0; count < MAX_RECURSION; count++) {
|
||||||
if ((new_addr = mail_addr_map(maps, STR(addr), propagate,
|
if ((new_addr = mail_addr_map_opt(maps, STR(addr), propagate,
|
||||||
MAIL_ADDR_FORM_EXTERNAL,
|
MAIL_ADDR_FORM_EXTERNAL,
|
||||||
MAIL_ADDR_FORM_EXTERNAL)) != 0) {
|
MAIL_ADDR_FORM_EXTERNAL)) != 0) {
|
||||||
if (new_addr->argc > 1)
|
if (new_addr->argc > 1)
|
||||||
msg_warn("%s: multi-valued %s entry for %s",
|
msg_warn("%s: multi-valued %s entry for %s",
|
||||||
state->queue_id, maps->title, STR(addr));
|
state->queue_id, maps->title, STR(addr));
|
||||||
|
@ -10,13 +10,13 @@
|
|||||||
/* const char *string;
|
/* const char *string;
|
||||||
/* const char *extension;
|
/* const char *extension;
|
||||||
/*
|
/*
|
||||||
/* ARGV *mail_addr_crunch(string, extension, in_form, out_form)
|
/* ARGV *mail_addr_crunch_opt(string, extension, in_form, out_form)
|
||||||
/* const char *string;
|
/* const char *string;
|
||||||
/* const char *extension;
|
/* const char *extension;
|
||||||
/* int in_form;
|
/* int in_form;
|
||||||
/* int out_form;
|
/* int out_form;
|
||||||
/* LEGACY SUPPORT
|
/* LEGACY SUPPORT
|
||||||
/* ARGV *mail_addr_crunch_noconv(string, extension)
|
/* ARGV *mail_addr_crunch(string, extension)
|
||||||
/* const char *string;
|
/* const char *string;
|
||||||
/* const char *extension;
|
/* const char *extension;
|
||||||
/* DESCRIPTION
|
/* DESCRIPTION
|
||||||
@ -28,10 +28,10 @@
|
|||||||
/* between internal and external forms. The caller is expected
|
/* between internal and external forms. The caller is expected
|
||||||
/* to pass the result to argv_free().
|
/* to pass the result to argv_free().
|
||||||
/*
|
/*
|
||||||
/* mail_addr_crunch() gives more control, at the cost of
|
/* mail_addr_crunch_opt() gives more control, at the cost of
|
||||||
/* additional conversions between internal and external forms.
|
/* additional conversions between internal and external forms.
|
||||||
/*
|
/*
|
||||||
/* mail_addr_crunch_noconv() is used by legacy code and performs
|
/* mail_addr_crunch() is used by legacy code and performs
|
||||||
/* no conversion between internal and external forms.
|
/* no conversion between internal and external forms.
|
||||||
/*
|
/*
|
||||||
/* Arguments:
|
/* Arguments:
|
||||||
@ -82,7 +82,7 @@
|
|||||||
|
|
||||||
/* mail_addr_crunch - break string into addresses, optionally add extension */
|
/* mail_addr_crunch - break string into addresses, optionally add extension */
|
||||||
|
|
||||||
ARGV *mail_addr_crunch(const char *string, const char *extension,
|
ARGV *mail_addr_crunch_opt(const char *string, const char *extension,
|
||||||
int in_form, int out_form)
|
int in_form, int out_form)
|
||||||
{
|
{
|
||||||
VSTRING *intern_addr = vstring_alloc(100);
|
VSTRING *intern_addr = vstring_alloc(100);
|
||||||
@ -216,7 +216,7 @@ int main(int unused_argc, char **unused_argv)
|
|||||||
vstream_fflush(VSTREAM_OUT);
|
vstream_fflush(VSTREAM_OUT);
|
||||||
}
|
}
|
||||||
while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF) {
|
while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF) {
|
||||||
argv = mail_addr_crunch(STR(buf), (VSTRING_LEN(extension) ?
|
argv = mail_addr_crunch_opt(STR(buf), (VSTRING_LEN(extension) ?
|
||||||
STR(extension) : 0),
|
STR(extension) : 0),
|
||||||
in_form, out_form);
|
in_form, out_form);
|
||||||
for (cpp = argv->argv; *cpp; cpp++)
|
for (cpp = argv->argv; *cpp; cpp++)
|
||||||
|
@ -20,21 +20,24 @@
|
|||||||
* Global library.
|
* Global library.
|
||||||
*/
|
*/
|
||||||
#include <mail_addr_form.h>
|
#include <mail_addr_form.h>
|
||||||
#include <argv.h>
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* External interface.
|
* External interface.
|
||||||
*/
|
*/
|
||||||
extern ARGV *mail_addr_crunch(const char *, const char *, int, int);
|
extern ARGV *mail_addr_crunch_opt(const char *, const char *, int, int);
|
||||||
|
|
||||||
/* The least-overhead form. */
|
/*
|
||||||
|
* The least-overhead form.
|
||||||
|
*/
|
||||||
#define mail_addr_crunch_ext_to_int(string, extension) \
|
#define mail_addr_crunch_ext_to_int(string, extension) \
|
||||||
mail_addr_crunch((string), (extension), MAIL_ADDR_FORM_EXTERNAL, \
|
mail_addr_crunch_opt((string), (extension), MAIL_ADDR_FORM_EXTERNAL, \
|
||||||
MAIL_ADDR_FORM_INTERNAL)
|
MAIL_ADDR_FORM_INTERNAL)
|
||||||
|
|
||||||
/* The legacy form. */
|
/*
|
||||||
#define mail_addr_crunch_noconv(string, extension) \
|
* The legacy form.
|
||||||
mail_addr_crunch((string), (extension), MAIL_ADDR_FORM_NOCONV, \
|
*/
|
||||||
|
#define mail_addr_crunch(string, extension) \
|
||||||
|
mail_addr_crunch_opt((string), (extension), MAIL_ADDR_FORM_NOCONV, \
|
||||||
MAIL_ADDR_FORM_NOCONV)
|
MAIL_ADDR_FORM_NOCONV)
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
|
@ -11,14 +11,15 @@
|
|||||||
/* const char *address;
|
/* const char *address;
|
||||||
/* char **extension;
|
/* char **extension;
|
||||||
/*
|
/*
|
||||||
/* const char *mail_addr_find(maps, address, extension, in_form, out_form)
|
/* const char *mail_addr_find_opt(maps, address, extension,
|
||||||
|
/* in_form, out_form)
|
||||||
/* MAPS *maps;
|
/* MAPS *maps;
|
||||||
/* const char *address;
|
/* const char *address;
|
||||||
/* char **extension;
|
/* char **extension;
|
||||||
/* int in_form;
|
/* int in_form;
|
||||||
/* int out_form;
|
/* int out_form;
|
||||||
/* LEGACY SUPPORT
|
/* LEGACY SUPPORT
|
||||||
/* const char *mail_addr_find_noconv(maps, address, extension)
|
/* const char *mail_addr_find(maps, address, extension)
|
||||||
/* MAPS *maps;
|
/* MAPS *maps;
|
||||||
/* const char *address;
|
/* const char *address;
|
||||||
/* char **extension;
|
/* char **extension;
|
||||||
@ -38,20 +39,20 @@
|
|||||||
/* (unquoted/quoted) conversions of the query, extension, or
|
/* (unquoted/quoted) conversions of the query, extension, or
|
||||||
/* result.
|
/* result.
|
||||||
/*
|
/*
|
||||||
/* mail_addr_find() gives more control, at the cost of
|
/* mail_addr_find_opt() gives more control, at the cost of
|
||||||
/* additional conversions between internal and external forms.
|
/* additional conversions between internal and external forms.
|
||||||
/* In particular, the output conversion to internal form assumes
|
/* In particular, the output conversion to internal form assumes
|
||||||
/* that the lookup result is an email address.
|
/* that the lookup result is an email address.
|
||||||
/*
|
/*
|
||||||
/* mail_addr_find_noconv() is used by legacy code that is not
|
/* mail_addr_find() is used by legacy code that is not
|
||||||
/* yet aware of internal versus external addres formats.
|
/* yet aware of internal versus external addres formats.
|
||||||
/*
|
/*
|
||||||
/* mail_addr_find_trans() implements transitional functionality.
|
/* mail_addr_find_trans() implements transitional functionality.
|
||||||
/* It behaves like mail_addr_find(...INTERNAL, ...NOCONV) and
|
/* It behaves like mail_addr_find_opt(...INTERNAL, ...NOCONV) and
|
||||||
/* searches a table with the quoted form of the address, but
|
/* searches a table with the quoted form of the address, but
|
||||||
/* if the lookup produces no result, and the quoted address
|
/* if the lookup produces no result, and the quoted address
|
||||||
/* differs from the unquoted form, it also tries
|
/* differs from the unquoted form, it also tries
|
||||||
/* mail_addr_find(...NOCONV, ...NOCONV).
|
/* mail_addr_find_opt(...NOCONV, ...NOCONV).
|
||||||
/*
|
/*
|
||||||
/* An address that is in the form \fIuser\fR matches itself.
|
/* An address that is in the form \fIuser\fR matches itself.
|
||||||
/*
|
/*
|
||||||
@ -137,18 +138,18 @@ const char *mail_addr_find_trans(MAPS *path, const char *address, char **extp)
|
|||||||
static VSTRING *quoted_addr;
|
static VSTRING *quoted_addr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First, let mail_addr_find() search with the address converted to
|
* First, let mail_addr_find_opt() search with the address converted to
|
||||||
* external form. Fall back to a search with the address in internal
|
* external form. Fall back to a search with the address in internal
|
||||||
* (unconverted) form, if no match was found and the internal and
|
* (unconverted) form, if no match was found and the internal and
|
||||||
* external forms differ.
|
* external forms differ.
|
||||||
*/
|
*/
|
||||||
if ((result = mail_addr_find(path, address, extp,
|
if ((result = mail_addr_find_opt(path, address, extp,
|
||||||
MAIL_ADDR_FORM_INTERNAL, MAIL_ADDR_FORM_NOCONV)) == 0) {
|
MAIL_ADDR_FORM_INTERNAL, MAIL_ADDR_FORM_NOCONV)) == 0) {
|
||||||
if (quoted_addr == 0)
|
if (quoted_addr == 0)
|
||||||
quoted_addr = vstring_alloc(100);
|
quoted_addr = vstring_alloc(100);
|
||||||
quote_822_local(quoted_addr, address);
|
quote_822_local(quoted_addr, address);
|
||||||
if (strcmp(STR(quoted_addr), address) != 0)
|
if (strcmp(STR(quoted_addr), address) != 0)
|
||||||
result = mail_addr_find(path, address, extp,
|
result = mail_addr_find_opt(path, address, extp,
|
||||||
MAIL_ADDR_FORM_NOCONV, MAIL_ADDR_FORM_NOCONV);
|
MAIL_ADDR_FORM_NOCONV, MAIL_ADDR_FORM_NOCONV);
|
||||||
}
|
}
|
||||||
return (result);
|
return (result);
|
||||||
@ -168,8 +169,8 @@ static const char *find_addr(MAPS *path, const char *address, int flags,
|
|||||||
|
|
||||||
/* mail_addr_find - map a canonical address */
|
/* mail_addr_find - map a canonical address */
|
||||||
|
|
||||||
const char *mail_addr_find(MAPS *path, const char *address, char **extp,
|
const char *mail_addr_find_opt(MAPS *path, const char *address, char **extp,
|
||||||
int in_form, int out_form)
|
int in_form, int out_form)
|
||||||
{
|
{
|
||||||
const char *myname = "mail_addr_find";
|
const char *myname = "mail_addr_find";
|
||||||
VSTRING *ext_addr_buf = 0;
|
VSTRING *ext_addr_buf = 0;
|
||||||
@ -205,7 +206,7 @@ const char *mail_addr_find(MAPS *path, const char *address, char **extp,
|
|||||||
int_bare_key = saved_ext = 0;
|
int_bare_key = saved_ext = 0;
|
||||||
} else {
|
} else {
|
||||||
int_bare_key =
|
int_bare_key =
|
||||||
strip_addr_internal(int_full_key, &saved_ext, var_rcpt_delim);
|
strip_addr(int_full_key, &saved_ext, var_rcpt_delim);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -364,7 +365,7 @@ int main(int argc, char **argv)
|
|||||||
expect_res = mystrtok(&bp, ":");
|
expect_res = mystrtok(&bp, ":");
|
||||||
expect_ext = mystrtok(&bp, ":");
|
expect_ext = mystrtok(&bp, ":");
|
||||||
extent = 0;
|
extent = 0;
|
||||||
result = mail_addr_find(path, key_field, &extent, in_form, out_form);
|
result = mail_addr_find_opt(path, key_field, &extent, in_form, out_form);
|
||||||
vstream_printf("%s:%s -> %s:%s (%s)\n",
|
vstream_printf("%s:%s -> %s:%s (%s)\n",
|
||||||
in_field, key_field, out_field, result ? result :
|
in_field, key_field, out_field, result ? result :
|
||||||
path->error ? "(try again)" :
|
path->error ? "(try again)" :
|
||||||
|
@ -20,16 +20,17 @@
|
|||||||
/*
|
/*
|
||||||
* External interface.
|
* External interface.
|
||||||
*/
|
*/
|
||||||
extern const char *mail_addr_find(MAPS *, const char *, char **, int, int);
|
extern const char *mail_addr_find_opt(MAPS *, const char *, char **, int, int);
|
||||||
|
extern const char *mail_addr_find_trans(MAPS *, const char *, char **);
|
||||||
|
|
||||||
/* The least-overhead form. */
|
/* The least-overhead form. */
|
||||||
#define mail_addr_find_int_to_ext(maps, address, extension) \
|
#define mail_addr_find_int_to_ext(maps, address, extension) \
|
||||||
mail_addr_find((maps), (address), (extension), \
|
mail_addr_find_opt((maps), (address), (extension), \
|
||||||
MAIL_ADDR_FORM_INTERNAL, MAIL_ADDR_FORM_EXTERNAL)
|
MAIL_ADDR_FORM_INTERNAL, MAIL_ADDR_FORM_EXTERNAL)
|
||||||
|
|
||||||
/* The legacy form. */
|
/* The legacy form. */
|
||||||
#define mail_addr_find_noconv(maps, address, extension) \
|
#define mail_addr_find(maps, address, extension) \
|
||||||
mail_addr_find((maps), (address), (extension), \
|
mail_addr_find_opt((maps), (address), (extension), \
|
||||||
MAIL_ADDR_FORM_NOCONV, MAIL_ADDR_FORM_NOCONV)
|
MAIL_ADDR_FORM_NOCONV, MAIL_ADDR_FORM_NOCONV)
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
/* const char *address;
|
/* const char *address;
|
||||||
/* int propagate;
|
/* int propagate;
|
||||||
/*
|
/*
|
||||||
/* ARGV *mail_addr_map(path, address, propagate, in_form, out_form)
|
/* ARGV *mail_addr_map_opt(path, address, propagate, in_form, out_form)
|
||||||
/* MAPS *path;
|
/* MAPS *path;
|
||||||
/* const char *address;
|
/* const char *address;
|
||||||
/* int propagate;
|
/* int propagate;
|
||||||
@ -21,7 +21,7 @@
|
|||||||
/* named address, or a null pointer if none is found. The
|
/* named address, or a null pointer if none is found. The
|
||||||
/* search address and results are in internal (unquoted) form.
|
/* search address and results are in internal (unquoted) form.
|
||||||
/*
|
/*
|
||||||
/* mail_addr_map() gives more control, at the cost of additional
|
/* mail_addr_map_opt() gives more control, at the cost of additional
|
||||||
/* conversions between internal and external forms.
|
/* conversions between internal and external forms.
|
||||||
/*
|
/*
|
||||||
/* When the \fBpropagate\fR argument is non-zero,
|
/* When the \fBpropagate\fR argument is non-zero,
|
||||||
@ -34,7 +34,7 @@
|
|||||||
/* the original user in
|
/* the original user in
|
||||||
/* \fIotherdomain\fR.
|
/* \fIotherdomain\fR.
|
||||||
/*
|
/*
|
||||||
/* mail_addr_map() gives additional control over whether the
|
/* mail_addr_map_opt() gives additional control over whether the
|
||||||
/* input is in internal (unquoted) or external (quoted) form.
|
/* input is in internal (unquoted) or external (quoted) form.
|
||||||
/* to internal form and invokes mail_addr_map_int_to_ext().
|
/* to internal form and invokes mail_addr_map_int_to_ext().
|
||||||
/* This may introduce additional unqoute822_local() and
|
/* This may introduce additional unqoute822_local() and
|
||||||
@ -96,8 +96,8 @@
|
|||||||
|
|
||||||
/* mail_addr_map - map a canonical address */
|
/* mail_addr_map - map a canonical address */
|
||||||
|
|
||||||
ARGV *mail_addr_map(MAPS *path, const char *address, int propagate,
|
ARGV *mail_addr_map_opt(MAPS *path, const char *address, int propagate,
|
||||||
int in_form, int out_form)
|
int in_form, int out_form)
|
||||||
{
|
{
|
||||||
VSTRING *buffer = 0;
|
VSTRING *buffer = 0;
|
||||||
const char *myname = "mail_addr_map";
|
const char *myname = "mail_addr_map";
|
||||||
@ -116,9 +116,10 @@ ARGV *mail_addr_map(MAPS *path, const char *address, int propagate,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Optionally convert input from external form. We prefer internal-form
|
* Optionally convert input from external form. We prefer internal-form
|
||||||
* input to avoid an unnecessary input conversion in mail_addr_find().
|
* input to avoid an unnecessary input conversion in
|
||||||
* But the consequence is that we have to convert the internal-form
|
* mail_addr_find_opt(). But the consequence is that we have to convert
|
||||||
* input's localpart to external form when mapping @domain -> @domain.
|
* the internal-form input's localpart to external form when mapping
|
||||||
|
* @domain -> @domain.
|
||||||
*/
|
*/
|
||||||
if (in_form == MAIL_ADDR_FORM_EXTERNAL) {
|
if (in_form == MAIL_ADDR_FORM_EXTERNAL) {
|
||||||
int_address = vstring_alloc(100);
|
int_address = vstring_alloc(100);
|
||||||
@ -132,11 +133,11 @@ ARGV *mail_addr_map(MAPS *path, const char *address, int propagate,
|
|||||||
/*
|
/*
|
||||||
* Look up the full address; if no match is found, look up the address
|
* Look up the full address; if no match is found, look up the address
|
||||||
* with the extension stripped off, and remember the unmatched extension.
|
* with the extension stripped off, and remember the unmatched extension.
|
||||||
* We explicitly call the mail_addr_find() variant that does not convert
|
* We explicitly call the mail_addr_find_opt() variant that does not
|
||||||
* the lookup result.
|
* convert the lookup result.
|
||||||
*/
|
*/
|
||||||
if ((string = mail_addr_find(path, int_addr, &extension,
|
if ((string = mail_addr_find_opt(path, int_addr, &extension,
|
||||||
in_form, mid_form)) != 0) {
|
in_form, mid_form)) != 0) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepend the original user to @otherdomain, but do not propagate
|
* Prepend the original user to @otherdomain, but do not propagate
|
||||||
@ -160,8 +161,8 @@ ARGV *mail_addr_map(MAPS *path, const char *address, int propagate,
|
|||||||
* Canonicalize the result, and propagate the unmatched extension to
|
* Canonicalize the result, and propagate the unmatched extension to
|
||||||
* each address found.
|
* each address found.
|
||||||
*/
|
*/
|
||||||
argv = mail_addr_crunch(string, propagate ? extension : 0,
|
argv = mail_addr_crunch_opt(string, propagate ? extension : 0,
|
||||||
mid_form, out_form);
|
mid_form, out_form);
|
||||||
if (buffer)
|
if (buffer)
|
||||||
vstring_free(buffer);
|
vstring_free(buffer);
|
||||||
if (ext_address)
|
if (ext_address)
|
||||||
|
@ -25,11 +25,11 @@
|
|||||||
/*
|
/*
|
||||||
* External interface.
|
* External interface.
|
||||||
*/
|
*/
|
||||||
extern ARGV *mail_addr_map(MAPS *, const char *, int, int, int);
|
extern ARGV *mail_addr_map_opt(MAPS *, const char *, int, int, int);
|
||||||
|
|
||||||
/* The least-overhead form. */
|
/* The least-overhead form. */
|
||||||
#define mail_addr_map_internal(path, address, propagate) \
|
#define mail_addr_map_internal(path, address, propagate) \
|
||||||
mail_addr_map((path), (address), (propagate), \
|
mail_addr_map_opt((path), (address), (propagate), \
|
||||||
MAIL_ADDR_FORM_INTERNAL, MAIL_ADDR_FORM_INTERNAL)
|
MAIL_ADDR_FORM_INTERNAL, MAIL_ADDR_FORM_INTERNAL)
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
|
@ -73,8 +73,8 @@ typedef struct {
|
|||||||
#define PLUS_RECIPIENT_DELIMITER "+"
|
#define PLUS_RECIPIENT_DELIMITER "+"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All these tests must pass, so that we know that mail_addr_map() works as
|
* All these tests must pass, so that we know that mail_addr_map_opt() works
|
||||||
* intended.
|
* as intended.
|
||||||
*/
|
*/
|
||||||
static MAIL_ADDR_MAP_TEST pass_tests[] = {
|
static MAIL_ADDR_MAP_TEST pass_tests[] = {
|
||||||
{
|
{
|
||||||
@ -284,8 +284,8 @@ int main(int argc, char **argv)
|
|||||||
| DICT_FLAG_FOLD_FIX | DICT_FLAG_UTF8_REQUEST);
|
| DICT_FLAG_FOLD_FIX | DICT_FLAG_UTF8_REQUEST);
|
||||||
|
|
||||||
UPDATE(var_rcpt_delim, test->delimiter);
|
UPDATE(var_rcpt_delim, test->delimiter);
|
||||||
result = mail_addr_map(maps, test->address, test->propagate,
|
result = mail_addr_map_opt(maps, test->address, test->propagate,
|
||||||
test->in_form, test->out_form);
|
test->in_form, test->out_form);
|
||||||
if (compare(test->testname, test->expect_argv, test->expect_argc,
|
if (compare(test->testname, test->expect_argv, test->expect_argc,
|
||||||
result ? result->argv : 0, result ? result->argc : 0) != 0) {
|
result ? result->argv : 0, result ? result->argc : 0) != 0) {
|
||||||
msg_info("database = %s", test->database);
|
msg_info("database = %s", test->database);
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
* 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 "20170108"
|
#define MAIL_RELEASE_DATE "20170109"
|
||||||
#define MAIL_VERSION_NUMBER "3.2"
|
#define MAIL_VERSION_NUMBER "3.2"
|
||||||
|
|
||||||
#ifdef SNAPSHOT
|
#ifdef SNAPSHOT
|
||||||
|
@ -15,6 +15,9 @@
|
|||||||
/* found, and returns a pointer to the remainder. The address
|
/* found, and returns a pointer to the remainder. The address
|
||||||
/* must be in internal (unquoted) form.
|
/* must be in internal (unquoted) form.
|
||||||
/*
|
/*
|
||||||
|
/* split_addr() is a backwards-compatible form for legacy code.
|
||||||
|
/* It is an alias for split_addr_internal().
|
||||||
|
/*
|
||||||
/* Reserved addresses are not split: postmaster, mailer-daemon,
|
/* Reserved addresses are not split: postmaster, mailer-daemon,
|
||||||
/* double-bounce. Addresses that begin with owner-, or addresses
|
/* double-bounce. Addresses that begin with owner-, or addresses
|
||||||
/* that end in -request are not split when the owner_request_special
|
/* that end in -request are not split when the owner_request_special
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
|
|
||||||
extern char *split_addr_internal(char *, const char *);
|
extern char *split_addr_internal(char *, const char *);
|
||||||
|
|
||||||
|
/* Legacy API. */
|
||||||
|
|
||||||
|
#define split_addr split_addr_internal
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
/* .ad
|
/* .ad
|
||||||
/* .fi
|
/* .fi
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
/* The caller is expected to pass the copy to myfree().
|
/* The caller is expected to pass the copy to myfree().
|
||||||
/* The input and result are in internal form.
|
/* The input and result are in internal form.
|
||||||
/*
|
/*
|
||||||
|
/* strip_addr() is a backwards-compatible form for legacy code.
|
||||||
|
/* It is an alias for strip_addr_internal().
|
||||||
|
/*
|
||||||
/* Arguments:
|
/* Arguments:
|
||||||
/* .IP address
|
/* .IP address
|
||||||
/* Address localpart or user@domain form in internal form.
|
/* Address localpart or user@domain form in internal form.
|
||||||
@ -78,7 +81,7 @@ char *strip_addr_internal(const char *full, char **extension,
|
|||||||
stripped = mystrdup(full);
|
stripped = mystrdup(full);
|
||||||
if ((ratsign = strrchr(stripped, '@')) != 0)
|
if ((ratsign = strrchr(stripped, '@')) != 0)
|
||||||
*ratsign = 0;
|
*ratsign = 0;
|
||||||
if ((extent = split_addr_internal(stripped, delimiter_set)) != 0) {
|
if ((extent = split_addr(stripped, delimiter_set)) != 0) {
|
||||||
extent -= 1;
|
extent -= 1;
|
||||||
if (extension) {
|
if (extension) {
|
||||||
*extent = full[strlen(stripped)];
|
*extent = full[strlen(stripped)];
|
||||||
|
@ -11,10 +11,11 @@
|
|||||||
/* DESCRIPTION
|
/* DESCRIPTION
|
||||||
/* .nf
|
/* .nf
|
||||||
|
|
||||||
/*
|
/* External interface. */
|
||||||
* External interface.
|
|
||||||
*/
|
extern char *strip_addr_internal(const char *, char **, const char *);
|
||||||
extern char * strip_addr_internal(const char *, char **, const char *);
|
|
||||||
|
#define strip_addr strip_addr_internal
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
/* .ad
|
/* .ad
|
||||||
|
@ -108,10 +108,9 @@ int bounce_workaround(LOCAL_STATE state)
|
|||||||
|
|
||||||
FIND_OWNER(owner_alias, owner_expansion, state.msg_attr.rcpt.address);
|
FIND_OWNER(owner_alias, owner_expansion, state.msg_attr.rcpt.address);
|
||||||
if (alias_maps->error == 0 && owner_expansion == 0
|
if (alias_maps->error == 0 && owner_expansion == 0
|
||||||
&& (stripped_recipient =
|
&& (stripped_recipient = strip_addr(state.msg_attr.rcpt.address,
|
||||||
strip_addr_internal(state.msg_attr.rcpt.address,
|
(char **) 0,
|
||||||
(char **) 0,
|
var_rcpt_delim)) != 0) {
|
||||||
var_rcpt_delim)) != 0) {
|
|
||||||
myfree(owner_alias);
|
myfree(owner_alias);
|
||||||
FIND_OWNER(owner_alias, owner_expansion, stripped_recipient);
|
FIND_OWNER(owner_alias, owner_expansion, stripped_recipient);
|
||||||
myfree(stripped_recipient);
|
myfree(stripped_recipient);
|
||||||
|
@ -267,7 +267,7 @@ int deliver_recipient(LOCAL_STATE state, USER_ATTR usr_attr)
|
|||||||
state.msg_attr.user = mystrdup(state.msg_attr.local);
|
state.msg_attr.user = mystrdup(state.msg_attr.local);
|
||||||
if (*var_rcpt_delim) {
|
if (*var_rcpt_delim) {
|
||||||
state.msg_attr.extension =
|
state.msg_attr.extension =
|
||||||
split_addr_internal(state.msg_attr.user, var_rcpt_delim);
|
split_addr(state.msg_attr.user, var_rcpt_delim);
|
||||||
if (state.msg_attr.extension && strchr(state.msg_attr.extension, '/')) {
|
if (state.msg_attr.extension && strchr(state.msg_attr.extension, '/')) {
|
||||||
msg_warn("%s: address with illegal extension: %s",
|
msg_warn("%s: address with illegal extension: %s",
|
||||||
state.msg_attr.queue_id, state.msg_attr.local);
|
state.msg_attr.queue_id, state.msg_attr.local);
|
||||||
|
@ -1204,8 +1204,7 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
|
|||||||
: strlen(STR(reply.recipient)));
|
: strlen(STR(reply.recipient)));
|
||||||
vstring_strncpy(queue_name, STR(reply.recipient), len);
|
vstring_strncpy(queue_name, STR(reply.recipient), len);
|
||||||
/* Remove the address extension from the recipient localpart. */
|
/* Remove the address extension from the recipient localpart. */
|
||||||
if (*var_rcpt_delim
|
if (*var_rcpt_delim && split_addr(STR(queue_name), var_rcpt_delim))
|
||||||
&& split_addr_internal(STR(queue_name), var_rcpt_delim))
|
|
||||||
vstring_truncate(queue_name, strlen(STR(queue_name)));
|
vstring_truncate(queue_name, strlen(STR(queue_name)));
|
||||||
/* Assume the recipient domain is equivalent to nexthop. */
|
/* Assume the recipient domain is equivalent to nexthop. */
|
||||||
vstring_sprintf_append(queue_name, "@%s", STR(reply.nexthop));
|
vstring_sprintf_append(queue_name, "@%s", STR(reply.nexthop));
|
||||||
|
@ -754,7 +754,7 @@ static ARGV *expand_argv(const char *service, char **argv,
|
|||||||
msg_warn("no @ in recipient address: %s",
|
msg_warn("no @ in recipient address: %s",
|
||||||
rcpt_list->info[i].address);
|
rcpt_list->info[i].address);
|
||||||
if (*var_rcpt_delim)
|
if (*var_rcpt_delim)
|
||||||
split_addr_internal(STR(buf), var_rcpt_delim);
|
split_addr(STR(buf), var_rcpt_delim);
|
||||||
if (*STR(buf) == 0)
|
if (*STR(buf) == 0)
|
||||||
continue;
|
continue;
|
||||||
dict_update(PIPE_DICT_TABLE, PIPE_DICT_USER, STR(buf));
|
dict_update(PIPE_DICT_TABLE, PIPE_DICT_USER, STR(buf));
|
||||||
@ -772,8 +772,7 @@ static ARGV *expand_argv(const char *service, char **argv,
|
|||||||
msg_warn("no @ in recipient address: %s",
|
msg_warn("no @ in recipient address: %s",
|
||||||
rcpt_list->info[i].address);
|
rcpt_list->info[i].address);
|
||||||
if (*var_rcpt_delim == 0
|
if (*var_rcpt_delim == 0
|
||||||
|| (ext = split_addr_internal(STR(buf),
|
|| (ext = split_addr(STR(buf), var_rcpt_delim)) == 0)
|
||||||
var_rcpt_delim)) == 0)
|
|
||||||
ext = ""; /* insert null arg */
|
ext = ""; /* insert null arg */
|
||||||
dict_update(PIPE_DICT_TABLE, PIPE_DICT_EXTENSION, ext);
|
dict_update(PIPE_DICT_TABLE, PIPE_DICT_EXTENSION, ext);
|
||||||
}
|
}
|
||||||
|
@ -1263,8 +1263,7 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
|
|||||||
: strlen(STR(reply.recipient)));
|
: strlen(STR(reply.recipient)));
|
||||||
vstring_strncpy(queue_name, STR(reply.recipient), len);
|
vstring_strncpy(queue_name, STR(reply.recipient), len);
|
||||||
/* Remove the address extension from the recipient localpart. */
|
/* Remove the address extension from the recipient localpart. */
|
||||||
if (*var_rcpt_delim
|
if (*var_rcpt_delim && split_addr(STR(queue_name), var_rcpt_delim))
|
||||||
&& split_addr_internal(STR(queue_name), var_rcpt_delim))
|
|
||||||
vstring_truncate(queue_name, strlen(STR(queue_name)));
|
vstring_truncate(queue_name, strlen(STR(queue_name)));
|
||||||
/* Assume the recipient domain is equivalent to nexthop. */
|
/* Assume the recipient domain is equivalent to nexthop. */
|
||||||
vstring_sprintf_append(queue_name, "@%s", STR(reply.nexthop));
|
vstring_sprintf_append(queue_name, "@%s", STR(reply.nexthop));
|
||||||
|
@ -80,7 +80,7 @@ int smtp_map11_external(VSTRING *addr, MAPS *maps, int propagate)
|
|||||||
ARGV *new_addr;
|
ARGV *new_addr;
|
||||||
const char *result;
|
const char *result;
|
||||||
|
|
||||||
if ((new_addr = mail_addr_map(maps, STR(addr), propagate,
|
if ((new_addr = mail_addr_map_opt(maps, STR(addr), propagate,
|
||||||
MAIL_ADDR_FORM_EXTERNAL, MAIL_ADDR_FORM_EXTERNAL)) != 0) {
|
MAIL_ADDR_FORM_EXTERNAL, MAIL_ADDR_FORM_EXTERNAL)) != 0) {
|
||||||
if (new_addr->argc > 1)
|
if (new_addr->argc > 1)
|
||||||
msg_warn("multi-valued %s result for %s", maps->title, STR(addr));
|
msg_warn("multi-valued %s result for %s", maps->title, STR(addr));
|
||||||
|
@ -142,6 +142,7 @@
|
|||||||
#include <ehlo_mask.h>
|
#include <ehlo_mask.h>
|
||||||
#include <maps.h>
|
#include <maps.h>
|
||||||
#include <tok822.h>
|
#include <tok822.h>
|
||||||
|
#include <mail_addr_map.h>
|
||||||
#include <ext_prop.h>
|
#include <ext_prop.h>
|
||||||
#include <namadr_list.h>
|
#include <namadr_list.h>
|
||||||
#include <match_parent_style.h>
|
#include <match_parent_style.h>
|
||||||
|
@ -184,7 +184,7 @@ int smtp_sasl_passwd_lookup(SMTP_SESSION *session)
|
|||||||
smtp_sasl_passwd_map->error = 0;
|
smtp_sasl_passwd_map->error = 0;
|
||||||
if ((smtp_mode
|
if ((smtp_mode
|
||||||
&& var_smtp_sender_auth && state->request->sender[0]
|
&& var_smtp_sender_auth && state->request->sender[0]
|
||||||
&& (value = mail_addr_find_noconv(smtp_sasl_passwd_map,
|
&& (value = mail_addr_find(smtp_sasl_passwd_map,
|
||||||
state->request->sender, (char **) 0)) != 0)
|
state->request->sender, (char **) 0)) != 0)
|
||||||
|| (smtp_sasl_passwd_map->error == 0
|
|| (smtp_sasl_passwd_map->error == 0
|
||||||
&& (value = maps_find(smtp_sasl_passwd_map,
|
&& (value = maps_find(smtp_sasl_passwd_map,
|
||||||
|
@ -1155,8 +1155,7 @@ static const char *check_mail_addr_find(SMTPD_STATE *state,
|
|||||||
{
|
{
|
||||||
const char *result;
|
const char *result;
|
||||||
|
|
||||||
if ((result = mail_addr_find_noconv(maps, key, ext)) != 0
|
if ((result = mail_addr_find(maps, key, ext)) != 0 || maps->error == 0)
|
||||||
|| maps->error == 0)
|
|
||||||
return (result);
|
return (result);
|
||||||
if (maps->error == DICT_ERR_RETRY)
|
if (maps->error == DICT_ERR_RETRY)
|
||||||
/* Warning is already logged. */
|
/* Warning is already logged. */
|
||||||
@ -3187,7 +3186,7 @@ static int check_mail_access(SMTPD_STATE *state, const char *table,
|
|||||||
if (*var_rcpt_delim == 0) {
|
if (*var_rcpt_delim == 0) {
|
||||||
bare_addr = 0;
|
bare_addr = 0;
|
||||||
} else {
|
} else {
|
||||||
bare_addr = strip_addr_internal(addr, (char **) 0, var_rcpt_delim);
|
bare_addr = strip_addr(addr, (char **) 0, var_rcpt_delim);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_MAIL_ACCESS_RETURN(x) \
|
#define CHECK_MAIL_ACCESS_RETURN(x) \
|
||||||
@ -5196,8 +5195,8 @@ static int check_rcpt_maps(SMTPD_STATE *state, const char *sender,
|
|||||||
* Search the recipient lookup tables of the respective address class.
|
* Search the recipient lookup tables of the respective address class.
|
||||||
*
|
*
|
||||||
* XXX Use the less expensive maps_find() (built-in case folding) instead of
|
* XXX Use the less expensive maps_find() (built-in case folding) instead of
|
||||||
* the baroque mail_addr_find(). But then we have to strip the domain and
|
* the baroque mail_addr_find(). But then we have to strip the domain
|
||||||
* deal with address extensions ourselves.
|
* and deal with address extensions ourselves.
|
||||||
*
|
*
|
||||||
* XXX But that would break sites that use the virtual delivery agent for
|
* XXX But that would break sites that use the virtual delivery agent for
|
||||||
* local delivery, because the virtual delivery agent requires
|
* local delivery, because the virtual delivery agent requires
|
||||||
|
@ -560,10 +560,10 @@ static void resolve_addr(RES_CONTEXT *rp, char *sender, char *addr,
|
|||||||
*/
|
*/
|
||||||
else {
|
else {
|
||||||
if (rp->snd_def_xp_info
|
if (rp->snd_def_xp_info
|
||||||
&& (xport = mail_addr_find_noconv(rp->snd_def_xp_info,
|
&& (xport = mail_addr_find(rp->snd_def_xp_info,
|
||||||
sender_key = (*sender ? sender :
|
sender_key = (*sender ? sender :
|
||||||
var_null_def_xport_maps_key),
|
var_null_def_xport_maps_key),
|
||||||
(char **) 0)) != 0) {
|
(char **) 0)) != 0) {
|
||||||
if (*xport == 0) {
|
if (*xport == 0) {
|
||||||
msg_warn("%s: ignoring null lookup result for %s",
|
msg_warn("%s: ignoring null lookup result for %s",
|
||||||
rp->snd_def_xp_maps_name, sender_key);
|
rp->snd_def_xp_maps_name, sender_key);
|
||||||
@ -589,10 +589,10 @@ static void resolve_addr(RES_CONTEXT *rp, char *sender, char *addr,
|
|||||||
* override the recipient domain.
|
* override the recipient domain.
|
||||||
*/
|
*/
|
||||||
if (rp->snd_relay_info
|
if (rp->snd_relay_info
|
||||||
&& (relay = mail_addr_find_noconv(rp->snd_relay_info,
|
&& (relay = mail_addr_find(rp->snd_relay_info,
|
||||||
sender_key = (*sender ? sender :
|
sender_key = (*sender ? sender :
|
||||||
var_null_relay_maps_key),
|
var_null_relay_maps_key),
|
||||||
(char **) 0)) != 0) {
|
(char **) 0)) != 0) {
|
||||||
if (*relay == 0) {
|
if (*relay == 0) {
|
||||||
msg_warn("%s: ignoring null lookup result for %s",
|
msg_warn("%s: ignoring null lookup result for %s",
|
||||||
rp->snd_relay_maps_name, sender_key);
|
rp->snd_relay_maps_name, sender_key);
|
||||||
@ -716,8 +716,8 @@ static void resolve_addr(RES_CONTEXT *rp, char *sender, char *addr,
|
|||||||
if (relocated_maps != 0) {
|
if (relocated_maps != 0) {
|
||||||
const char *newloc;
|
const char *newloc;
|
||||||
|
|
||||||
if ((newloc = mail_addr_find_noconv(relocated_maps, STR(nextrcpt),
|
if ((newloc = mail_addr_find(relocated_maps, STR(nextrcpt),
|
||||||
IGNORE_ADDR_EXTENSION)) != 0) {
|
IGNORE_ADDR_EXTENSION)) != 0) {
|
||||||
vstring_strcpy(channel, MAIL_SERVICE_ERROR);
|
vstring_strcpy(channel, MAIL_SERVICE_ERROR);
|
||||||
/* 5.1.6 is the closest match, but not perfect. */
|
/* 5.1.6 is the closest match, but not perfect. */
|
||||||
vstring_sprintf(nexthop, "5.1.6 User has moved to %s", newloc);
|
vstring_sprintf(nexthop, "5.1.6 User has moved to %s", newloc);
|
||||||
|
@ -287,8 +287,8 @@ int transport_lookup(TRANSPORT_INFO *tp, const char *addr,
|
|||||||
* look up the stripped address with the PARTIAL flag to avoid matching
|
* look up the stripped address with the PARTIAL flag to avoid matching
|
||||||
* partial lookup keys with regular expressions.
|
* partial lookup keys with regular expressions.
|
||||||
*/
|
*/
|
||||||
if ((stripped_addr = strip_addr_internal(addr, DISCARD_EXTENSION,
|
if ((stripped_addr = strip_addr(addr, DISCARD_EXTENSION,
|
||||||
var_rcpt_delim)) != 0) {
|
var_rcpt_delim)) != 0) {
|
||||||
found = find_transport_entry(tp, stripped_addr, rcpt_domain, PARTIAL,
|
found = find_transport_entry(tp, stripped_addr, rcpt_domain, PARTIAL,
|
||||||
channel, nexthop);
|
channel, nexthop);
|
||||||
|
|
||||||
|
@ -193,9 +193,8 @@ int deliver_mailbox(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp)
|
|||||||
*/
|
*/
|
||||||
#define IGNORE_EXTENSION ((char **) 0)
|
#define IGNORE_EXTENSION ((char **) 0)
|
||||||
|
|
||||||
mailbox_res = mail_addr_find_noconv(virtual_mailbox_maps,
|
mailbox_res = mail_addr_find(virtual_mailbox_maps, state.msg_attr.user,
|
||||||
state.msg_attr.user,
|
IGNORE_EXTENSION);
|
||||||
IGNORE_EXTENSION);
|
|
||||||
if (mailbox_res == 0) {
|
if (mailbox_res == 0) {
|
||||||
if (virtual_mailbox_maps->error == 0)
|
if (virtual_mailbox_maps->error == 0)
|
||||||
return (NO);
|
return (NO);
|
||||||
@ -214,8 +213,8 @@ int deliver_mailbox(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp)
|
|||||||
/*
|
/*
|
||||||
* Look up the mailbox owner rights. Defer in case of trouble.
|
* Look up the mailbox owner rights. Defer in case of trouble.
|
||||||
*/
|
*/
|
||||||
uid_res = mail_addr_find_noconv(virtual_uid_maps, state.msg_attr.user,
|
uid_res = mail_addr_find(virtual_uid_maps, state.msg_attr.user,
|
||||||
IGNORE_EXTENSION);
|
IGNORE_EXTENSION);
|
||||||
if (uid_res == 0) {
|
if (uid_res == 0) {
|
||||||
msg_warn("recipient %s: not found in %s",
|
msg_warn("recipient %s: not found in %s",
|
||||||
state.msg_attr.user, virtual_uid_maps->title);
|
state.msg_attr.user, virtual_uid_maps->title);
|
||||||
@ -237,8 +236,8 @@ int deliver_mailbox(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp)
|
|||||||
/*
|
/*
|
||||||
* Look up the mailbox group rights. Defer in case of trouble.
|
* Look up the mailbox group rights. Defer in case of trouble.
|
||||||
*/
|
*/
|
||||||
gid_res = mail_addr_find_noconv(virtual_gid_maps, state.msg_attr.user,
|
gid_res = mail_addr_find(virtual_gid_maps, state.msg_attr.user,
|
||||||
IGNORE_EXTENSION);
|
IGNORE_EXTENSION);
|
||||||
if (gid_res == 0) {
|
if (gid_res == 0) {
|
||||||
msg_warn("recipient %s: not found in %s",
|
msg_warn("recipient %s: not found in %s",
|
||||||
state.msg_attr.user, virtual_gid_maps->title);
|
state.msg_attr.user, virtual_gid_maps->title);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user