From: Wietse Venema Date: Sun, 15 Jan 2012 05:00:00 +0000 (-0500) Subject: postfix-2.9-20120115 X-Git-Tag: v2.9.0-RC1~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=beab543c462e980bcf30d840da94117128e8577b;p=thirdparty%2Fpostfix.git postfix-2.9-20120115 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 1d43a28cb..56e9bde29 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -17544,3 +17544,16 @@ Apologies for any names omitted. SMTP client to report about sessions that fail because a table is unavailable. Files: global/mail_error.[hc], smtpd/smtpd_check.c, smtp/smtp_trouble.c. + +20111215 + + Fine tuning: SMTP server error messages. File: smtpd/smtpd.c. + + Fine tuning: documentation. Files: proto/MEMCACHE_README.html. + proto/memcache_table.html. + + Apply "gradual degradation" also when an unsupported database + *type* is specified. File: util/dict_open.c. + + Cleanup: tiny memory leaks after surrogate database opens. + Files: util/dict_cidr.c, util/dict_db.c. diff --git a/postfix/README_FILES/MEMCACHE_README b/postfix/README_FILES/MEMCACHE_README index 56b31cd4c..c668b177c 100644 --- a/postfix/README_FILES/MEMCACHE_README +++ b/postfix/README_FILES/MEMCACHE_README @@ -24,7 +24,7 @@ LLiimmiittaattiioonnss virtual_mailbox_maps (these specify UNIX process privileges or "/file/name" destinations). Typically, a memcache database is writable by any process that can talk to the memcache server; in contrast, security-sensitive - tables must not be writable by the unprivileged Postfix user. + tables must never be writable by the unprivileged Postfix user. * The Postfix memcache client requires additional configuration when used as postscreen(8) or verify(8) cache. For details see the backup and ttl diff --git a/postfix/html/MEMCACHE_README.html b/postfix/html/MEMCACHE_README.html index 5ee1d554c..78be1733a 100644 --- a/postfix/html/MEMCACHE_README.html +++ b/postfix/html/MEMCACHE_README.html @@ -44,7 +44,7 @@ and "/file/name" destinations), or /file/name" destinations). Typically, a memcache database is writable by any process that can talk to the memcache server; in contrast, security-sensitive tables -must not be writable by the unprivileged Postfix user.

+must never be writable by the unprivileged Postfix user.

  • The Postfix memcache client requires additional configuration when used as postscreen(8) or verify(8) cache. For details see the diff --git a/postfix/html/memcache_table.5.html b/postfix/html/memcache_table.5.html index 11ab0ff7e..c10aab16a 100644 --- a/postfix/html/memcache_table.5.html +++ b/postfix/html/memcache_table.5.html @@ -75,12 +75,12 @@ MEMCACHE_TABLE(5) MEMCACHE_TABLE(5) in all Postfix instances except for one instance that will be responsible for cache cleanup. - NOTE 2: In the case of a proxied database, the full - database name (including the "proxy:" prefix) must - be specified in the proxymap server's - proxy_read_maps or proxy_write_maps setting - (depending on whether the access is read-only or - read-write). + NOTE 2: In the case of a proxied backup database, + the full backup database name (including the + "proxy:" prefix) must be specified in the proxymap + server's proxy_read_maps or proxy_write_maps set- + ting (depending on whether the access is read-only + or read-write). flags (default: 0) Optional flags that should be stored along with a @@ -200,7 +200,7 @@ MEMCACHE_TABLE(5) MEMCACHE_TABLE(5) destinations). In a typical deployment a memcache data- base is writable by any process that can talk to the mem- cache server; in contrast, security-sensitive tables must - not be writable by the unprivileged Postfix user. + never be writable by the unprivileged Postfix user. The Postfix memcache client requires additional configura- tion when used as postscreen(8) or verify(8) cache. For diff --git a/postfix/man/man5/memcache_table.5 b/postfix/man/man5/memcache_table.5 index 002766859..f8f286e28 100644 --- a/postfix/man/man5/memcache_table.5 +++ b/postfix/man/man5/memcache_table.5 @@ -80,7 +80,8 @@ automatic cache cleanup (*_cache_cleanup_interval = 0) in all Postfix instances except for one instance that will be responsible for cache cleanup. -NOTE 2: In the case of a proxied database, the full database +NOTE 2: In the case of a proxied backup database, the full +backup database name (including the "proxy:" prefix) must be specified in the proxymap server's proxy_read_maps or proxy_write_maps setting (depending on whether the access is read-only or @@ -198,7 +199,7 @@ tables such as \fBalias_maps\fR (these may contain privileges or "\fI/file/name\fR" destinations). In a typical deployment a memcache database is writable by any process that can talk to the memcache server; in contrast, -security-sensitive tables must not be writable by the +security-sensitive tables must never be writable by the unprivileged Postfix user. The Postfix memcache client requires additional configuration diff --git a/postfix/proto/MEMCACHE_README.html b/postfix/proto/MEMCACHE_README.html index 3f2c3e09b..ad445892f 100644 --- a/postfix/proto/MEMCACHE_README.html +++ b/postfix/proto/MEMCACHE_README.html @@ -44,7 +44,7 @@ and "/file/name" destinations), or virtual_uid_maps, specify UNIX process privileges or "/file/name" destinations). Typically, a memcache database is writable by any process that can talk to the memcache server; in contrast, security-sensitive tables -must not be writable by the unprivileged Postfix user.

    +must never be writable by the unprivileged Postfix user.

  • The Postfix memcache client requires additional configuration when used as postscreen(8) or verify(8) cache. For details see the diff --git a/postfix/proto/memcache_table b/postfix/proto/memcache_table index fc5827c13..d4a3658c3 100644 --- a/postfix/proto/memcache_table +++ b/postfix/proto/memcache_table @@ -72,7 +72,8 @@ # all Postfix instances except for one instance that will be # responsible for cache cleanup. # -# NOTE 2: In the case of a proxied database, the full database +# NOTE 2: In the case of a proxied backup database, the full +# backup database # name (including the "proxy:" prefix) must be specified in # the proxymap server's proxy_read_maps or proxy_write_maps # setting (depending on whether the access is read-only or @@ -184,7 +185,7 @@ # privileges or "\fI/file/name\fR" destinations). In a typical # deployment a memcache database is writable by any process # that can talk to the memcache server; in contrast, -# security-sensitive tables must not be writable by the +# security-sensitive tables must never be writable by the # unprivileged Postfix user. # # The Postfix memcache client requires additional configuration diff --git a/postfix/src/global/Makefile.in b/postfix/src/global/Makefile.in index 0a5d596ef..a1644a32a 100644 --- a/postfix/src/global/Makefile.in +++ b/postfix/src/global/Makefile.in @@ -422,6 +422,20 @@ maps_test: maps maps.in maps.ref diff maps.ref maps.tmp rm -f maps.tmp +surrogate_test: mail_dict surrogate.ref + cp /dev/null surrogate.tmp + echo get foo|./mail_dict ldap:/xx write >>surrogate.tmp 2>&1 + echo get foo|./mail_dict ldap:/xx read >>surrogate.tmp 2>&1 + echo get foo|./mail_dict mysql:/xx write >>surrogate.tmp 2>&1 + echo get foo|./mail_dict mysql:/xx read >>surrogate.tmp 2>&1 + echo get foo|./mail_dict pgsql:/xx write >>surrogate.tmp 2>&1 + echo get foo|./mail_dict pgsql:/xx read >>surrogate.tmp 2>&1 + echo get foo|./mail_dict sqlite:/xx write >>surrogate.tmp 2>&1 + echo get foo|./mail_dict sqlite:/xx read >>surrogate.tmp 2>&1 + echo get foo|./mail_dict memcache:/xx read >>surrogate.tmp 2>&1 + diff surrogate.ref surrogate.tmp + rm -f surrogate.tmp + # Requires: Postfix running, root privileges rewrite_clnt_test: rewrite_clnt rewrite_clnt.in rewrite_clnt.ref diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index cbb946c71..870efbe8c 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 "20120114" +#define MAIL_RELEASE_DATE "20120115" #define MAIL_VERSION_NUMBER "2.9" #ifdef SNAPSHOT diff --git a/postfix/src/global/namadr_list.ref b/postfix/src/global/namadr_list.ref index 1f62aa216..1aa895a6c 100644 --- a/postfix/src/global/namadr_list.ref +++ b/postfix/src/global/namadr_list.ref @@ -7,7 +7,10 @@ dummy/168.100.189.16: ERROR ./namadr_list: warning: bad net/mask pattern: "168.100.589.0/28" dummy/168.100.189.16: ERROR dummy/168.100.989.16: NO -./namadr_list: fatal: unsupported dictionary type: 2001 +./namadr_list: error: unsupported dictionary type: 2001 +./namadr_list: warning: 2001:240:5c7:0:2d0:b7ff:fe88:2ca7 is unavailable. unsupported dictionary type: 2001 +./namadr_list: warning: 2001:240:5c7:0:2d0:b7ff:fe88:2ca7: table lookup problem +dummy/2001:240:5c7:0:2d0:b7ff:fe88:2ca7: ERROR dummy/2001:240:5c7:0:2d0:b7ff:fe88:2ca7: YES dummy/2001:240:5c7:0:2d0:b7ff:fe88:2ca8: NO ./namadr_list: warning: non-null host address bits in "2001:240:5c7:0:2d0:b7ff:fe88:2ca7/64", perhaps you should use "2001:240:5c7::/64" instead diff --git a/postfix/src/global/surrogate.ref b/postfix/src/global/surrogate.ref new file mode 100644 index 000000000..cd12a5490 --- /dev/null +++ b/postfix/src/global/surrogate.ref @@ -0,0 +1,36 @@ +./mail_dict: error: ldap:/xx map requires O_RDONLY access mode +> get foo +./mail_dict: warning: ldap:/xx is unavailable. ldap:/xx map requires O_RDONLY access mode +foo: error +./mail_dict: error: open /xx: No such file or directory +> get foo +./mail_dict: warning: ldap:/xx is unavailable. open /xx: No such file or directory +foo: error +./mail_dict: error: mysql:/xx map requires O_RDONLY access mode +> get foo +./mail_dict: warning: mysql:/xx is unavailable. mysql:/xx map requires O_RDONLY access mode +foo: error +./mail_dict: error: open /xx: No such file or directory +> get foo +./mail_dict: warning: mysql:/xx is unavailable. open /xx: No such file or directory +foo: error +./mail_dict: error: pgsql:/xx map requires O_RDONLY access mode +> get foo +./mail_dict: warning: pgsql:/xx is unavailable. pgsql:/xx map requires O_RDONLY access mode +foo: error +./mail_dict: error: open /xx: No such file or directory +> get foo +./mail_dict: warning: pgsql:/xx is unavailable. open /xx: No such file or directory +foo: error +./mail_dict: error: sqlite:/xx map requires O_RDONLY access mode +> get foo +./mail_dict: warning: sqlite:/xx is unavailable. sqlite:/xx map requires O_RDONLY access mode +foo: error +./mail_dict: error: open /xx: No such file or directory +> get foo +./mail_dict: warning: sqlite:/xx is unavailable. open /xx: No such file or directory +foo: error +./mail_dict: error: open /xx: No such file or directory +> get foo +./mail_dict: warning: memcache:/xx is unavailable. open /xx: No such file or directory +foo: error diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index b2bfd231d..a95f08a97 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -1559,7 +1559,7 @@ static int helo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) static NORETURN cant_announce_feature(SMTPD_STATE *state, const char *feature) { - msg_warn("don't know if feature %s should be announced to %s", + msg_warn("don't know if EHLO feature %s should be announced to %s", feature, state->namaddr); vstream_longjmp(state->client, SMTP_ERR_DATA); } @@ -1677,7 +1677,8 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) if (discard_mask && !(discard_mask & EHLO_MASK_SILENT)) msg_info("discarding EHLO keywords: %s", str_ehlo_mask(discard_mask)); if (ehlo_discard_maps && ehlo_discard_maps->error) { - msg_warn("don't know what features to announce in EHLO"); + msg_warn("don't know what EHLO features to announce to %s", + state->namaddr); vstream_longjmp(state->client, SMTP_ERR_DATA); } @@ -4491,12 +4492,12 @@ static void smtpd_proto(SMTPD_STATE *state) case SMTP_ERR_DATA: msg_info("%s: reject: %s from %s: " - "421 4.3.0 %s Server configuration error", + "421 4.3.0 %s Server local data error", (state->queue_id ? state->queue_id : "NOQUEUE"), state->where, state->namaddr, var_myhostname); state->error_mask |= MAIL_ERROR_DATA; if (vstream_setjmp(state->client) == 0) - smtpd_chat_reply(state, "421 4.3.0 %s Server configuration error", + smtpd_chat_reply(state, "421 4.3.0 %s Server local data error", var_myhostname); break; diff --git a/postfix/src/util/Makefile.in b/postfix/src/util/Makefile.in index cff7d8a05..c73642c98 100644 --- a/postfix/src/util/Makefile.in +++ b/postfix/src/util/Makefile.in @@ -444,7 +444,7 @@ tests: valid_hostname_test mac_expand_test dict_test unescape_test \ attr_scan64_test attr_scan0_test dict_pcre_test host_port_test \ dict_cidr_test attr_scan_plain_test htable_test hex_code_test \ myaddrinfo_test format_tv_test ip_match_test name_mask_tests \ - base32_code_test dict_thash_test + base32_code_test dict_thash_test surrogate_test root_tests: @@ -633,6 +633,22 @@ dict_thash_test: ../postmap/postmap dict_thash.map sort dict_thash.tmp | diff -b dict_thash.map - rm -f dict_thash.tmp +surrogate_test: dict_open surrogate.ref + cp /dev/null surrogate.tmp + echo get foo|./dict_open cidr:/xx write >>surrogate.tmp 2>&1 + echo get foo|./dict_open cidr:/xx read >>surrogate.tmp 2>&1 + echo get foo|./dict_open pcre:/xx write >>surrogate.tmp 2>&1 + echo get foo|./dict_open pcre:/xx read >>surrogate.tmp 2>&1 + echo get foo|./dict_open regexp:/xx write >>surrogate.tmp 2>&1 + echo get foo|./dict_open regexp:/xx read >>surrogate.tmp 2>&1 + echo get foo|./dict_open unix:xx write >>surrogate.tmp 2>&1 + echo get foo|./dict_open unix:xx read >>surrogate.tmp 2>&1 + echo get foo|./dict_open texthash:/xx write >>surrogate.tmp 2>&1 + echo get foo|./dict_open texthash:/xx read >>surrogate.tmp 2>&1 + echo get foo|./dict_open hash:/xx read >>surrogate.tmp 2>&1 + diff surrogate.ref surrogate.tmp + rm -f surrogate.tmp + depend: $(MAKES) (sed '1,/^# do not edit/!d' Makefile.in; \ set -e; for i in [a-z][a-z0-9]*.c; do \ diff --git a/postfix/src/util/dict_cidr.c b/postfix/src/util/dict_cidr.c index 5731e58d4..2ea7ab1fd 100644 --- a/postfix/src/util/dict_cidr.c +++ b/postfix/src/util/dict_cidr.c @@ -166,8 +166,8 @@ DICT *dict_cidr_open(const char *mapname, int open_flags, int dict_flags) DICT_CIDR *dict_cidr; VSTREAM *map_fp; struct stat st; - VSTRING *line_buffer = vstring_alloc(100); - VSTRING *why = vstring_alloc(100); + VSTRING *line_buffer; + VSTRING *why; DICT_CIDR_ENTRY *rule; DICT_CIDR_ENTRY *last_rule = 0; int lineno = 0; @@ -189,6 +189,12 @@ DICT *dict_cidr_open(const char *mapname, int open_flags, int dict_flags) if (fstat(vstream_fileno(map_fp), &st) < 0) msg_fatal("fstat %s: %m", mapname); + /* + * No early returns without memory leaks. + */ + line_buffer = vstring_alloc(100); + why = vstring_alloc(100); + /* * XXX Eliminate unnecessary queries by setting a flag that says "this * map matches network addresses only". diff --git a/postfix/src/util/dict_db.c b/postfix/src/util/dict_db.c index 29e4cda09..5a4287c86 100644 --- a/postfix/src/util/dict_db.c +++ b/postfix/src/util/dict_db.c @@ -573,8 +573,8 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags, { DICT_DB *dict_db; struct stat st; - DB *db; - char *db_path; + DB *db = 0; + char *db_path = 0; int lock_fd = -1; int dbfd; @@ -624,12 +624,16 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags, * db_open() create a non-existent file for us. */ #define LOCK_OPEN_FLAGS(f) ((f) & ~(O_CREAT|O_TRUNC)) +#define FREE_RETURN(e) do { \ + DICT *_dict = (e); if (db) DICT_DB_CLOSE(db); \ + if (db_path) myfree(db_path); return (_dict); \ + } while (0) if (dict_flags & DICT_FLAG_LOCK) { if ((lock_fd = open(db_path, LOCK_OPEN_FLAGS(open_flags), 0644)) < 0) { if (errno != ENOENT) - return (dict_surrogate(class, path, open_flags, dict_flags, - "open database %s: %m", db_path)); + FREE_RETURN(dict_surrogate(class, path, open_flags, dict_flags, + "open database %s: %m", db_path)); } else { if (myflock(lock_fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0) msg_fatal("shared-lock database %s for open: %m", db_path); @@ -644,8 +648,8 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags, */ #if DB_VERSION_MAJOR < 2 if ((db = dbopen(db_path, open_flags, 0644, type, tweak)) == 0) - return (dict_surrogate(class, path, open_flags, dict_flags, - "open database %s: %m", db_path)); + FREE_RETURN(dict_surrogate(class, path, open_flags, dict_flags, + "open database %s: %m", db_path)); dbfd = db->fd(db); #endif @@ -661,8 +665,8 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags, if (open_flags & O_TRUNC) db_flags |= DB_TRUNCATE; if ((errno = db_open(db_path, type, db_flags, 0644, 0, tweak, &db)) != 0) - return (dict_surrogate(class, path, open_flags, dict_flags, - "open database %s: %m", db_path)); + FREE_RETURN(dict_surrogate(class, path, open_flags, dict_flags, + "open database %s: %m", db_path)); if (db == 0) msg_panic("db_open null result"); if ((errno = db->fd(db, &dbfd)) != 0) @@ -690,12 +694,12 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags, msg_fatal("set DB hash element count %d: %m", DICT_DB_NELM); #if DB_VERSION_MAJOR == 5 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 0) if ((errno = db->open(db, 0, db_path, 0, type, db_flags, 0644)) != 0) - return (dict_surrogate(class, path, open_flags, dict_flags, - "open database %s: %m", db_path)); + FREE_RETURN(dict_surrogate(class, path, open_flags, dict_flags, + "open database %s: %m", db_path)); #elif (DB_VERSION_MAJOR == 3 || DB_VERSION_MAJOR == 4) if ((errno = db->open(db, db_path, 0, type, db_flags, 0644)) != 0) - return (dict_surrogate(class, path, open_flags, dict_flags, - "open database %s: %m", db_path)); + FREE_RETURN(dict_surrogate(class, path, open_flags, dict_flags, + "open database %s: %m", db_path)); #else #error "Unsupported Berkeley DB version" #endif diff --git a/postfix/src/util/dict_open.c b/postfix/src/util/dict_open.c index 49e2b2c3c..7b7c0c56c 100644 --- a/postfix/src/util/dict_open.c +++ b/postfix/src/util/dict_open.c @@ -339,9 +339,11 @@ DICT *dict_open3(const char *dict_type, const char *dict_name, if (dict_open_hash == 0) dict_open_init(); if ((dp = (DICT_OPEN_INFO *) htable_find(dict_open_hash, dict_type)) == 0) - msg_fatal("unsupported dictionary type: %s", dict_type); + return (dict_surrogate(dict_type, dict_name, open_flags, dict_flags, + "unsupported dictionary type: %s", dict_type)); if ((dict = dp->open(dict_name, open_flags, dict_flags)) == 0) - msg_fatal("opening %s:%s %m", dict_type, dict_name); + return (dict_surrogate(dict_type, dict_name, open_flags, dict_flags, + "cannot open %s:%s: %m", dict_type, dict_name)); if (msg_verbose) msg_info("%s: %s:%s", myname, dict_type, dict_name); /* XXX the choice between wait-for-lock or no-wait is hard-coded. */ diff --git a/postfix/src/util/dict_surrogate.c b/postfix/src/util/dict_surrogate.c index 42dbe8fad..4183d9259 100644 --- a/postfix/src/util/dict_surrogate.c +++ b/postfix/src/util/dict_surrogate.c @@ -6,7 +6,7 @@ /* SYNOPSIS /* #include /* -/* DICT *dict_surrogate(dict_type, dict_name, +/* DICT *dict_surrogate(dict_type, dict_name, /* open_flags, dict_flags, /* format, ...) /* const char *dict_type; @@ -24,7 +24,8 @@ /* /* The global dict_allow_surrogate variable controls the choice /* between fatal error or reduced functionality. The default -/* value is zero (fatal error). +/* value is zero (fatal error). This is appropriate for user +/* commands; the non-default is more appropriate for daemons. /* /* Arguments: /* .IP dict_type @@ -34,7 +35,8 @@ /* The parameters to the failed dictionary open() request. /* .IP format, ... /* The reason why the table could not be opened. This text is -/* logged immediately, and upon every attempt to access the +/* logged immediately as an "error" class message, and is logged +/* as a "warning" class message upon every attempt to access the /* surrogate dictionary, before returning a "failed" completion /* status. /* SEE ALSO @@ -53,6 +55,7 @@ /* System library. */ #include +#include /* Utility library. */ @@ -123,7 +126,7 @@ static void dict_surrogate_close(DICT *dict) dict_free(dict); } -int dict_allow_surrogate = 0; +int dict_allow_surrogate = 0; /* dict_surrogate - terminate or provide surrogate dictionary */ @@ -135,6 +138,7 @@ DICT *dict_surrogate(const char *dict_type, const char *dict_name, DICT_SURROGATE *dp; VSTRING *buf; void (*log_fn) (const char *, va_list); + int saved_errno = errno; /* * Log the problem immediately when it is detected. The table may not be @@ -161,6 +165,7 @@ DICT *dict_surrogate(const char *dict_type, const char *dict_name, dp->dict.flags = dict_flags | DICT_FLAG_PATTERN; dp->dict.owner.status = DICT_OWNER_TRUSTED; buf = vstring_alloc(10); + errno = saved_errno; va_start(ap, fmt); vstring_vsprintf(buf, fmt, ap); va_end(ap); diff --git a/postfix/src/util/dict_thash.c b/postfix/src/util/dict_thash.c index 2c35db9a3..0f09d4b93 100644 --- a/postfix/src/util/dict_thash.c +++ b/postfix/src/util/dict_thash.c @@ -148,7 +148,7 @@ DICT *dict_thash_open(const char *path, int open_flags, int dict_flags) struct stat st; time_t before; time_t after; - VSTRING *line_buffer = vstring_alloc(100); + VSTRING *line_buffer = 0; int lineno; char *key; char *value; @@ -172,6 +172,8 @@ DICT *dict_thash_open(const char *path, int open_flags, int dict_flags) return (dict_surrogate(DICT_TYPE_THASH, path, open_flags, dict_flags, "open database %s: %m", path)); } + if (line_buffer == 0) + line_buffer = vstring_alloc(100); lineno = 0; table = htable_create(13); while (readlline(line_buffer, fp, &lineno)) { diff --git a/postfix/src/util/surrogate.ref b/postfix/src/util/surrogate.ref new file mode 100644 index 000000000..2b8429b9b --- /dev/null +++ b/postfix/src/util/surrogate.ref @@ -0,0 +1,44 @@ +./dict_open: error: cidr:/xx map requires O_RDONLY access mode +> get foo +./dict_open: warning: cidr:/xx is unavailable. cidr:/xx map requires O_RDONLY access mode +foo: error +./dict_open: error: open /xx: No such file or directory +> get foo +./dict_open: warning: cidr:/xx is unavailable. open /xx: No such file or directory +foo: error +./dict_open: error: pcre:/xx map requires O_RDONLY access mode +> get foo +./dict_open: warning: pcre:/xx is unavailable. pcre:/xx map requires O_RDONLY access mode +foo: error +./dict_open: error: open /xx: No such file or directory +> get foo +./dict_open: warning: pcre:/xx is unavailable. open /xx: No such file or directory +foo: error +./dict_open: error: regexp:/xx map requires O_RDONLY access mode +> get foo +./dict_open: warning: regexp:/xx is unavailable. regexp:/xx map requires O_RDONLY access mode +foo: error +./dict_open: error: open /xx: No such file or directory +> get foo +./dict_open: warning: regexp:/xx is unavailable. open /xx: No such file or directory +foo: error +./dict_open: error: unix:xx map requires O_RDONLY access mode +> get foo +./dict_open: warning: unix:xx is unavailable. unix:xx map requires O_RDONLY access mode +foo: error +./dict_open: error: unknown table: unix:xx +> get foo +./dict_open: warning: unix:xx is unavailable. unknown table: unix:xx +foo: error +./dict_open: error: texthash:/xx map requires O_RDONLY access mode +> get foo +./dict_open: warning: texthash:/xx is unavailable. texthash:/xx map requires O_RDONLY access mode +foo: error +./dict_open: error: open database /xx: No such file or directory +> get foo +./dict_open: warning: texthash:/xx is unavailable. open database /xx: No such file or directory +foo: error +./dict_open: error: open database /xx.db: No such file or directory +> get foo +./dict_open: warning: hash:/xx is unavailable. open database /xx.db: No such file or directory +foo: error