diff --git a/postfix/HISTORY b/postfix/HISTORY index f1237ed8f..534b439ac 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -18208,3 +18208,19 @@ Apologies for any names omitted. master.cf options parser didn't support "clusters" of command-line option letters. Files: postconf/postconf_master.c, postconf/test40.ref. + +20130105 + + Undo a change made around 20121224, and always whitelist + configuration parameter names for legacy-style proxy:ldap:prefix + etc. lookup tables. Files: postconf/postconf_dbms.c, + postconf/test28.ref, postconf/test29.ref, postconf/Makefile.in. + +20130107 + + Factor out the master.cf line parser so that it can be + reused for "postconf -Me". File: postconf/postconf_master.c. + +20130113 + + Start of work on integrating a pile of new code. diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index af5878dd7..3db2d3f10 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -1737,6 +1737,12 @@ the process marches on. If you use an X-based debugger, be sure to set up your XAUTHORITY environment variable before starting Postfix.

+

+Note: the command is subject to $name expansion, before it is +passed to the default commmand interpreter. Specify "$$" to +produce a single "$" character. +

+

Example:

diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index 5c0164575..2c547b493 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -1004,6 +1004,10 @@ Use "command .. & sleep 5" so that the debugger can attach before the process marches on. If you use an X-based debugger, be sure to set up your XAUTHORITY environment variable before starting Postfix. .PP +Note: the command is subject to $name expansion, before it is +passed to the default commmand interpreter. Specify "$$" to +produce a single "$" character. +.PP Example: .PP .nf diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index 307c10d11..9283bc6a9 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -6810,6 +6810,12 @@ the process marches on. If you use an X-based debugger, be sure to set up your XAUTHORITY environment variable before starting Postfix.

+

+Note: the command is subject to $name expansion, before it is +passed to the default commmand interpreter. Specify "$$" to +produce a single "$" character. +

+

Example:

diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 61019449d..86532ce2e 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 "20130101" +#define MAIL_RELEASE_DATE "20130113" #define MAIL_VERSION_NUMBER "2.10" #ifdef SNAPSHOT diff --git a/postfix/src/postconf/Makefile.in b/postfix/src/postconf/Makefile.in index 66c565cc1..85864a2a6 100644 --- a/postfix/src/postconf/Makefile.in +++ b/postfix/src/postconf/Makefile.in @@ -377,7 +377,7 @@ test27: $(PROG) test27.ref test28: $(PROG) test28.ref rm -f main.cf master.cf touch main.cf master.cf - echo 'xx = ldap:foo' >> main.cf + echo 'xx = proxy:ldap:foo' >> main.cf echo 'foo_domain = bar' >> main.cf echo 'header_checks = ldap:hh' >> main.cf echo 'hh_domain = whatever' >> main.cf @@ -397,19 +397,19 @@ test28: $(PROG) test28.ref test29: $(PROG) test29.ref rm -f main.cf master.cf touch main.cf master.cf - echo 'ldapxx = ldap:ldapfoo' >> main.cf + echo 'ldapxx = proxy:ldap:ldapfoo' >> main.cf echo 'ldapfoo_domain = bar' >> main.cf echo 'ldapfoo_domainx = bar' >> main.cf - echo 'mysqlxx = mysql:mysqlfoo' >> main.cf + echo 'mysqlxx = proxy:mysql:mysqlfoo' >> main.cf echo 'mysqlfoo_domain = bar' >> main.cf echo 'mysqlfoo_domainx = bar' >> main.cf - echo 'pgsqlxx = pgsql:pgsqlfoo' >> main.cf + echo 'pgsqlxx = proxy:pgsql:pgsqlfoo' >> main.cf echo 'pgsqlfoo_domain = bar' >> main.cf echo 'pgsqlfoo_domainx = bar' >> main.cf - echo 'sqlitexx = sqlite:sqlitefoo' >> main.cf + echo 'sqlitexx = proxy:sqlite:sqlitefoo' >> main.cf echo 'sqlitefoo_domain = bar' >> main.cf echo 'sqlitefoo_domainx = bar' >> main.cf - echo 'memcachexx = memcache:memcachefoo' >> main.cf + echo 'memcachexx = proxy:memcache:memcachefoo' >> main.cf echo 'memcachefoo_domain = bar' >> main.cf echo 'memcachefoo_domainx = bar' >> main.cf ./$(PROG) -nc . >test29.tmp 2>&1 diff --git a/postfix/src/postconf/postconf_dbms.c b/postfix/src/postconf/postconf_dbms.c index 128a8adda..9d12bd8b3 100644 --- a/postfix/src/postconf/postconf_dbms.c +++ b/postfix/src/postconf/postconf_dbms.c @@ -172,17 +172,21 @@ void register_dbms_parameters(const char *param_value, while ((db_type = mystrtok(&bufp, " ,\t\r\n")) != 0) { /* - * Don't skip over "proxy:" indirections. They don't introduce - * database-specific main.cf parameters on the proxy client side. - * - * Look for database:prefix where the prefix is not a pathname and the - * database is a known type. Synthesize candidate parameter names + * Skip over "proxy:" maptypes, to emulate the proxymap(8) server's + * behavior when opening a local database configuration file. + */ + while ((prefix = split_at(db_type, ':')) != 0 + && strcmp(db_type, DICT_TYPE_PROXY) == 0) + db_type = prefix; + + /* + * Look for database:prefix where the prefix is not a pathname and + * the database is a known type. Synthesize candidate parameter names * from the user-defined prefix and from the database-defined suffix * list, and see if those parameters have a "name=value" entry in the * local or global namespace. */ - if ((prefix = split_at(db_type, ':')) != 0 - && *prefix != '/' && *prefix != '.') { + if (prefix != 0 && *prefix != '/' && *prefix != '.') { for (dp = dbms_info; dp->db_type != 0; dp++) { if (strcmp(db_type, dp->db_type) == 0) { for (cpp = dp->db_suffixes; *cpp; cpp++) { diff --git a/postfix/src/postconf/postconf_master.c b/postfix/src/postconf/postconf_master.c index 251d94eb8..9bf79a78e 100644 --- a/postfix/src/postconf/postconf_master.c +++ b/postfix/src/postconf/postconf_master.c @@ -101,7 +101,7 @@ static void normalize_options(ARGV *argv) junk = concatenate("-", cp, (char *) 0); argv_insert_one(argv, field + 1, junk); myfree(junk); - *cp = 0; + *cp = 0; /* XXX argv_replace_one() */ break; } } @@ -111,7 +111,7 @@ static void normalize_options(ARGV *argv) if (arg[2] != 0) { /* Split "-oname=value" into "-o" "name=value". */ argv_insert_one(argv, field + 1, arg + 2); - arg[2] = 0; + arg[2] = 0; /* XXX argv_replace_one() */ field += 1; } else if (argv->argv[field + 1] != 0) { /* Already in "-o" "name=value" form. */ @@ -120,6 +120,36 @@ static void normalize_options(ARGV *argv) } } +/* parse_master_line - parse one master line */ + +static void parse_master_line(PC_MASTER_ENT *masterp, const char *buf, + const char *path, int line_count) +{ + ARGV *argv; + + /* + * We can't use the master daemon's master_ent routines in their current + * form. They convert everything to internal form, and they skip disabled + * services. + * + * The postconf command needs to show default fields as "-", and needs to + * know about all service names so that it can generate service-dependent + * parameter names (transport-dependent etc.). + */ +#define MASTER_BLANKS " \t\r\n" /* XXX */ + + argv = argv_split(buf, MASTER_BLANKS); + if (argv->argc < PC_MASTER_MIN_FIELDS) + msg_fatal("file %s: line %d: bad field count", + path, line_count); + normalize_options(argv); + masterp->name_space = + concatenate(argv->argv[0], ".", argv->argv[1], (char *) 0); + masterp->argv = argv; + masterp->valid_names = 0; + masterp->all_params = 0; +} + /* read_master - read and digest the master.cf file */ void read_master(int fail_on_open_error) @@ -127,7 +157,6 @@ void read_master(int fail_on_open_error) const char *myname = "read_master"; char *path; VSTRING *buf; - ARGV *argv; VSTREAM *fp; int entry_count = 0; int line_count = 0; @@ -145,17 +174,6 @@ void read_master(int fail_on_open_error) set_config_dir(); path = concatenate(var_config_dir, "/", MASTER_CONF_FILE, (char *) 0); - /* - * We can't use the master daemon's master_ent routines in their current - * form. They convert everything to internal form, and they skip disabled - * services. - * - * The postconf command needs to show default fields as "-", and needs to - * know about all service names so that it can generate service-dependent - * parameter names (transport-dependent etc.). - */ -#define MASTER_BLANKS " \t\r\n" /* XXX */ - /* * Initialize the in-memory master table. */ @@ -174,16 +192,8 @@ void read_master(int fail_on_open_error) while (readlline(buf, fp, &line_count) != 0) { master_table = (PC_MASTER_ENT *) myrealloc((char *) master_table, (entry_count + 2) * sizeof(*master_table)); - argv = argv_split(STR(buf), MASTER_BLANKS); - if (argv->argc < PC_MASTER_MIN_FIELDS) - msg_fatal("file %s: line %d: bad field count", - path, line_count); - normalize_options(argv); - master_table[entry_count].name_space = - concatenate(argv->argv[0], ".", argv->argv[1], (char *) 0); - master_table[entry_count].argv = argv; - master_table[entry_count].valid_names = 0; - master_table[entry_count].all_params = 0; + parse_master_line(master_table + entry_count, STR(buf), + path, line_count); entry_count += 1; } vstream_fclose(fp); diff --git a/postfix/src/postconf/test28.ref b/postfix/src/postconf/test28.ref index f3310e1d9..a16ae5e02 100644 --- a/postfix/src/postconf/test28.ref +++ b/postfix/src/postconf/test28.ref @@ -7,4 +7,4 @@ yy = aap zz_domain = whatever ./postconf: warning: ./main.cf: unused parameter: zz=$yy ./postconf: warning: ./main.cf: unused parameter: aa_domain=whatever -./postconf: warning: ./main.cf: unused parameter: xx=ldap:foo +./postconf: warning: ./main.cf: unused parameter: xx=proxy:ldap:foo diff --git a/postfix/src/postconf/test29.ref b/postfix/src/postconf/test29.ref index 8ab8fdb53..75a2efafd 100644 --- a/postfix/src/postconf/test29.ref +++ b/postfix/src/postconf/test29.ref @@ -4,13 +4,13 @@ memcachefoo_domain = bar mysqlfoo_domain = bar pgsqlfoo_domain = bar sqlitefoo_domain = bar -./postconf: warning: ./main.cf: unused parameter: sqlitexx=sqlite:sqlitefoo -./postconf: warning: ./main.cf: unused parameter: pgsqlxx=pgsql:pgsqlfoo +./postconf: warning: ./main.cf: unused parameter: sqlitexx=proxy:sqlite:sqlitefoo +./postconf: warning: ./main.cf: unused parameter: pgsqlxx=proxy:pgsql:pgsqlfoo ./postconf: warning: ./main.cf: unused parameter: memcachefoo_domainx=bar ./postconf: warning: ./main.cf: unused parameter: sqlitefoo_domainx=bar -./postconf: warning: ./main.cf: unused parameter: memcachexx=memcache:memcachefoo -./postconf: warning: ./main.cf: unused parameter: mysqlxx=mysql:mysqlfoo -./postconf: warning: ./main.cf: unused parameter: ldapxx=ldap:ldapfoo +./postconf: warning: ./main.cf: unused parameter: memcachexx=proxy:memcache:memcachefoo +./postconf: warning: ./main.cf: unused parameter: mysqlxx=proxy:mysql:mysqlfoo +./postconf: warning: ./main.cf: unused parameter: ldapxx=proxy:ldap:ldapfoo ./postconf: warning: ./main.cf: unused parameter: ldapfoo_domainx=bar ./postconf: warning: ./main.cf: unused parameter: pgsqlfoo_domainx=bar ./postconf: warning: ./main.cf: unused parameter: mysqlfoo_domainx=bar diff --git a/postfix/src/util/argv.c b/postfix/src/util/argv.c index de2d4b329..7a0ce1f15 100644 --- a/postfix/src/util/argv.c +++ b/postfix/src/util/argv.c @@ -256,7 +256,7 @@ void argv_insert_one(ARGV *argvp, ssize_t where, const char *arg) argvp->argc += 1; } -/* argv_replace_one - insert one string into array */ +/* argv_replace_one - replace one string in array */ void argv_replace_one(ARGV *argvp, ssize_t where, const char *arg) {