1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  *
8  * See the COPYRIGHT file distributed with this work for additional
9  * information regarding copyright ownership.
10  */
11 
12 #ifndef ISCCFG_CFG_H
13 #define ISCCFG_CFG_H 1
14 
15 /*****
16 ***** Module Info
17 *****/
18 
19 /*! \file isccfg/cfg.h
20  * \brief
21  * This is the new, table-driven, YACC-free configuration file parser.
22  */
23 
24 /***
25  *** Imports
26  ***/
27 
28 #include <inttypes.h>
29 #include <stdbool.h>
30 #include <time.h>
31 
32 #include <isc/formatcheck.h>
33 #include <isc/lang.h>
34 #include <isc/list.h>
35 #include <isc/refcount.h>
36 #include <isc/types.h>
37 
38 /***
39  *** Types
40  ***/
41 
42 /*%
43  * A configuration parser.
44  */
45 typedef struct cfg_parser cfg_parser_t;
46 
47 /*%
48  * A configuration type definition object.  There is a single
49  * static cfg_type_t object for each data type supported by
50  * the configuration parser.
51  */
52 typedef struct cfg_type cfg_type_t;
53 
54 /*%
55  * A configuration object.  This is the basic building block of the
56  * configuration parse tree.  It contains a value (which may be
57  * of one of several types) and information identifying the file
58  * and line number the value came from, for printing error
59  * messages.
60  */
61 typedef struct cfg_obj cfg_obj_t;
62 
63 /*%
64  * A configuration object list element.
65  */
66 typedef struct cfg_listelt cfg_listelt_t;
67 
68 /*%
69  * A callback function to be called when parsing an option
70  * that needs to be interpreted at parsing time, like
71  * "directory".
72  */
73 typedef isc_result_t (*cfg_parsecallback_t)(const char *     clausename,
74 					    const cfg_obj_t *obj, void *arg);
75 
76 /***
77  *** Functions
78  ***/
79 
80 ISC_LANG_BEGINDECLS
81 
82 void
83 cfg_parser_attach(cfg_parser_t *src, cfg_parser_t **dest);
84 /*%<
85  * Reference a parser object.
86  */
87 
88 isc_result_t
89 cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret);
90 /*%<
91  * Create a configuration file parser.  Any warning and error
92  * messages will be logged to 'lctx'.
93  *
94  * The parser object returned can be used for a single call
95  * to cfg_parse_file() or cfg_parse_buffer().  It must not
96  * be reused for parsing multiple files or buffers.
97  */
98 
99 void
100 cfg_parser_setflags(cfg_parser_t *pctx, unsigned int flags, bool turn_on);
101 /*%<
102  * Set parser context flags. The flags are not checked for sensibility.
103  * If 'turn_on' is 'true' the flags will be set, otherwise the flags will
104  * be cleared.
105  *
106  * Requires:
107  *\li 	"pctx" is not NULL.
108  */
109 
110 void
111 cfg_parser_setcallback(cfg_parser_t *pctx, cfg_parsecallback_t callback,
112 		       void *arg);
113 /*%<
114  * Make the parser call 'callback' whenever it encounters
115  * a configuration clause with the callback attribute,
116  * passing it the clause name, the clause value,
117  * and 'arg' as arguments.
118  *
119  * To restore the default of not invoking callbacks, pass
120  * callback==NULL and arg==NULL.
121  */
122 
123 isc_result_t
124 cfg_parse_file(cfg_parser_t *pctx, const char *file, const cfg_type_t *type,
125 	       cfg_obj_t **ret);
126 
127 isc_result_t
128 cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, const char *file,
129 		 unsigned int line, const cfg_type_t *type, unsigned int flags,
130 		 cfg_obj_t **ret);
131 /*%<
132  * Read a configuration containing data of type 'type'
133  * and make '*ret' point to its parse tree.
134  *
135  * The configuration is read from the file 'filename'
136  * (isc_parse_file()) or the buffer 'buffer'
137  * (isc_parse_buffer()).
138  *
139  * If 'file' is not NULL, it is the name of the file, or a name to use
140  * for the buffer in place of the filename, when logging errors.
141  *
142  * If 'line' is not 0, then it is the beginning line number to report
143  * when logging errors. This is useful when passing text that has been
144  * read from the middle of a file.
145  *
146  * Returns an error if the file or buffer does not parse correctly.
147  *
148  * Requires:
149  *\li 	"filename" is valid.
150  *\li 	"mem" is valid.
151  *\li	"type" is valid.
152  *\li 	"cfg" is non-NULL and "*cfg" is NULL.
153  *\li   "flags" be one or more of CFG_PCTX_NODEPRECATED or zero.
154  *
155  * Returns:
156  *     \li #ISC_R_SUCCESS                 - success
157  *\li      #ISC_R_NOMEMORY                - no memory available
158  *\li      #ISC_R_INVALIDFILE             - file doesn't exist or is unreadable
159  *\li      others	                      - file contains errors
160  */
161 
162 isc_result_t
163 cfg_parser_mapadd(cfg_parser_t *pctx, cfg_obj_t *mapobj, cfg_obj_t *obj,
164 		  const char *clause);
165 /*%<
166  * Add the object 'obj' to the specified clause in mapbody 'mapobj'.
167  * Used for adding new zones.
168  *
169  * Require:
170  * \li     'obj' is a valid cfg_obj_t.
171  * \li     'mapobj' is a valid cfg_obj_t of type map.
172  * \li     'pctx' is a valid cfg_parser_t.
173  */
174 
175 void
176 cfg_parser_reset(cfg_parser_t *pctx);
177 /*%<
178  * Reset an existing parser so it can be re-used for a new file or
179  * buffer.
180  */
181 
182 void
183 cfg_parser_destroy(cfg_parser_t **pctxp);
184 /*%<
185  * Remove a reference to a configuration parser; destroy it if there are no
186  * more references.
187  */
188 
189 bool
190 cfg_obj_isvoid(const cfg_obj_t *obj);
191 /*%<
192  * Return true iff 'obj' is of void type (e.g., an optional
193  * value not specified).
194  */
195 
196 bool
197 cfg_obj_ismap(const cfg_obj_t *obj);
198 /*%<
199  * Return true iff 'obj' is of a map type.
200  */
201 
202 bool
203 cfg_obj_isfixedpoint(const cfg_obj_t *obj);
204 /*%<
205  * Return true iff 'obj' is of a fixedpoint type.
206  */
207 
208 bool
209 cfg_obj_ispercentage(const cfg_obj_t *obj);
210 /*%<
211  * Return true iff 'obj' is of a percentage type.
212  */
213 
214 isc_result_t
215 cfg_map_get(const cfg_obj_t *mapobj, const char *name, const cfg_obj_t **obj);
216 /*%<
217  * Extract an element from a configuration object, which
218  * must be of a map type.
219  *
220  * Requires:
221  * \li     'mapobj' points to a valid configuration object of a map type.
222  * \li     'name' points to a null-terminated string.
223  * \li	'obj' is non-NULL and '*obj' is NULL.
224  *
225  * Returns:
226  * \li     #ISC_R_SUCCESS                  - success
227  * \li     #ISC_R_NOTFOUND                 - name not found in map
228  */
229 
230 const cfg_obj_t *
231 cfg_map_getname(const cfg_obj_t *mapobj);
232 /*%<
233  * Get the name of a named map object, like a server "key" clause.
234  *
235  * Requires:
236  *    \li  'mapobj' points to a valid configuration object of a map type.
237  *
238  * Returns:
239  * \li     A pointer to a configuration object naming the map object,
240  *	or NULL if the map object does not have a name.
241  */
242 
243 unsigned int
244 cfg_map_count(const cfg_obj_t *mapobj);
245 /*%<
246  * Get the number of elements defined in the symbol table of a map object.
247  *
248  * Requires:
249  *    \li  'mapobj' points to a valid configuration object of a map type.
250  *
251  * Returns:
252  * \li     The number of elements in the map object.
253  */
254 
255 bool
256 cfg_obj_istuple(const cfg_obj_t *obj);
257 /*%<
258  * Return true iff 'obj' is of a map type.
259  */
260 
261 const cfg_obj_t *
262 cfg_tuple_get(const cfg_obj_t *tupleobj, const char *name);
263 /*%<
264  * Extract an element from a configuration object, which
265  * must be of a tuple type.
266  *
267  * Requires:
268  * \li     'tupleobj' points to a valid configuration object of a tuple type.
269  * \li     'name' points to a null-terminated string naming one of the
270  *\li	fields of said tuple type.
271  */
272 
273 bool
274 cfg_obj_isuint32(const cfg_obj_t *obj);
275 /*%<
276  * Return true iff 'obj' is of integer type.
277  */
278 
279 uint32_t
280 cfg_obj_asuint32(const cfg_obj_t *obj);
281 /*%<
282  * Returns the value of a configuration object of 32-bit integer type.
283  *
284  * Requires:
285  * \li     'obj' points to a valid configuration object of 32-bit integer type.
286  *
287  * Returns:
288  * \li     A 32-bit unsigned integer.
289  */
290 
291 bool
292 cfg_obj_isuint64(const cfg_obj_t *obj);
293 /*%<
294  * Return true iff 'obj' is of integer type.
295  */
296 
297 uint64_t
298 cfg_obj_asuint64(const cfg_obj_t *obj);
299 /*%<
300  * Returns the value of a configuration object of 64-bit integer type.
301  *
302  * Requires:
303  * \li     'obj' points to a valid configuration object of 64-bit integer type.
304  *
305  * Returns:
306  * \li     A 64-bit unsigned integer.
307  */
308 
309 uint32_t
310 cfg_obj_asfixedpoint(const cfg_obj_t *obj);
311 /*%<
312  * Returns the value of a configuration object of fixed point number.
313  *
314  * Requires:
315  * \li     'obj' points to a valid configuration object of fixed point type.
316  *
317  * Returns:
318  * \li     A 32-bit unsigned integer.
319  */
320 
321 uint32_t
322 cfg_obj_aspercentage(const cfg_obj_t *obj);
323 /*%<
324  * Returns the value of a configuration object of percentage
325  *
326  * Requires:
327  * \li     'obj' points to a valid configuration object of percentage type.
328  *
329  * Returns:
330  * \li     A 32-bit unsigned integer.
331  */
332 
333 bool
334 cfg_obj_isduration(const cfg_obj_t *obj);
335 /*%<
336  * Return true iff 'obj' is of duration type.
337  */
338 
339 uint32_t
340 cfg_obj_asduration(const cfg_obj_t *obj);
341 /*%<
342  * Returns the value of a configuration object of duration
343  *
344  * Requires:
345  * \li     'obj' points to a valid configuration object of duration type.
346  *
347  * Returns:
348  * \li     A duration in seconds.
349  */
350 
351 bool
352 cfg_obj_isstring(const cfg_obj_t *obj);
353 /*%<
354  * Return true iff 'obj' is of string type.
355  */
356 
357 const char *
358 cfg_obj_asstring(const cfg_obj_t *obj);
359 /*%<
360  * Returns the value of a configuration object of a string type
361  * as a null-terminated string.
362  *
363  * Requires:
364  * \li     'obj' points to a valid configuration object of a string type.
365  *
366  * Returns:
367  * \li     A pointer to a null terminated string.
368  */
369 
370 bool
371 cfg_obj_isboolean(const cfg_obj_t *obj);
372 /*%<
373  * Return true iff 'obj' is of a boolean type.
374  */
375 
376 bool
377 cfg_obj_asboolean(const cfg_obj_t *obj);
378 /*%<
379  * Returns the value of a configuration object of a boolean type.
380  *
381  * Requires:
382  * \li     'obj' points to a valid configuration object of a boolean type.
383  *
384  * Returns:
385  * \li     A boolean value.
386  */
387 
388 bool
389 cfg_obj_issockaddr(const cfg_obj_t *obj);
390 /*%<
391  * Return true iff 'obj' is a socket address.
392  */
393 
394 const isc_sockaddr_t *
395 cfg_obj_assockaddr(const cfg_obj_t *obj);
396 /*%<
397  * Returns the value of a configuration object representing a socket address.
398  *
399  * Requires:
400  * \li     'obj' points to a valid configuration object of a socket address
401  * type.
402  *
403  * Returns:
404  * \li     A pointer to a sockaddr.  The sockaddr must be copied by the caller
405  *      if necessary.
406  */
407 
408 isc_dscp_t
409 cfg_obj_getdscp(const cfg_obj_t *obj);
410 /*%<
411  * Returns the DSCP value of a configuration object representing a
412  * socket address.
413  *
414  * Requires:
415  * \li     'obj' points to a valid configuration object of a
416  *         socket address type.
417  *
418  * Returns:
419  * \li     DSCP value associated with a sockaddr, or -1.
420  */
421 
422 bool
423 cfg_obj_isnetprefix(const cfg_obj_t *obj);
424 /*%<
425  * Return true iff 'obj' is a network prefix.
426  */
427 
428 void
429 cfg_obj_asnetprefix(const cfg_obj_t *obj, isc_netaddr_t *netaddr,
430 		    unsigned int *prefixlen);
431 /*%<
432  * Gets the value of a configuration object representing a network
433  * prefix.  The network address is returned through 'netaddr' and the
434  * prefix length in bits through 'prefixlen'.
435  *
436  * Requires:
437  * \li     'obj' points to a valid configuration object of network prefix type.
438  *\li	'netaddr' and 'prefixlen' are non-NULL.
439  */
440 
441 bool
442 cfg_obj_islist(const cfg_obj_t *obj);
443 /*%<
444  * Return true iff 'obj' is of list type.
445  */
446 
447 const cfg_listelt_t *
448 cfg_list_first(const cfg_obj_t *obj);
449 /*%<
450  * Returns the first list element in a configuration object of a list type.
451  *
452  * Requires:
453  * \li     'obj' points to a valid configuration object of a list type or NULL.
454  *
455  * Returns:
456  *   \li   A pointer to a cfg_listelt_t representing the first list element,
457  * 	or NULL if the list is empty or nonexistent.
458  */
459 
460 const cfg_listelt_t *
461 cfg_list_next(const cfg_listelt_t *elt);
462 /*%<
463  * Returns the next element of a list of configuration objects.
464  *
465  * Requires:
466  * \li     'elt' points to cfg_listelt_t obtained from cfg_list_first() or
467  *	a previous call to cfg_list_next().
468  *
469  * Returns:
470  * \li     A pointer to a cfg_listelt_t representing the next element,
471  * 	or NULL if there are no more elements.
472  */
473 
474 unsigned int
475 cfg_list_length(const cfg_obj_t *obj, bool recurse);
476 /*%<
477  * Returns the length of a list of configure objects.  If obj is
478  * not a list, returns 0.  If recurse is true, add in the length of
479  * all contained lists.
480  */
481 
482 cfg_obj_t *
483 cfg_listelt_value(const cfg_listelt_t *elt);
484 /*%<
485  * Returns the configuration object associated with cfg_listelt_t.
486  *
487  * Requires:
488  * \li     'elt' points to cfg_listelt_t obtained from cfg_list_first() or
489  *	cfg_list_next().
490  *
491  * Returns:
492  * \li     A non-NULL pointer to a configuration object.
493  */
494 
495 void
496 cfg_print(const cfg_obj_t *obj,
497 	  void (*f)(void *closure, const char *text, int textlen),
498 	  void *closure);
499 void
500 cfg_printx(const cfg_obj_t *obj, unsigned int flags,
501 	   void (*f)(void *closure, const char *text, int textlen),
502 	   void *closure);
503 
504 #define CFG_PRINTER_XKEY    0x1 /* '?' out shared keys. */
505 #define CFG_PRINTER_ONELINE 0x2 /* print config as a single line */
506 #define CFG_PRINTER_ACTIVEONLY                 \
507 	0x4 /* print only active configuration \
508 	     * options, omitting ancient,      \
509 	     * obsolete, nonimplemented,       \
510 	     * and test-only options. */
511 
512 /*%<
513  * Print the configuration object 'obj' by repeatedly calling the
514  * function 'f', passing 'closure' and a region of text starting
515  * at 'text' and comprising 'textlen' characters.
516  *
517  * If CFG_PRINTER_XKEY the contents of shared keys will be obscured
518  * by replacing them with question marks ('?')
519  */
520 
521 void
522 cfg_print_grammar(const cfg_type_t *type, unsigned int flags,
523 		  void (*f)(void *closure, const char *text, int textlen),
524 		  void *closure);
525 /*%<
526  * Print a summary of the grammar of the configuration type 'type'.
527  */
528 
529 bool
530 cfg_obj_istype(const cfg_obj_t *obj, const cfg_type_t *type);
531 /*%<
532  * Return true iff 'obj' is of type 'type'.
533  */
534 
535 void
536 cfg_obj_attach(cfg_obj_t *src, cfg_obj_t **dest);
537 /*%<
538  * Reference a configuration object.
539  */
540 
541 void
542 cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **obj);
543 /*%<
544  * Delete a reference to a configuration object; destroy the object if
545  * there are no more references.
546  *
547  * Require:
548  * \li     '*obj' is a valid cfg_obj_t.
549  * \li     'pctx' is a valid cfg_parser_t.
550  */
551 
552 void
553 cfg_obj_log(const cfg_obj_t *obj, isc_log_t *lctx, int level, const char *fmt,
554 	    ...) ISC_FORMAT_PRINTF(4, 5);
555 /*%<
556  * Log a message concerning configuration object 'obj' to the logging
557  * channel of 'pctx', at log level 'level'.  The message will be prefixed
558  * with the file name(s) and line number where 'obj' was defined.
559  */
560 
561 const char *
562 cfg_obj_file(const cfg_obj_t *obj);
563 /*%<
564  * Return the file that defined this object.
565  */
566 
567 unsigned int
568 cfg_obj_line(const cfg_obj_t *obj);
569 /*%<
570  * Return the line in file where this object was defined.
571  */
572 
573 const char *
574 cfg_map_firstclause(const cfg_type_t *map, const void **clauses,
575 		    unsigned int *idx);
576 const char *
577 cfg_map_nextclause(const cfg_type_t *map, const void **clauses,
578 		   unsigned int *idx);
579 
580 typedef isc_result_t(pluginlist_cb_t)(const cfg_obj_t *config,
581 				      const cfg_obj_t *obj,
582 				      const char *     plugin_path,
583 				      const char *     parameters,
584 				      void *	       callback_data);
585 /*%<
586  * Function prototype for the callback used with cfg_pluginlist_foreach().
587  * Called once for each element of the list passed to cfg_pluginlist_foreach().
588  * If this callback returns anything else than #ISC_R_SUCCESS, no further list
589  * elements will be processed.
590  *
591  * \li 'config' - the 'config' object passed to cfg_pluginlist_foreach()
592  * \li 'obj' - object representing the specific "plugin" stanza to be processed
593  * \li 'plugin_path' - path to the shared object with plugin code
594  * \li 'parameters' - configuration text for the plugin
595  * \li 'callback_data' - the pointer passed to cfg_pluginlist_foreach()
596  */
597 
598 isc_result_t
599 cfg_pluginlist_foreach(const cfg_obj_t *config, const cfg_obj_t *list,
600 		       isc_log_t *lctx, pluginlist_cb_t *callback,
601 		       void *callback_data);
602 /*%<
603  * For every "plugin" stanza present in 'list' (which in turn is a part of
604  * 'config'), invoke the given 'callback', passing 'callback_data' to it along
605  * with a fixed set of arguments (see the definition of the #pluginlist_cb_t
606  * type).  Use logging context 'lctx' for logging error messages.  Interrupt
607  * processing if 'callback' returns something else than #ISC_R_SUCCESS for any
608  * element of 'list'.
609  *
610  * Requires:
611  *
612  * \li 'config' is not NULL
613  * \li 'callback' is not NULL
614  *
615  * Returns:
616  *
617  * \li #ISC_R_SUCCESS if 'callback' returned #ISC_R_SUCCESS for all elements of
618  *     'list'
619  * \li first 'callback' return value which was not #ISC_R_SUCCESS otherwise
620  */
621 
622 ISC_LANG_ENDDECLS
623 
624 #endif /* ISCCFG_CFG_H */
625