and appending null bytes to key/value. The latter was needed
for a clean implementation of NIS master alias maps support.
- Feature: POSIX regular expressions by Lamont Jones.
+ Feature: POSIX regular expressions by Lamont Jones. See
+ config/sample-regexp.c. Right now, enabled on *BSD and
+ LINUX only.
19990328
Feature: new dictionary types can be registered with
dict_open_register(). File: util/dict_open.c.
+1990330
+
+ Bug fix: match_list membership dictionary lookups were case
+ sensitive when they should not. Patch by Lutz Jaenicke,
+ BTU Cottbus, Germany.
+
Future:
Planned: must be able to list the same hash table in
#
always_bcc =
+# The daemon_timeout parameter specifies how much time a daemon may
+# take to handle a request before it assumes it is wedged and commits
+# suicide.
+#
+daemon_timeout = 18000
+
# The default_database_type parameter specifies the default database
# type to use in postalias(1) and postmap(1) commands. On many UNIX
# systems the default type is either `dbm' or `hash'. The default is
# TIMEOUT CONTROLS
#
# Note: if you set SMTP timeouts to large values you must update the
-# global ipc_timeout parameter as well. See sample-misc.cf for details.
+# global ipc_timeout and daemon_timeout parameters as well. See
+# sample-misc.cf for details.
#
# The smtp_connect_timeout parameter specifies the SMTP client
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
-#define DEF_MAIL_VERSION "Snapshot-19990329"
+#define DEF_MAIL_VERSION "Snapshot-19990330"
extern char *var_mail_version;
/* LICENSE
uid_t alias_uid;
struct mypasswd *alias_pwd;
VSTRING *canon_owner;
+ DICT *dict;
/*
* Make verbose logging easier to understand.
* With aliases that have an owner- alias, the latter is used to set the
* sender and owner attributes. Otherwise, the owner attribute is reset
* (the alias is globally visible and could be sent to by anyone).
+ *
+ * Don't match aliases that are based on regexps.
*/
for (cpp = maps->argv->argv; *cpp; cpp++) {
- if ((alias_result = dict_lookup(*cpp, state.msg_attr.local)) != 0) {
+ if ((dict = dict_handle(*cpp)) == 0)
+ msg_panic("%s: dictionary not found: %s", myname, *cpp);
+ if ((dict->flags & DICT_FLAG_FIXED) == 0) {
+ msg_warn("invalid alias map type: %s", *cpp);
+ continue;
+ }
+ if ((alias_result = dict_get(dict, state.msg_attr.local)) != 0) {
if (msg_verbose)
msg_info("%s: %s: %s = %s", myname, *cpp,
state.msg_attr.local, alias_result);
* Use the owner- alias if one is specified, otherwise reset the
* owner attribute and use the include file ownership if we can.
* Save the dict_lookup() result before something clobbers it.
+ *
+ * Don't match aliases that are based on regexps.
*/
#define STR(x) vstring_str(x)
#define OWNER_ASSIGN(own) \
concatenate("owner-", state.msg_attr.local, (char *) 0)))
expansion = mystrdup(alias_result);
- if (OWNER_ASSIGN(owner) != 0 && maps_find(maps, owner, 0)) {
+ if (OWNER_ASSIGN(owner) != 0 && maps_find(maps, owner,
+ DICT_FLAG_FIXED)) {
canon_owner = canon_addr_internal(vstring_alloc(10), owner);
SET_OWNER_ATTR(state.msg_attr, STR(canon_owner), state.level);
} else {
int listen_fd = (int) context;
int time_left = -1;
int fd;
- VSTREAM *stream;
/*
* Some buggy systems cause Postfix to lock up.
/* .IP \fB-v\fR
/* Enable verbose logging for debugging purposes. Multiple \fB-v\fR
/* options make the software increasingly verbose.
+/* .IP \f\B-w\fR
+/* Do not warn about duplicate entries; silently ignore them.
/* .PP
/* Arguments:
/* .IP \fIfile_type\fR
/* .IP \fB-v\fR
/* Enable verbose logging for debugging purposes. Multiple \fB-v\fR
/* options make the software increasingly verbose.
+/* .IP \f\B-w\fR
+/* Do not warn about duplicate entries; silently ignore them.
/* .PP
/* Arguments:
/* .IP \fIfile_type\fR
for (name = low_domain; (next = strchr(name, '.')) != 0; name = next + 1) {
if ((dict = dict_handle(table)) == 0)
msg_panic("%s: dictionary not found: %s", myname, table);
- if (flags != 0 && (flags & dict->flags) == 0)
- continue;
- if ((value = dict_get(dict, name)) != 0)
- CHK_DOMAIN_RETURN(check_table_result(state, table, value, domain));
- if (dict_errno != 0)
- msg_fatal("%s: table lookup problem", table);
+ if (flags == 0 || (flags & dict->flags) != 0) {
+ if ((value = dict_get(dict, name)) != 0)
+ CHK_DOMAIN_RETURN(check_table_result(state, table, value, domain));
+ if (dict_errno != 0)
+ msg_fatal("%s: table lookup problem", table);
+ }
flags = PARTIAL;
}
CHK_DOMAIN_RETURN(SMTPD_CHECK_DUNNO);
do {
if ((dict = dict_handle(table)) == 0)
msg_panic("%s: dictionary not found: %s", myname, table);
- if (flags != 0 && (flags & dict->flags) == 0)
- continue;
- if ((value = dict_get(dict, addr)) != 0)
- return (check_table_result(state, table, value, address));
- if (dict_errno != 0)
- msg_fatal("%s: table lookup problem", table);
+ if (flags == 0 || (flags & dict->flags) != 0) {
+ if ((value = dict_get(dict, addr)) != 0)
+ return (check_table_result(state, table, value, address));
+ if (dict_errno != 0)
+ msg_fatal("%s: table lookup problem", table);
+ }
flags = PARTIAL;
} while (split_at_right(addr, '.'));
return (dict_db_open(path, open_flags, DB_BTREE, (void *) &tweak, dict_flags));
}
-/**INDENT** Error@188: Unmatched #endif */
#endif
typedef struct {
DICT dict; /* generic members */
char *map; /* NIS map name */
- int flags; /* see below */
} DICT_NIS;
/*
* See if this NIS map was written with one null byte appended to key and
* value.
*/
- if (dict_nis->flags & DICT_FLAG_TRY1NULL) {
+ if (dict->flags & DICT_FLAG_TRY1NULL) {
err = yp_match(dict_nis_domain, dict_nis->map,
(void *) key, strlen(key) + 1,
&result, &result_len);
if (err == 0) {
- dict_nis->flags &= ~DICT_FLAG_TRY0NULL;
+ dict->flags &= ~DICT_FLAG_TRY0NULL;
return (result);
}
}
* See if this NIS map was written with no null byte appended to key and
* value. This should never be the case, but better play safe.
*/
- if (dict_nis->flags & DICT_FLAG_TRY0NULL) {
+ if (dict->flags & DICT_FLAG_TRY0NULL) {
err = yp_match(dict_nis_domain, dict_nis->map,
(void *) key, strlen(key),
&result, &result_len);
if (err == 0) {
- dict_nis->flags &= ~DICT_FLAG_TRY1NULL;
+ dict->flags &= ~DICT_FLAG_TRY1NULL;
if (buf == 0)
buf = vstring_alloc(10);
vstring_strncpy(buf, result, result_len);
/* support duplicate keys. The default is to terminate with a fatal
/* error.
/* .IP DICT_FLAG_TRY0NULL
-/* With maps where this is appropriate, append no null byte to
+/* With maps where this is appropriate, append no null byte to
/* keys and values.
/* When neither DICT_FLAG_TRY0NULL nor DICT_FLAG_TRY1NULL are
/* specified, the software guesses what format to use for reading;
/* and in the absence of definite information, a system-dependent
/* default is chosen for writing.
/* .IP DICT_FLAG_TRY1NULL
-/* With maps where this is appropriate, append one null byte to
+/* With maps where this is appropriate, append one null byte to
/* keys and values.
/* When neither DICT_FLAG_TRY0NULL nor DICT_FLAG_TRY1NULL are
/* specified, the software guesses what format to use for reading;
#include <stdlib.h>
#include <fcntl.h>
+#include <unistd.h>
/* Utility library. */
int name_len = strlen(name);
struct dict_pcre_context ctxt;
static VSTRING *buf;
- char *at;
dict_errno = 0;
DICT_REGEXP_RULE *rule;
struct dict_regexp_context ctxt;
static VSTRING *buf;
- char *at;
int error;
dict_errno = 0;
*/
if (strchr(pattern, ':') != 0) {
key = lowercase(mystrdup(string));
- match = (dict_lookup(pattern, string) != 0);
+ match = (dict_lookup(pattern, key) != 0);
myfree(key);
if (match != 0)
return (1);