1/*	$NetBSD: postconf.h,v 1.4 2023/12/23 20:30:44 christos Exp $	*/
2
3/*++
4/* NAME
5/*	postconf 3h
6/* SUMMARY
7/*	module interfaces
8/* SYNOPSIS
9/*	#include <postconf.h>
10/* DESCRIPTION
11/* .nf
12
13 /*
14  * System library.
15  */
16#include <unistd.h>
17
18 /*
19  * Utility library.
20  */
21#include <htable.h>
22#include <argv.h>
23#include <dict.h>
24#include <name_code.h>
25
26 /*
27  * What we're supposed to be doing.
28  */
29#define PCF_SHOW_NONDEF		(1<<0)	/* show main.cf non-default settings */
30#define PCF_SHOW_DEFS		(1<<1)	/* show main.cf default setting */
31#define PCF_HIDE_NAME		(1<<2)	/* hide main.cf parameter name */
32#define PCF_SHOW_MAPS		(1<<3)	/* show map types */
33#define PCF_EDIT_CONF		(1<<4)	/* edit main.cf or master.cf */
34#define PCF_SHOW_LOCKS		(1<<5)	/* show mailbox lock methods */
35#define PCF_SHOW_EVAL		(1<<6)	/* expand main.cf right-hand sides */
36#define PCF_SHOW_SASL_SERV	(1<<7)	/* show server auth plugin types */
37#define PCF_SHOW_SASL_CLNT	(1<<8)	/* show client auth plugin types */
38#define PCF_COMMENT_OUT		(1<<9)	/* #-out selected main.cf entries */
39#define PCF_MASTER_ENTRY	(1<<10)	/* manage master.cf entries */
40#define PCF_FOLD_LINE		(1<<11)	/* fold long *.cf entries */
41#define PCF_EDIT_EXCL		(1<<12)	/* exclude main.cf entries */
42#define PCF_MASTER_FLD		(1<<13)	/* hierarchical pathname */
43#define PCF_MAIN_PARAM		(1<<14)	/* manage main.cf entries */
44#define PCF_EXP_DSN_TEMPL	(1<<15)	/* expand bounce templates */
45#define PCF_PARAM_CLASS		(1<<16)	/* select parameter class */
46#define PCF_MAIN_OVER		(1<<17)	/* override parameter values */
47#define PCF_DUMP_DSN_TEMPL	(1<<18)	/* show bounce templates */
48#define PCF_MASTER_PARAM	(1<<19)	/* manage master.cf -o name=value */
49#define PCF_HIDE_VALUE		(1<<20)	/* hide main.cf/master.cf =value */
50#define PCF_SHOW_TLS		(1<<21)	/* TLS support introspection */
51
52#define PCF_DEF_MODE	0
53
54 /*
55  * Structure for one "valid parameter" (built-in, service-defined or valid
56  * user-defined). See the postconf_builtin, postconf_service and
57  * postconf_user modules for narrative text.
58  */
59typedef struct {
60    int     flags;			/* see below */
61    void   *param_data;			/* mostly, the default value */
62    const char *(*convert_fn) (void *);	/* value to string */
63} PCF_PARAM_NODE;
64
65 /* Values for flags. See the postconf_node module for narrative text. */
66#define PCF_PARAM_FLAG_RAW	(1<<0)	/* raw parameter value */
67#define PCF_PARAM_FLAG_BUILTIN	(1<<1)	/* built-in parameter name */
68#define PCF_PARAM_FLAG_SERVICE	(1<<2)	/* service-defined parameter name */
69#define PCF_PARAM_FLAG_USER	(1<<3)	/* user-defined parameter name */
70#define PCF_PARAM_FLAG_LEGACY	(1<<4)	/* legacy parameter name */
71#define PCF_PARAM_FLAG_READONLY	(1<<5)	/* legacy parameter name */
72#define PCF_PARAM_FLAG_DBMS	(1<<6)	/* dbms-defined parameter name */
73
74#define PCF_PARAM_MASK_CLASS \
75	(PCF_PARAM_FLAG_BUILTIN | PCF_PARAM_FLAG_SERVICE | PCF_PARAM_FLAG_USER)
76#define PCF_PARAM_CLASS_OVERRIDE(node, class) \
77	((node)->flags = (((node)->flags & ~PCF_PARAM_MASK_CLASS) | (class)))
78
79#define PCF_RAW_PARAMETER(node) ((node)->flags & PCF_PARAM_FLAG_RAW)
80#define PCF_BUILTIN_PARAMETER(node) ((node)->flags & PCF_PARAM_FLAG_BUILTIN)
81#define PCF_SERVICE_PARAMETER(node) ((node)->flags & PCF_PARAM_FLAG_SERVICE)
82#define PCF_USER_PARAMETER(node) ((node)->flags & PCF_PARAM_FLAG_USER)
83#define PCF_LEGACY_PARAMETER(node) ((node)->flags & PCF_PARAM_FLAG_LEGACY)
84#define PCF_READONLY_PARAMETER(node) ((node)->flags & PCF_PARAM_FLAG_READONLY)
85#define PCF_DBMS_PARAMETER(node) ((node)->flags & PCF_PARAM_FLAG_DBMS)
86
87 /* Values for param_data. See postconf_node module for narrative text. */
88#define PCF_PARAM_NO_DATA	((char *) 0)
89
90 /*
91  * Lookup table for global "valid parameter" information.
92  */
93#define PCF_PARAM_TABLE			HTABLE
94#define PCF_PARAM_INFO			HTABLE_INFO
95
96extern PCF_PARAM_TABLE *pcf_param_table;
97
98 /*
99  * postconf_node.c.
100  */
101#define PCF_PARAM_TABLE_CREATE(size)	htable_create(size);
102#define PCF_PARAM_NODE_CAST(ptr)	((PCF_PARAM_NODE *) (ptr))
103
104#define PCF_PARAM_TABLE_LIST(table)	htable_list(table)
105#define PCF_PARAM_INFO_NAME(ht)		((const char *) (ht)->key)
106#define PCF_PARAM_INFO_NODE(ht)		PCF_PARAM_NODE_CAST((ht)->value)
107
108#define PCF_PARAM_TABLE_FIND(table, name) \
109	PCF_PARAM_NODE_CAST(htable_find((table), (name)))
110#define PCF_PARAM_TABLE_LOCATE(table, name) htable_locate((table), (name))
111#define PCF_PARAM_TABLE_ENTER(table, name, flags, data, func) \
112	htable_enter((table), (name), (char *) pcf_make_param_node((flags), \
113	    (data), (func)))
114
115extern PCF_PARAM_NODE *pcf_make_param_node(int, void *, const char *(*) (void *));
116extern const char *pcf_convert_param_node(int, const char *, PCF_PARAM_NODE *);
117extern VSTRING *pcf_param_string_buf;
118
119 /*
120  * Structure of one master.cf entry.
121  */
122typedef struct {
123    char   *name_space;			/* service/type, parameter name space */
124    ARGV   *argv;			/* null, or master.cf fields */
125    DICT   *all_params;			/* null, or all name=value entries */
126    DICT   *ro_params;			/* read-only name=value entries */
127    HTABLE *valid_names;		/* null, or "valid" parameter names */
128} PCF_MASTER_ENT;
129
130#define PCF_MASTER_MIN_FIELDS	8	/* mandatory field minimum */
131
132#define PCF_MASTER_NAME_SERVICE	"service"
133#define PCF_MASTER_NAME_TYPE	"type"
134#define PCF_MASTER_NAME_PRIVATE	"private"
135#define PCF_MASTER_NAME_UNPRIV	"unprivileged"
136#define PCF_MASTER_NAME_CHROOT	"chroot"
137#define PCF_MASTER_NAME_WAKEUP	"wakeup"
138#define PCF_MASTER_NAME_MAXPROC	"process_limit"
139#define PCF_MASTER_NAME_CMD	"command"
140
141#define PCF_MASTER_FLD_SERVICE	0	/* service name */
142#define PCF_MASTER_FLD_TYPE	1	/* service type */
143#define PCF_MASTER_FLD_PRIVATE	2	/* private service */
144#define PCF_MASTER_FLD_UNPRIV	3	/* unprivileged service */
145#define PCF_MASTER_FLD_CHROOT	4	/* chrooted service */
146#define PCF_MASTER_FLD_WAKEUP	5	/* wakeup timer */
147#define PCF_MASTER_FLD_MAXPROC	6	/* process limit */
148#define PCF_MASTER_FLD_CMD	7	/* command */
149
150#define PCF_MASTER_FLD_WILDC	-1	/* wild-card */
151#define PCF_MASTER_FLD_NONE	-2	/* not available */
152
153 /*
154  * Lookup table for master.cf entries. The table is terminated with an entry
155  * that has a null argv member.
156  */
157extern PCF_MASTER_ENT *pcf_master_table;
158
159 /*
160  * Line-wrapping support.
161  */
162#define PCF_LINE_LIMIT	80		/* try to fold longer lines */
163#define PCF_SEPARATORS	" \t\r\n"
164#define PCF_INDENT_LEN	4		/* indent long text by 4 */
165#define PCF_INDENT_TEXT	"    "
166
167 /*
168  * XXX Global so that postconf_builtin.c call-backs can see it.
169  */
170extern int pcf_cmd_mode;
171
172 /*
173  * postconf_misc.c.
174  */
175extern void pcf_set_config_dir(void);
176extern const char *pcf_get_main_path(void);
177extern const char *pcf_get_master_path(void);
178
179 /*
180  * postconf_main.c
181  */
182extern void pcf_read_parameters(void);
183extern void pcf_set_parameters(char **);
184extern void pcf_show_parameters(VSTREAM *, int, int, char **);
185
186 /*
187  * postconf_edit.c
188  */
189extern void pcf_edit_main(int, int, char **);
190extern void pcf_edit_master(int, int, char **);
191
192 /*
193  * postconf_master.c.
194  */
195extern const char pcf_daemon_options_expecting_value[];
196extern void pcf_read_master(int);
197extern void pcf_show_master_entries(VSTREAM *, int, int, char **);
198extern const char *pcf_parse_master_entry(PCF_MASTER_ENT *, const char *);
199extern void pcf_print_master_entry(VSTREAM *, int, PCF_MASTER_ENT *);
200extern void pcf_free_master_entry(PCF_MASTER_ENT *);
201extern void pcf_show_master_fields(VSTREAM *, int, int, char **);
202extern void pcf_edit_master_field(PCF_MASTER_ENT *, int, const char *);
203extern void pcf_show_master_params(VSTREAM *, int, int, char **);
204extern void pcf_edit_master_param(PCF_MASTER_ENT *, int, const char *, const char *);
205
206#define PCF_WARN_ON_OPEN_ERROR	0
207#define PCF_FAIL_ON_OPEN_ERROR	1
208
209#define PCF_MASTER_BLANKS	" \t\r\n"	/* XXX */
210
211 /*
212  * Master.cf parameter namespace management. The idea is to manage master.cf
213  * "-o name=value" settings with other tools than text editors.
214  *
215  * The natural choice is to use "service-name.service-type.parameter-name", but
216  * unfortunately the '.' may appear in service and parameter names.
217  *
218  * For example, a spawn(8) listener can have a service name 127.0.0.1:10028.
219  * This service name becomes part of a service-dependent parameter name
220  * "127.0.0.1:10028_time_limit". All those '.' characters mean we can't use
221  * '.' as the parameter namespace delimiter.
222  *
223  * (We could require that such service names are specified as $foo:port with
224  * the value of "foo" defined in main.cf or at the top of master.cf.)
225  *
226  * But it is easier if we use '/' instead.
227  */
228#define PCF_NAMESP_SEP_CH	'/'
229#define PCF_NAMESP_SEP_STR	"/"
230
231#define PCF_LEGACY_SEP_CH	'.'
232
233 /*
234  * postconf_match.c.
235  */
236#define PCF_MATCH_WILDC_STR	"*"
237#define PCF_MATCH_ANY(p)		((p)[0] == PCF_MATCH_WILDC_STR[0] && (p)[1] == 0)
238#define PCF_MATCH_STRING(p, s)	(PCF_MATCH_ANY(p) || strcmp((p), (s)) == 0)
239
240extern ARGV *pcf_parse_service_pattern(const char *, int, int);
241extern int pcf_parse_field_pattern(const char *);
242
243#define PCF_IS_MAGIC_SERVICE_PATTERN(pat) \
244    (PCF_MATCH_ANY((pat)->argv[0]) || PCF_MATCH_ANY((pat)->argv[1]))
245#define PCF_MATCH_SERVICE_PATTERN(pat, name, type) \
246    (PCF_MATCH_STRING((pat)->argv[0], (name)) \
247	&& PCF_MATCH_STRING((pat)->argv[1], (type)))
248
249#define pcf_is_magic_field_pattern(pat) ((pat) == PCF_MASTER_FLD_WILDC)
250#define pcf_str_field_pattern(pat) ((const char *) (pcf_field_name_offset[pat].name))
251
252#define PCF_IS_MAGIC_PARAM_PATTERN(pat) PCF_MATCH_ANY(pat)
253#define PCF_MATCH_PARAM_PATTERN(pat, name) PCF_MATCH_STRING((pat), (name))
254
255/* The following is not part of the postconf_match API. */
256extern NAME_CODE pcf_field_name_offset[];
257
258 /*
259  * postconf_builtin.c.
260  */
261extern void pcf_register_builtin_parameters(const char *, pid_t);
262
263 /*
264  * postconf_service.c.
265  */
266extern void pcf_register_service_parameters(void);
267
268 /*
269  * Parameter context structure.
270  */
271typedef struct {
272    PCF_MASTER_ENT *local_scope;
273    int     param_class;
274} PCF_PARAM_CTX;
275
276 /*
277  * postconf_user.c.
278  */
279extern void pcf_register_user_parameters(void);
280
281 /*
282  * postconf_dbms.c
283  */
284extern void pcf_register_dbms_parameters(const char *,
285	              const char *(*) (const char *, int, PCF_MASTER_ENT *),
286					         PCF_MASTER_ENT *);
287
288 /*
289  * postconf_lookup.c.
290  */
291extern const char *pcf_lookup_parameter_value(int, const char *,
292					              PCF_MASTER_ENT *,
293					              PCF_PARAM_NODE *);
294
295extern char *pcf_expand_parameter_value(VSTRING *, int, const char *,
296					        PCF_MASTER_ENT *);
297
298 /*
299  * postconf_print.c.
300  */
301extern void PRINTFLIKE(3, 4) pcf_print_line(VSTREAM *, int, const char *,...);
302
303 /*
304  * postconf_unused.c.
305  */
306extern void pcf_flag_unused_main_parameters(void);
307extern void pcf_flag_unused_master_parameters(void);
308
309 /*
310  * postconf_other.c.
311  */
312extern void pcf_show_maps(void);
313extern void pcf_show_locks(void);
314extern void pcf_show_sasl(int);
315extern void pcf_show_tls(const char *);
316
317/* LICENSE
318/* .ad
319/* .fi
320/*	The Secure Mailer license must be distributed with this software.
321/* AUTHOR(S)
322/*	Wietse Venema
323/*	IBM T.J. Watson Research
324/*	P.O. Box 704
325/*	Yorktown Heights, NY 10598, USA
326/*
327/*	Wietse Venema
328/*	Google, Inc.
329/*	111 8th Avenue
330/*	New York, NY 10011, USA
331/*--*/
332