1 /*
2    Bacula(R) - The Network Backup Solution
3 
4    Copyright (C) 2000-2020 Kern Sibbald
5 
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8 
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13 
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16 
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  *
21  *     Kern Sibbald, January MM
22  *
23  */
24 #pragma once
25 /* Used for certain keyword tables */
26 struct s_kw {
27    const char *name;
28    int token;
29 };
30 
31 /* Collector Type keyword structure */
32 struct s_collt {
33    const char *type_name;
34    int32_t coll_type;
35 };
36 
37 struct RES_ITEM;                   /* Declare forward referenced structure */
38 struct RES_ITEM1;
39 struct RES_ITEM2;                  /* Declare forward referenced structure */
40 class RES;                         /* Declare forward referenced structure */
41 struct HPKT;                       /* Declare forward referenced structure */
42 typedef void (RES_HANDLER)(HPKT &hpkt);
43 typedef void (MSG_RES_HANDLER)(LEX *lc, RES_ITEM *item, int index, int pass);
44 /* The INC_RES handler has an extra argument */
45 typedef void (INC_RES_HANDLER)(LEX *lc, RES_ITEM2 *item, int index, int pass, bool exclude);
46 
47 /* This is the structure that defines
48  * the record types (items) permitted within each
49  * resource. It is used to define the configuration
50  * tables.
51  */
52 struct RES_ITEM {
53    const char *name;                  /* Resource name i.e. Director, ... */
54    MSG_RES_HANDLER *handler;          /* Routine storing the resource item */
55    union {
56       char **value;                   /* Where to store the item */
57       char **charvalue;
58       uint32_t ui32value;
59       int32_t i32value;
60       uint64_t ui64value;
61       int64_t i64value;
62       bool boolvalue;
63       utime_t utimevalue;
64       RES *resvalue;
65       RES **presvalue;
66    };
67    int32_t  code;                     /* item code/additional info */
68    uint32_t  flags;                   /* flags: default, required, ... */
69    int32_t  default_value;            /* default value */
70 };
71 
72 /*
73  * This handler takes only the RPKT as an argument
74  */
75 struct RES_ITEM1 {
76    const char *name;                  /* Resource name i.e. Director, ... */
77    RES_HANDLER *handler;              /* Routine storing/displaying the resource */
78    union {
79       char **value;                   /* Where to store the item */
80       char **charvalue;
81       uint32_t ui32value;
82       int32_t i32value;
83       uint64_t ui64value;
84       int64_t i64value;
85       bool boolvalue;
86       utime_t utimevalue;
87       RES *resvalue;
88       RES **presvalue;
89    };
90    int32_t  code;                     /* item code/additional info */
91    uint32_t  flags;                   /* flags: default, required, ... */
92    int32_t  default_value;            /* default value */
93 };
94 
95 /* INC_RES_HANDLER has exclude argument */
96 struct RES_ITEM2 {
97    const char *name;                  /* Resource name i.e. Director, ... */
98    INC_RES_HANDLER *handler;          /* Routine storing the resource item */
99    union {
100       char **value;                   /* Where to store the item */
101       char **charvalue;
102       uint32_t ui32value;
103       int32_t i32value;
104       uint64_t ui64value;
105       int64_t i64value;
106       bool boolvalue;
107       utime_t utimevalue;
108       RES *resvalue;
109       RES **presvalue;
110    };
111    int32_t  code;                     /* item code/additional info */
112    uint32_t  flags;                   /* flags: default, required, ... */
113    int32_t  default_value;            /* default value */
114 };
115 
116 
117 /* For storing name_addr items in res_items table */
118 #define ITEM(x) {(char **)&res_all.x}
119 
120 #define MAX_RES_ITEMS 100             /* maximum resource items per RES */
121 
122 class RES_HEAD {
123 public:
124    rblist *res_list;                  /* Resource list */
125    RES *first;                        /* First RES item in list */
126    RES *last;                         /* Last RES item inserted */
127 };
128 
129 /*
130  * This is the universal header that is
131  * at the beginning of every resource
132  * record.
133  */
134 class RES {
135 public:
136    rblink link;                       /* red-black link */
137    RES *res_next;                     /* pointer to next resource of this type */
138    char *name;                        /* resource name */
139    char *desc;                        /* resource description */
140    uint32_t rcode;                    /* resource id or type */
141    int32_t  refcnt;                   /* reference count for releasing */
142    char  item_present[MAX_RES_ITEMS]; /* set if item is present in conf file */
143 };
144 
145 
146 /*
147  * Master Resource configuration structure definition
148  * This is the structure that defines the
149  * resources that are available to this daemon.
150  */
151 struct RES_TABLE {
152    const char *name;                  /* resource name */
153    RES_ITEM *items;                   /* list of resource keywords */
154    uint32_t rcode;                    /* code if needed */
155 };
156 
157 /* Common Resource definitions */
158 
159 #define MAX_RES_NAME_LENGTH MAX_NAME_LENGTH-1       /* maximum resource name length */
160 
161 /* Permitted bits in Flags field */
162 #define ITEM_REQUIRED    (1<<0)       /* item required */
163 #define ITEM_DEFAULT     (1<<1)       /* default supplied */
164 #define ITEM_NO_EQUALS   (1<<2)       /* Don't scan = after name */
165 #define ITEM_LAST        (1<<3)       /* Last item in list */
166 #define ITEM_ALLOW_DUPS  (1<<4)       /* Allow duplicate directives */
167 
168 /* Message Resource */
169 class MSGS {
170 public:
171    RES   hdr;
172    char *mail_cmd;                    /* mail command */
173    char *operator_cmd;                /* Operator command */
174    DEST *dest_chain;                  /* chain of destinations */
175    char send_msg[nbytes_for_bits(M_MAX+1)];  /* bit array of types */
176 
177 private:
178    bool m_in_use;                     /* set when using to send a message */
179    bool m_closing;                    /* set when closing message resource */
180 
181 public:
182    /* Methods */
183    char *name() const;
clear_in_use()184    void clear_in_use() { lock(); m_in_use=false; unlock(); }
set_in_use()185    void set_in_use() { wait_not_in_use(); m_in_use=true; unlock(); }
set_closing()186    void set_closing() { m_closing=true; }
get_closing()187    bool get_closing() { return m_closing; }
clear_closing()188    void clear_closing() { lock(); m_closing=false; unlock(); }
is_closing()189    bool is_closing() { lock(); bool rtn=m_closing; unlock(); return rtn; }
190 
191    void wait_not_in_use();            /* in message.c */
192    void lock();                       /* in message.c */
193    void unlock();                     /* in message.c */
194 };
195 
name()196 inline char *MSGS::name() const { return hdr.name; }
197 
198 /* just for reference */
199 class bstatcollect;
200 
201 /* Statistics Resource */
202 class COLLECTOR {
203 public:
204    RES   hdr;                          /* standard resource header */
205    char *file;                         /* stat file if required */
206    char *prefix;                       /* metric prefix */
207    const char *daemon;                 /* the Daemon type string for spooling */
208    const char *spool_directory;        /* a working directory of the Daemon */
209    utime_t interval;                   /* interval in seconds between metrics collection */
210    uint32_t port;                      /* TCP port when using network backend */
211    char *host;                         /* remote host address when using network backend */
212    int32_t type;                       /* the Collector backend type */
213    alist *metrics;                     /* the list for Metrics parameters in resource */
214    /* private */
215    JCR *jcr;                           /* JCR resource */
216    bstatcollect *statcollector;        /* the reference to daemon's bstatcollect'or class */
217    time_t timestamp;                   /* the last collection time */
218    bool valid;                         /* when set to false the collector thread should involuntary exit */
219    bool running;                       /* set when a collector thread is running */
220    bool mangle_name;                   /* when set metrics name will be mangled by replacing dot '.' for "%32" */
221    int spooled;                        /* the spooling status of the collector */
222    POOLMEM *errmsg;                    /* error message if any */
223    pthread_t thid;                     /* thread id for collector thread */
224    pthread_mutex_t mutex;              /* when accessing collector resource data you should lock it first */
225 
226 public:
227    /* Methods */
228    char *name() const;
229    void lock();                        /* in bcollector.c */
230    void unlock();                      /* in bcollector.c */
231    void setspooled(int s);             /* in bcollector.c */
232    int getspooled();                   /* in bcollector.c */
233    void updatetimestamp();             /* in bcollector.c */
234 };
235 
name()236 inline char *COLLECTOR::name() const { return hdr.name; }
237 
238 /*
239  * New C++ configuration routines
240  */
241 
242 class CONFIG: public SMARTALLOC {
243 public:
244    const char *m_cf;                   /* config file */
245    LEX_ERROR_HANDLER *m_scan_error;    /* error handler if non-null */
246    int32_t m_err_type;                 /* the way to terminate on failure */
247    void *m_res_all;                    /* pointer to res_all buffer */
248    int32_t m_res_all_size;             /* length of buffer */
249    bool  m_encode_pass;                /* Encode passwords with MD5 or not */
250 
251    /* The below are not yet implemented */
252    int32_t m_r_first;                  /* first daemon resource type */
253    int32_t m_r_last;                   /* last daemon resource type */
254    RES_TABLE *m_resources;             /* pointer to table of permitted resources */
255    RES_HEAD **m_res_head;              /* pointer to list of resources this type */
256    brwlock_t m_res_lock;               /* resource lock */
257    POOLMEM *m_errmsg;
258 
259    /* functions */
260    void init(
261       const char *cf,
262       LEX_ERROR_HANDLER *scan_error,
263       int32_t err_type,
264       void *vres_all,
265       int32_t res_all_size,
266       int32_t r_first,
267       int32_t r_last,
268       RES_TABLE *resources,
269       RES_HEAD ***res_head);
270 
271    CONFIG();
272    ~CONFIG();
273    void encode_password(bool encode);
274    bool parse_config();
275    void free_all_resources();
276    bool insert_res(int rindex, int size);
277    RES_HEAD **save_resources();
278    RES_HEAD **new_res_head();
279    void init_res_head(RES_HEAD ***rhead, int32_t first, int32_t last);
280 };
281 
282 /* Resource routines */
283 int res_compare(void *item1, void *item2);
284 RES *GetResWithName(int rcode, const char *name);
285 RES *GetNextRes(int rcode, RES *res);
286 RES *GetNextRes(RES_HEAD **rhead, int rcode, RES *res);
287 void b_LockRes(const char *file, int line);
288 void b_UnlockRes(const char *file, int line);
289 void dump_resource(int type, RES *res, void sendmsg(void *sock, const char *fmt, ...), void *sock);
290 void dump_each_resource(int type, void sendmsg(void *sock, const char *fmt, ...), void *sock);
291 void free_resource(RES *res, int type);
292 bool init_resource(CONFIG *config, uint32_t type, void *res, int size);
293 bool save_resource(CONFIG *config, int type, RES_ITEM *item, int pass);
294 void unstrip_password(RES_TABLE *resources); /* Used for json stuff */
295 void strip_password(RES_TABLE *resources);   /* Used for tray monitor */
296 const char *res_to_str(int rcode);
297 bool find_config_file(const char *config_file, char *full_path, int max_path);
298 
299 /* Loop through each resource of type, returning in var */
300 #ifdef HAVE_TYPEOF
301 #define foreach_res(var, type) \
302         for((var)=NULL; ((var)=(typeof(var))GetNextRes((type), (RES *)var));)
303 #else
304 #define foreach_res(var, type) \
305     for(var=NULL; (*((void **)&(var))=(void *)GetNextRes((type), (RES *)var));)
306 #endif
307 
308 
309 /*
310  * Standard global parsers defined in parse_config.c and bcollector.c
311  */
312 void store_str(LEX *lc, RES_ITEM *item, int index, int pass);
313 void store_dir(LEX *lc, RES_ITEM *item, int index, int pass);
314 void store_clear_password(LEX *lc, RES_ITEM *item, int index, int pass);
315 void store_password(LEX *lc, RES_ITEM *item, int index, int pass);
316 void store_name(LEX *lc, RES_ITEM *item, int index, int pass);
317 void store_strname(LEX *lc, RES_ITEM *item, int index, int pass);
318 void store_res(LEX *lc, RES_ITEM *item, int index, int pass);
319 void store_alist_res(LEX *lc, RES_ITEM *item, int index, int pass);
320 void store_alist_str(LEX *lc, RES_ITEM *item, int index, int pass);
321 void store_int32(LEX *lc, RES_ITEM *item, int index, int pass);
322 void store_pint32(LEX *lc, RES_ITEM *item, int index, int pass);
323 void store_msgs(LEX *lc, RES_ITEM *item, int index, int pass);
324 void store_int64(LEX *lc, RES_ITEM *item, int index, int pass);
325 void store_bit(LEX *lc, RES_ITEM *item, int index, int pass);
326 void store_bool(LEX *lc, RES_ITEM *item, int index, int pass);
327 void store_time(LEX *lc, RES_ITEM *item, int index, int pass);
328 void store_size64(LEX *lc, RES_ITEM *item, int index, int pass);
329 void store_size32(LEX *lc, RES_ITEM *item, int index, int pass);
330 void store_speed(LEX *lc, RES_ITEM *item, int index, int pass);
331 void store_defs(LEX *lc, RES_ITEM *item, int index, int pass);
332 void store_label(LEX *lc, RES_ITEM *item, int index, int pass);
333 void store_coll_type(LEX *lc, RES_ITEM *item, int index, int pass);
334 
335 /* ***FIXME*** eliminate these globals */
336 extern int32_t r_first;
337 extern int32_t r_last;
338 extern RES_TABLE resources[];
339 extern RES_HEAD **res_head;
340 extern int32_t res_all_size;
341