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