xref: /netbsd-src/external/ibm-public/postfix/dist/src/postconf/postconf_dbms.c (revision 413d532bcc3f62d122e56d92e13ac64825a40baf)
1 /*	$NetBSD: postconf_dbms.c,v 1.1.1.2 2013/09/25 19:06:33 tron Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	postconf_dbms 3
6 /* SUMMARY
7 /*	legacy support for database-defined main.cf parameter names
8 /* SYNOPSIS
9 /*	#include <postconf.h>
10 /*
11 /*	void	register_dbms_parameters(param_value, flag_parameter,
12 /*					local_scope)
13 /*	const char *param_value;
14 /*	const char *(flag_parameter) (const char *, int, PC_MASTER_ENT *);
15 /*	PC_MASTER_ENT *local_scope;
16 /* DESCRIPTION
17 /*	This module implements legacy support for database configuration
18 /*	where main.cf parameter names are generated by prepending
19 /*	the database name to a database-defined suffix.
20 /*
21 /*	Arguments:
22 /* .IP param_value
23 /*	A parameter value to be searched for "type:table" strings.
24 /*	When a database type is found that supports legacy-style
25 /*	configuration, the table name is combined with each of the
26 /*	database-defined suffixes to generate candidate parameter
27 /*	names for that database type.
28 /* .IP flag_parameter
29 /*	A function that takes as arguments a candidate parameter
30 /*	name, parameter flags, and a PC_MASTER_ENT pointer.  The
31 /*	function will flag the parameter as "used" if it has a
32 /*	"name=value" entry in the local or global namespace.
33 /* .IP local_scope
34 /*	The local namespace.
35 /* DIAGNOSTICS
36 /*	No explicit diagnostics.
37 /* LICENSE
38 /* .ad
39 /* .fi
40 /*	The Secure Mailer license must be distributed with this software.
41 /* AUTHOR(S)
42 /*	Wietse Venema
43 /*	IBM T.J. Watson Research
44 /*	P.O. Box 704
45 /*	Yorktown Heights, NY 10598, USA
46 /*--*/
47 
48 /* System library. */
49 
50 #include <sys_defs.h>
51 #include <string.h>
52 
53 /* Utility library. */
54 
55 #include <stringops.h>
56 #include <split_at.h>
57 #include <mac_expand.h>
58 #include <dict.h>
59 
60 /* Global library. */
61 
62 #include <mail_conf.h>
63 #include <dict_proxy.h>
64 #include <dict_ldap.h>
65 #include <dict_mysql.h>
66 #include <dict_pgsql.h>
67 #include <dict_sqlite.h>
68 #include <dict_memcache.h>
69 
70 /* Application-specific. */
71 
72 #include <postconf.h>
73 
74  /*
75   * SLMs.
76   */
77 #define STR(x)	vstring_str(x)
78 
79 #ifdef LEGACY_DBMS_SUPPORT
80 
81  /*
82   * The legacy database interface automagically instantiates a list of
83   * parameters by prepending the table name to database-specific suffixes.
84   */
85 
86 /* See ldap_table(5). */
87 
88 static const char *ldap_suffixes[] = {
89     "bind", "bind_dn", "bind_pw", "cache", "cache_expiry", "cache_size",
90     "chase_referrals", "debuglevel", "dereference", "domain",
91     "expansion_limit", "leaf_result_attribute", "query_filter",
92     "recursion_limit", "result_attribute", "result_format", "scope",
93     "search_base", "server_host", "server_port", "size_limit",
94     "special_result_attribute", "terminal_result_attribute",
95     "timeout", "version", 0,
96 };
97 
98 /* See mysql_table(5). */
99 
100 static const char *mysql_suffixes[] = {
101     "additional_conditions", "dbname", "domain", "expansion_limit",
102     "hosts", "password", "query", "result_format", "select_field",
103     "table", "user", "where_field", 0,
104 };
105 
106 /* See pgsql_table(5). */
107 
108 static const char *pgsql_suffixes[] = {
109     "additional_conditions", "dbname", "domain", "expansion_limit",
110     "hosts", "password", "query", "result_format", "select_field",
111     "select_function", "table", "user", "where_field", 0,
112 };
113 
114 /* See sqlite_table(5). */
115 
116 static const char *sqlite_suffixes[] = {
117     "additional_conditions", "dbpath", "domain", "expansion_limit",
118     "query", "result_format", "select_field", "table", "where_field",
119     0,
120 };
121 
122 /* See memcache_table(5). */
123 
124 static const char *memcache_suffixes[] = {
125     "backup", "data_size_limit", "domain", "flags", "key_format",
126     "line_size_limit", "max_try", "memcache", "retry_pause",
127     "timeout", "ttl", 0,
128 };
129 
130  /*
131   * Bundle up the database types and their suffix lists.
132   */
133 typedef struct {
134     const char *db_type;
135     const char **db_suffixes;
136 } PC_DBMS_INFO;
137 
138 static const PC_DBMS_INFO dbms_info[] = {
139     DICT_TYPE_LDAP, ldap_suffixes,
140     DICT_TYPE_MYSQL, mysql_suffixes,
141     DICT_TYPE_PGSQL, pgsql_suffixes,
142     DICT_TYPE_SQLITE, sqlite_suffixes,
143     DICT_TYPE_MEMCACHE, memcache_suffixes,
144     0,
145 };
146 
147 /* register_dbms_parameters - look for database_type:prefix_name */
148 
149 void    register_dbms_parameters(const char *param_value,
150           const char *(flag_parameter) (const char *, int, PC_MASTER_ENT *),
151 				         PC_MASTER_ENT *local_scope)
152 {
153     const PC_DBMS_INFO *dp;
154     char   *bufp;
155     char   *db_type;
156     char   *prefix;
157     static VSTRING *buffer = 0;
158     static VSTRING *candidate = 0;
159     const char **cpp;
160 
161     /*
162      * XXX This does not examine both sides of conditional macro expansion,
163      * and may expand the "wrong" conditional macros. This is the best we can
164      * do for legacy database configuration support.
165      */
166     if (buffer == 0)
167 	buffer = vstring_alloc(100);
168     bufp = expand_parameter_value(buffer, SHOW_EVAL, param_value, local_scope);
169 
170     /*
171      * Naive parsing. We don't really know if the parameter specifies free
172      * text or a list of databases.
173      */
174     while ((db_type = mystrtok(&bufp, " ,\t\r\n")) != 0) {
175 
176 	/*
177 	 * Skip over "proxy:" maptypes, to emulate the proxymap(8) server's
178 	 * behavior when opening a local database configuration file.
179 	 */
180 	while ((prefix = split_at(db_type, ':')) != 0
181 	       && strcmp(db_type, DICT_TYPE_PROXY) == 0)
182 	    db_type = prefix;
183 
184 	/*
185 	 * Look for database:prefix where the prefix is not a pathname and
186 	 * the database is a known type. Synthesize candidate parameter names
187 	 * from the user-defined prefix and from the database-defined suffix
188 	 * list, and see if those parameters have a "name=value" entry in the
189 	 * local or global namespace.
190 	 */
191 	if (prefix != 0 && *prefix != '/' && *prefix != '.') {
192 	    for (dp = dbms_info; dp->db_type != 0; dp++) {
193 		if (strcmp(db_type, dp->db_type) == 0) {
194 		    for (cpp = dp->db_suffixes; *cpp; cpp++) {
195 			vstring_sprintf(candidate ? candidate :
196 					(candidate = vstring_alloc(30)),
197 					"%s_%s", prefix, *cpp);
198 			flag_parameter(STR(candidate),
199 				    PC_PARAM_FLAG_DBMS | PC_PARAM_FLAG_USER,
200 				       local_scope);
201 		    }
202 		    break;
203 		}
204 	    }
205 	}
206     }
207 }
208 
209 #endif
210