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