xref: /netbsd-src/external/ibm-public/postfix/dist/src/postconf/postconf_builtin.c (revision 5dd36a3bc8bf2a9dec29ceb6349550414570c447)
1 /*	$NetBSD: postconf_builtin.c,v 1.2 2017/02/14 01:16:46 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_INT_TABLE pcf_adhoc_pid = {VAR_PID};
179 
180 #define STR(x) vstring_str(x)
181 
182 /* pcf_check_myhostname - lookup hostname and validate */
183 
184 static const char *pcf_check_myhostname(void)
185 {
186     static const char *name;
187     const char *dot;
188     const char *domain;
189 
190     /*
191      * Use cached result.
192      */
193     if (name)
194 	return (name);
195 
196     /*
197      * If the local machine name is not in FQDN form, try to append the
198      * contents of $mydomain.
199      */
200     name = get_hostname();
201     if ((dot = strchr(name, '.')) == 0) {
202 	if ((domain = mail_conf_lookup_eval(VAR_MYDOMAIN)) == 0)
203 	    domain = DEF_MYDOMAIN;
204 	name = concatenate(name, ".", domain, (char *) 0);
205     }
206     return (name);
207 }
208 
209 /* pcf_get_myhostname - look up and store my hostname */
210 
211 static void pcf_get_myhostname(void)
212 {
213     const char *name;
214 
215     if ((name = mail_conf_lookup_eval(VAR_MYHOSTNAME)) == 0)
216 	name = pcf_check_myhostname();
217     var_myhostname = mystrdup(name);
218 }
219 
220 /* pcf_check_mydomainname - lookup domain name and validate */
221 
222 static const char *pcf_check_mydomainname(void)
223 {
224     static const char *domain;
225     char   *dot;
226 
227     /*
228      * Use cached result.
229      */
230     if (domain)
231 	return (domain);
232 
233     /*
234      * Use a default domain when the hostname is not a FQDN ("foo").
235      */
236     if (var_myhostname == 0)
237 	pcf_get_myhostname();
238     if ((dot = strchr(var_myhostname, '.')) == 0)
239 	return (domain = DEF_MYDOMAIN);
240     return (domain = mystrdup(dot + 1));
241 }
242 
243 /* pcf_mynetworks - lookup network address list */
244 
245 static const char *pcf_mynetworks(void)
246 {
247     static const char *networks;
248     const char *junk;
249 
250     /*
251      * Use cached result.
252      */
253     if (networks)
254 	return (networks);
255 
256     if (var_inet_interfaces == 0) {
257 	if ((pcf_cmd_mode & PCF_SHOW_DEFS)
258 	    || (junk = mail_conf_lookup_eval(VAR_INET_INTERFACES)) == 0)
259 	    junk = pcf_expand_parameter_value((VSTRING *) 0, pcf_cmd_mode,
260 					      DEF_INET_INTERFACES,
261 					      (PCF_MASTER_ENT *) 0);
262 	var_inet_interfaces = mystrdup(junk);
263     }
264     if (var_mynetworks_style == 0) {
265 	if ((pcf_cmd_mode & PCF_SHOW_DEFS)
266 	    || (junk = mail_conf_lookup_eval(VAR_MYNETWORKS_STYLE)) == 0)
267 	    junk = pcf_expand_parameter_value((VSTRING *) 0, pcf_cmd_mode,
268 					      DEF_MYNETWORKS_STYLE,
269 					      (PCF_MASTER_ENT *) 0);
270 	var_mynetworks_style = mystrdup(junk);
271     }
272     if (var_inet_protocols == 0) {
273 	if ((pcf_cmd_mode & PCF_SHOW_DEFS)
274 	    || (junk = mail_conf_lookup_eval(VAR_INET_PROTOCOLS)) == 0)
275 	    junk = pcf_expand_parameter_value((VSTRING *) 0, pcf_cmd_mode,
276 					      DEF_INET_PROTOCOLS,
277 					      (PCF_MASTER_ENT *) 0);
278 	var_inet_protocols = mystrdup(junk);
279 	(void) inet_proto_init(VAR_INET_PROTOCOLS, var_inet_protocols);
280     }
281     return (networks = mystrdup(mynetworks()));
282 }
283 
284 /* pcf_conv_bool_parameter - get boolean parameter string value */
285 
286 static const char *pcf_conv_bool_parameter(void *ptr)
287 {
288     CONFIG_BOOL_TABLE *cbt = (CONFIG_BOOL_TABLE *) ptr;
289 
290     return (cbt->defval ? "yes" : "no");
291 }
292 
293 /* pcf_conv_time_parameter - get relative time parameter string value */
294 
295 static const char *pcf_conv_time_parameter(void *ptr)
296 {
297     CONFIG_TIME_TABLE *ctt = (CONFIG_TIME_TABLE *) ptr;
298 
299     return (ctt->defval);
300 }
301 
302 /* pcf_conv_int_parameter - get integer parameter string value */
303 
304 static const char *pcf_conv_int_parameter(void *ptr)
305 {
306     CONFIG_INT_TABLE *cit = (CONFIG_INT_TABLE *) ptr;
307 
308     return (STR(vstring_sprintf(pcf_param_string_buf, "%d", cit->defval)));
309 }
310 
311 /* pcf_conv_str_parameter - get string parameter string value */
312 
313 static const char *pcf_conv_str_parameter(void *ptr)
314 {
315     CONFIG_STR_TABLE *cst = (CONFIG_STR_TABLE *) ptr;
316 
317     return (cst->defval);
318 }
319 
320 /* pcf_conv_str_fn_parameter - get string-function parameter string value */
321 
322 static const char *pcf_conv_str_fn_parameter(void *ptr)
323 {
324     CONFIG_STR_FN_TABLE *cft = (CONFIG_STR_FN_TABLE *) ptr;
325 
326     return (cft->defval());
327 }
328 
329 /* pcf_conv_raw_parameter - get raw string parameter string value */
330 
331 static const char *pcf_conv_raw_parameter(void *ptr)
332 {
333     CONFIG_RAW_TABLE *rst = (CONFIG_RAW_TABLE *) ptr;
334 
335     return (rst->defval);
336 }
337 
338 /* pcf_conv_nint_parameter - get new integer parameter string value */
339 
340 static const char *pcf_conv_nint_parameter(void *ptr)
341 {
342     CONFIG_NINT_TABLE *rst = (CONFIG_NINT_TABLE *) ptr;
343 
344     return (rst->defval);
345 }
346 
347 /* pcf_conv_nbool_parameter - get new boolean parameter string value */
348 
349 static const char *pcf_conv_nbool_parameter(void *ptr)
350 {
351     CONFIG_NBOOL_TABLE *bst = (CONFIG_NBOOL_TABLE *) ptr;
352 
353     return (bst->defval);
354 }
355 
356 /* pcf_conv_long_parameter - get long parameter string value */
357 
358 static const char *pcf_conv_long_parameter(void *ptr)
359 {
360     CONFIG_LONG_TABLE *clt = (CONFIG_LONG_TABLE *) ptr;
361 
362     return (STR(vstring_sprintf(pcf_param_string_buf, "%ld", clt->defval)));
363 }
364 
365 /* pcf_register_builtin_parameters - add built-ins to the global name space */
366 
367 void    pcf_register_builtin_parameters(const char *procname, pid_t pid)
368 {
369     const char *myname = "pcf_register_builtin_parameters";
370     const CONFIG_TIME_TABLE *ctt;
371     const CONFIG_BOOL_TABLE *cbt;
372     const CONFIG_INT_TABLE *cit;
373     const CONFIG_STR_TABLE *cst;
374     const CONFIG_STR_FN_TABLE *cft;
375     const CONFIG_RAW_TABLE *rst;
376     const CONFIG_NINT_TABLE *nst;
377     const CONFIG_NBOOL_TABLE *bst;
378     const CONFIG_LONG_TABLE *lst;
379 
380     /*
381      * Sanity checks.
382      */
383     if (pcf_param_table != 0)
384 	msg_panic("%s: global parameter table is already initialized", myname);
385 
386     /*
387      * Initialize the global parameter table.
388      */
389     pcf_param_table = PCF_PARAM_TABLE_CREATE(1000);
390 
391     /*
392      * Add the built-in parameters to the global name space. The class
393      * (built-in) is tentative; some parameters are actually service-defined,
394      * but they have their own default value.
395      */
396     for (ctt = pcf_time_table; ctt->name; ctt++)
397 	PCF_PARAM_TABLE_ENTER(pcf_param_table, ctt->name,
398 			      PCF_PARAM_FLAG_BUILTIN, (void *) ctt,
399 			      pcf_conv_time_parameter);
400     for (cbt = pcf_bool_table; cbt->name; cbt++)
401 	PCF_PARAM_TABLE_ENTER(pcf_param_table, cbt->name,
402 			      PCF_PARAM_FLAG_BUILTIN, (void *) cbt,
403 			      pcf_conv_bool_parameter);
404     for (cit = pcf_int_table; cit->name; cit++)
405 	PCF_PARAM_TABLE_ENTER(pcf_param_table, cit->name,
406 			      PCF_PARAM_FLAG_BUILTIN, (void *) cit,
407 			      pcf_conv_int_parameter);
408     for (cst = pcf_str_table; cst->name; cst++)
409 	PCF_PARAM_TABLE_ENTER(pcf_param_table, cst->name,
410 			      PCF_PARAM_FLAG_BUILTIN, (void *) cst,
411 			      pcf_conv_str_parameter);
412     for (cft = pcf_str_fn_table; cft->name; cft++)
413 	PCF_PARAM_TABLE_ENTER(pcf_param_table, cft->name,
414 			      PCF_PARAM_FLAG_BUILTIN, (void *) cft,
415 			      pcf_conv_str_fn_parameter);
416     for (rst = pcf_raw_table; rst->name; rst++)
417 	PCF_PARAM_TABLE_ENTER(pcf_param_table, rst->name,
418 			      PCF_PARAM_FLAG_BUILTIN | PCF_PARAM_FLAG_RAW,
419 			      (void *) rst, pcf_conv_raw_parameter);
420     for (nst = pcf_nint_table; nst->name; nst++)
421 	PCF_PARAM_TABLE_ENTER(pcf_param_table, nst->name,
422 			      PCF_PARAM_FLAG_BUILTIN, (void *) nst,
423 			      pcf_conv_nint_parameter);
424     for (bst = pcf_nbool_table; bst->name; bst++)
425 	PCF_PARAM_TABLE_ENTER(pcf_param_table, bst->name,
426 			      PCF_PARAM_FLAG_BUILTIN, (void *) bst,
427 			      pcf_conv_nbool_parameter);
428     for (lst = pcf_long_table; lst->name; lst++)
429 	PCF_PARAM_TABLE_ENTER(pcf_param_table, lst->name,
430 			      PCF_PARAM_FLAG_BUILTIN, (void *) lst,
431 			      pcf_conv_long_parameter);
432 
433     /*
434      * Register legacy parameters (used as a backwards-compatible migration
435      * aid).
436      */
437     for (cst = pcf_legacy_str_table; cst->name; cst++)
438 	PCF_PARAM_TABLE_ENTER(pcf_param_table, cst->name,
439 			      PCF_PARAM_FLAG_LEGACY, (void *) cst,
440 			      pcf_conv_str_parameter);
441 
442     /*
443      * Register parameters whose default value is normally initialized by
444      * ad-hoc code.
445      */
446     pcf_adhoc_procname.defval = mystrdup(procname);
447     PCF_PARAM_TABLE_ENTER(pcf_param_table, pcf_adhoc_procname.name,
448 			  PCF_PARAM_FLAG_BUILTIN | PCF_PARAM_FLAG_READONLY,
449 		      (void *) &pcf_adhoc_procname, pcf_conv_str_parameter);
450     pcf_adhoc_pid.defval = pid;
451     PCF_PARAM_TABLE_ENTER(pcf_param_table, pcf_adhoc_pid.name,
452 			  PCF_PARAM_FLAG_BUILTIN | PCF_PARAM_FLAG_READONLY,
453 			  (void *) &pcf_adhoc_pid, pcf_conv_int_parameter);
454 }
455