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 */
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 {"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 */
166 static const char *pcf_check_myhostname(void);
167 static const char *pcf_check_mydomainname(void);
168 static const char *pcf_mynetworks(void);
169
170 #include "str_fn_vars.h"
171
172 static 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 */
185 static CONFIG_STR_TABLE pcf_adhoc_procname = {VAR_PROCNAME};
186 static CONFIG_STR_TABLE pcf_adhoc_servname = {VAR_SERVNAME};
187 static 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
pcf_check_myhostname(void)193 static 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
pcf_get_myhostname(void)220 static 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
pcf_check_mydomainname(void)231 static 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
pcf_mynetworks(void)254 static 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
pcf_conv_bool_parameter(void * ptr)299 static 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
pcf_conv_time_parameter(void * ptr)308 static 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
pcf_conv_int_parameter(void * ptr)317 static 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
pcf_conv_str_parameter(void * ptr)326 static 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
pcf_conv_str_fn_parameter(void * ptr)335 static 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
pcf_conv_raw_parameter(void * ptr)344 static 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
pcf_conv_nint_parameter(void * ptr)353 static 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
pcf_conv_nbool_parameter(void * ptr)362 static 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
pcf_conv_long_parameter(void * ptr)371 static 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
pcf_register_builtin_parameters(const char * procname,pid_t pid)380 void 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