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  *   Bacula Director daemon -- this is the main program
21  *
22  *     Kern Sibbald, March MM
23  */
24 
25 #include "bacula.h"
26 #include "dird.h"
27 #ifndef HAVE_REGEX_H
28 #include "lib/bregex.h"
29 #else
30 #include <regex.h>
31 #endif
32 #ifdef HAVE_DIRENT_H
33 #include <dirent.h>
34 #endif
35 int breaddir(DIR *dirp, POOLMEM *&d_name);
36 
37 /* Forward referenced subroutines */
38 void terminate_dird(int sig);
39 static bool check_resources();
40 static void cleanup_old_files();
41 static void resize_reload(int nb);
42 
43 /* Exported subroutines */
44 extern "C" void reload_config(int sig);
45 extern void invalidate_schedules();
46 extern bool parse_dir_config(CONFIG *config, const char *configfile, int exit_code);
47 
48 /* Imported subroutines */
49 JCR *wait_for_next_job(char *runjob);
50 void term_scheduler();
51 void start_UA_server(dlist *addrs);
52 void stop_UA_server();
53 void init_job_server(int max_workers);
54 void term_job_server();
55 void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass);
56 void store_level(LEX *lc, RES_ITEM *item, int index, int pass);
57 void store_replace(LEX *lc, RES_ITEM *item, int index, int pass);
58 void store_migtype(LEX *lc, RES_ITEM *item, int index, int pass);
59 void init_device_resources();
60 
61 
62 static char *runjob = NULL;
63 static bool foreground = false;
64 static bool make_pid_file = true;     /* create pid file */
65 static void init_reload(void);
66 static CONFIG *config;
67 static bool test_config = false;
68 
69 /* Globals Exported */
70 DIRRES *director;                     /* Director resource */
71 int FDConnectTimeout;
72 int SDConnectTimeout;
73 char *configfile = NULL;
74 void *start_heap;
75 utime_t last_reload_time = 0;
76 bstatcollect *statcollector = NULL;
77 dirdstatmetrics_t dirstatmetrics;
78 
79 /* Globals Imported */
80 extern dlist client_globals;
81 extern dlist store_globals;
82 extern dlist job_globals;
83 extern dlist sched_globals;
84 extern RES_ITEM job_items[];
85 #if defined(_MSC_VER)
86 extern "C" { // work around visual compiler mangling variables
87    extern URES res_all;
88 }
89 #else
90 extern URES res_all;
91 #endif
92 
93 typedef enum {
94    CHECK_CONNECTION,  /* Check catalog connection */
95    UPDATE_CATALOG,    /* Ensure that catalog is ok with conf */
96    UPDATE_AND_FIX     /* Ensure that catalog is ok, and fix old jobs */
97 } cat_op;
98 static bool check_catalog(cat_op mode);
99 
100 #define CONFIG_FILE "bacula-dir.conf" /* default configuration file */
101 
dir_sql_query(JCR * jcr,const char * cmd)102 static bool dir_sql_query(JCR *jcr, const char *cmd)
103 {
104    if (jcr && jcr->db && jcr->db->is_connected()) {
105       return db_sql_query(jcr->db, cmd, NULL, NULL);
106    }
107    return false;
108 }
109 
dir_sql_escape(JCR * jcr,BDB * mdb,char * snew,char * sold,int len)110 static bool dir_sql_escape(JCR *jcr, BDB *mdb, char *snew, char *sold, int len)
111 {
112    if (jcr && jcr->db && jcr->db->is_connected()) {
113       db_escape_string(jcr, mdb, snew, sold, len);
114       return true;
115    }
116    return false;
117 }
118 
usage()119 static void usage()
120 {
121    fprintf(stderr, _(
122       PROG_COPYRIGHT
123       "\n%sVersion: %s (%s)\n\n"
124       "Usage: bacula-dir [-f -s] [-c config_file] [-d debug_level] [config_file]\n"
125       "     -c <file>        set configuration file to file\n"
126       "     -d <nn>[,<tags>] set debug level to <nn>, debug tags to <tags>\n"
127       "     -dt              print timestamp in debug output\n"
128       "     -T               set trace on\n"
129       "     -f               run in foreground (for debugging)\n"
130       "     -g               groupid\n"
131       "     -m               print kaboom output (for debugging)\n"
132       "     -r <job>         run <job> now\n"
133       "     -P               do not create pid file\n"
134       "     -s               no signals\n"
135       "     -t               test - read configuration and exit\n"
136       "     -u               userid\n"
137       "     -v               verbose user messages\n"
138       "     -?               print this message.\n"
139       "\n"), 2000, "", VERSION, BDATE);
140 
141    exit(1);
142 }
143 
144 /*
145  * !!! WARNING !!! Use this function only when bacula is stopped.
146  * ie, after a fatal signal and before exiting the program
147  * Print information about a JCR
148  */
dir_debug_print(JCR * jcr,FILE * fp)149 static void dir_debug_print(JCR *jcr, FILE *fp)
150 {
151    fprintf(fp, "\twstore=%p rstore=%p wjcr=%p client=%p reschedule_count=%d SD_msg_chan_started=%d\n",
152            jcr->wstore, jcr->rstore, jcr->wjcr, jcr->client, jcr->reschedule_count, (int)jcr->SD_msg_chan_started);
153 }
154 
155 /*********************************************************************
156  *
157  *         Main Bacula Director Server program
158  *
159  */
160 #if defined(HAVE_WIN32)
161 /* For Win32 main() is in src/win32 code ... */
162 #define main BaculaMain
163 #endif
164 
165 /* DELETE ME when bugs in MA1512, MA1632 MA1639 are fixed */
166 extern void (*MA1512_reload_job_end_cb)(JCR *,void *);
167 static void reload_job_end_cb(JCR *jcr, void *ctx);
168 
main(int argc,char * argv[])169 int main (int argc, char *argv[])
170 {
171    int ch;
172    JCR *jcr;
173    bool no_signals = false;
174    char *uid = NULL;
175    char *gid = NULL;
176 
177    /* DELETE ME when bugs in MA1512, MA1632 MA1639 are fixed */
178    MA1512_reload_job_end_cb = reload_job_end_cb;
179 
180    start_heap = sbrk(0);
181    setlocale(LC_ALL, "");
182    bindtextdomain("bacula", LOCALEDIR);
183    textdomain("bacula");
184 
185    init_stack_dump();
186    my_name_is(argc, argv, "bacula-dir");
187    init_msg(NULL, NULL);              /* initialize message handler */
188    init_reload();
189    daemon_start_time = time(NULL);
190    setup_daemon_message_queue();
191    console_command = run_console_command;
192 
193    while ((ch = getopt(argc, argv, "c:d:fg:mPr:stu:v?T")) != -1) {
194       switch (ch) {
195       case 'c':                    /* specify config file */
196          if (configfile != NULL) {
197             free(configfile);
198          }
199          configfile = bstrdup(optarg);
200          break;
201 
202       case 'd':                    /* set debug level */
203          if (*optarg == 't') {
204             dbg_timestamp = true;
205          } else {
206             char *p;
207             /* We probably find a tag list -d 10,sql,bvfs */
208             if ((p = strchr(optarg, ',')) != NULL) {
209                *p = 0;
210             }
211             debug_level = atoi(optarg);
212             if (debug_level <= 0) {
213                debug_level = 1;
214             }
215             if (p) {
216                debug_parse_tags(p+1, &debug_level_tags);
217             }
218          }
219          Dmsg1(10, "Debug level = %lld\n", debug_level);
220          break;
221 
222       case 'T':
223          set_trace(true);
224          break;
225 
226       case 'f':                    /* run in foreground */
227          foreground = true;
228          break;
229 
230       case 'g':                    /* set group id */
231          gid = optarg;
232          break;
233 
234       case 'm':                    /* print kaboom output */
235          prt_kaboom = true;
236          break;
237 
238       case 'P':                    /* no pid file */
239          make_pid_file = false;
240          break;
241 
242       case 'r':                    /* run job */
243          if (runjob != NULL) {
244             free(runjob);
245          }
246          if (optarg) {
247             runjob = bstrdup(optarg);
248          }
249          break;
250 
251       case 's':                    /* turn off signals */
252          no_signals = true;
253          break;
254 
255       case 't':                    /* test config */
256          test_config = true;
257          break;
258 
259       case 'u':                    /* set uid */
260          uid = optarg;
261          break;
262 
263       case 'v':                    /* verbose */
264          verbose++;
265          break;
266 
267       case '?':
268       default:
269          usage();
270 
271       }
272    }
273    argc -= optind;
274    argv += optind;
275 
276    if (argc) {
277       if (configfile != NULL) {
278          free(configfile);
279       }
280       configfile = bstrdup(*argv);
281       argc--;
282       argv++;
283    }
284    if (argc) {
285       usage();
286    }
287 
288    if (!foreground && !test_config) {
289       daemon_start();
290       init_stack_dump();              /* grab new pid */
291    }
292 
293    if (!no_signals) {
294       init_signals(terminate_dird);
295    }
296 
297    if (configfile == NULL) {
298       configfile = bstrdup(CONFIG_FILE);
299    }
300 
301    config = New(CONFIG());
302    parse_dir_config(config, configfile, M_ERROR_TERM);
303 
304    if (init_crypto() != 0) {
305       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n"));
306    }
307 
308    if (!check_resources()) {
309       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
310    }
311 
312    /* The configuration is correct */
313    director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
314 
315    if (!test_config) {
316       /* Create pid must come after we are a daemon -- so we have our final pid */
317       if (make_pid_file) {
318          create_pid_file(director->pid_directory, "bacula-dir",
319                           get_first_port_host_order(director->DIRaddrs));
320       }
321       read_state_file(director->working_directory, "bacula-dir",
322                       get_first_port_host_order(director->DIRaddrs));
323    }
324 
325    set_jcr_in_tsd(INVALID_JCR);
326    set_thread_concurrency(director->MaxConcurrentJobs * 2 +
327                           4 /* UA */ + 5 /* sched+watchdog+jobsvr+misc */);
328    lmgr_init_thread(); /* initialize the lockmanager stack */
329 
330    load_dir_plugins(director->plugin_directory);
331 
332    drop(uid, gid, false);                    /* reduce privileges if requested */
333 
334    /* initialize a statistics collector */
335    initialize_statcollector();
336 
337    /* If we are in testing mode, we don't try to fix the catalog */
338    cat_op mode=(test_config)?CHECK_CONNECTION:UPDATE_AND_FIX;
339 
340    if (!check_catalog(mode)) {
341       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
342    }
343 
344    if (test_config) {
345       terminate_dird(0);
346    }
347 
348    update_permanent_stats(NULL);
349 
350    my_name_is(0, NULL, director->name());    /* set user defined name */
351 
352    cleanup_old_files();
353 
354    /* Plug database interface for library routines */
355    p_sql_query = (sql_query_call)dir_sql_query;
356    p_sql_escape = (sql_escape_call)dir_sql_escape;
357 
358    FDConnectTimeout = (int)director->FDConnectTimeout;
359    SDConnectTimeout = (int)director->SDConnectTimeout;
360 
361    resize_reload(director->MaxReload);
362 
363 #if !defined(HAVE_WIN32)
364    signal(SIGHUP, reload_config);
365 #endif
366 
367    init_console_msg(working_directory);
368 
369    Dmsg0(200, "Start UA server\n");
370    start_UA_server(director->DIRaddrs);
371 
372    start_watchdog();                  /* start network watchdog thread */
373 
374    init_jcr_subsystem();              /* start JCR watchdogs etc. */
375 
376    init_job_server(director->MaxConcurrentJobs);
377 
378    dbg_jcr_add_hook(dir_debug_print); /* used to director variables */
379    dbg_jcr_add_hook(bdb_debug_print);     /* used to debug B_DB connection after fatal signal */
380 
381    start_collector_threads();    /* start collector thread for every Collector resource */
382 
383 //   init_device_resources();
384 
385    Dmsg0(200, "wait for next job\n");
386    /* Main loop -- call scheduler to get next job to run */
387    while ( (jcr = wait_for_next_job(runjob)) ) {
388       run_job(jcr);                   /* run job */
389       free_jcr(jcr);                  /* release jcr */
390       set_jcr_in_tsd(INVALID_JCR);
391       if (runjob) {                   /* command line, run a single job? */
392          break;                       /* yes, terminate */
393       }
394    }
395 
396    terminate_dird(0);
397 
398    return 0;
399 }
400 
401 struct RELOAD_TABLE {
402    int job_count;
403    RES_HEAD **res_head;
404 };
405 
406 static int max_reloads = 32;
407 static RELOAD_TABLE *reload_table=NULL;
408 
resize_reload(int nb)409 static void resize_reload(int nb)
410 {
411    if (nb <= max_reloads) {
412       return;
413    }
414 
415    reload_table = (RELOAD_TABLE*)realloc(reload_table, nb * sizeof(RELOAD_TABLE));
416    for (int i=max_reloads; i < nb ; i++) {
417       reload_table[i].job_count = 0;
418       reload_table[i].res_head = NULL;
419    }
420    max_reloads = nb;
421 }
422 
init_reload(void)423 static void init_reload(void)
424 {
425    reload_table = (RELOAD_TABLE*)malloc(max_reloads * sizeof(RELOAD_TABLE));
426    for (int i=0; i < max_reloads; i++) {
427       reload_table[i].job_count = 0;
428       reload_table[i].res_head = NULL;
429    }
430 }
431 
432 /*
433  * This subroutine frees a saved resource table.
434  *  It was saved when a new table was created with "reload"
435  */
free_saved_resources(int table)436 static void free_saved_resources(int table)
437 {
438    RES *next, *res;
439    int num = r_last - r_first + 1;
440    RES_HEAD **res_tab = reload_table[table].res_head;
441 
442    if (res_tab == NULL) {
443       Dmsg1(100, "res_tab for table %d already released.\n", table);
444       return;
445    }
446    Dmsg1(100, "Freeing resources for table %d\n", table);
447    for (int j=0; j<num; j++) {
448       if (res_tab[j]) {
449          next = res_tab[j]->first;
450          for ( ; next; ) {
451             res = next;
452             next = res->res_next;
453             free_resource(res, r_first + j);
454          }
455          free(res_tab[j]->res_list);
456          free(res_tab[j]);
457          res_tab[j] = NULL;
458       }
459    }
460    free(res_tab);
461    reload_table[table].job_count = 0;
462    reload_table[table].res_head = NULL;
463 }
464 
465 /*
466  * Called here at the end of every job that was
467  * hooked decrementing the active job_count. When
468  * it goes to zero, no one is using the associated
469  * resource table, so free it.
470  */
reload_job_end_cb(JCR * jcr,void * ctx)471 static void reload_job_end_cb(JCR *jcr, void *ctx)
472 {
473    int reload_id = (int)((intptr_t)ctx);
474    Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
475       reload_id, reload_table[reload_id].job_count);
476    lock_jobs();
477    LockRes();
478    if (--reload_table[reload_id].job_count <= 0) {
479       free_saved_resources(reload_id);
480    }
481    UnlockRes();
482    unlock_jobs();
483 }
484 
find_free_reload_table_entry()485 static int find_free_reload_table_entry()
486 {
487    int table = -1;
488    for (int i=0; i < max_reloads; i++) {
489       if (reload_table[i].res_head == NULL) {
490          table = i;
491          break;
492       }
493    }
494    return table;
495 }
496 
497 static pthread_mutex_t reload_mutex = PTHREAD_MUTEX_INITIALIZER;
498 
499 /*
500  * If we get here, we have received a SIGHUP, which means to
501  *    reread our configuration file.
502  *
503  * The algorithm used is as follows: we count how many jobs are
504  *   running and mark the running jobs to make a callback on
505  *   exiting. The old config is saved with the reload table
506  *   id in a reload table. The new config file is read. Now, as
507  *   each job exits, it calls back to the reload_job_end_cb(), which
508  *   decrements the count of open jobs for the given reload table.
509  *   When the count goes to zero, we release those resources.
510  *   This allows us to have pointers into the resource table (from
511  *   jobs), and once they exit and all the pointers are released, we
512  *   release the old table. Note, if no new jobs are running since the
513  *   last reload, then the old resources will be immediately release.
514  *   A console is considered a job because it may have pointers to
515  *   resources, but a SYSTEM job is not since it *should* not have any
516  *   permanent pointers to jobs.
517  */
518 extern "C"
reload_config(int sig)519 void reload_config(int sig)
520 {
521    static bool already_here = false;
522 #if !defined(HAVE_WIN32)
523    sigset_t set;
524 #endif
525    JCR *jcr;
526    int njobs = 0;                     /* number of running jobs */
527    int table, rtable;
528    bool ok=false;
529    int tries=0;
530 
531    /* Wait to do the reload */
532    do {
533       P(reload_mutex);
534       if (already_here) {
535          V(reload_mutex);
536          if (tries++ > 10) {
537             Qmsg(NULL, M_INFO, 0, _("Already doing a reload request, "
538                                     "request ignored.\n"));
539             return;
540          }
541          Dmsg0(10, "Already doing a reload request, waiting a bit\n");
542          bmicrosleep(1, 0);
543       } else {
544          already_here = true;
545          V(reload_mutex);
546          ok = true;
547       }
548    } while (!ok);
549 
550 #if !defined(HAVE_WIN32)
551    sigemptyset(&set);
552    sigaddset(&set, SIGHUP);
553    sigprocmask(SIG_BLOCK, &set, NULL);
554 #endif
555 
556    /* handle collector threads restart*/
557    terminate_collector_threads();
558 
559    lock_jobs();
560    LockRes();
561 
562    table = find_free_reload_table_entry();
563    if (table < 0) {
564       Qmsg(NULL, M_ERROR, 0, _("Too many (%d) open reload requests. "
565                                "Request ignored.\n"), max_reloads);
566       goto bail_out;
567    }
568 
569    Dmsg1(100, "Reload_config njobs=%d\n", njobs);
570    /* Save current res_head */
571    reload_table[table].res_head = res_head;
572    Dmsg1(100, "Saved old config in table %d\n", table);
573 
574    /* Create a new res_head and parse into it */
575    ok = parse_dir_config(config, configfile, M_ERROR);
576 
577    Dmsg0(100, "Reloaded config file\n");
578    if (!ok || !check_resources() || !check_catalog(UPDATE_CATALOG)) {
579       /*
580        * We got an error, save broken point, restore old one,
581        *  then release everything from broken pointer.
582        */
583       rtable = find_free_reload_table_entry();    /* save new, bad table */
584       if (rtable < 0) {
585          Qmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
586          Qmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n"));
587       } else {
588          Qmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
589          Qmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n"));
590       }
591       /* Save broken res_head pointer */
592       reload_table[rtable].res_head = res_head;
593 
594       /* Now restore old resource pointer */
595       res_head = reload_table[table].res_head;
596       table = rtable;           /* release new, bad, saved table below */
597    } else {
598       invalidate_schedules();
599 
600       /* We know that the configuration is correct and we will keep it,
601        * so we can update the global pointer to the director resource.
602        */
603       director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
604 
605       /*
606        * Hook all active jobs so that they release this table
607        */
608       foreach_jcr(jcr) {
609          if (jcr->getJobType() != JT_SYSTEM) {
610             reload_table[table].job_count++;
611             job_end_push(jcr, reload_job_end_cb, (void *)((long int)table));
612             njobs++;
613          }
614       }
615       endeach_jcr(jcr);
616       /*
617        * Now walk through globals tables and plug them into the
618        * new resources.
619        */
620       CLIENT_GLOBALS *cg;
621       foreach_dlist(cg, &client_globals) {
622          CLIENT *client;
623          client = GetClientResWithName(cg->name);
624          if (!client) {
625             Qmsg(NULL, M_INFO, 0, _("Client=%s not found. Assuming it was removed!!!\n"), cg->name);
626          } else {
627             client->globals = cg;      /* Set globals pointer */
628          }
629       }
630       STORE_GLOBALS *sg;
631       foreach_dlist(sg, &store_globals) {
632          STORE *store;
633          store = GetStoreResWithName(sg->name);
634          if (!store) {
635             Qmsg(NULL, M_INFO, 0, _("Storage=%s not found. Assuming it was removed!!!\n"), sg->name);
636          } else {
637             store->globals = sg;       /* set globals pointer */
638             Dmsg2(200, "Reload found numConcurrent=%ld for Store %s\n",
639                sg->NumConcurrentJobs, sg->name);
640          }
641       }
642       JOB_GLOBALS *jg;
643       foreach_dlist(jg, &job_globals) {
644          JOB *job;
645          job = GetJobResWithName(jg->name);
646          if (!job) {
647             Qmsg(NULL, M_INFO, 0, _("Job=%s not found. Assuming it was removed!!!\n"), jg->name);
648          } else {
649             job->globals = jg;         /* Set globals pointer */
650          }
651       }
652       SCHED_GLOBALS *schg;
653       foreach_dlist(schg, &sched_globals) {
654          SCHED *sched;
655          sched = GetSchedResWithName(schg->name);
656          if (!sched) {
657             Qmsg(NULL, M_INFO, 0, _("Schedule=%s not found. Assuming it was removed!!!\n"), schg->name);
658          } else {
659             sched->globals = schg;     /* Set globals pointer */
660          }
661       };
662    }
663 
664    /* Reset other globals */
665    set_working_directory(director->working_directory);
666    FDConnectTimeout = director->FDConnectTimeout;
667    SDConnectTimeout = director->SDConnectTimeout;
668    Dmsg0(10, "Director's configuration file reread.\n");
669 
670    /* populate statistics data */
671    update_config_stats();
672 
673    /* Now release saved resources, if no jobs using the resources */
674    if (njobs == 0) {
675       free_saved_resources(table);
676    }
677 
678 bail_out:
679    UnlockRes();
680    unlock_jobs();
681 /* start collector threads again */
682    start_collector_threads();
683 #if !defined(HAVE_WIN32)
684    sigprocmask(SIG_UNBLOCK, &set, NULL);
685    signal(SIGHUP, reload_config);
686 #endif
687    already_here = false;
688 }
689 
690 /* Cleanup and then exit */
terminate_dird(int sig)691 void terminate_dird(int sig)
692 {
693    static bool already_here = false;
694 
695    if (already_here) {                /* avoid recursive temination problems */
696       bmicrosleep(2, 0);              /* yield */
697       exit(1);
698    }
699    already_here = true;
700    debug_level = 0;                   /* turn off debug */
701    stop_watchdog();
702    terminate_collector_threads();
703    generate_daemon_event(NULL, "Exit");
704    unload_plugins();
705    if (!test_config) {
706       write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
707       if (make_pid_file) {
708          delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
709       }
710    }
711    term_scheduler();
712    term_job_server();
713    if (runjob) {
714       free(runjob);
715    }
716    if (configfile != NULL) {
717       free(configfile);
718    }
719    if (chk_dbglvl(5)) {
720       print_memory_pool_stats();
721    }
722    if (config) {
723       delete config;
724       config = NULL;
725    }
726    stop_UA_server();
727    term_msg();                        /* terminate message handler */
728    cleanup_crypto();
729 
730    free_daemon_message_queue();
731 
732    if (reload_table) {
733       free(reload_table);
734    }
735    free(res_head);
736    res_head = NULL;
737    /*
738     * Now walk through resource globals tables and release them
739     */
740    CLIENT_GLOBALS *cg;
741    foreach_dlist(cg, &client_globals) {
742       free(cg->name);
743       if (cg->SetIPaddress) {
744          free(cg->SetIPaddress);
745       }
746    }
747    client_globals.destroy();
748 
749    STORE_GLOBALS *sg;
750    foreach_dlist(sg, &store_globals) {
751       free(sg->name);
752    }
753    store_globals.destroy();
754 
755    JOB_GLOBALS *jg;
756    foreach_dlist(jg, &job_globals) {
757       free(jg->name);
758    }
759    job_globals.destroy();
760 
761    if (statcollector){
762       // statcollector->dump();
763       delete(statcollector);
764    }
765 
766    close_memory_pool();               /* release free memory in pool */
767    lmgr_cleanup_main();
768    sm_dump(false);
769    exit(sig);
770 }
771 
772 /*
773  * Make a quick check to see that we have all the
774  * resources needed.
775  *
776  *  **** FIXME **** this routine could be a lot more
777  *   intelligent and comprehensive.
778  */
check_resources()779 static bool check_resources()
780 {
781    bool OK = true;
782    JOB *job;
783    bool need_tls;
784    DIRRES *newDirector;
785 
786    LockRes();
787 
788    job = (JOB *)GetNextRes(R_JOB, NULL);
789    newDirector = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
790    if (!newDirector) {
791       Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n"
792 "Without that I don't know who I am :-(\n"), configfile);
793       OK = false;
794    } else {
795       set_working_directory(newDirector->working_directory);
796       if (!newDirector->messages) { /* If message resource not specified */
797          newDirector->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
798          if (!newDirector->messages) {
799             Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
800             OK = false;
801          }
802       }
803       if (GetNextRes(R_DIRECTOR, (RES *)newDirector) != NULL) {
804          Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"),
805             configfile);
806          OK = false;
807       }
808       /* tls_require implies tls_enable */
809       if (newDirector->tls_require) {
810          if (have_tls) {
811             newDirector->tls_enable = true;
812          } else {
813             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
814             OK = false;
815          }
816       }
817 
818       need_tls = newDirector->tls_enable || newDirector->tls_authenticate;
819 
820       if (!newDirector->tls_certfile && need_tls) {
821          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
822             newDirector->name(), configfile);
823          OK = false;
824       }
825 
826       if (!newDirector->tls_keyfile && need_tls) {
827          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
828             newDirector->name(), configfile);
829          OK = false;
830       }
831 
832       if ((!newDirector->tls_ca_certfile && !newDirector->tls_ca_certdir) &&
833            need_tls && newDirector->tls_verify_peer) {
834          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
835               " Certificate Dir\" are defined for Director \"%s\" in %s."
836               " At least one CA certificate store is required"
837               " when using \"TLS Verify Peer\".\n"),
838               newDirector->name(), configfile);
839          OK = false;
840       }
841 
842       /* If everything is well, attempt to initialize our per-resource TLS context */
843       if (OK && (need_tls || newDirector->tls_require)) {
844          /* Initialize TLS context:
845           * Args: CA certfile, CA certdir, Certfile, Keyfile,
846           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
847          newDirector->tls_ctx = new_tls_context(newDirector->tls_ca_certfile,
848             newDirector->tls_ca_certdir, newDirector->tls_certfile,
849             newDirector->tls_keyfile, NULL, NULL, newDirector->tls_dhfile,
850             newDirector->tls_verify_peer);
851 
852          if (!newDirector->tls_ctx) {
853             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
854                  newDirector->name(), configfile);
855             OK = false;
856          }
857       }
858    }
859 
860    if (!job) {
861       Jmsg(NULL, M_FATAL, 0, _("No Job records defined in %s\n"), configfile);
862       OK = false;
863    }
864    foreach_res(job, R_JOB) {
865       int i;
866 
867       if (job->jobdefs) {
868          JOB *jobdefs = job->jobdefs;
869          /* Handle RunScripts alists specifically */
870          if (jobdefs->RunScripts) {
871             RUNSCRIPT *rs, *elt;
872 
873             if (!job->RunScripts) {
874                job->RunScripts = New(alist(10, not_owned_by_alist));
875             }
876 
877             foreach_alist(rs, jobdefs->RunScripts) {
878                elt = copy_runscript(rs);
879                job->RunScripts->append(elt); /* we have to free it */
880             }
881          }
882 
883          /* Transfer default items from JobDefs Resource */
884          for (i=0; job_items[i].name; i++) {
885             char **def_svalue, **svalue;  /* string value */
886             uint32_t *def_ivalue, *ivalue;     /* integer value */
887             bool *def_bvalue, *bvalue;    /* bool value */
888             int64_t *def_lvalue, *lvalue; /* 64 bit values */
889             alist **def_avalue, **avalue; /* alist values */
890             uint32_t offset;
891 
892             Dmsg4(1400, "Job \"%s\", field \"%s\" bit=%d def=%d\n",
893                 job->name(), job_items[i].name,
894                 bit_is_set(i, job->hdr.item_present),
895                 bit_is_set(i, job->jobdefs->hdr.item_present));
896 
897             if (!bit_is_set(i, job->hdr.item_present) &&
898                  bit_is_set(i, job->jobdefs->hdr.item_present)) {
899                Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n",
900                  job->name(), job_items[i].name);
901                offset = (char *)(job_items[i].value) - (char *)&res_all;
902                /*
903                 * Handle strings and directory strings
904                 */
905                if (job_items[i].handler == store_str ||
906                    job_items[i].handler == store_dir) {
907                   def_svalue = (char **)((char *)(job->jobdefs) + offset);
908                   Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n",
909                        job->name(), job_items[i].name, *def_svalue, i, offset);
910                   svalue = (char **)((char *)job + offset);
911                   if (*svalue) {
912                      Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
913                   }
914                   *svalue = bstrdup(*def_svalue);
915                   set_bit(i, job->hdr.item_present);
916                /*
917                 * Handle resources
918                 */
919                } else if (job_items[i].handler == store_res) {
920                   def_svalue = (char **)((char *)(job->jobdefs) + offset);
921                   Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n",
922                        job->name(), job_items[i].name, i, offset);
923                   svalue = (char **)((char *)job + offset);
924                   if (*svalue) {
925                      Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
926                   }
927                   *svalue = *def_svalue;
928                   set_bit(i, job->hdr.item_present);
929                /*
930                 * Handle alist resources
931                 */
932                } else if (job_items[i].handler == store_alist_res) {
933                   void *elt;
934 
935                   def_avalue = (alist **)((char *)(job->jobdefs) + offset);
936                   avalue = (alist **)((char *)job + offset);
937 
938                   *avalue = New(alist(10, not_owned_by_alist));
939 
940                   foreach_alist(elt, (*def_avalue)) {
941                      (*avalue)->append(elt);
942                   }
943                   set_bit(i, job->hdr.item_present);
944                /*
945                 * Handle integer fields
946                 *    Note, our store_bit does not handle bitmaped fields
947                 */
948                } else if (job_items[i].handler == store_bit     ||
949                           job_items[i].handler == store_pint32  ||
950                           job_items[i].handler == store_jobtype ||
951                           job_items[i].handler == store_level   ||
952                           job_items[i].handler == store_int32   ||
953                           job_items[i].handler == store_size32  ||
954                           job_items[i].handler == store_migtype ||
955                           job_items[i].handler == store_replace) {
956                   def_ivalue = (uint32_t *)((char *)(job->jobdefs) + offset);
957                   Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n",
958                        job->name(), job_items[i].name, *def_ivalue, i, offset);
959                   ivalue = (uint32_t *)((char *)job + offset);
960                   *ivalue = *def_ivalue;
961                   set_bit(i, job->hdr.item_present);
962                /*
963                 * Handle 64 bit integer fields
964                 */
965                } else if (job_items[i].handler == store_time   ||
966                           job_items[i].handler == store_size64 ||
967                           job_items[i].handler == store_speed  ||
968                           job_items[i].handler == store_int64) {
969                   def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset);
970                   Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n",
971                        job->name(), job_items[i].name, *def_lvalue, i, offset);
972                   lvalue = (int64_t *)((char *)job + offset);
973                   *lvalue = *def_lvalue;
974                   set_bit(i, job->hdr.item_present);
975                /*
976                 * Handle bool fields
977                 */
978                } else if (job_items[i].handler == store_bool) {
979                   def_bvalue = (bool *)((char *)(job->jobdefs) + offset);
980                   Dmsg5(400, "Job \"%s\", field \"%s\" def_bvalue=%d item %d offset=%u\n",
981                        job->name(), job_items[i].name, *def_bvalue, i, offset);
982                   bvalue = (bool *)((char *)job + offset);
983                   *bvalue = *def_bvalue;
984                   set_bit(i, job->hdr.item_present);
985                }
986             }
987          }
988       }
989       /*
990        * Ensure that all required items are present
991        */
992       for (i=0; job_items[i].name; i++) {
993          if (job_items[i].flags & ITEM_REQUIRED) {
994                if (!bit_is_set(i, job->hdr.item_present)) {
995                   Jmsg(NULL, M_ERROR_TERM, 0, _("\"%s\" directive in Job \"%s\" resource is required, but not found.\n"),
996                     job_items[i].name, job->name());
997                   OK = false;
998                 }
999          }
1000          /* If this triggers, take a look at lib/parse_conf.h */
1001          if (i >= MAX_RES_ITEMS) {
1002             Emsg0(M_ERROR_TERM, 0, _("Too many items in Job resource\n"));
1003          }
1004       }
1005       if (!job->storage && !job->pool->storage) {
1006          Jmsg(NULL, M_FATAL, 0, _("No storage specified in Job \"%s\" nor in Pool.\n"),
1007             job->name());
1008          OK = false;
1009       }
1010 
1011       /* Make sure the job doesn't use the Scratch Pool to start with */
1012       const char *name;
1013       if (!check_pool(job->JobType, job->JobLevel,
1014                       job->pool, job->next_pool, &name)) {
1015          Jmsg(NULL, M_FATAL, 0,
1016               _("%s \"Scratch\" not valid in Job \"%s\".\n"),
1017               name, job->name());
1018          OK = false;
1019       }
1020    } /* End loop over Job res */
1021 
1022 
1023    /* Loop over Consoles */
1024    CONRES *cons;
1025    foreach_res(cons, R_CONSOLE) {
1026       /* tls_require implies tls_enable */
1027       if (cons->tls_require) {
1028          if (have_tls) {
1029             cons->tls_enable = true;
1030          } else {
1031             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
1032             OK = false;
1033             continue;
1034          }
1035       }
1036 
1037       need_tls = cons->tls_enable || cons->tls_authenticate;
1038 
1039       if (!cons->tls_certfile && need_tls) {
1040          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
1041             cons->name(), configfile);
1042          OK = false;
1043       }
1044 
1045       if (!cons->tls_keyfile && need_tls) {
1046          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
1047             cons->name(), configfile);
1048          OK = false;
1049       }
1050 
1051       if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir)
1052             && need_tls && cons->tls_verify_peer) {
1053          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
1054             " Certificate Dir\" are defined for Console \"%s\" in %s."
1055             " At least one CA certificate store is required"
1056             " when using \"TLS Verify Peer\".\n"),
1057             cons->name(), configfile);
1058          OK = false;
1059       }
1060       /* If everything is well, attempt to initialize our per-resource TLS context */
1061       if (OK && (need_tls || cons->tls_require)) {
1062          /* Initialize TLS context:
1063           * Args: CA certfile, CA certdir, Certfile, Keyfile,
1064           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
1065          cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
1066             cons->tls_ca_certdir, cons->tls_certfile,
1067             cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
1068 
1069          if (!cons->tls_ctx) {
1070             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
1071                cons->name(), configfile);
1072             OK = false;
1073          }
1074       }
1075 
1076    }
1077 
1078    /* Loop over Clients */
1079    CLIENT *client;
1080    foreach_res(client, R_CLIENT) {
1081       /* tls_require implies tls_enable */
1082       if (client->tls_require) {
1083          if (have_tls) {
1084             client->tls_enable = true;
1085          } else {
1086             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
1087             OK = false;
1088             continue;
1089          }
1090       }
1091       need_tls = client->tls_enable || client->tls_authenticate;
1092       if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && need_tls) {
1093          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
1094             " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
1095             client->name(), configfile);
1096          OK = false;
1097       }
1098 
1099       /* If everything is well, attempt to initialize our per-resource TLS context */
1100       if (OK && (need_tls || client->tls_require)) {
1101          /* Initialize TLS context:
1102           * Args: CA certfile, CA certdir, Certfile, Keyfile,
1103           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
1104          client->tls_ctx = new_tls_context(client->tls_ca_certfile,
1105             client->tls_ca_certdir, client->tls_certfile,
1106             client->tls_keyfile, NULL, NULL, NULL,
1107             true);
1108 
1109          if (!client->tls_ctx) {
1110             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
1111                client->name(), configfile);
1112             OK = false;
1113          }
1114       }
1115    }
1116 
1117    /* Loop over all pools, check PoolType */
1118    POOL *pool;
1119    foreach_res(pool, R_POOL) {
1120       if (!pool->pool_type) {
1121          /* This case is checked by the parse engine, we should not */
1122          Jmsg(NULL, M_FATAL, 0, _("PoolType required in Pool resource \"%s\".\n"), pool->hdr.name);
1123          OK = false;
1124          continue;
1125       }
1126       if ((strcasecmp(pool->pool_type, NT_("backup"))  != 0) &&
1127           (strcasecmp(pool->pool_type, NT_("copy"))    != 0) &&
1128           (strcasecmp(pool->pool_type, NT_("cloned"))  != 0) &&
1129           (strcasecmp(pool->pool_type, NT_("archive")) != 0) &&
1130           (strcasecmp(pool->pool_type, NT_("migration")) != 0) &&
1131           (strcasecmp(pool->pool_type, NT_("scratch")) != 0))
1132       {
1133          Jmsg(NULL, M_FATAL, 0, _("Invalid PoolType \"%s\" in Pool resource \"%s\".\n"), pool->pool_type, pool->hdr.name);
1134          OK = false;
1135       }
1136 
1137       if (pool->NextPool && strcmp(pool->NextPool->name(), "Scratch") == 0) {
1138          Jmsg(NULL, M_FATAL, 0,
1139               _("NextPool \"Scratch\" not valid in Pool \"%s\".\n"),
1140               pool->name());
1141          OK = false;
1142       }
1143    }
1144 
1145    /* verify a Collector resource */
1146    COLLECTOR *collect;
1147    foreach_res(collect, R_COLLECTOR){
1148       switch (collect->type){
1149          case COLLECTOR_BACKEND_CSV:
1150             /* a CSV backend require a file parameter */
1151             if (!collect->file){
1152                Jmsg(NULL, M_FATAL, 0, _("File parameter required in Collector CSV resource \"%s\".\n"),
1153                      collect->hdr.name);
1154                OK = false;
1155             }
1156             break;
1157          case COLLECTOR_BACKEND_Graphite:
1158             /* we require a host parameter at least */
1159             if (!collect->host){
1160                Jmsg(NULL, M_FATAL, 0, _("Host parameter required in Collector Graphite resource \"%s\".\n"),
1161                      collect->hdr.name);
1162                OK = false;
1163             }
1164             break;
1165       }
1166    }
1167 
1168    UnlockRes();
1169    if (OK) {
1170       close_msg(NULL);                /* close temp message handler */
1171       init_msg(NULL, newDirector->messages); /* open daemon message handler */
1172       last_reload_time = time(NULL);
1173    }
1174    return OK;
1175 }
1176 
1177 /*
1178  * In this routine,
1179  *  - we can check the connection (mode=CHECK_CONNECTION)
1180  *  - we can synchronize the catalog with the configuration (mode=UPDATE_CATALOG)
1181  *  - we can synchronize, and fix old job records (mode=UPDATE_AND_FIX)
1182  *  - we hook up the Autochange children with the parent, and
1183  *    we hook the shared autochangers together.
1184  */
check_catalog(cat_op mode)1185 static bool check_catalog(cat_op mode)
1186 {
1187    bool OK = true;
1188    bool need_tls;
1189    STORE *store, *ac_child;
1190 
1191    /* Loop over databases */
1192    CAT *catalog;
1193    const char *BDB_db_driver = NULL; // global dbdriver from BDB class
1194    int db_driver_len = 0;
1195 
1196    foreach_res(catalog, R_CATALOG) {
1197       BDB *db;
1198       /*
1199        * Make sure we can open catalog, otherwise print a warning
1200        * message because the server is probably not running.
1201        */
1202       db = db_init_database(NULL, catalog->db_driver, catalog->db_name,
1203               catalog->db_user,
1204               catalog->db_password, catalog->db_address,
1205               catalog->db_port, catalog->db_socket,
1206               catalog->db_ssl_mode, catalog->db_ssl_key,
1207               catalog->db_ssl_cert, catalog->db_ssl_ca,
1208               catalog->db_ssl_capath, catalog->db_ssl_cipher,
1209               catalog->mult_db_connections,
1210               catalog->disable_batch_insert);
1211 
1212       /*  To fill appropriate "dbdriver" field into "CAT" catalog resource class */
1213 
1214       if (db) {
1215          /* To fetch dbdriver from "BDB" Catalog DB Interface class (global)
1216           * filled with database passed during bacula compilation
1217           */
1218          BDB_db_driver = db_get_engine_name(db);
1219          db_driver_len = strlen(BDB_db_driver);
1220 
1221          if (catalog->db_driver == NULL) { // dbdriver  field not present in bacula director conf file
1222             catalog->db_driver = (char *)malloc(db_driver_len + 1);
1223             memset(catalog->db_driver, 0 , (db_driver_len + 1));
1224          } else { // dbdriver  field present in bacula director conf file
1225             if (strlen(catalog->db_driver) == 0) {  // dbdriver  field present but empty in bacula director conf file
1226                 /* warning message displayed on Console while running bacula command:
1227                  * "bacula-dir -tc", in case "dbdriver" field  is empty in director
1228                  * configuration file while database argument is passed during compile time
1229                  */
1230                Pmsg1(000, _("Dbdriver field within director config file is empty " \
1231                   "but Database argument \"%s\" is " \
1232                   "passed during Bacula compilation. \n"),
1233                   BDB_db_driver);
1234                /* warning message displayed in log file (bacula.log) while running
1235                 * bacula command: "bacula-dir -tc", in case "dbdriver" field  is empty in director
1236                 * configuration file while database argument is passed during compile time
1237                 */
1238                Jmsg(NULL, M_WARNING, 0, _("Dbdriver field within director config file " \
1239                   "is empty but Database argument \"%s\" is " \
1240                   "passed during Bacula compilation. \n"),
1241                   BDB_db_driver);
1242 
1243             } else if (strcasecmp(catalog->db_driver, BDB_db_driver)) { // dbdriver  field mismatch in bacula director conf file
1244                /* warning message displayed on Console while running bacula command:
1245                 * "bacula-dir -tc", in case "catalog->db_driver" field  doesn’t match
1246                 * with database argument  during compile time
1247                 */
1248                Pmsg2(000, _("Dbdriver field within director config file \"%s\" " \
1249                   "mismatched with the Database argument \"%s\" " \
1250                   "passed during Bacula compilation. \n"),
1251                   catalog->db_driver, BDB_db_driver);
1252                /* warning message displayed on log file (bacula.log) while running
1253                 * bacula command: "bacula-dir -tc", in case "catalog->db_driver" field
1254                 * doesn’t match with database argument  during compile time
1255                 */
1256                Jmsg(NULL, M_WARNING, 0, _("Dbdriver field within director config file \"%s\" " \
1257                   "mismatched with the Database argument \"%s\" " \
1258                   "passed during Bacula compilation. \n"),
1259                   catalog->db_driver, BDB_db_driver);
1260             }
1261             catalog->db_driver = (char *)realloc(catalog->db_driver, (db_driver_len + 1));
1262             memset(catalog->db_driver, 0 , (db_driver_len + 1));
1263          }
1264          if (catalog->db_driver) {
1265            /* To copy dbdriver field into "CAT" catalog resource class (local)
1266             * from dbdriver in "BDB" catalog DB Interface class (global)
1267             */
1268             bstrncpy(catalog->db_driver, BDB_db_driver, db_driver_len);
1269          }
1270       }
1271 
1272       if (!db || !db_open_database(NULL, db)) {
1273          Pmsg2(000, _("Could not open Catalog \"%s\", database \"%s\".\n"),
1274               catalog->name(), catalog->db_name);
1275          Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
1276               catalog->name(), catalog->db_name);
1277          if (db) {
1278             Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
1279             Pmsg1(000, "%s", db_strerror(db));
1280             db_close_database(NULL, db);
1281          }
1282          OK = false;
1283          continue;
1284       }
1285 
1286       /* Display a message if the db max_connections is too low */
1287       if (!db_check_max_connections(NULL, db, director->MaxConcurrentJobs)) {
1288          Pmsg1(000, "Warning, settings problem for Catalog=%s\n", catalog->name());
1289          Pmsg1(000, "%s", db_strerror(db));
1290       }
1291 
1292       /* we are in testing mode, so don't touch anything in the catalog */
1293       if (mode == CHECK_CONNECTION) {
1294          if (db) db_close_database(NULL, db);
1295          continue;
1296       }
1297 
1298       /* Loop over all pools, defining/updating them in each database */
1299       POOL *pool;
1300       foreach_res(pool, R_POOL) {
1301          /*
1302           * If the Pool has a catalog resource create the pool only
1303           *   in that catalog.
1304           */
1305          if (!pool->catalog || pool->catalog == catalog) {
1306             create_pool(NULL, db, pool, POOL_OP_UPDATE);  /* update request */
1307          }
1308       }
1309 
1310       /* Once they are created, we can loop over them again, updating
1311        * references (RecyclePool)
1312        */
1313       foreach_res(pool, R_POOL) {
1314          /*
1315           * If the Pool has a catalog resource update the pool only
1316           *   in that catalog.
1317           */
1318          if (!pool->catalog || pool->catalog == catalog) {
1319             update_pool_references(NULL, db, pool);
1320          }
1321       }
1322 
1323       /* Ensure basic client record is in DB */
1324       CLIENT *client;
1325       foreach_res(client, R_CLIENT) {
1326          CLIENT_DBR cr;
1327          /* Create clients only if they use the current catalog */
1328          if (client->catalog != catalog) {
1329             Dmsg3(500, "Skip client=%s with cat=%s not catalog=%s\n",
1330                   client->name(), client->catalog->name(), catalog->name());
1331             continue;
1332          }
1333          Dmsg2(500, "create cat=%s for client=%s\n",
1334                client->catalog->name(), client->name());
1335          memset(&cr, 0, sizeof(cr));
1336          bstrncpy(cr.Name, client->name(), sizeof(cr.Name));
1337          cr.AutoPrune = client->AutoPrune;
1338          cr.FileRetention = client->FileRetention;
1339          cr.JobRetention = client->JobRetention;
1340 
1341          db_create_client_record(NULL, db, &cr);
1342 
1343          /* If the record doesn't reflect the current settings
1344           * we can adjust the catalog record.
1345           */
1346          if (cr.AutoPrune     != client->AutoPrune     ||
1347              cr.JobRetention  != client->JobRetention  ||
1348              cr.FileRetention != client->FileRetention)
1349          {
1350             cr.AutoPrune = client->AutoPrune;
1351             cr.FileRetention = client->FileRetention;
1352             cr.JobRetention = client->JobRetention;
1353             db_update_client_record(NULL, db, &cr);
1354          }
1355       }
1356 
1357       /* Ensure basic storage record is in DB */
1358       foreach_res(store, R_STORAGE) {
1359          STORAGE_DBR sr;
1360          MEDIATYPE_DBR mtr;
1361          memset(&sr, 0, sizeof(sr));
1362          memset(&mtr, 0, sizeof(mtr));
1363          if (store->media_type) {
1364             bstrncpy(mtr.MediaType, store->media_type, sizeof(mtr.MediaType));
1365             mtr.ReadOnly = 0;
1366             db_create_mediatype_record(NULL, db, &mtr);
1367          } else {
1368             mtr.MediaTypeId = 0;
1369          }
1370          bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
1371          sr.AutoChanger = store->autochanger;
1372          if (!db_create_storage_record(NULL, db, &sr)) {
1373             Jmsg(NULL, M_FATAL, 0, _("Could not create storage record for %s\n"),
1374                  store->name());
1375             OK = false;
1376          }
1377          store->StorageId = sr.StorageId;   /* set storage Id */
1378          if (!sr.created) {                 /* if not created, update it */
1379             sr.AutoChanger = store->autochanger;
1380             if (!db_update_storage_record(NULL, db, &sr)) {
1381                Jmsg(NULL, M_FATAL, 0, _("Could not update storage record for %s\n"),
1382                     store->name());
1383                OK = false;
1384             }
1385          }
1386 
1387          /* tls_require implies tls_enable */
1388          if (store->tls_require) {
1389             if (have_tls) {
1390                store->tls_enable = true;
1391             } else {
1392                Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
1393                OK = false;
1394             }
1395          }
1396 
1397          need_tls = store->tls_enable || store->tls_authenticate;
1398 
1399          if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && need_tls) {
1400             Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
1401                  " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
1402                  store->name(), configfile);
1403             OK = false;
1404          }
1405 
1406          /* If everything is well, attempt to initialize our per-resource TLS context */
1407          if (OK && (need_tls || store->tls_require)) {
1408            /* Initialize TLS context:
1409             * Args: CA certfile, CA certdir, Certfile, Keyfile,
1410             * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
1411             store->tls_ctx = new_tls_context(store->tls_ca_certfile,
1412                store->tls_ca_certdir, store->tls_certfile,
1413                store->tls_keyfile, NULL, NULL, NULL, true);
1414 
1415             if (!store->tls_ctx) {
1416                Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
1417                     store->name(), configfile);
1418                OK = false;
1419             }
1420          }
1421       }
1422 
1423       /* Link up all the children for each changer */
1424       foreach_res(store, R_STORAGE) {
1425          char sid[50];
1426          if (store->changer == store) {  /* we are a real Autochanger */
1427             store->ac_group = get_pool_memory(PM_FNAME);
1428             store->ac_group[0] = 0;
1429             pm_strcat(store->ac_group, edit_int64(store->StorageId, sid));
1430             /* Now look for children who point to this storage */
1431             foreach_res(ac_child, R_STORAGE) {
1432                if (ac_child != store && ac_child->changer == store) {
1433                   /* Found a child -- add StorageId */
1434                   pm_strcat(store->ac_group, ",");
1435                   pm_strcat(store->ac_group, edit_int64(ac_child->StorageId, sid));
1436                }
1437             }
1438          }
1439       }
1440 
1441       /* Link up all the shared storage devices */
1442       foreach_res(store, R_STORAGE) {
1443          if (store->ac_group) {  /* we are a real Autochanger */
1444             /* Now look for Shared Storage who point to this storage */
1445             foreach_res(ac_child, R_STORAGE) {
1446                if (ac_child->shared_storage == store && ac_child->ac_group &&
1447                    ac_child->shared_storage != ac_child) {
1448                   pm_strcat(store->ac_group, ",");
1449                   pm_strcat(store->ac_group, ac_child->ac_group);
1450                }
1451             }
1452          }
1453       }
1454 
1455       /* Loop over all counters, defining them in each database */
1456       /* Set default value in all counters */
1457       COUNTER *counter;
1458       foreach_res(counter, R_COUNTER) {
1459          /* Write to catalog? */
1460          if (!counter->created && counter->Catalog == catalog) {
1461             COUNTER_DBR cr;
1462             bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter));
1463             cr.MinValue = counter->MinValue;
1464             cr.MaxValue = counter->MaxValue;
1465             cr.CurrentValue = counter->MinValue;
1466             if (counter->WrapCounter) {
1467                bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter));
1468             } else {
1469                cr.WrapCounter[0] = 0;  /* empty string */
1470             }
1471             if (db_create_counter_record(NULL, db, &cr)) {
1472                counter->CurrentValue = cr.CurrentValue;
1473                counter->created = true;
1474                Dmsg2(100, "Create counter %s val=%d\n", counter->name(), counter->CurrentValue);
1475             }
1476          }
1477          if (!counter->created) {
1478             counter->CurrentValue = counter->MinValue;  /* default value */
1479          }
1480       }
1481       /* cleanup old job records */
1482       if (mode == UPDATE_AND_FIX) {
1483          db_sql_query(db, cleanup_created_job, NULL, NULL);
1484          db_sql_query(db, cleanup_running_job, NULL, NULL);
1485       }
1486 
1487       /* Set SQL engine name in global for debugging */
1488       set_db_engine_name(db_get_engine_name(db));
1489       if (db) db_close_database(NULL, db);
1490    }
1491    return OK;
1492 }
1493 
cleanup_old_files()1494 static void cleanup_old_files()
1495 {
1496    DIR* dp;
1497    int rc, name_max;
1498    int my_name_len = strlen(my_name);
1499    int len = strlen(director->working_directory);
1500    POOL_MEM dname(PM_FNAME);
1501    POOLMEM *cleanup = get_pool_memory(PM_MESSAGE);
1502    POOLMEM *basename = get_pool_memory(PM_MESSAGE);
1503    regex_t preg1;
1504    char prbuf[500];
1505    const int nmatch = 30;
1506    regmatch_t pmatch[nmatch];
1507    berrno be;
1508 
1509    /* Exclude spaces and look for .mail, .tmp or .restore.xx.bsr files */
1510    const char *pat1 = "^[^ ]+\\.(restore\\.[^ ]+\\.bsr|mail|tmp)$";
1511 
1512    /* Setup working directory prefix */
1513    pm_strcpy(basename, director->working_directory);
1514    if (len > 0 && !IsPathSeparator(director->working_directory[len-1])) {
1515       pm_strcat(basename, "/");
1516    }
1517 
1518    /* Compile regex expressions */
1519    rc = regcomp(&preg1, pat1, REG_EXTENDED);
1520    if (rc != 0) {
1521       regerror(rc, &preg1, prbuf, sizeof(prbuf));
1522       Pmsg2(000,  _("Could not compile regex pattern \"%s\" ERR=%s\n"),
1523            pat1, prbuf);
1524       goto get_out2;
1525    }
1526 
1527    name_max = pathconf(".", _PC_NAME_MAX);
1528    if (name_max < 1024) {
1529       name_max = 1024;
1530    }
1531 
1532    if (!(dp = opendir(director->working_directory))) {
1533       berrno be;
1534       Pmsg2(000, "Failed to open working dir %s for cleanup: ERR=%s\n",
1535             director->working_directory, be.bstrerror());
1536       goto get_out1;
1537    }
1538 
1539    while (1) {
1540       if (breaddir(dp, dname.addr()) != 0) {
1541          break;
1542       }
1543       /* Exclude any name with ., .., not my_name or containing a space */
1544       if (strcmp(dname.c_str(), ".") == 0 || strcmp(dname.c_str(), "..") == 0 ||
1545           strncmp(dname.c_str(), my_name, my_name_len) != 0) {
1546          Dmsg1(500, "Skipped: %s\n", dname.c_str());
1547          continue;
1548       }
1549 
1550       /* Unlink files that match regexes */
1551       if (regexec(&preg1, dname.c_str(), nmatch, pmatch,  0) == 0) {
1552          pm_strcpy(cleanup, basename);
1553          pm_strcat(cleanup, dname);
1554          Dmsg1(100, "Unlink: %s\n", cleanup);
1555          unlink(cleanup);
1556       }
1557    }
1558 
1559    closedir(dp);
1560 /* Be careful to free up the correct resources */
1561 get_out1:
1562    regfree(&preg1);
1563 get_out2:
1564    free_pool_memory(cleanup);
1565    free_pool_memory(basename);
1566 }
1567