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