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