2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-22 18:07:41 +00:00

postfix-2.8-20100618

This commit is contained in:
Wietse Venema 2010-06-18 00:00:00 -05:00 committed by Viktor Dukhovni
parent fef3bc167b
commit 2cee07704f
10 changed files with 119 additions and 94 deletions

View File

@ -15846,8 +15846,12 @@ Apologies for any names omitted.
Feature: read-only sqlite support based on code by Axel Feature: read-only sqlite support based on code by Axel
Steiner and documentation by Jesus Garcia Crespo. Files: Steiner and documentation by Jesus Garcia Crespo. Files:
conf/postfix-files, mantools/postlink, proto/DATABASE_README.html, conf/postfix-files, mantools/postlink, proto/DATABASE_README.html,
proto/Makefile.in, proto/INSTALL.html, proto/SASL_README.html, proto/Makefile.in, proto/INSTALL.html, proto/mysql_table,
proto/mysql_table, proto/pgsql_table, proto/sqlite_table, proto/pgsql_table, proto/sqlite_table, proto/SQLITE_README.html,
proto/SQLITE_README.html, global/Makefile.in, global/mail_dict.c, global/Makefile.in, global/mail_dict.c, global/dict_sqlite.c,
global/dict_sqlite.c, global/dict_sqlite.h, postconf/postconf.c, global/dict_sqlite.h, postconf/postconf.c, postfix/postfix.c.
postfix/postfix.c.
20100618
Cleanup: SQLite read-only driver and documentation. Files:
global/dict_sqlite.c, proto/mysql_table, proto/SQLITE_README.html.

View File

@ -54,7 +54,7 @@ map type in <a href="postconf.5.html">main.cf</a> like this: </p>
<blockquote> <blockquote>
<pre> <pre>
<a href="postconf.5.html#alias_maps">alias_maps</a> = sqlite:/etc/postfix/sqlite-aliases.cf <a href="postconf.5.html#alias_maps">alias_maps</a> = <a href="mysql_table.5.html">sqlite</a>:/etc/postfix/sqlite-aliases.cf
</pre> </pre>
</blockquote> </blockquote>

View File

@ -10,9 +10,9 @@ SQLITE_TABLE(5) SQLITE_TABLE(5)
sqlite_table - Postfix SQLite configuration sqlite_table - Postfix SQLite configuration
<b>SYNOPSIS</b> <b>SYNOPSIS</b>
<b>postmap -q "</b><i>string</i><b>" sqlite:/etc/postfix/filename</b> <b>postmap -q "</b><i>string</i><b>" <a href="mysql_table.5.html">sqlite</a>:/etc/postfix/filename</b>
<b>postmap -q - sqlite:/etc/postfix/</b><i>filename</i> &lt;<i>inputfile</i> <b>postmap -q - <a href="mysql_table.5.html">sqlite</a>:/etc/postfix/</b><i>filename</i> &lt;<i>inputfile</i>
<b>DESCRIPTION</b> <b>DESCRIPTION</b>
The Postfix mail system uses optional tables for address The Postfix mail system uses optional tables for address
@ -20,9 +20,9 @@ SQLITE_TABLE(5) SQLITE_TABLE(5)
or <b>db</b> format. or <b>db</b> format.
Alternatively, lookup tables can be specified as SQLite Alternatively, lookup tables can be specified as SQLite
databases. In order to use SQLite lookups, define a databases. In order to use SQLite lookups, define an
SQLite source as a lookup table in <a href="postconf.5.html">main.cf</a>, for example: SQLite source as a lookup table in <a href="postconf.5.html">main.cf</a>, for example:
<a href="postconf.5.html#alias_maps">alias_maps</a> = sqlite:/etc/sqlite-aliases.cf <a href="postconf.5.html#alias_maps">alias_maps</a> = <a href="mysql_table.5.html">sqlite</a>:/etc/sqlite-aliases.cf
The file /etc/postfix/sqlite-aliases.cf has the same for- The file /etc/postfix/sqlite-aliases.cf has the same for-
mat as the Postfix <a href="postconf.5.html">main.cf</a> file, and can specify the mat as the Postfix <a href="postconf.5.html">main.cf</a> file, and can specify the
@ -35,7 +35,7 @@ SQLITE_TABLE(5) SQLITE_TABLE(5)
with a slash or a dot. The SQLite parameters will then be with a slash or a dot. The SQLite parameters will then be
accessible as the name you've given the source in its def- accessible as the name you've given the source in its def-
inition, an underscore, and the name of the parameter. inition, an underscore, and the name of the parameter.
For example, if the map is specified as "sqlite:<i>sqlite-</i> For example, if the map is specified as "<a href="mysql_table.5.html">sqlite</a>:<i>sqlite-</i>
<i>name</i>", the parameter "query" below would be defined in <i>name</i>", the parameter "query" below would be defined in
<a href="postconf.5.html">main.cf</a> as "<i>sqlitename</i>_query". <a href="postconf.5.html">main.cf</a> as "<i>sqlitename</i>_query".
@ -269,7 +269,7 @@ SQLITE_TABLE(5) SQLITE_TABLE(5)
<b>README FILES</b> <b>README FILES</b>
<a href="DATABASE_README.html">DATABASE_README</a>, Postfix lookup table overview <a href="DATABASE_README.html">DATABASE_README</a>, Postfix lookup table overview
<a href="SQLITE_README.html">SQLITE_README</a>, Postfix SQLITE driver <a href="SQLITE_README.html">SQLITE_README</a>, Postfix SQLITE howto
<b>LICENSE</b> <b>LICENSE</b>
The Secure Mailer license must be distributed with this The Secure Mailer license must be distributed with this

View File

@ -19,7 +19,7 @@ rewriting or mail routing. These tables are usually in
\fBdbm\fR or \fBdb\fR format. \fBdbm\fR or \fBdb\fR format.
Alternatively, lookup tables can be specified as SQLite databases. Alternatively, lookup tables can be specified as SQLite databases.
In order to use SQLite lookups, define a SQLite source as a lookup In order to use SQLite lookups, define an SQLite source as a lookup
table in main.cf, for example: table in main.cf, for example:
.nf .nf
alias_maps = sqlite:/etc/sqlite-aliases.cf alias_maps = sqlite:/etc/sqlite-aliases.cf
@ -286,7 +286,7 @@ Use "\fBpostconf readme_directory\fR" or
.na .na
.nf .nf
DATABASE_README, Postfix lookup table overview DATABASE_README, Postfix lookup table overview
SQLITE_README, Postfix SQLITE driver SQLITE_README, Postfix SQLITE howto
.SH "LICENSE" .SH "LICENSE"
.na .na
.nf .nf

View File

@ -979,6 +979,7 @@ while (<>) {
s/\b(nisplus):/<a href="nisplus_table.5.html">$1<\/a>:/g; s/\b(nisplus):/<a href="nisplus_table.5.html">$1<\/a>:/g;
s/\b(ldap):/<a href="ldap_table.5.html">$1<\/a>:/g; s/\b(ldap):/<a href="ldap_table.5.html">$1<\/a>:/g;
s/\b(regexp):/<a href="regexp_table.5.html">$1<\/a>:/g; s/\b(regexp):/<a href="regexp_table.5.html">$1<\/a>:/g;
s/\b(sqlite):/<a href="mysql_table.5.html">$1<\/a>:/g;
s/\b(tcp):/<a href="tcp_table.5.html">$1<\/a>:/g; s/\b(tcp):/<a href="tcp_table.5.html">$1<\/a>:/g;
# Do nice links for smtp:host:port etc. # Do nice links for smtp:host:port etc.

View File

@ -13,7 +13,7 @@
# \fBdbm\fR or \fBdb\fR format. # \fBdbm\fR or \fBdb\fR format.
# #
# Alternatively, lookup tables can be specified as SQLite databases. # Alternatively, lookup tables can be specified as SQLite databases.
# In order to use SQLite lookups, define a SQLite source as a lookup # In order to use SQLite lookups, define an SQLite source as a lookup
# table in main.cf, for example: # table in main.cf, for example:
# .nf # .nf
# alias_maps = sqlite:/etc/sqlite-aliases.cf # alias_maps = sqlite:/etc/sqlite-aliases.cf
@ -268,7 +268,7 @@
# .na # .na
# .nf # .nf
# DATABASE_README, Postfix lookup table overview # DATABASE_README, Postfix lookup table overview
# SQLITE_README, Postfix SQLITE driver # SQLITE_README, Postfix SQLITE howto
# LICENSE # LICENSE
# .ad # .ad
# .fi # .fi

View File

@ -100,19 +100,19 @@
/* "vmailer" and password "passwd" then the configuration file /* "vmailer" and password "passwd" then the configuration file
/* should read: /* should read:
/* .PP /* .PP
/* \fIuser\fR = \fBvmailer\fR /* user = vmailer
/* .br /* .br
/* \fIpassword\fR = \fBpasswd\fR /* password = passwd
/* .br /* .br
/* \fIdbname\fR = \fBvmailer_info\fR /* dbname = vmailer_info
/* .br /* .br
/* \fItable\fR = \fBaliases\fR /* table = aliases
/* .br /* .br
/* \fIselect_field\fR = \fBforw_addr\fR /* select_field = forw_addr
/* .br /* .br
/* \fIwhere_field\fR = \fBalias\fR /* where_field = alias
/* .br /* .br
/* \fIhosts\fR = \fBhost1.some.domain\fR \fBhost2.some.domain\fR /* hosts = host1.some.domain\fR \fBhost2.some.domain
/* .IP additional_conditions /* .IP additional_conditions
/* Backward compatibility when \fIquery\fR is not set, additional /* Backward compatibility when \fIquery\fR is not set, additional
/* conditions to the WHERE clause. /* conditions to the WHERE clause.
@ -127,19 +127,19 @@
/* "vmailer" and password "passwd" then the configuration file /* "vmailer" and password "passwd" then the configuration file
/* should read: /* should read:
/* .PP /* .PP
/* \fIuser\fR = \fBvmailer\fR /* user = vmailer
/* .br /* .br
/* \fIpassword\fR = \fBpasswd\fR /* password = passwd
/* .br /* .br
/* \fIdbname\fR = \fBvmailer_info\fR /* dbname = vmailer_info
/* .br /* .br
/* \fItable\fR = \fBaliases\fR /* table = aliases
/* .br /* .br
/* \fIselect_field\fR = \fBforw_addr\fR /* select_field = forw_addr
/* .br /* .br
/* \fIwhere_field\fR = \fBalias\fR /* where_field = alias
/* .br /* .br
/* \fIhosts\fR = \fBhost1.some.domain\fR \fBhost2.some.domain\fR /* hosts = host1.some.domain\fR \fBhost2.some.domain
/* .PP /* .PP
/* SEE ALSO /* SEE ALSO
/* dict(3) generic dictionary manager /* dict(3) generic dictionary manager

View File

@ -103,19 +103,19 @@
/* "postfix" and password "passwd" then the configuration file /* "postfix" and password "passwd" then the configuration file
/* should read: /* should read:
/* .PP /* .PP
/* \fIuser\fR = \fBpostfix\fR /* user = postfix
/* .br /* .br
/* \fIpassword\fR = \fBpasswd\fR /* password = passwd
/* .br /* .br
/* \fIdbname\fR = \fBpostfix_info\fR /* dbname = postfix_info
/* .br /* .br
/* \fItable\fR = \fBaliases\fR /* table = aliases
/* .br /* .br
/* \fIselect_field\fR = \fBforw_addr\fR /* select_field = forw_addr
/* .br /* .br
/* \fIwhere_field\fR = \fBalias\fR /* where_field = alias
/* .br /* .br
/* \fIhosts\fR = \fBhost1.some.domain\fR \fBhost2.some.domain\fR /* hosts = host1.some.domain\fR \fBhost2.some.domain
/* .PP /* .PP
/* SEE ALSO /* SEE ALSO
/* dict(3) generic dictionary manager /* dict(3) generic dictionary manager

View File

@ -14,7 +14,7 @@
/* dict_sqlite_open() creates a dictionary of type 'sqlite'. /* dict_sqlite_open() creates a dictionary of type 'sqlite'.
/* This dictionary is an interface for the postfix key->value /* This dictionary is an interface for the postfix key->value
/* mappings to SQLite. The result is a pointer to the installed /* mappings to SQLite. The result is a pointer to the installed
/* dictionary, or a null pointer in case of problems. /* dictionary.
/* .PP /* .PP
/* Arguments: /* Arguments:
/* .IP name /* .IP name
@ -39,7 +39,7 @@
/* .IP dbpath /* .IP dbpath
/* Path to SQLite database /* Path to SQLite database
/* .IP query /* .IP query
/* Query template, before the query is actually issued, variable /* Query template. Before the query is actually issued, variable
/* substitutions are performed. See sqlite_table(5) for details. /* substitutions are performed. See sqlite_table(5) for details.
/* .IP result_format /* .IP result_format
/* The format used to expand results from queries. Substitutions /* The format used to expand results from queries. Substitutions
@ -101,16 +101,16 @@ typedef struct {
/* dict_sqlite_quote - escape SQL metacharacters in input string */ /* dict_sqlite_quote - escape SQL metacharacters in input string */
static void dict_sqlite_quote(DICT *dict, const char *name, VSTRING *result) static void dict_sqlite_quote(DICT *dict, const char *raw_text, VSTRING *result)
{ {
char *q; char *quoted_text;
q = sqlite3_mprintf("%q", name); quoted_text = sqlite3_mprintf("%q", raw_text);
/* Fix 20100616 */ /* Fix 20100616 */
if (q == 0) if (quoted_text == 0)
msg_fatal("dict_sqlite_quote: out of memory"); msg_fatal("dict_sqlite_quote: out of memory");
vstring_strcat(result, q); vstring_strcat(result, raw_text);
sqlite3_free(q); sqlite3_free(quoted_text);
} }
/* dict_sqlite_close - close the database */ /* dict_sqlite_close - close the database */
@ -142,11 +142,11 @@ static const char *dict_sqlite_lookup(DICT *dict, const char *name)
{ {
const char *myname = "dict_sqlite_lookup"; const char *myname = "dict_sqlite_lookup";
DICT_SQLITE *dict_sqlite = (DICT_SQLITE *) dict; DICT_SQLITE *dict_sqlite = (DICT_SQLITE *) dict;
sqlite3_stmt *sql; sqlite3_stmt *sql_stmt;
const char *zErrMsg; const char *query_remainder;
static VSTRING *query; static VSTRING *query;
static VSTRING *result; static VSTRING *result;
const char *r; const char *retval;
int expansion = 0; int expansion = 0;
int status; int status;
@ -161,17 +161,17 @@ static const char *dict_sqlite_lookup(DICT *dict, const char *name)
} }
/* /*
* Optionally fold the key. * Optionally fold the key. Folding may be enabled on on-the-fly.
*/ */
if (dict->flags & DICT_FLAG_FOLD_FIX) { if (dict->flags & DICT_FLAG_FOLD_FIX) {
if (dict->fold_buf == 0) if (dict->fold_buf == 0)
dict->fold_buf = vstring_alloc(10); dict->fold_buf = vstring_alloc(100);
vstring_strcpy(dict->fold_buf, name); vstring_strcpy(dict->fold_buf, name);
name = lowercase(vstring_str(dict->fold_buf)); name = lowercase(vstring_str(dict->fold_buf));
} }
/* /*
* Domain filter for email address lookups. * Apply the optional domain filter for email address lookups.
*/ */
if (db_common_check_domain(dict_sqlite->ctx, name) == 0) { if (db_common_check_domain(dict_sqlite->ctx, name) == 0) {
if (msg_verbose) if (msg_verbose)
@ -201,75 +201,95 @@ static const char *dict_sqlite_lookup(DICT *dict, const char *name)
myname, dict_sqlite->parser->name, vstring_str(query)); myname, dict_sqlite->parser->name, vstring_str(query));
if (sqlite3_prepare_v2(dict_sqlite->db, vstring_str(query), -1, if (sqlite3_prepare_v2(dict_sqlite->db, vstring_str(query), -1,
&sql, &zErrMsg) != SQLITE_OK) { &sql_stmt, &query_remainder) != SQLITE_OK)
msg_fatal("%s: %s: SQL prepare failed: %s\n", msg_fatal("%s: %s: SQL prepare failed: %s\n",
myname, dict_sqlite->parser->name, myname, dict_sqlite->parser->name,
sqlite3_errmsg(dict_sqlite->db)); sqlite3_errmsg(dict_sqlite->db));
}
if (*query_remainder && msg_verbose)
msg_info("%s: %s: Ignoring text at end of query: %s",
myname, dict_sqlite->parser->name, query_remainder);
/* /*
* Retrieve and expand the result(s). * Retrieve and expand the result(s).
*/ */
INIT_VSTR(result, 10); INIT_VSTR(result, 10);
while ((status = sqlite3_step(sql)) == SQLITE_ROW) { while ((status = sqlite3_step(sql_stmt)) != SQLITE_DONE) {
if (db_common_expand(dict_sqlite->ctx, dict_sqlite->result_format, if (status == SQLITE_ROW) {
(char *) sqlite3_column_text(sql, 0), if (db_common_expand(dict_sqlite->ctx, dict_sqlite->result_format,
name, result, 0) (char *) sqlite3_column_text(sql_stmt, 0),
&& dict_sqlite->expansion_limit > 0 name, result, 0)
&& ++expansion > dict_sqlite->expansion_limit) { && dict_sqlite->expansion_limit > 0
msg_warn("%s: %s: Expansion limit exceeded for key: '%s'", && ++expansion > dict_sqlite->expansion_limit) {
myname, dict_sqlite->parser->name, name); msg_warn("%s: %s: Expansion limit exceeded for key '%s'",
myname, dict_sqlite->parser->name, name);
dict_errno = DICT_ERR_RETRY;
break;
}
}
/* Fix 20100616 */
else {
msg_warn("%s: %s: SQL step failed for query '%s': %s\n",
myname, dict_sqlite->parser->name,
vstring_str(query), sqlite3_errmsg(dict_sqlite->db));
dict_errno = DICT_ERR_RETRY; dict_errno = DICT_ERR_RETRY;
break; break;
} }
} }
/* Fix 20100616 */
if (status != SQLITE_ROW && status != SQLITE_DONE) {
msg_warn("%s: %s: sql step for %s; %s\n",
myname, dict_sqlite->parser->name,
vstring_str(query), sqlite3_errmsg(dict_sqlite->db));
dict_errno = DICT_ERR_RETRY;
}
/* /*
* Clean up. * Clean up.
*/ */
if (sqlite3_finalize(sql)) if (sqlite3_finalize(sql_stmt))
msg_fatal("%s: %s: SQL finalize for %s; %s\n", msg_fatal("%s: %s: SQL finalize failed for query '%s': %s\n",
myname, dict_sqlite->parser->name, myname, dict_sqlite->parser->name,
vstring_str(query), sqlite3_errmsg(dict_sqlite->db)); vstring_str(query), sqlite3_errmsg(dict_sqlite->db));
r = vstring_str(result); return ((dict_errno == 0 && *(retval = vstring_str(result)) != 0) ?
return ((dict_errno == 0 && *r) ? r : 0); retval : 0);
} }
/* sqlite_parse_config - parse sqlite configuration file */ /* sqlite_parse_config - parse sqlite configuration file */
static void sqlite_parse_config(DICT_SQLITE *dict_sqlite, const char *sqlitecf) static void sqlite_parse_config(DICT_SQLITE *dict_sqlite, const char *sqlitecf)
{ {
CFG_PARSER *p;
VSTRING *buf; VSTRING *buf;
p = dict_sqlite->parser = cfg_parser_alloc(sqlitecf); /*
dict_sqlite->dbpath = cfg_get_str(p, "dbpath", "", 1, 0); * Parse the primary configuration parameters, and emulate the legacy
dict_sqlite->result_format = cfg_get_str(p, "result_format", "%s", 1, 0); * query interface if necessary. This simplifies migration from one SQL
* database type to another.
if ((dict_sqlite->query = cfg_get_str(p, "query", NULL, 0, 0)) == 0) { */
buf = vstring_alloc(64); dict_sqlite->parser = cfg_parser_alloc(sqlitecf);
db_common_sql_build_query(buf, p); dict_sqlite->dbpath = cfg_get_str(dict_sqlite->parser, "dbpath", "", 1, 0);
dict_sqlite->query = cfg_get_str(dict_sqlite->parser, "query", NULL, 0, 0);
if (dict_sqlite->query == 0) {
buf = vstring_alloc(100);
db_common_sql_build_query(buf, dict_sqlite->parser);
dict_sqlite->query = vstring_export(buf); dict_sqlite->query = vstring_export(buf);
} }
dict_sqlite->expansion_limit = cfg_get_int(p, "expansion_limit", 0, 0, 0); dict_sqlite->result_format =
cfg_get_str(dict_sqlite->parser, "result_format", "%s", 1, 0);
dict_sqlite->expansion_limit =
cfg_get_int(dict_sqlite->parser, "expansion_limit", 0, 0, 0);
/*
* Parse the query / result templates and the optional domain filter.
*/
dict_sqlite->ctx = 0; dict_sqlite->ctx = 0;
(void) db_common_parse(&dict_sqlite->dict, &dict_sqlite->ctx,
(void) db_common_parse(&dict_sqlite->dict, &dict_sqlite->ctx, dict_sqlite->query, 1); dict_sqlite->query, 1);
(void) db_common_parse(0, &dict_sqlite->ctx, dict_sqlite->result_format, 0); (void) db_common_parse(0, &dict_sqlite->ctx, dict_sqlite->result_format, 0);
db_common_parse_domain(dict_sqlite->parser, dict_sqlite->ctx);
db_common_parse_domain(p, dict_sqlite->ctx); /*
* Maps that use substring keys should only be used with the full input
if (dict_sqlite->dict.flags & DICT_FLAG_FOLD_FIX) * key.
dict_sqlite->dict.fold_buf = vstring_alloc(10); */
if (db_common_dict_partial(dict_sqlite->ctx))
dict_sqlite->dict.flags |= DICT_FLAG_PATTERN;
else
dict_sqlite->dict.flags |= DICT_FLAG_FIXED;
} }
/* dict_sqlite_open - open sqlite database */ /* dict_sqlite_open - open sqlite database */
@ -290,13 +310,13 @@ DICT *dict_sqlite_open(const char *name, int open_flags, int dict_flags)
dict_sqlite->dict.lookup = dict_sqlite_lookup; dict_sqlite->dict.lookup = dict_sqlite_lookup;
dict_sqlite->dict.close = dict_sqlite_close; dict_sqlite->dict.close = dict_sqlite_close;
dict_sqlite->dict.flags = dict_flags; dict_sqlite->dict.flags = dict_flags;
dict_sqlite->dict.flags |= DICT_FLAG_FIXED;
sqlite_parse_config(dict_sqlite, name); sqlite_parse_config(dict_sqlite, name);
if (sqlite3_open(dict_sqlite->dbpath, &dict_sqlite->db)) { if (sqlite3_open(dict_sqlite->dbpath, &dict_sqlite->db))
msg_fatal("Can't open database: %s\n", sqlite3_errmsg(dict_sqlite->db)); msg_fatal("%s:%s: Can't open database: %s\n",
sqlite3_close(dict_sqlite->db); DICT_TYPE_SQLITE, name, sqlite3_errmsg(dict_sqlite->db));
}
return (DICT_DEBUG (&dict_sqlite->dict)); return (DICT_DEBUG (&dict_sqlite->dict));
} }

View File

@ -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 "20100617" #define MAIL_RELEASE_DATE "20100618"
#define MAIL_VERSION_NUMBER "2.8" #define MAIL_VERSION_NUMBER "2.8"
#ifdef SNAPSHOT #ifdef SNAPSHOT