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