summaryrefslogtreecommitdiffstats
path: root/src/postconf/postconf.h
blob: 24a1ed782fe941a1be9e44cfb8ccd4ed53736983 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
/*++
/* NAME
/*	postconf 3h
/* SUMMARY
/*	module interfaces
/* SYNOPSIS
/*	#include <postconf.h>
/* DESCRIPTION
/* .nf

 /*
  * System library.
  */
#include <unistd.h>

 /*
  * Utility library.
  */
#include <htable.h>
#include <argv.h>
#include <dict.h>
#include <name_code.h>

 /*
  * What we're supposed to be doing.
  */
#define PCF_SHOW_NONDEF		(1<<0)	/* show main.cf non-default settings */
#define PCF_SHOW_DEFS		(1<<1)	/* show main.cf default setting */
#define PCF_HIDE_NAME		(1<<2)	/* hide main.cf parameter name */
#define PCF_SHOW_MAPS		(1<<3)	/* show map types */
#define PCF_EDIT_CONF		(1<<4)	/* edit main.cf or master.cf */
#define PCF_SHOW_LOCKS		(1<<5)	/* show mailbox lock methods */
#define PCF_SHOW_EVAL		(1<<6)	/* expand main.cf right-hand sides */
#define PCF_SHOW_SASL_SERV	(1<<7)	/* show server auth plugin types */
#define PCF_SHOW_SASL_CLNT	(1<<8)	/* show client auth plugin types */
#define PCF_COMMENT_OUT		(1<<9)	/* #-out selected main.cf entries */
#define PCF_MASTER_ENTRY	(1<<10)	/* manage master.cf entries */
#define PCF_FOLD_LINE		(1<<11)	/* fold long *.cf entries */
#define PCF_EDIT_EXCL		(1<<12)	/* exclude main.cf entries */
#define PCF_MASTER_FLD		(1<<13)	/* hierarchical pathname */
#define PCF_MAIN_PARAM		(1<<14)	/* manage main.cf entries */
#define PCF_EXP_DSN_TEMPL	(1<<15)	/* expand bounce templates */
#define PCF_PARAM_CLASS		(1<<16)	/* select parameter class */
#define PCF_MAIN_OVER		(1<<17)	/* override parameter values */
#define PCF_DUMP_DSN_TEMPL	(1<<18)	/* show bounce templates */
#define PCF_MASTER_PARAM	(1<<19)	/* manage master.cf -o name=value */
#define PCF_HIDE_VALUE		(1<<20)	/* hide main.cf/master.cf =value */
#define PCF_SHOW_TLS		(1<<21)	/* TLS support introspection */

#define PCF_DEF_MODE	0

 /*
  * Structure for one "valid parameter" (built-in, service-defined or valid
  * user-defined). See the postconf_builtin, postconf_service and
  * postconf_user modules for narrative text.
  */
typedef struct {
    int     flags;			/* see below */
    void   *param_data;			/* mostly, the default value */
    const char *(*convert_fn) (void *);	/* value to string */
} PCF_PARAM_NODE;

 /* Values for flags. See the postconf_node module for narrative text. */
#define PCF_PARAM_FLAG_RAW	(1<<0)	/* raw parameter value */
#define PCF_PARAM_FLAG_BUILTIN	(1<<1)	/* built-in parameter name */
#define PCF_PARAM_FLAG_SERVICE	(1<<2)	/* service-defined parameter name */
#define PCF_PARAM_FLAG_USER	(1<<3)	/* user-defined parameter name */
#define PCF_PARAM_FLAG_LEGACY	(1<<4)	/* legacy parameter name */
#define PCF_PARAM_FLAG_READONLY	(1<<5)	/* legacy parameter name */
#define PCF_PARAM_FLAG_DBMS	(1<<6)	/* dbms-defined parameter name */

#define PCF_PARAM_MASK_CLASS \
	(PCF_PARAM_FLAG_BUILTIN | PCF_PARAM_FLAG_SERVICE | PCF_PARAM_FLAG_USER)
#define PCF_PARAM_CLASS_OVERRIDE(node, class) \
	((node)->flags = (((node)->flags & ~PCF_PARAM_MASK_CLASS) | (class)))

#define PCF_RAW_PARAMETER(node) ((node)->flags & PCF_PARAM_FLAG_RAW)
#define PCF_BUILTIN_PARAMETER(node) ((node)->flags & PCF_PARAM_FLAG_BUILTIN)
#define PCF_SERVICE_PARAMETER(node) ((node)->flags & PCF_PARAM_FLAG_SERVICE)
#define PCF_USER_PARAMETER(node) ((node)->flags & PCF_PARAM_FLAG_USER)
#define PCF_LEGACY_PARAMETER(node) ((node)->flags & PCF_PARAM_FLAG_LEGACY)
#define PCF_READONLY_PARAMETER(node) ((node)->flags & PCF_PARAM_FLAG_READONLY)
#define PCF_DBMS_PARAMETER(node) ((node)->flags & PCF_PARAM_FLAG_DBMS)

 /* Values for param_data. See postconf_node module for narrative text. */
#define PCF_PARAM_NO_DATA	((char *) 0)

 /*
  * Lookup table for global "valid parameter" information.
  */
#define PCF_PARAM_TABLE			HTABLE
#define PCF_PARAM_INFO			HTABLE_INFO

extern PCF_PARAM_TABLE *pcf_param_table;

 /*
  * postconf_node.c.
  */
#define PCF_PARAM_TABLE_CREATE(size)	htable_create(size);
#define PCF_PARAM_NODE_CAST(ptr)	((PCF_PARAM_NODE *) (ptr))

#define PCF_PARAM_TABLE_LIST(table)	htable_list(table)
#define PCF_PARAM_INFO_NAME(ht)		((const char *) (ht)->key)
#define PCF_PARAM_INFO_NODE(ht)		PCF_PARAM_NODE_CAST((ht)->value)

#define PCF_PARAM_TABLE_FIND(table, name) \
	PCF_PARAM_NODE_CAST(htable_find((table), (name)))
#define PCF_PARAM_TABLE_LOCATE(table, name) htable_locate((table), (name))
#define PCF_PARAM_TABLE_ENTER(table, name, flags, data, func) \
	htable_enter((table), (name), (char *) pcf_make_param_node((flags), \
	    (data), (func)))

extern PCF_PARAM_NODE *pcf_make_param_node(int, void *, const char *(*) (void *));
extern const char *pcf_convert_param_node(int, const char *, PCF_PARAM_NODE *);
extern VSTRING *pcf_param_string_buf;

 /*
  * Structure of one master.cf entry.
  */
typedef struct {
    char   *name_space;			/* service/type, parameter name space */
    ARGV   *argv;			/* null, or master.cf fields */
    DICT   *all_params;			/* null, or all name=value entries */
    DICT   *ro_params;			/* read-only name=value entries */
    HTABLE *valid_names;		/* null, or "valid" parameter names */
} PCF_MASTER_ENT;

#define PCF_MASTER_MIN_FIELDS	8	/* mandatory field minimum */

#define PCF_MASTER_NAME_SERVICE	"service"
#define PCF_MASTER_NAME_TYPE	"type"
#define PCF_MASTER_NAME_PRIVATE	"private"
#define PCF_MASTER_NAME_UNPRIV	"unprivileged"
#define PCF_MASTER_NAME_CHROOT	"chroot"
#define PCF_MASTER_NAME_WAKEUP	"wakeup"
#define PCF_MASTER_NAME_MAXPROC	"process_limit"
#define PCF_MASTER_NAME_CMD	"command"

#define PCF_MASTER_FLD_SERVICE	0	/* service name */
#define PCF_MASTER_FLD_TYPE	1	/* service type */
#define PCF_MASTER_FLD_PRIVATE	2	/* private service */
#define PCF_MASTER_FLD_UNPRIV	3	/* unprivileged service */
#define PCF_MASTER_FLD_CHROOT	4	/* chrooted service */
#define PCF_MASTER_FLD_WAKEUP	5	/* wakeup timer */
#define PCF_MASTER_FLD_MAXPROC	6	/* process limit */
#define PCF_MASTER_FLD_CMD	7	/* command */

#define PCF_MASTER_FLD_WILDC	-1	/* wild-card */
#define PCF_MASTER_FLD_NONE	-2	/* not available */

 /*
  * Lookup table for master.cf entries. The table is terminated with an entry
  * that has a null argv member.
  */
extern PCF_MASTER_ENT *pcf_master_table;

 /*
  * Line-wrapping support.
  */
#define PCF_LINE_LIMIT	80		/* try to fold longer lines */
#define PCF_SEPARATORS	" \t\r\n"
#define PCF_INDENT_LEN	4		/* indent long text by 4 */
#define PCF_INDENT_TEXT	"    "

 /*
  * XXX Global so that postconf_builtin.c call-backs can see it.
  */
extern int pcf_cmd_mode;

 /*
  * postconf_misc.c.
  */
extern void pcf_set_config_dir(void);
extern const char *pcf_get_main_path(void);
extern const char *pcf_get_master_path(void);

 /*
  * postconf_main.c
  */
extern void pcf_read_parameters(void);
extern void pcf_set_parameters(char **);
extern void pcf_show_parameters(VSTREAM *, int, int, char **);

 /*
  * postconf_edit.c
  */
extern void pcf_edit_main(int, int, char **);
extern void pcf_edit_master(int, int, char **);

 /*
  * postconf_master.c.
  */
extern const char pcf_daemon_options_expecting_value[];
extern void pcf_read_master(int);
extern void pcf_show_master_entries(VSTREAM *, int, int, char **);
extern const char *pcf_parse_master_entry(PCF_MASTER_ENT *, const char *);
extern void pcf_print_master_entry(VSTREAM *, int, PCF_MASTER_ENT *);
extern void pcf_free_master_entry(PCF_MASTER_ENT *);
extern void pcf_show_master_fields(VSTREAM *, int, int, char **);
extern void pcf_edit_master_field(PCF_MASTER_ENT *, int, const char *);
extern void pcf_show_master_params(VSTREAM *, int, int, char **);
extern void pcf_edit_master_param(PCF_MASTER_ENT *, int, const char *, const char *);

#define PCF_WARN_ON_OPEN_ERROR	0
#define PCF_FAIL_ON_OPEN_ERROR	1

#define PCF_MASTER_BLANKS	" \t\r\n"	/* XXX */

 /*
  * Master.cf parameter namespace management. The idea is to manage master.cf
  * "-o name=value" settings with other tools than text editors.
  * 
  * The natural choice is to use "service-name.service-type.parameter-name", but
  * unfortunately the '.' may appear in service and parameter names.
  * 
  * For example, a spawn(8) listener can have a service name 127.0.0.1:10028.
  * This service name becomes part of a service-dependent parameter name
  * "127.0.0.1:10028_time_limit". All those '.' characters mean we can't use
  * '.' as the parameter namespace delimiter.
  * 
  * (We could require that such service names are specified as $foo:port with
  * the value of "foo" defined in main.cf or at the top of master.cf.)
  * 
  * But it is easier if we use '/' instead.
  */
#define PCF_NAMESP_SEP_CH	'/'
#define PCF_NAMESP_SEP_STR	"/"

#define PCF_LEGACY_SEP_CH	'.'

 /*
  * postconf_match.c.
  */
#define PCF_MATCH_WILDC_STR	"*"
#define PCF_MATCH_ANY(p)		((p)[0] == PCF_MATCH_WILDC_STR[0] && (p)[1] == 0)
#define PCF_MATCH_STRING(p, s)	(PCF_MATCH_ANY(p) || strcmp((p), (s)) == 0)

extern ARGV *pcf_parse_service_pattern(const char *, int, int);
extern int pcf_parse_field_pattern(const char *);

#define PCF_IS_MAGIC_SERVICE_PATTERN(pat) \
    (PCF_MATCH_ANY((pat)->argv[0]) || PCF_MATCH_ANY((pat)->argv[1]))
#define PCF_MATCH_SERVICE_PATTERN(pat, name, type) \
    (PCF_MATCH_STRING((pat)->argv[0], (name)) \
	&& PCF_MATCH_STRING((pat)->argv[1], (type)))

#define pcf_is_magic_field_pattern(pat) ((pat) == PCF_MASTER_FLD_WILDC)
#define pcf_str_field_pattern(pat) ((const char *) (pcf_field_name_offset[pat].name))

#define PCF_IS_MAGIC_PARAM_PATTERN(pat) PCF_MATCH_ANY(pat)
#define PCF_MATCH_PARAM_PATTERN(pat, name) PCF_MATCH_STRING((pat), (name))

/* The following is not part of the postconf_match API. */
extern NAME_CODE pcf_field_name_offset[];

 /*
  * postconf_builtin.c.
  */
extern void pcf_register_builtin_parameters(const char *, pid_t);

 /*
  * postconf_service.c.
  */
extern void pcf_register_service_parameters(void);

 /*
  * Parameter context structure.
  */
typedef struct {
    PCF_MASTER_ENT *local_scope;
    int     param_class;
} PCF_PARAM_CTX;

 /*
  * postconf_user.c.
  */
extern void pcf_register_user_parameters(void);

 /*
  * postconf_dbms.c
  */
extern void pcf_register_dbms_parameters(const char *,
	              const char *(*) (const char *, int, PCF_MASTER_ENT *),
					         PCF_MASTER_ENT *);

 /*
  * postconf_lookup.c.
  */
extern const char *pcf_lookup_parameter_value(int, const char *,
					              PCF_MASTER_ENT *,
					              PCF_PARAM_NODE *);

extern char *pcf_expand_parameter_value(VSTRING *, int, const char *,
					        PCF_MASTER_ENT *);

 /*
  * postconf_print.c.
  */
extern void PRINTFLIKE(3, 4) pcf_print_line(VSTREAM *, int, const char *,...);

 /*
  * postconf_unused.c.
  */
extern void pcf_flag_unused_main_parameters(void);
extern void pcf_flag_unused_master_parameters(void);

 /*
  * postconf_other.c.
  */
extern void pcf_show_maps(void);
extern void pcf_show_locks(void);
extern void pcf_show_sasl(int);
extern void pcf_show_tls(const char *);

/* LICENSE
/* .ad
/* .fi
/*	The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/*	Wietse Venema
/*	IBM T.J. Watson Research
/*	P.O. Box 704
/*	Yorktown Heights, NY 10598, USA
/*
/*	Wietse Venema
/*	Google, Inc.
/*	111 8th Avenue
/*	New York, NY 10011, USA
/*--*/