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