/*++ /* NAME /* postconf_dbms 3 /* SUMMARY /* legacy support for database-defined main.cf parameter names /* SYNOPSIS /* #include /* /* void pcf_register_dbms_parameters(param_value, flag_parameter, /* local_scope) /* const char *param_value; /* const char *(flag_parameter) (const char *, int, PCF_MASTER_ENT *); /* PCF_MASTER_ENT *local_scope; /* DESCRIPTION /* This module implements legacy support for database configuration /* where main.cf parameter names are generated by prepending /* the database name to a database-defined suffix. /* /* Arguments: /* .IP param_value /* A parameter value to be searched for "type:table" strings. /* When a database type is found that supports legacy-style /* configuration, the table name is combined with each of the /* database-defined suffixes to generate candidate parameter /* names for that database type. /* .IP flag_parameter /* A function that takes as arguments a candidate parameter /* name, parameter flags, and a PCF_MASTER_ENT pointer. The /* function will flag the parameter as "used" if it has a /* "name=value" entry in the local or global namespace. /* .IP local_scope /* The local namespace. /* DIAGNOSTICS /* No explicit diagnostics. /* LICENSE /* .ad /* .fi /* The Secure Mailer license must be distributed with this software. /* AUTHOR(S) /* Wietse Venema /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA /*--*/ /* System library. */ #include #include /* Utility library. */ #include #include #include #include /* Global library. */ #include #include #include #include #include #include #include /* Application-specific. */ #include /* * SLMs. */ #define STR(x) vstring_str(x) #ifdef LEGACY_DBMS_SUPPORT /* * The legacy database interface automagically instantiates a list of * parameters by prepending the table name to database-specific suffixes. */ /* See ldap_table(5). */ static const char *pcf_ldap_suffixes[] = { "bind", "bind_dn", "bind_pw", "cache", "cache_expiry", "cache_size", "chase_referrals", "debuglevel", "dereference", "domain", "expansion_limit", "leaf_result_attribute", "query_filter", "recursion_limit", "result_attribute", "result_format", "scope", "search_base", "server_host", "server_port", "size_limit", "special_result_attribute", "terminal_result_attribute", "timeout", "version", 0, }; /* See mysql_table(5). */ static const char *pcf_mysql_suffixes[] = { "additional_conditions", "dbname", "domain", "expansion_limit", "hosts", "password", "query", "result_format", "select_field", "table", "user", "where_field", 0, }; /* See pgsql_table(5). */ static const char *pcf_pgsql_suffixes[] = { "additional_conditions", "dbname", "domain", "expansion_limit", "hosts", "password", "query", "result_format", "select_field", "select_function", "table", "user", "where_field", 0, }; /* See sqlite_table(5). */ static const char *pcf_sqlite_suffixes[] = { "additional_conditions", "dbpath", "domain", "expansion_limit", "query", "result_format", "select_field", "table", "where_field", 0, }; /* See memcache_table(5). */ static const char *pcf_memcache_suffixes[] = { "backup", "data_size_limit", "domain", "flags", "key_format", "line_size_limit", "max_try", "memcache", "retry_pause", "timeout", "ttl", 0, }; /* * Bundle up the database types and their suffix lists. */ typedef struct { const char *db_type; const char **db_suffixes; } PCF_DBMS_INFO; static const PCF_DBMS_INFO pcf_dbms_info[] = { DICT_TYPE_LDAP, pcf_ldap_suffixes, DICT_TYPE_MYSQL, pcf_mysql_suffixes, DICT_TYPE_PGSQL, pcf_pgsql_suffixes, DICT_TYPE_SQLITE, pcf_sqlite_suffixes, DICT_TYPE_MEMCACHE, pcf_memcache_suffixes, 0, }; /* pcf_register_dbms_parameters - look for database_type:prefix_name */ void pcf_register_dbms_parameters(const char *param_value, const char *(flag_parameter) (const char *, int, PCF_MASTER_ENT *), PCF_MASTER_ENT *local_scope) { const PCF_DBMS_INFO *dp; char *bufp; char *db_type; char *prefix; static VSTRING *buffer = 0; static VSTRING *candidate = 0; const char **cpp; /* * XXX This does not examine both sides of conditional macro expansion, * and may expand the "wrong" conditional macros. This is the best we can * do for legacy database configuration support. */ if (buffer == 0) buffer = vstring_alloc(100); bufp = pcf_expand_parameter_value(buffer, PCF_SHOW_EVAL, param_value, local_scope); /* * Naive parsing. We don't really know if the parameter specifies free * text or a list of databases. */ while ((db_type = mystrtok(&bufp, " ,\t\r\n")) != 0) { /* * 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 != 0 && *prefix != '/' && *prefix != '.') { for (dp = pcf_dbms_info; dp->db_type != 0; dp++) { if (strcmp(db_type, dp->db_type) == 0) { for (cpp = dp->db_suffixes; *cpp; cpp++) { vstring_sprintf(candidate ? candidate : (candidate = vstring_alloc(30)), "%s_%s", prefix, *cpp); flag_parameter(STR(candidate), PCF_PARAM_FLAG_DBMS | PCF_PARAM_FLAG_USER, local_scope); } break; } } } } } #endif