1/*++ 2/* NAME 3/* postconf_builtin 3 4/* SUMMARY 5/* built-in main.cf parameter support 6/* SYNOPSIS 7/* #include <postconf.h> 8/* 9/* void pcf_register_builtin_parameters(procname, pid) 10/* const char *procname; 11/* pid_t pid; 12/* DESCRIPTION 13/* pcf_register_builtin_parameters() initializes the global 14/* main.cf parameter name space and adds all built-in parameter 15/* information. 16/* 17/* Arguments: 18/*.IP procname 19/* Provides the default value for the "process_name" parameter. 20/*.IP pid 21/* Provides the default value for the "process_id" parameter. 22/* DIAGNOSTICS 23/* Problems are reported to the standard error stream. 24/* LICENSE 25/* .ad 26/* .fi 27/* The Secure Mailer license must be distributed with this software. 28/* AUTHOR(S) 29/* Wietse Venema 30/* IBM T.J. Watson Research 31/* P.O. Box 704 32/* Yorktown Heights, NY 10598, USA 33/*--*/ 34 35/* System library. */ 36 37#include <sys_defs.h> 38#include <string.h> 39 40#ifdef USE_PATHS_H 41#include <paths.h> 42#endif 43 44/* Utility library. */ 45 46#include <msg.h> 47#include <mymalloc.h> 48#include <htable.h> 49#include <vstring.h> 50#include <get_hostname.h> 51#include <stringops.h> 52 53/* Global library. */ 54 55#include <mynetworks.h> 56#include <mail_conf.h> 57#include <mail_params.h> 58#include <mail_version.h> 59#include <mail_proto.h> 60#include <mail_addr.h> 61#include <inet_proto.h> 62#include <server_acl.h> 63 64/* Application-specific. */ 65 66#include <postconf.h> 67 68 /* 69 * Support for built-in parameters: declarations generated by scanning 70 * actual C source files. 71 */ 72#include "time_vars.h" 73#include "bool_vars.h" 74#include "int_vars.h" 75#include "str_vars.h" 76#include "raw_vars.h" 77#include "nint_vars.h" 78#include "nbool_vars.h" 79#include "long_vars.h" 80 81 /* 82 * Support for built-in parameters: manually extracted. 83 */ 84#include "install_vars.h" 85 86 /* 87 * Support for built-in parameters: lookup tables generated by scanning 88 * actual C source files. 89 */ 90static const CONFIG_TIME_TABLE pcf_time_table[] = { 91#include "time_table.h" 92 0, 93}; 94 95static const CONFIG_BOOL_TABLE pcf_bool_table[] = { 96#include "bool_table.h" 97 0, 98}; 99 100static const CONFIG_INT_TABLE pcf_int_table[] = { 101#include "int_table.h" 102 0, 103}; 104 105static const CONFIG_STR_TABLE pcf_str_table[] = { 106#include "str_table.h" 107#include "install_table.h" 108 0, 109}; 110 111static const CONFIG_RAW_TABLE pcf_raw_table[] = { 112#include "raw_table.h" 113 0, 114}; 115 116static const CONFIG_NINT_TABLE pcf_nint_table[] = { 117#include "nint_table.h" 118 0, 119}; 120 121static const CONFIG_NBOOL_TABLE pcf_nbool_table[] = { 122#include "nbool_table.h" 123 0, 124}; 125 126static const CONFIG_LONG_TABLE pcf_long_table[] = { 127#include "long_table.h" 128 0, 129}; 130 131 /* 132 * Legacy parameters for backwards compatibility. 133 */ 134static const CONFIG_STR_TABLE pcf_legacy_str_table[] = { 135 {"virtual_maps", ""}, 136 {"fallback_relay", ""}, 137 {"authorized_verp_clients", ""}, 138 {"smtpd_client_connection_limit_exceptions", ""}, 139 0, 140}; 141 142 /* 143 * Parameters whose default values are normally initialized by calling a 144 * function. We direct the calls to our own versions of those functions 145 * because the run-time conditions are slightly different. 146 * 147 * Important: if the evaluation of a parameter default value has any side 148 * effects, then those side effects must happen only once. 149 */ 150static const char *pcf_check_myhostname(void); 151static const char *pcf_check_mydomainname(void); 152static const char *pcf_mynetworks(void); 153 154#include "str_fn_vars.h" 155 156static const CONFIG_STR_FN_TABLE pcf_str_fn_table[] = { 157#include "str_fn_table.h" 158 0, 159}; 160 161 /* 162 * Parameters whose default values are normally initialized by ad-hoc code. 163 * The AWK script cannot identify these parameters or values, so we provide 164 * our own. 165 * 166 * Important: if the evaluation of a parameter default value has any side 167 * effects, then those side effects must happen only once. 168 */ 169static CONFIG_STR_TABLE pcf_adhoc_procname = {VAR_PROCNAME}; 170static CONFIG_INT_TABLE pcf_adhoc_pid = {VAR_PID}; 171 172#define STR(x) vstring_str(x) 173 174/* pcf_check_myhostname - lookup hostname and validate */ 175 176static const char *pcf_check_myhostname(void) 177{ 178 static const char *name; 179 const char *dot; 180 const char *domain; 181 182 /* 183 * Use cached result. 184 */ 185 if (name) 186 return (name); 187 188 /* 189 * If the local machine name is not in FQDN form, try to append the 190 * contents of $mydomain. 191 */ 192 name = get_hostname(); 193 if ((dot = strchr(name, '.')) == 0) { 194 if ((domain = mail_conf_lookup_eval(VAR_MYDOMAIN)) == 0) 195 domain = DEF_MYDOMAIN; 196 name = concatenate(name, ".", domain, (char *) 0); 197 } 198 return (name); 199} 200 201/* pcf_get_myhostname - look up and store my hostname */ 202 203static void pcf_get_myhostname(void) 204{ 205 const char *name; 206 207 if ((name = mail_conf_lookup_eval(VAR_MYHOSTNAME)) == 0) 208 name = pcf_check_myhostname(); 209 var_myhostname = mystrdup(name); 210} 211 212/* pcf_check_mydomainname - lookup domain name and validate */ 213 214static const char *pcf_check_mydomainname(void) 215{ 216 static const char *domain; 217 char *dot; 218 219 /* 220 * Use cached result. 221 */ 222 if (domain) 223 return (domain); 224 225 /* 226 * Use the hostname when it is not a FQDN ("foo"), or when the hostname 227 * actually is a domain name ("foo.com"). 228 */ 229 if (var_myhostname == 0) 230 pcf_get_myhostname(); 231 if ((dot = strchr(var_myhostname, '.')) == 0 || strchr(dot + 1, '.') == 0) 232 return (domain = DEF_MYDOMAIN); 233 return (domain = mystrdup(dot + 1)); 234} 235 236/* pcf_mynetworks - lookup network address list */ 237 238static const char *pcf_mynetworks(void) 239{ 240 static const char *networks; 241 INET_PROTO_INFO *proto_info; 242 const char *junk; 243 244 /* 245 * Use cached result. 246 */ 247 if (networks) 248 return (networks); 249 250 if (var_inet_interfaces == 0) { 251 if ((pcf_cmd_mode & PCF_SHOW_DEFS) 252 || (junk = mail_conf_lookup_eval(VAR_INET_INTERFACES)) == 0) 253 junk = DEF_INET_INTERFACES; 254 var_inet_interfaces = mystrdup(junk); 255 } 256 if (var_mynetworks_style == 0) { 257 if ((pcf_cmd_mode & PCF_SHOW_DEFS) 258 || (junk = mail_conf_lookup_eval(VAR_MYNETWORKS_STYLE)) == 0) 259 junk = DEF_MYNETWORKS_STYLE; 260 var_mynetworks_style = mystrdup(junk); 261 } 262 if (var_inet_protocols == 0) { 263 if ((pcf_cmd_mode & PCF_SHOW_DEFS) 264 || (junk = mail_conf_lookup_eval(VAR_INET_PROTOCOLS)) == 0) 265 junk = DEF_INET_PROTOCOLS; 266 var_inet_protocols = mystrdup(junk); 267 proto_info = inet_proto_init(VAR_INET_PROTOCOLS, var_inet_protocols); 268 } 269 return (networks = mystrdup(mynetworks())); 270} 271 272/* pcf_conv_bool_parameter - get boolean parameter string value */ 273 274static const char *pcf_conv_bool_parameter(char *ptr) 275{ 276 CONFIG_BOOL_TABLE *cbt = (CONFIG_BOOL_TABLE *) ptr; 277 278 return (cbt->defval ? "yes" : "no"); 279} 280 281/* pcf_conv_time_parameter - get relative time parameter string value */ 282 283static const char *pcf_conv_time_parameter(char *ptr) 284{ 285 CONFIG_TIME_TABLE *ctt = (CONFIG_TIME_TABLE *) ptr; 286 287 return (ctt->defval); 288} 289 290/* pcf_conv_int_parameter - get integer parameter string value */ 291 292static const char *pcf_conv_int_parameter(char *ptr) 293{ 294 CONFIG_INT_TABLE *cit = (CONFIG_INT_TABLE *) ptr; 295 296 return (STR(vstring_sprintf(pcf_param_string_buf, "%d", cit->defval))); 297} 298 299/* pcf_conv_str_parameter - get string parameter string value */ 300 301static const char *pcf_conv_str_parameter(char *ptr) 302{ 303 CONFIG_STR_TABLE *cst = (CONFIG_STR_TABLE *) ptr; 304 305 return (cst->defval); 306} 307 308/* pcf_conv_str_fn_parameter - get string-function parameter string value */ 309 310static const char *pcf_conv_str_fn_parameter(char *ptr) 311{ 312 CONFIG_STR_FN_TABLE *cft = (CONFIG_STR_FN_TABLE *) ptr; 313 314 return (cft->defval()); 315} 316 317/* pcf_conv_raw_parameter - get raw string parameter string value */ 318 319static const char *pcf_conv_raw_parameter(char *ptr) 320{ 321 CONFIG_RAW_TABLE *rst = (CONFIG_RAW_TABLE *) ptr; 322 323 return (rst->defval); 324} 325 326/* pcf_conv_nint_parameter - get new integer parameter string value */ 327 328static const char *pcf_conv_nint_parameter(char *ptr) 329{ 330 CONFIG_NINT_TABLE *rst = (CONFIG_NINT_TABLE *) ptr; 331 332 return (rst->defval); 333} 334 335/* pcf_conv_nbool_parameter - get new boolean parameter string value */ 336 337static const char *pcf_conv_nbool_parameter(char *ptr) 338{ 339 CONFIG_NBOOL_TABLE *bst = (CONFIG_NBOOL_TABLE *) ptr; 340 341 return (bst->defval); 342} 343 344/* pcf_conv_long_parameter - get long parameter string value */ 345 346static const char *pcf_conv_long_parameter(char *ptr) 347{ 348 CONFIG_LONG_TABLE *clt = (CONFIG_LONG_TABLE *) ptr; 349 350 return (STR(vstring_sprintf(pcf_param_string_buf, "%ld", clt->defval))); 351} 352 353/* pcf_register_builtin_parameters - add built-ins to the global name space */ 354 355void pcf_register_builtin_parameters(const char *procname, pid_t pid) 356{ 357 const char *myname = "pcf_register_builtin_parameters"; 358 const CONFIG_TIME_TABLE *ctt; 359 const CONFIG_BOOL_TABLE *cbt; 360 const CONFIG_INT_TABLE *cit; 361 const CONFIG_STR_TABLE *cst; 362 const CONFIG_STR_FN_TABLE *cft; 363 const CONFIG_RAW_TABLE *rst; 364 const CONFIG_NINT_TABLE *nst; 365 const CONFIG_NBOOL_TABLE *bst; 366 const CONFIG_LONG_TABLE *lst; 367 368 /* 369 * Sanity checks. 370 */ 371 if (pcf_param_table != 0) 372 msg_panic("%s: global parameter table is already initialized", myname); 373 374 /* 375 * Initialize the global parameter table. 376 */ 377 pcf_param_table = PCF_PARAM_TABLE_CREATE(1000); 378 379 /* 380 * Add the built-in parameters to the global name space. The class 381 * (built-in) is tentative; some parameters are actually service-defined, 382 * but they have their own default value. 383 */ 384 for (ctt = pcf_time_table; ctt->name; ctt++) 385 PCF_PARAM_TABLE_ENTER(pcf_param_table, ctt->name, 386 PCF_PARAM_FLAG_BUILTIN, (char *) ctt, 387 pcf_conv_time_parameter); 388 for (cbt = pcf_bool_table; cbt->name; cbt++) 389 PCF_PARAM_TABLE_ENTER(pcf_param_table, cbt->name, 390 PCF_PARAM_FLAG_BUILTIN, (char *) cbt, 391 pcf_conv_bool_parameter); 392 for (cit = pcf_int_table; cit->name; cit++) 393 PCF_PARAM_TABLE_ENTER(pcf_param_table, cit->name, 394 PCF_PARAM_FLAG_BUILTIN, (char *) cit, 395 pcf_conv_int_parameter); 396 for (cst = pcf_str_table; cst->name; cst++) 397 PCF_PARAM_TABLE_ENTER(pcf_param_table, cst->name, 398 PCF_PARAM_FLAG_BUILTIN, (char *) cst, 399 pcf_conv_str_parameter); 400 for (cft = pcf_str_fn_table; cft->name; cft++) 401 PCF_PARAM_TABLE_ENTER(pcf_param_table, cft->name, 402 PCF_PARAM_FLAG_BUILTIN, (char *) cft, 403 pcf_conv_str_fn_parameter); 404 for (rst = pcf_raw_table; rst->name; rst++) 405 PCF_PARAM_TABLE_ENTER(pcf_param_table, rst->name, 406 PCF_PARAM_FLAG_BUILTIN | PCF_PARAM_FLAG_RAW, 407 (char *) rst, pcf_conv_raw_parameter); 408 for (nst = pcf_nint_table; nst->name; nst++) 409 PCF_PARAM_TABLE_ENTER(pcf_param_table, nst->name, 410 PCF_PARAM_FLAG_BUILTIN, (char *) nst, 411 pcf_conv_nint_parameter); 412 for (bst = pcf_nbool_table; bst->name; bst++) 413 PCF_PARAM_TABLE_ENTER(pcf_param_table, bst->name, 414 PCF_PARAM_FLAG_BUILTIN, (char *) bst, 415 pcf_conv_nbool_parameter); 416 for (lst = pcf_long_table; lst->name; lst++) 417 PCF_PARAM_TABLE_ENTER(pcf_param_table, lst->name, 418 PCF_PARAM_FLAG_BUILTIN, (char *) lst, 419 pcf_conv_long_parameter); 420 421 /* 422 * Register legacy parameters (used as a backwards-compatible migration 423 * aid). 424 */ 425 for (cst = pcf_legacy_str_table; cst->name; cst++) 426 PCF_PARAM_TABLE_ENTER(pcf_param_table, cst->name, 427 PCF_PARAM_FLAG_LEGACY, (char *) cst, 428 pcf_conv_str_parameter); 429 430 /* 431 * Register parameters whose default value is normally initialized by 432 * ad-hoc code. 433 */ 434 pcf_adhoc_procname.defval = mystrdup(procname); 435 PCF_PARAM_TABLE_ENTER(pcf_param_table, pcf_adhoc_procname.name, 436 PCF_PARAM_FLAG_BUILTIN | PCF_PARAM_FLAG_READONLY, 437 (char *) &pcf_adhoc_procname, pcf_conv_str_parameter); 438 pcf_adhoc_pid.defval = pid; 439 PCF_PARAM_TABLE_ENTER(pcf_param_table, pcf_adhoc_pid.name, 440 PCF_PARAM_FLAG_BUILTIN | PCF_PARAM_FLAG_READONLY, 441 (char *) &pcf_adhoc_pid, pcf_conv_int_parameter); 442} 443