]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/dird.c
617400c8a208b42f247feda2433861f2b62099fb
[bacula/bacula] / bacula / src / dird / dird.c
1 /*
2  *
3  *   Bacula Director daemon -- this is the main program
4  *
5  *     Kern Sibbald, March MM
6  *
7  *   Version $Id$
8  */
9 /*
10    Copyright (C) 2000-2006 Kern Sibbald
11
12    This program is free software; you can redistribute it and/or
13    modify it under the terms of the GNU General Public License
14    version 2 as amended with additional clauses defined in the
15    file LICENSE in the main source directory.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
20    the file LICENSE for additional details.
21
22  */
23
24 #include "bacula.h"
25 #include "dird.h"
26
27 /* Forward referenced subroutines */
28 static void terminate_dird(int sig);
29 static int check_resources();
30
31 /* Exported subroutines */
32
33 extern "C" void reload_config(int sig);
34
35
36 /* Imported subroutines */
37 JCR *wait_for_next_job(char *runjob);
38 void term_scheduler();
39 void term_ua_server();
40 void start_UA_server(dlist *addrs);
41 void init_job_server(int max_workers);
42 void term_job_server();
43 void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass);
44 void store_level(LEX *lc, RES_ITEM *item, int index, int pass);
45 void store_replace(LEX *lc, RES_ITEM *item, int index, int pass);
46 void init_device_resources();
47
48 static char *runjob = NULL;
49 static int background = 1;
50 static void init_reload(void);
51
52 /* Globals Exported */
53 DIRRES *director;                     /* Director resource */
54 int FDConnectTimeout;
55 int SDConnectTimeout;
56 char *configfile = NULL;
57
58 /* Globals Imported */
59 extern int r_first, r_last;           /* first and last resources */
60 extern RES_TABLE resources[];
61 extern RES **res_head;
62 extern RES_ITEM job_items[];
63 extern URES res_all;
64
65
66 #define CONFIG_FILE "./bacula-dir.conf" /* default configuration file */
67
68 static void usage()
69 {
70    fprintf(stderr, _(
71 "Copyright (C) 2000-2005 Kern Sibbald.\n"
72 "\nVersion: %s (%s)\n\n"
73 "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n"
74 "       -c <file>   set configuration file to file\n"
75 "       -dnn        set debug level to nn\n"
76 "       -f          run in foreground (for debugging)\n"
77 "       -g          groupid\n"
78 "       -r <job>    run <job> now\n"
79 "       -s          no signals\n"
80 "       -t          test - read configuration and exit\n"
81 "       -u          userid\n"
82 "       -v          verbose user messages\n"
83 "       -?          print this message.\n"
84 "\n"), VERSION, BDATE);
85
86    exit(1);
87 }
88
89
90 /*********************************************************************
91  *
92  *         Main Bacula Server program
93  *
94  */
95 int main (int argc, char *argv[])
96 {
97    int ch;
98    JCR *jcr;
99    int no_signals = FALSE;
100    int test_config = FALSE;
101    char *uid = NULL;
102    char *gid = NULL;
103
104    setlocale(LC_ALL, "");
105    bindtextdomain("bacula", LOCALEDIR);
106    textdomain("bacula");
107
108    init_stack_dump();
109    my_name_is(argc, argv, "bacula-dir");
110    init_msg(NULL, NULL);              /* initialize message handler */
111    init_reload();
112    daemon_start_time = time(NULL);
113
114    while ((ch = getopt(argc, argv, "c:d:fg:r:stu:v?")) != -1) {
115       switch (ch) {
116       case 'c':                    /* specify config file */
117          if (configfile != NULL) {
118             free(configfile);
119          }
120          configfile = bstrdup(optarg);
121          break;
122
123       case 'd':                    /* set debug level */
124          debug_level = atoi(optarg);
125          if (debug_level <= 0) {
126             debug_level = 1;
127          }
128          Dmsg1(0, "Debug level = %d\n", debug_level);
129          break;
130
131       case 'f':                    /* run in foreground */
132          background = FALSE;
133          break;
134
135       case 'g':                    /* set group id */
136          gid = optarg;
137          break;
138
139       case 'r':                    /* run job */
140          if (runjob != NULL) {
141             free(runjob);
142          }
143          if (optarg) {
144             runjob = bstrdup(optarg);
145          }
146          break;
147
148       case 's':                    /* turn off signals */
149          no_signals = TRUE;
150          break;
151
152       case 't':                    /* test config */
153          test_config = TRUE;
154          break;
155
156       case 'u':                    /* set uid */
157          uid = optarg;
158          break;
159
160       case 'v':                    /* verbose */
161          verbose++;
162          break;
163
164       case '?':
165       default:
166          usage();
167
168       }
169    }
170    argc -= optind;
171    argv += optind;
172
173    if (!no_signals) {
174       init_signals(terminate_dird);
175    }
176
177    if (argc) {
178       if (configfile != NULL) {
179          free(configfile);
180       }
181       configfile = bstrdup(*argv);
182       argc--;
183       argv++;
184    }
185    if (argc) {
186       usage();
187    }
188
189    if (configfile == NULL) {
190       configfile = bstrdup(CONFIG_FILE);
191    }
192
193    parse_config(configfile);
194
195    if (init_crypto() != 0) {
196       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n"));
197    }
198
199    if (!check_resources()) {
200       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
201    }
202
203    if (test_config) {
204       terminate_dird(0);
205    }
206
207    my_name_is(0, NULL, director->hdr.name);    /* set user defined name */
208
209    FDConnectTimeout = (int)director->FDConnectTimeout;
210    SDConnectTimeout = (int)director->SDConnectTimeout;
211
212    if (background) {
213       daemon_start();
214       init_stack_dump();              /* grab new pid */
215    }
216
217    /* Create pid must come after we are a daemon -- so we have our final pid */
218    create_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
219    read_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
220
221    drop(uid, gid);                    /* reduce priveleges if requested */
222
223    signal(SIGHUP, reload_config);
224
225    init_console_msg(working_directory);
226
227    init_python_interpreter(director->hdr.name, director->scripts_directory, 
228        "DirStartUp");
229
230    set_thread_concurrency(director->MaxConcurrentJobs * 2 +
231       4 /* UA */ + 4 /* sched+watchdog+jobsvr+misc */);
232
233    Dmsg0(200, "Start UA server\n");
234    start_UA_server(director->DIRaddrs);
235
236    start_watchdog();                  /* start network watchdog thread */
237
238    init_jcr_subsystem();              /* start JCR watchdogs etc. */
239
240    init_job_server(director->MaxConcurrentJobs);
241
242    Dmsg0(200, "wait for next job\n");
243    /* Main loop -- call scheduler to get next job to run */
244    while ( (jcr = wait_for_next_job(runjob)) ) {
245       run_job(jcr);                   /* run job */
246       free_jcr(jcr);                  /* release jcr */
247       if (runjob) {                   /* command line, run a single job? */
248          break;                       /* yes, terminate */
249       }
250    }
251
252    terminate_dird(0);
253 }
254
255 /* Cleanup and then exit */
256 static void terminate_dird(int sig)
257 {
258    static bool already_here = false;
259
260    if (already_here) {                /* avoid recursive temination problems */
261       exit(1);
262    }
263    already_here = true;
264    generate_daemon_event(NULL, "Exit");
265    write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
266    delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
267 // signal(SIGCHLD, SIG_IGN);          /* don't worry about children now */
268    term_scheduler();
269    term_job_server();
270    if (runjob) {
271       free(runjob);
272    }
273    if (configfile != NULL) {
274       free(configfile);
275    }
276    if (debug_level > 5) {
277       print_memory_pool_stats();
278    }
279    free_config_resources();
280    term_ua_server();
281    term_msg();                        /* terminate message handler */
282    stop_watchdog();
283    cleanup_crypto();
284    close_memory_pool();               /* release free memory in pool */
285    sm_dump(false);
286    exit(sig);
287 }
288
289 struct RELOAD_TABLE {
290    int job_count;
291    RES **res_table;
292 };
293
294 static const int max_reloads = 10;
295 static RELOAD_TABLE reload_table[max_reloads];
296
297 static void init_reload(void)
298 {
299    for (int i=0; i < max_reloads; i++) {
300       reload_table[i].job_count = 0;
301       reload_table[i].res_table = NULL;
302    }
303 }
304
305 static void free_saved_resources(int table)
306 {
307    int num = r_last - r_first + 1;
308    RES **res_tab = reload_table[table].res_table;
309    if (!res_tab) {
310       Dmsg1(100, "res_tab for table %d already released.\n", table);
311       return;
312    }
313    Dmsg1(100, "Freeing resources for table %d\n", table);
314    for (int j=0; j<num; j++) {
315       free_resource(res_tab[j], r_first + j);
316    }
317    free(res_tab);
318    reload_table[table].job_count = 0;
319    reload_table[table].res_table = NULL;
320 }
321
322 /*
323  * Called here at the end of every job that was
324  * hooked decrementing the active job_count. When
325  * it goes to zero, no one is using the associated
326  * resource table, so free it.
327  */
328 static void reload_job_end_cb(JCR *jcr, void *ctx)
329 {
330    int reload_id = (int)((long int)ctx);
331    Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
332       reload_id, reload_table[reload_id].job_count);
333    lock_jobs();
334    LockRes();
335    if (--reload_table[reload_id].job_count <= 0) {
336       free_saved_resources(reload_id);
337    }
338    UnlockRes();
339    unlock_jobs();
340 }
341
342 static int find_free_reload_table_entry()
343 {
344    int table = -1;
345    for (int i=0; i < max_reloads; i++) {
346       if (reload_table[i].res_table == NULL) {
347          table = i;
348          break;
349       }
350    }
351    return table;
352 }
353
354 /*
355  * If we get here, we have received a SIGHUP, which means to
356  *    reread our configuration file.
357  *
358  * The algorithm used is as follows: we count how many jobs are
359  *   running and mark the running jobs to make a callback on
360  *   exiting. The old config is saved with the reload table
361  *   id in a reload table. The new config file is read. Now, as
362  *   each job exits, it calls back to the reload_job_end_cb(), which
363  *   decrements the count of open jobs for the given reload table.
364  *   When the count goes to zero, we release those resources.
365  *   This allows us to have pointers into the resource table (from
366  *   jobs), and once they exit and all the pointers are released, we
367  *   release the old table. Note, if no new jobs are running since the
368  *   last reload, then the old resources will be immediately release.
369  *   A console is considered a job because it may have pointers to
370  *   resources, but a SYSTEM job is not since it *should* not have any
371  *   permanent pointers to jobs.
372  */
373 extern "C"
374 void reload_config(int sig)
375 {
376    static bool already_here = false;
377    sigset_t set;
378    JCR *jcr;
379    int njobs = 0;                     /* number of running jobs */
380    int table, rtable;
381    bool ok;       
382
383    if (already_here) {
384       abort();                        /* Oops, recursion -> die */
385    }
386    already_here = true;
387    sigemptyset(&set);
388    sigaddset(&set, SIGHUP);
389    sigprocmask(SIG_BLOCK, &set, NULL);
390
391    lock_jobs();
392    LockRes();
393
394    table = find_free_reload_table_entry();
395    if (table < 0) {
396       Jmsg(NULL, M_ERROR, 0, _("Too many open reload requests. Request ignored.\n"));
397       goto bail_out;
398    }
399
400    Dmsg1(100, "Reload_config njobs=%d\n", njobs);
401    reload_table[table].res_table = save_config_resources();
402    Dmsg1(100, "Saved old config in table %d\n", table);
403
404    ok = parse_config(configfile, 0);  /* no exit on error */
405
406    Dmsg0(100, "Reloaded config file\n");
407    if (!ok || !check_resources()) {
408       rtable = find_free_reload_table_entry();    /* save new, bad table */
409       if (rtable < 0) {
410          Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
411          Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n"));
412       } else {
413          Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
414          Jmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n"));
415       }
416       reload_table[rtable].res_table = save_config_resources();
417       /* Now restore old resoure values */
418       int num = r_last - r_first + 1;
419       RES **res_tab = reload_table[table].res_table;
420       for (int i=0; i<num; i++) {
421          res_head[i] = res_tab[i];
422       }
423       table = rtable;                 /* release new, bad, saved table below */
424    } else {
425       /*
426        * Hook all active jobs so that they release this table
427        */
428       foreach_jcr(jcr) {
429          if (jcr->JobType != JT_SYSTEM) {
430             reload_table[table].job_count++;
431             job_end_push(jcr, reload_job_end_cb, (void *)((long int)table));
432             njobs++;
433          }
434       }
435       endeach_jcr(jcr);
436    }
437
438    /* Reset globals */
439    set_working_directory(director->working_directory);
440    FDConnectTimeout = director->FDConnectTimeout;
441    SDConnectTimeout = director->SDConnectTimeout;
442    Dmsg0(0, "Director's configuration file reread.\n");
443
444    /* Now release saved resources, if no jobs using the resources */
445    if (njobs == 0) {
446       free_saved_resources(table);
447    }
448
449 bail_out:
450    UnlockRes();
451    unlock_jobs();
452    sigprocmask(SIG_UNBLOCK, &set, NULL);
453    signal(SIGHUP, reload_config);
454    already_here = false;
455 }
456
457 /*
458  * Make a quick check to see that we have all the
459  * resources needed.
460  *
461  *  **** FIXME **** this routine could be a lot more
462  *   intelligent and comprehensive.
463  */
464 static int check_resources()
465 {
466    bool OK = true;
467    JOB *job;
468
469    LockRes();
470
471    job = (JOB *)GetNextRes(R_JOB, NULL);
472    director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
473    if (!director) {
474       Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n"
475 "Without that I don't know who I am :-(\n"), configfile);
476       OK = false;
477    } else {
478       set_working_directory(director->working_directory);
479       if (!director->messages) {       /* If message resource not specified */
480          director->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
481          if (!director->messages) {
482             Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
483             OK = false;
484          }
485       }
486       if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) {
487          Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"),
488             configfile);
489          OK = false;
490       }
491       /* tls_require implies tls_enable */
492       if (director->tls_require) {
493          if (have_tls) {
494             director->tls_enable = true;
495          } else {
496             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
497             OK = false;
498          }
499       }
500
501       if (!director->tls_certfile && director->tls_enable) {
502          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
503             director->hdr.name, configfile);
504          OK = false;
505       }
506
507       if (!director->tls_keyfile && director->tls_enable) {
508          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
509             director->hdr.name, configfile);
510          OK = false;
511       }
512
513       if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable && director->tls_verify_peer) {
514          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
515               " Certificate Dir\" are defined for Director \"%s\" in %s."
516               " At least one CA certificate store is required"
517               " when using \"TLS Verify Peer\".\n"),
518               director->hdr.name, configfile);
519          OK = false;
520       }
521
522       /* If everything is well, attempt to initialize our per-resource TLS context */
523       if (OK && (director->tls_enable || director->tls_require)) {
524          /* Initialize TLS context:
525           * Args: CA certfile, CA certdir, Certfile, Keyfile,
526           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
527          director->tls_ctx = new_tls_context(director->tls_ca_certfile,
528             director->tls_ca_certdir, director->tls_certfile,
529             director->tls_keyfile, NULL, NULL, director->tls_dhfile,
530             director->tls_verify_peer);
531          
532          if (!director->tls_ctx) {
533             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
534                  director->hdr.name, configfile);
535             OK = false;
536          }
537       }
538    }
539
540    if (!job) {
541       Jmsg(NULL, M_FATAL, 0, _("No Job records defined in %s\n"), configfile);
542       OK = false;
543    }
544    foreach_res(job, R_JOB) {
545       int i;
546
547       if (job->jobdefs) {
548          /* Handle Storage alists specifically */
549          JOB *jobdefs = job->jobdefs;
550          if (jobdefs->storage && !job->storage) {
551             STORE *st;
552             job->storage = New(alist(10, not_owned_by_alist));
553             foreach_alist(st, jobdefs->storage) {
554                job->storage->append(st);
555             }
556          }
557
558          /* Transfer default items from JobDefs Resource */
559          for (i=0; job_items[i].name; i++) {
560             char **def_svalue, **svalue;  /* string value */
561             int *def_ivalue, *ivalue;     /* integer value */
562             bool *def_bvalue, *bvalue;    /* bool value */
563             int64_t *def_lvalue, *lvalue; /* 64 bit values */
564             uint32_t offset;
565
566             Dmsg4(1400, "Job \"%s\", field \"%s\" bit=%d def=%d\n",
567                 job->hdr.name, job_items[i].name,
568                 bit_is_set(i, job->hdr.item_present),
569                 bit_is_set(i, job->jobdefs->hdr.item_present));
570
571             if (!bit_is_set(i, job->hdr.item_present) &&
572                  bit_is_set(i, job->jobdefs->hdr.item_present)) {
573                Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n",
574                  job->hdr.name, job_items[i].name);
575                offset = (char *)(job_items[i].value) - (char *)&res_all;
576                /*
577                 * Handle strings and directory strings
578                 */
579                if (job_items[i].handler == store_str ||
580                    job_items[i].handler == store_dir) {
581                   def_svalue = (char **)((char *)(job->jobdefs) + offset);
582                   Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n",
583                        job->hdr.name, job_items[i].name, *def_svalue, i, offset);
584                   svalue = (char **)((char *)job + offset);
585                   if (*svalue) {
586                      Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
587                   }
588                   *svalue = bstrdup(*def_svalue);
589                   set_bit(i, job->hdr.item_present);
590                /*
591                 * Handle resources
592                 */
593                } else if (job_items[i].handler == store_res) {
594                   def_svalue = (char **)((char *)(job->jobdefs) + offset);
595                   Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n",
596                        job->hdr.name, job_items[i].name, i, offset);
597                   svalue = (char **)((char *)job + offset);
598                   if (*svalue) {
599                      Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
600                   }
601                   *svalue = *def_svalue;
602                   set_bit(i, job->hdr.item_present);
603                /*
604                 * Handle alist resources
605                 */
606                } else if (job_items[i].handler == store_alist_res) {
607                   if (bit_is_set(i, job->jobdefs->hdr.item_present)) {
608                      set_bit(i, job->hdr.item_present);
609                   }
610                /*
611                 * Handle integer fields
612                 *    Note, our store_bit does not handle bitmaped fields
613                 */
614                } else if (job_items[i].handler == store_bit     ||
615                           job_items[i].handler == store_pint    ||
616                           job_items[i].handler == store_jobtype ||
617                           job_items[i].handler == store_level   ||
618                           job_items[i].handler == store_pint    ||
619                           job_items[i].handler == store_replace) {
620                   def_ivalue = (int *)((char *)(job->jobdefs) + offset);
621                   Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n",
622                        job->hdr.name, job_items[i].name, *def_ivalue, i, offset);
623                   ivalue = (int *)((char *)job + offset);
624                   *ivalue = *def_ivalue;
625                   set_bit(i, job->hdr.item_present);
626                /*
627                 * Handle 64 bit integer fields
628                 */
629                } else if (job_items[i].handler == store_time   ||
630                           job_items[i].handler == store_size   ||
631                           job_items[i].handler == store_int64) {
632                   def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset);
633                   Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n",
634                        job->hdr.name, job_items[i].name, *def_lvalue, i, offset);
635                   lvalue = (int64_t *)((char *)job + offset);
636                   *lvalue = *def_lvalue;
637                   set_bit(i, job->hdr.item_present);
638                /*
639                 * Handle bool fields
640                 */
641                } else if (job_items[i].handler == store_bool) {
642                   def_bvalue = (bool *)((char *)(job->jobdefs) + offset);
643                   Dmsg5(400, "Job \"%s\", field \"%s\" def_bvalue=%d item %d offset=%u\n",
644                        job->hdr.name, job_items[i].name, *def_bvalue, i, offset);
645                   bvalue = (bool *)((char *)job + offset);
646                   *bvalue = *def_bvalue;
647                   set_bit(i, job->hdr.item_present);
648                }
649             }
650          }
651       }
652       /*
653        * Ensure that all required items are present
654        */
655       for (i=0; job_items[i].name; i++) {
656          if (job_items[i].flags & ITEM_REQUIRED) {
657                if (!bit_is_set(i, job->hdr.item_present)) {
658                   Jmsg(NULL, M_FATAL, 0, _("\"%s\" directive in Job \"%s\" resource is required, but not found.\n"),
659                     job_items[i].name, job->hdr.name);
660                   OK = false;
661                 }
662          }
663          /* If this triggers, take a look at lib/parse_conf.h */
664          if (i >= MAX_RES_ITEMS) {
665             Emsg0(M_ERROR_TERM, 0, _("Too many items in Job resource\n"));
666          }
667       }
668    } /* End loop over Job res */
669
670    /* Loop over databases */
671    CAT *catalog;
672    foreach_res(catalog, R_CATALOG) {
673       B_DB *db;
674       /*
675        * Make sure we can open catalog, otherwise print a warning
676        * message because the server is probably not running.
677        */
678       db = db_init_database(NULL, catalog->db_name, catalog->db_user,
679                          catalog->db_password, catalog->db_address,
680                          catalog->db_port, catalog->db_socket,
681                          catalog->mult_db_connections);
682       if (!db || !db_open_database(NULL, db)) {
683          Jmsg(NULL, M_FATAL, 0, _("Could not open database \"%s\".\n"),
684               catalog->db_name);
685          if (db) {
686             Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
687          }
688          OK = false;
689          continue;
690       }
691
692       /* Loop over all pools, defining/updating them in each database */
693       POOL *pool;
694       foreach_res(pool, R_POOL) {
695          create_pool(NULL, db, pool, POOL_OP_UPDATE);  /* update request */
696       }
697
698       STORE *store;
699       foreach_res(store, R_STORAGE) {
700          STORAGE_DBR sr;
701          MEDIATYPE_DBR mr;
702          if (store->media_type) {
703             bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
704             mr.ReadOnly = 0;
705             db_create_mediatype_record(NULL, db, &mr);
706          } else {
707             mr.MediaTypeId = 0;
708          }
709          bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
710          sr.AutoChanger = store->autochanger;
711          db_create_storage_record(NULL, db, &sr);
712          store->StorageId = sr.StorageId;   /* set storage Id */
713          if (!sr.created) {                 /* if not created, update it */
714             db_update_storage_record(NULL, db, &sr);
715          }
716
717          /* tls_require implies tls_enable */
718          if (store->tls_require) {
719             if (have_tls) {
720                store->tls_enable = true;
721             } else {
722                Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
723                OK = false;
724             }
725          } 
726
727          if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && store->tls_enable) {
728             Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
729                  " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
730                  store->hdr.name, configfile);
731             OK = false;
732          }
733
734          /* If everything is well, attempt to initialize our per-resource TLS context */
735          if (OK && (store->tls_enable || store->tls_require)) {
736            /* Initialize TLS context:
737             * Args: CA certfile, CA certdir, Certfile, Keyfile,
738             * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
739             store->tls_ctx = new_tls_context(store->tls_ca_certfile,
740                store->tls_ca_certdir, store->tls_certfile,
741                store->tls_keyfile, NULL, NULL, NULL, true);
742          
743             if (!store->tls_ctx) {
744                Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
745                     store->hdr.name, configfile);
746                OK = false;
747             }
748          }
749       }
750
751       /* Loop over all counters, defining them in each database */
752       /* Set default value in all counters */
753       COUNTER *counter;
754       foreach_res(counter, R_COUNTER) {
755          /* Write to catalog? */
756          if (!counter->created && counter->Catalog == catalog) {
757             COUNTER_DBR cr;
758             bstrncpy(cr.Counter, counter->hdr.name, sizeof(cr.Counter));
759             cr.MinValue = counter->MinValue;
760             cr.MaxValue = counter->MaxValue;
761             cr.CurrentValue = counter->MinValue;
762             if (counter->WrapCounter) {
763                bstrncpy(cr.WrapCounter, counter->WrapCounter->hdr.name, sizeof(cr.WrapCounter));
764             } else {
765                cr.WrapCounter[0] = 0;  /* empty string */
766             }
767             if (db_create_counter_record(NULL, db, &cr)) {
768                counter->CurrentValue = cr.CurrentValue;
769                counter->created = true;
770                Dmsg2(100, "Create counter %s val=%d\n", counter->hdr.name, counter->CurrentValue);
771             }
772          }
773          if (!counter->created) {
774             counter->CurrentValue = counter->MinValue;  /* default value */
775          }
776       }
777       db_close_database(NULL, db);
778    }
779
780    /* Loop over Consoles */
781    CONRES *cons;
782    foreach_res(cons, R_CONSOLE) {
783       /* tls_require implies tls_enable */
784       if (cons->tls_require) {
785          if (have_tls) {
786             cons->tls_enable = true;
787          } else {
788             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
789             OK = false;
790             continue;
791          }
792       }
793
794       if (!cons->tls_certfile && cons->tls_enable) {
795          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
796             cons->hdr.name, configfile);
797          OK = false;
798       }
799
800       if (!cons->tls_keyfile && cons->tls_enable) {
801          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
802             cons->hdr.name, configfile);
803          OK = false;
804       }
805
806       if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && cons->tls_enable && cons->tls_verify_peer) {
807          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
808             " Certificate Dir\" are defined for Console \"%s\" in %s."
809             " At least one CA certificate store is required"
810             " when using \"TLS Verify Peer\".\n"),
811             cons->hdr.name, configfile);
812          OK = false;
813       }
814       /* If everything is well, attempt to initialize our per-resource TLS context */
815       if (OK && (cons->tls_enable || cons->tls_require)) {
816          /* Initialize TLS context:
817           * Args: CA certfile, CA certdir, Certfile, Keyfile,
818           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
819          cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
820             cons->tls_ca_certdir, cons->tls_certfile,
821             cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
822          
823          if (!cons->tls_ctx) {
824             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
825                cons->hdr.name, configfile);
826             OK = false;
827          }
828       }
829
830    }
831
832    /* Loop over Clients */
833    CLIENT *client;
834    foreach_res(client, R_CLIENT) {
835       /* tls_require implies tls_enable */
836       if (client->tls_require) {
837          if (have_tls) {
838             client->tls_enable = true;
839          } else {
840             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
841             OK = false;
842             continue;
843          }
844       }
845
846       if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && client->tls_enable) {
847          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
848             " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
849             client->hdr.name, configfile);
850          OK = false;
851       }
852
853       /* If everything is well, attempt to initialize our per-resource TLS context */
854       if (OK && (client->tls_enable || client->tls_require)) {
855          /* Initialize TLS context:
856           * Args: CA certfile, CA certdir, Certfile, Keyfile,
857           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
858          client->tls_ctx = new_tls_context(client->tls_ca_certfile,
859             client->tls_ca_certdir, client->tls_certfile,
860             client->tls_keyfile, NULL, NULL, NULL,
861             true);
862          
863          if (!client->tls_ctx) {
864             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
865                client->hdr.name, configfile);
866             OK = false;
867          }
868       }
869    }
870
871    UnlockRes();
872    if (OK) {
873       close_msg(NULL);                /* close temp message handler */
874       init_msg(NULL, director->messages); /* open daemon message handler */
875    }
876    return OK;
877 }