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