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