Current File : //root/postfix-3.2.0/src/postconf/postconf_dbms.c |
/*++
/* NAME
/* postconf_dbms 3
/* SUMMARY
/* legacy support for database-defined main.cf parameter names
/* SYNOPSIS
/* #include <postconf.h>
/*
/* 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 <sys_defs.h>
#include <string.h>
/* Utility library. */
#include <stringops.h>
#include <split_at.h>
#include <mac_expand.h>
#include <dict.h>
#include <msg.h>
#include <mymalloc.h>
/* Global library. */
#include <mail_conf.h>
#include <mail_params.h>
#include <dict_proxy.h>
#include <dict_ldap.h>
#include <dict_mysql.h>
#include <dict_pgsql.h>
#include <dict_sqlite.h>
#include <dict_memcache.h>
/* Application-specific. */
#include <postconf.h>
/*
* 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", "require_result_set",
"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_helper - parse one possible database type:name */
static void pcf_register_dbms_helper(char *str_value,
const char *(flag_parameter) (const char *, int, PCF_MASTER_ENT *),
PCF_MASTER_ENT *local_scope)
{
const PCF_DBMS_INFO *dp;
char *db_type;
char *prefix;
static VSTRING *candidate = 0;
const char **cpp;
char *err;
/*
* Naive parsing. We don't really know if this substring specifies a
* database or some other text.
*/
while ((db_type = mystrtokq(&str_value, CHARS_COMMA_SP, CHARS_BRACE)) != 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 != '.') {
if (*prefix == CHARS_BRACE[0]) {
if ((err = extpar(&prefix, CHARS_BRACE, EXTPAR_FLAG_NONE)) != 0) {
/* XXX Encapsulate this in pcf_warn() function. */
if (local_scope)
msg_warn("%s:%s: %s",
MASTER_CONF_FILE, local_scope->name_space,
err);
else
msg_warn("%s: %s", MAIN_CONF_FILE, err);
myfree(err);
}
pcf_register_dbms_helper(prefix, flag_parameter,
local_scope);
} else {
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;
}
}
}
}
}
}
/* 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)
{
char *bufp;
static VSTRING *buffer = 0;
/*
* 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);
pcf_register_dbms_helper(bufp, flag_parameter, local_scope);
}
#endif