1 /* $NetBSD: postconf_builtin.c,v 1.3 2020/03/18 19:05:17 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 */ 97 static const CONFIG_TIME_TABLE pcf_time_table[] = { 98 #include "time_table.h" 99 0, 100 }; 101 102 static const CONFIG_BOOL_TABLE pcf_bool_table[] = { 103 #include "bool_table.h" 104 0, 105 }; 106 107 static const CONFIG_INT_TABLE pcf_int_table[] = { 108 #include "int_table.h" 109 0, 110 }; 111 112 static const CONFIG_STR_TABLE pcf_str_table[] = { 113 #include "str_table.h" 114 #include "install_table.h" 115 0, 116 }; 117 118 static const CONFIG_RAW_TABLE pcf_raw_table[] = { 119 #include "raw_table.h" 120 0, 121 }; 122 123 static const CONFIG_NINT_TABLE pcf_nint_table[] = { 124 #include "nint_table.h" 125 0, 126 }; 127 128 static const CONFIG_NBOOL_TABLE pcf_nbool_table[] = { 129 #include "nbool_table.h" 130 0, 131 }; 132 133 static const CONFIG_LONG_TABLE pcf_long_table[] = { 134 #include "long_table.h" 135 0, 136 }; 137 138 /* 139 * Legacy parameters for backwards compatibility. 140 */ 141 static 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 0, 148 }; 149 150 /* 151 * Parameters whose default values are normally initialized by calling a 152 * function. We direct the calls to our own versions of those functions 153 * because the run-time conditions are slightly different. 154 * 155 * Important: if the evaluation of a parameter default value has any side 156 * effects, then those side effects must happen only once. 157 */ 158 static const char *pcf_check_myhostname(void); 159 static const char *pcf_check_mydomainname(void); 160 static const char *pcf_mynetworks(void); 161 162 #include "str_fn_vars.h" 163 164 static const CONFIG_STR_FN_TABLE pcf_str_fn_table[] = { 165 #include "str_fn_table.h" 166 0, 167 }; 168 169 /* 170 * Parameters whose default values are normally initialized by ad-hoc code. 171 * The AWK script cannot identify these parameters or values, so we provide 172 * our own. 173 * 174 * Important: if the evaluation of a parameter default value has any side 175 * effects, then those side effects must happen only once. 176 */ 177 static CONFIG_STR_TABLE pcf_adhoc_procname = {VAR_PROCNAME}; 178 static CONFIG_STR_TABLE pcf_adhoc_servname = {VAR_SERVNAME}; 179 static CONFIG_INT_TABLE pcf_adhoc_pid = {VAR_PID}; 180 181 #define STR(x) vstring_str(x) 182 183 /* pcf_check_myhostname - lookup hostname and validate */ 184 185 static const char *pcf_check_myhostname(void) 186 { 187 static const char *name; 188 const char *dot; 189 const char *domain; 190 191 /* 192 * Use cached result. 193 */ 194 if (name) 195 return (name); 196 197 /* 198 * If the local machine name is not in FQDN form, try to append the 199 * contents of $mydomain. 200 */ 201 name = get_hostname(); 202 if ((dot = strchr(name, '.')) == 0) { 203 if ((domain = mail_conf_lookup_eval(VAR_MYDOMAIN)) == 0) 204 domain = DEF_MYDOMAIN; 205 name = concatenate(name, ".", domain, (char *) 0); 206 } 207 return (name); 208 } 209 210 /* pcf_get_myhostname - look up and store my hostname */ 211 212 static void pcf_get_myhostname(void) 213 { 214 const char *name; 215 216 if ((name = mail_conf_lookup_eval(VAR_MYHOSTNAME)) == 0) 217 name = pcf_check_myhostname(); 218 var_myhostname = mystrdup(name); 219 } 220 221 /* pcf_check_mydomainname - lookup domain name and validate */ 222 223 static const char *pcf_check_mydomainname(void) 224 { 225 static const char *domain; 226 char *dot; 227 228 /* 229 * Use cached result. 230 */ 231 if (domain) 232 return (domain); 233 234 /* 235 * Use a default domain when the hostname is not a FQDN ("foo"). 236 */ 237 if (var_myhostname == 0) 238 pcf_get_myhostname(); 239 if ((dot = strchr(var_myhostname, '.')) == 0) 240 return (domain = DEF_MYDOMAIN); 241 return (domain = mystrdup(dot + 1)); 242 } 243 244 /* pcf_mynetworks - lookup network address list */ 245 246 static const char *pcf_mynetworks(void) 247 { 248 static const char *networks; 249 const char *junk; 250 251 /* 252 * Use cached result. 253 */ 254 if (networks) 255 return (networks); 256 257 if (var_inet_interfaces == 0) { 258 if ((pcf_cmd_mode & PCF_SHOW_DEFS) 259 || (junk = mail_conf_lookup_eval(VAR_INET_INTERFACES)) == 0) 260 junk = pcf_expand_parameter_value((VSTRING *) 0, pcf_cmd_mode, 261 DEF_INET_INTERFACES, 262 (PCF_MASTER_ENT *) 0); 263 var_inet_interfaces = mystrdup(junk); 264 } 265 if (var_mynetworks_style == 0) { 266 if ((pcf_cmd_mode & PCF_SHOW_DEFS) 267 || (junk = mail_conf_lookup_eval(VAR_MYNETWORKS_STYLE)) == 0) 268 junk = pcf_expand_parameter_value((VSTRING *) 0, pcf_cmd_mode, 269 DEF_MYNETWORKS_STYLE, 270 (PCF_MASTER_ENT *) 0); 271 var_mynetworks_style = mystrdup(junk); 272 } 273 if (var_inet_protocols == 0) { 274 if ((pcf_cmd_mode & PCF_SHOW_DEFS) 275 || (junk = mail_conf_lookup_eval(VAR_INET_PROTOCOLS)) == 0) 276 junk = pcf_expand_parameter_value((VSTRING *) 0, pcf_cmd_mode, 277 DEF_INET_PROTOCOLS, 278 (PCF_MASTER_ENT *) 0); 279 var_inet_protocols = mystrdup(junk); 280 (void) inet_proto_init(VAR_INET_PROTOCOLS, var_inet_protocols); 281 } 282 return (networks = mystrdup(mynetworks())); 283 } 284 285 /* pcf_conv_bool_parameter - get boolean parameter string value */ 286 287 static const char *pcf_conv_bool_parameter(void *ptr) 288 { 289 CONFIG_BOOL_TABLE *cbt = (CONFIG_BOOL_TABLE *) ptr; 290 291 return (cbt->defval ? "yes" : "no"); 292 } 293 294 /* pcf_conv_time_parameter - get relative time parameter string value */ 295 296 static const char *pcf_conv_time_parameter(void *ptr) 297 { 298 CONFIG_TIME_TABLE *ctt = (CONFIG_TIME_TABLE *) ptr; 299 300 return (ctt->defval); 301 } 302 303 /* pcf_conv_int_parameter - get integer parameter string value */ 304 305 static const char *pcf_conv_int_parameter(void *ptr) 306 { 307 CONFIG_INT_TABLE *cit = (CONFIG_INT_TABLE *) ptr; 308 309 return (STR(vstring_sprintf(pcf_param_string_buf, "%d", cit->defval))); 310 } 311 312 /* pcf_conv_str_parameter - get string parameter string value */ 313 314 static const char *pcf_conv_str_parameter(void *ptr) 315 { 316 CONFIG_STR_TABLE *cst = (CONFIG_STR_TABLE *) ptr; 317 318 return (cst->defval); 319 } 320 321 /* pcf_conv_str_fn_parameter - get string-function parameter string value */ 322 323 static const char *pcf_conv_str_fn_parameter(void *ptr) 324 { 325 CONFIG_STR_FN_TABLE *cft = (CONFIG_STR_FN_TABLE *) ptr; 326 327 return (cft->defval()); 328 } 329 330 /* pcf_conv_raw_parameter - get raw string parameter string value */ 331 332 static const char *pcf_conv_raw_parameter(void *ptr) 333 { 334 CONFIG_RAW_TABLE *rst = (CONFIG_RAW_TABLE *) ptr; 335 336 return (rst->defval); 337 } 338 339 /* pcf_conv_nint_parameter - get new integer parameter string value */ 340 341 static const char *pcf_conv_nint_parameter(void *ptr) 342 { 343 CONFIG_NINT_TABLE *rst = (CONFIG_NINT_TABLE *) ptr; 344 345 return (rst->defval); 346 } 347 348 /* pcf_conv_nbool_parameter - get new boolean parameter string value */ 349 350 static const char *pcf_conv_nbool_parameter(void *ptr) 351 { 352 CONFIG_NBOOL_TABLE *bst = (CONFIG_NBOOL_TABLE *) ptr; 353 354 return (bst->defval); 355 } 356 357 /* pcf_conv_long_parameter - get long parameter string value */ 358 359 static const char *pcf_conv_long_parameter(void *ptr) 360 { 361 CONFIG_LONG_TABLE *clt = (CONFIG_LONG_TABLE *) ptr; 362 363 return (STR(vstring_sprintf(pcf_param_string_buf, "%ld", clt->defval))); 364 } 365 366 /* pcf_register_builtin_parameters - add built-ins to the global name space */ 367 368 void pcf_register_builtin_parameters(const char *procname, pid_t pid) 369 { 370 const char *myname = "pcf_register_builtin_parameters"; 371 const CONFIG_TIME_TABLE *ctt; 372 const CONFIG_BOOL_TABLE *cbt; 373 const CONFIG_INT_TABLE *cit; 374 const CONFIG_STR_TABLE *cst; 375 const CONFIG_STR_FN_TABLE *cft; 376 const CONFIG_RAW_TABLE *rst; 377 const CONFIG_NINT_TABLE *nst; 378 const CONFIG_NBOOL_TABLE *bst; 379 const CONFIG_LONG_TABLE *lst; 380 381 /* 382 * Sanity checks. 383 */ 384 if (pcf_param_table != 0) 385 msg_panic("%s: global parameter table is already initialized", myname); 386 387 /* 388 * Initialize the global parameter table. 389 */ 390 pcf_param_table = PCF_PARAM_TABLE_CREATE(1000); 391 392 /* 393 * Add the built-in parameters to the global name space. The class 394 * (built-in) is tentative; some parameters are actually service-defined, 395 * but they have their own default value. 396 */ 397 for (ctt = pcf_time_table; ctt->name; ctt++) 398 PCF_PARAM_TABLE_ENTER(pcf_param_table, ctt->name, 399 PCF_PARAM_FLAG_BUILTIN, (void *) ctt, 400 pcf_conv_time_parameter); 401 for (cbt = pcf_bool_table; cbt->name; cbt++) 402 PCF_PARAM_TABLE_ENTER(pcf_param_table, cbt->name, 403 PCF_PARAM_FLAG_BUILTIN, (void *) cbt, 404 pcf_conv_bool_parameter); 405 for (cit = pcf_int_table; cit->name; cit++) 406 PCF_PARAM_TABLE_ENTER(pcf_param_table, cit->name, 407 PCF_PARAM_FLAG_BUILTIN, (void *) cit, 408 pcf_conv_int_parameter); 409 for (cst = pcf_str_table; cst->name; cst++) 410 PCF_PARAM_TABLE_ENTER(pcf_param_table, cst->name, 411 PCF_PARAM_FLAG_BUILTIN, (void *) cst, 412 pcf_conv_str_parameter); 413 for (cft = pcf_str_fn_table; cft->name; cft++) 414 PCF_PARAM_TABLE_ENTER(pcf_param_table, cft->name, 415 PCF_PARAM_FLAG_BUILTIN, (void *) cft, 416 pcf_conv_str_fn_parameter); 417 for (rst = pcf_raw_table; rst->name; rst++) 418 PCF_PARAM_TABLE_ENTER(pcf_param_table, rst->name, 419 PCF_PARAM_FLAG_BUILTIN | PCF_PARAM_FLAG_RAW, 420 (void *) rst, pcf_conv_raw_parameter); 421 for (nst = pcf_nint_table; nst->name; nst++) 422 PCF_PARAM_TABLE_ENTER(pcf_param_table, nst->name, 423 PCF_PARAM_FLAG_BUILTIN, (void *) nst, 424 pcf_conv_nint_parameter); 425 for (bst = pcf_nbool_table; bst->name; bst++) 426 PCF_PARAM_TABLE_ENTER(pcf_param_table, bst->name, 427 PCF_PARAM_FLAG_BUILTIN, (void *) bst, 428 pcf_conv_nbool_parameter); 429 for (lst = pcf_long_table; lst->name; lst++) 430 PCF_PARAM_TABLE_ENTER(pcf_param_table, lst->name, 431 PCF_PARAM_FLAG_BUILTIN, (void *) lst, 432 pcf_conv_long_parameter); 433 434 /* 435 * Register legacy parameters (used as a backwards-compatible migration 436 * aid). 437 */ 438 for (cst = pcf_legacy_str_table; cst->name; cst++) 439 PCF_PARAM_TABLE_ENTER(pcf_param_table, cst->name, 440 PCF_PARAM_FLAG_LEGACY, (void *) cst, 441 pcf_conv_str_parameter); 442 443 /* 444 * Register parameters whose default value is normally initialized by 445 * ad-hoc code. 446 */ 447 pcf_adhoc_procname.defval = mystrdup(procname); 448 PCF_PARAM_TABLE_ENTER(pcf_param_table, pcf_adhoc_procname.name, 449 PCF_PARAM_FLAG_BUILTIN | PCF_PARAM_FLAG_READONLY, 450 (void *) &pcf_adhoc_procname, pcf_conv_str_parameter); 451 pcf_adhoc_servname.defval = mystrdup(""); 452 PCF_PARAM_TABLE_ENTER(pcf_param_table, pcf_adhoc_servname.name, 453 PCF_PARAM_FLAG_BUILTIN | PCF_PARAM_FLAG_READONLY, 454 (void *) &pcf_adhoc_servname, pcf_conv_str_parameter); 455 pcf_adhoc_pid.defval = pid; 456 PCF_PARAM_TABLE_ENTER(pcf_param_table, pcf_adhoc_pid.name, 457 PCF_PARAM_FLAG_BUILTIN | PCF_PARAM_FLAG_READONLY, 458 (void *) &pcf_adhoc_pid, pcf_conv_int_parameter); 459 } 460