]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/dird.c
kes Remove double quotes from ChangeLog and ReleaseNotes
[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 CONFIG *config;
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    config = new_config_parser();
232    config->init(configfile, NULL, M_ERROR_TERM, (void *)&res_all, res_all_size,
233                 r_first, r_last, resources, res_head);
234    config->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    debug_level = 0;                   /* turn off debug */
342    stop_watchdog();
343    generate_daemon_event(NULL, "Exit");
344    unload_plugins();
345    write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
346    delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
347    term_scheduler();
348    term_job_server();
349    if (runjob) {
350       free(runjob);
351    }
352    if (configfile != NULL) {
353       free(configfile);
354    }
355    if (debug_level > 5) {
356       print_memory_pool_stats();
357    }
358    config->free_resources();
359    free(config);
360    config = NULL;
361    term_ua_server();
362    term_msg();                        /* terminate message handler */
363    cleanup_crypto();
364    close_memory_pool();               /* release free memory in pool */
365    sm_dump(false);
366    exit(sig);
367 }
368
369 struct RELOAD_TABLE {
370    int job_count;
371    RES **res_table;
372 };
373
374 static const int max_reloads = 32;
375 static RELOAD_TABLE reload_table[max_reloads];
376
377 static void init_reload(void)
378 {
379    for (int i=0; i < max_reloads; i++) {
380       reload_table[i].job_count = 0;
381       reload_table[i].res_table = NULL;
382    }
383 }
384
385 static void free_saved_resources(int table)
386 {
387    int num = r_last - r_first + 1;
388    RES **res_tab = reload_table[table].res_table;
389    if (!res_tab) {
390       Dmsg1(100, "res_tab for table %d already released.\n", table);
391       return;
392    }
393    Dmsg1(100, "Freeing resources for table %d\n", table);
394    for (int j=0; j<num; j++) {
395       free_resource(res_tab[j], r_first + j);
396    }
397    free(res_tab);
398    reload_table[table].job_count = 0;
399    reload_table[table].res_table = NULL;
400 }
401
402 /*
403  * Called here at the end of every job that was
404  * hooked decrementing the active job_count. When
405  * it goes to zero, no one is using the associated
406  * resource table, so free it.
407  */
408 static void reload_job_end_cb(JCR *jcr, void *ctx)
409 {
410    int reload_id = (int)((long int)ctx);
411    Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
412       reload_id, reload_table[reload_id].job_count);
413    lock_jobs();
414    LockRes();
415    if (--reload_table[reload_id].job_count <= 0) {
416       free_saved_resources(reload_id);
417    }
418    UnlockRes();
419    unlock_jobs();
420 }
421
422 static int find_free_reload_table_entry()
423 {
424    int table = -1;
425    for (int i=0; i < max_reloads; i++) {
426       if (reload_table[i].res_table == NULL) {
427          table = i;
428          break;
429       }
430    }
431    return table;
432 }
433
434 /*
435  * If we get here, we have received a SIGHUP, which means to
436  *    reread our configuration file.
437  *
438  * The algorithm used is as follows: we count how many jobs are
439  *   running and mark the running jobs to make a callback on
440  *   exiting. The old config is saved with the reload table
441  *   id in a reload table. The new config file is read. Now, as
442  *   each job exits, it calls back to the reload_job_end_cb(), which
443  *   decrements the count of open jobs for the given reload table.
444  *   When the count goes to zero, we release those resources.
445  *   This allows us to have pointers into the resource table (from
446  *   jobs), and once they exit and all the pointers are released, we
447  *   release the old table. Note, if no new jobs are running since the
448  *   last reload, then the old resources will be immediately release.
449  *   A console is considered a job because it may have pointers to
450  *   resources, but a SYSTEM job is not since it *should* not have any
451  *   permanent pointers to jobs.
452  */
453 extern "C"
454 void reload_config(int sig)
455 {
456    static bool already_here = false;
457 #if !defined(HAVE_WIN32)
458    sigset_t set;
459 #endif
460    JCR *jcr;
461    int njobs = 0;                     /* number of running jobs */
462    int table, rtable;
463    bool ok;       
464
465    if (already_here) {
466       abort();                        /* Oops, recursion -> die */
467    }
468    already_here = true;
469
470 #if !defined(HAVE_WIN32)
471    sigemptyset(&set);
472    sigaddset(&set, SIGHUP);
473    sigprocmask(SIG_BLOCK, &set, NULL);
474 #endif
475
476    lock_jobs();
477    LockRes();
478
479    table = find_free_reload_table_entry();
480    if (table < 0) {
481       Jmsg(NULL, M_ERROR, 0, _("Too many open reload requests. Request ignored.\n"));
482       goto bail_out;
483    }
484
485    Dmsg1(100, "Reload_config njobs=%d\n", njobs);
486    reload_table[table].res_table = config->save_resources();
487    Dmsg1(100, "Saved old config in table %d\n", table);
488
489    ok = parse_config(configfile, 0, M_ERROR);  /* no exit on error */
490
491    Dmsg0(100, "Reloaded config file\n");
492    if (!ok || !check_resources() || !check_catalog()) {
493       rtable = find_free_reload_table_entry();    /* save new, bad table */
494       if (rtable < 0) {
495          Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
496          Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n"));
497       } else {
498          Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
499          Jmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n"));
500       }
501       reload_table[rtable].res_table = config->save_resources();
502       /* Now restore old resoure values */
503       int num = r_last - r_first + 1;
504       RES **res_tab = reload_table[table].res_table;
505       for (int i=0; i<num; i++) {
506          res_head[i] = res_tab[i];
507       }
508       table = rtable;                 /* release new, bad, saved table below */
509    } else {
510       invalidate_schedules();
511       /*
512        * Hook all active jobs so that they release this table
513        */
514       foreach_jcr(jcr) {
515          if (jcr->JobType != JT_SYSTEM) {
516             reload_table[table].job_count++;
517             job_end_push(jcr, reload_job_end_cb, (void *)((long int)table));
518             njobs++;
519          }
520       }
521       endeach_jcr(jcr);
522    }
523
524    /* Reset globals */
525    set_working_directory(director->working_directory);
526    FDConnectTimeout = director->FDConnectTimeout;
527    SDConnectTimeout = director->SDConnectTimeout;
528    Dmsg0(10, "Director's configuration file reread.\n");
529
530    /* Now release saved resources, if no jobs using the resources */
531    if (njobs == 0) {
532       free_saved_resources(table);
533    }
534
535 bail_out:
536    UnlockRes();
537    unlock_jobs();
538 #if !defined(HAVE_WIN32)
539    sigprocmask(SIG_UNBLOCK, &set, NULL);
540    signal(SIGHUP, reload_config);
541 #endif
542    already_here = false;
543 }
544
545 /*
546  * Make a quick check to see that we have all the
547  * resources needed.
548  *
549  *  **** FIXME **** this routine could be a lot more
550  *   intelligent and comprehensive.
551  */
552 static bool check_resources()
553 {
554    bool OK = true;
555    JOB *job;
556    bool need_tls;
557
558    LockRes();
559
560    job = (JOB *)GetNextRes(R_JOB, NULL);
561    director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
562    if (!director) {
563       Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n"
564 "Without that I don't know who I am :-(\n"), configfile);
565       OK = false;
566    } else {
567       set_working_directory(director->working_directory);
568       if (!director->messages) {       /* If message resource not specified */
569          director->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
570          if (!director->messages) {
571             Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
572             OK = false;
573          }
574       }
575       if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) {
576          Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"),
577             configfile);
578          OK = false;
579       }
580       /* tls_require implies tls_enable */
581       if (director->tls_require) {
582          if (have_tls) {
583             director->tls_enable = true;
584          } else {
585             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
586             OK = false;
587          }
588       }
589
590       need_tls = director->tls_enable || director->tls_authenticate;
591
592       if (!director->tls_certfile && need_tls) {
593          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
594             director->name(), configfile);
595          OK = false;
596       }
597
598       if (!director->tls_keyfile && need_tls) {
599          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
600             director->name(), configfile);
601          OK = false;
602       }
603
604       if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && 
605            need_tls && director->tls_verify_peer) {
606          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
607               " Certificate Dir\" are defined for Director \"%s\" in %s."
608               " At least one CA certificate store is required"
609               " when using \"TLS Verify Peer\".\n"),
610               director->name(), configfile);
611          OK = false;
612       }
613
614       /* If everything is well, attempt to initialize our per-resource TLS context */
615       if (OK && (need_tls || director->tls_require)) {
616          /* Initialize TLS context:
617           * Args: CA certfile, CA certdir, Certfile, Keyfile,
618           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
619          director->tls_ctx = new_tls_context(director->tls_ca_certfile,
620             director->tls_ca_certdir, director->tls_certfile,
621             director->tls_keyfile, NULL, NULL, director->tls_dhfile,
622             director->tls_verify_peer);
623          
624          if (!director->tls_ctx) {
625             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
626                  director->name(), configfile);
627             OK = false;
628          }
629       }
630    }
631
632    if (!job) {
633       Jmsg(NULL, M_FATAL, 0, _("No Job records defined in %s\n"), configfile);
634       OK = false;
635    }
636    foreach_res(job, R_JOB) {
637       int i;
638
639       if (job->jobdefs) {
640          /* Handle Storage alists specifically */
641          JOB *jobdefs = job->jobdefs;
642          if (jobdefs->storage && !job->storage) {
643             STORE *st;
644             job->storage = New(alist(10, not_owned_by_alist));
645             foreach_alist(st, jobdefs->storage) {
646                job->storage->append(st);
647             }
648          }
649          /* Handle RunScripts alists specifically */
650          if (jobdefs->RunScripts) {
651             RUNSCRIPT *rs, *elt;
652             
653             if (!job->RunScripts) {
654                job->RunScripts = New(alist(10, not_owned_by_alist));
655             }
656            
657             foreach_alist(rs, jobdefs->RunScripts) {
658                elt = copy_runscript(rs);
659                job->RunScripts->append(elt); /* we have to free it */
660             }
661          }
662
663          /* Transfer default items from JobDefs Resource */
664          for (i=0; job_items[i].name; i++) {
665             char **def_svalue, **svalue;  /* string value */
666             int *def_ivalue, *ivalue;     /* integer value */
667             bool *def_bvalue, *bvalue;    /* bool value */
668             int64_t *def_lvalue, *lvalue; /* 64 bit values */
669             uint32_t offset;
670
671             Dmsg4(1400, "Job \"%s\", field \"%s\" bit=%d def=%d\n",
672                 job->name(), job_items[i].name,
673                 bit_is_set(i, job->hdr.item_present),
674                 bit_is_set(i, job->jobdefs->hdr.item_present));
675
676             if (!bit_is_set(i, job->hdr.item_present) &&
677                  bit_is_set(i, job->jobdefs->hdr.item_present)) {
678                Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n",
679                  job->name(), job_items[i].name);
680                offset = (char *)(job_items[i].value) - (char *)&res_all;
681                /*
682                 * Handle strings and directory strings
683                 */
684                if (job_items[i].handler == store_str ||
685                    job_items[i].handler == store_dir) {
686                   def_svalue = (char **)((char *)(job->jobdefs) + offset);
687                   Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n",
688                        job->name(), job_items[i].name, *def_svalue, i, offset);
689                   svalue = (char **)((char *)job + offset);
690                   if (*svalue) {
691                      Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
692                   }
693                   *svalue = bstrdup(*def_svalue);
694                   set_bit(i, job->hdr.item_present);
695                /*
696                 * Handle resources
697                 */
698                } else if (job_items[i].handler == store_res) {
699                   def_svalue = (char **)((char *)(job->jobdefs) + offset);
700                   Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n",
701                        job->name(), job_items[i].name, i, offset);
702                   svalue = (char **)((char *)job + offset);
703                   if (*svalue) {
704                      Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue);
705                   }
706                   *svalue = *def_svalue;
707                   set_bit(i, job->hdr.item_present);
708                /*
709                 * Handle alist resources
710                 */
711                } else if (job_items[i].handler == store_alist_res) {
712                   if (bit_is_set(i, job->jobdefs->hdr.item_present)) {
713                      set_bit(i, job->hdr.item_present);
714                   }
715                /*
716                 * Handle integer fields
717                 *    Note, our store_bit does not handle bitmaped fields
718                 */
719                } else if (job_items[i].handler == store_bit     ||
720                           job_items[i].handler == store_pint    ||
721                           job_items[i].handler == store_jobtype ||
722                           job_items[i].handler == store_level   ||
723                           job_items[i].handler == store_pint    ||
724                           job_items[i].handler == store_migtype ||
725                           job_items[i].handler == store_replace) {
726                   def_ivalue = (int *)((char *)(job->jobdefs) + offset);
727                   Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n",
728                        job->name(), job_items[i].name, *def_ivalue, i, offset);
729                   ivalue = (int *)((char *)job + offset);
730                   *ivalue = *def_ivalue;
731                   set_bit(i, job->hdr.item_present);
732                /*
733                 * Handle 64 bit integer fields
734                 */
735                } else if (job_items[i].handler == store_time   ||
736                           job_items[i].handler == store_size   ||
737                           job_items[i].handler == store_int64) {
738                   def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset);
739                   Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n",
740                        job->name(), job_items[i].name, *def_lvalue, i, offset);
741                   lvalue = (int64_t *)((char *)job + offset);
742                   *lvalue = *def_lvalue;
743                   set_bit(i, job->hdr.item_present);
744                /*
745                 * Handle bool fields
746                 */
747                } else if (job_items[i].handler == store_bool) {
748                   def_bvalue = (bool *)((char *)(job->jobdefs) + offset);
749                   Dmsg5(400, "Job \"%s\", field \"%s\" def_bvalue=%d item %d offset=%u\n",
750                        job->name(), job_items[i].name, *def_bvalue, i, offset);
751                   bvalue = (bool *)((char *)job + offset);
752                   *bvalue = *def_bvalue;
753                   set_bit(i, job->hdr.item_present);
754                }
755             }
756          }
757       }
758       /*
759        * Ensure that all required items are present
760        */
761       for (i=0; job_items[i].name; i++) {
762          if (job_items[i].flags & ITEM_REQUIRED) {
763                if (!bit_is_set(i, job->hdr.item_present)) {
764                   Jmsg(NULL, M_ERROR_TERM, 0, _("\"%s\" directive in Job \"%s\" resource is required, but not found.\n"),
765                     job_items[i].name, job->name());
766                   OK = false;
767                 }
768          }
769          /* If this triggers, take a look at lib/parse_conf.h */
770          if (i >= MAX_RES_ITEMS) {
771             Emsg0(M_ERROR_TERM, 0, _("Too many items in Job resource\n"));
772          }
773       }
774       if (!job->storage && !job->pool->storage) {
775          Jmsg(NULL, M_FATAL, 0, _("No storage specified in Job \"%s\" nor in Pool.\n"),
776             job->name());
777          OK = false;
778       }
779    } /* End loop over Job res */
780
781
782    /* Loop over Consoles */
783    CONRES *cons;
784    foreach_res(cons, R_CONSOLE) {
785       /* tls_require implies tls_enable */
786       if (cons->tls_require) {
787          if (have_tls) {
788             cons->tls_enable = true;
789          } else {
790             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
791             OK = false;
792             continue;
793          }
794       }
795
796       need_tls = cons->tls_enable || cons->tls_authenticate;
797       
798       if (!cons->tls_certfile && need_tls) {
799          Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
800             cons->name(), configfile);
801          OK = false;
802       }
803
804       if (!cons->tls_keyfile && need_tls) {
805          Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"),
806             cons->name(), configfile);
807          OK = false;
808       }
809
810       if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) 
811             && need_tls && cons->tls_verify_peer) {
812          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA"
813             " Certificate Dir\" are defined for Console \"%s\" in %s."
814             " At least one CA certificate store is required"
815             " when using \"TLS Verify Peer\".\n"),
816             cons->name(), configfile);
817          OK = false;
818       }
819       /* If everything is well, attempt to initialize our per-resource TLS context */
820       if (OK && (need_tls || cons->tls_require)) {
821          /* Initialize TLS context:
822           * Args: CA certfile, CA certdir, Certfile, Keyfile,
823           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
824          cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
825             cons->tls_ca_certdir, cons->tls_certfile,
826             cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer);
827          
828          if (!cons->tls_ctx) {
829             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
830                cons->name(), configfile);
831             OK = false;
832          }
833       }
834
835    }
836
837    /* Loop over Clients */
838    CLIENT *client;
839    foreach_res(client, R_CLIENT) {
840       /* tls_require implies tls_enable */
841       if (client->tls_require) {
842          if (have_tls) {
843             client->tls_enable = true;
844          } else {
845             Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
846             OK = false;
847             continue;
848          }
849       }
850       need_tls = client->tls_enable || client->tls_authenticate;
851       if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && need_tls) {
852          Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
853             " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"),
854             client->name(), configfile);
855          OK = false;
856       }
857
858       /* If everything is well, attempt to initialize our per-resource TLS context */
859       if (OK && (need_tls || client->tls_require)) {
860          /* Initialize TLS context:
861           * Args: CA certfile, CA certdir, Certfile, Keyfile,
862           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
863          client->tls_ctx = new_tls_context(client->tls_ca_certfile,
864             client->tls_ca_certdir, client->tls_certfile,
865             client->tls_keyfile, NULL, NULL, NULL,
866             true);
867          
868          if (!client->tls_ctx) {
869             Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
870                client->name(), configfile);
871             OK = false;
872          }
873       }
874    }
875
876    UnlockRes();
877    if (OK) {
878       close_msg(NULL);                /* close temp message handler */
879       init_msg(NULL, director->messages); /* open daemon message handler */
880    }
881    return OK;
882 }
883
884 static bool check_catalog()
885 {
886    bool OK = true;
887    bool need_tls;
888
889    /* Loop over databases */
890    CAT *catalog;
891    foreach_res(catalog, R_CATALOG) {
892       B_DB *db;
893       /*
894        * Make sure we can open catalog, otherwise print a warning
895        * message because the server is probably not running.
896        */
897       db = db_init(NULL, catalog->db_driver, catalog->db_name, catalog->db_user,
898                          catalog->db_password, catalog->db_address,
899                          catalog->db_port, catalog->db_socket,
900                          catalog->mult_db_connections);
901       if (!db || !db_open_database(NULL, db)) {
902          Pmsg2(000, _("Could not open Catalog \"%s\", database \"%s\".\n"),
903               catalog->name(), catalog->db_name);
904          Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
905               catalog->name(), catalog->db_name);
906          if (db) {
907             Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
908             Pmsg1(000, "%s", db_strerror(db));
909             db_close_database(NULL, db);
910          }
911          OK = false;
912          continue;
913       }
914
915       /* Loop over all pools, defining/updating them in each database */
916       POOL *pool;
917       foreach_res(pool, R_POOL) {
918          /*
919           * If the Pool has a catalog resource create the pool only
920           *   in that catalog.
921           */
922          if (!pool->catalog || pool->catalog == catalog) {
923             create_pool(NULL, db, pool, POOL_OP_UPDATE);  /* update request */
924             update_pool_recyclepool(NULL, db, pool);
925          }
926       }
927
928       STORE *store;
929       foreach_res(store, R_STORAGE) {
930          STORAGE_DBR sr;
931          MEDIATYPE_DBR mr;
932          if (store->media_type) {
933             bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
934             mr.ReadOnly = 0;
935             db_create_mediatype_record(NULL, db, &mr);
936          } else {
937             mr.MediaTypeId = 0;
938          }
939          bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
940          sr.AutoChanger = store->autochanger;
941          db_create_storage_record(NULL, db, &sr);
942          store->StorageId = sr.StorageId;   /* set storage Id */
943          if (!sr.created) {                 /* if not created, update it */
944             db_update_storage_record(NULL, db, &sr);
945          }
946
947          /* tls_require implies tls_enable */
948          if (store->tls_require) {
949             if (have_tls) {
950                store->tls_enable = true;
951             } else {
952                Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
953                OK = false;
954             }
955          } 
956
957          need_tls = store->tls_enable || store->tls_authenticate;
958
959          if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && need_tls) {
960             Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
961                  " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"),
962                  store->name(), configfile);
963             OK = false;
964          }
965
966          /* If everything is well, attempt to initialize our per-resource TLS context */
967          if (OK && (need_tls || store->tls_require)) {
968            /* Initialize TLS context:
969             * Args: CA certfile, CA certdir, Certfile, Keyfile,
970             * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
971             store->tls_ctx = new_tls_context(store->tls_ca_certfile,
972                store->tls_ca_certdir, store->tls_certfile,
973                store->tls_keyfile, NULL, NULL, NULL, true);
974          
975             if (!store->tls_ctx) {
976                Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"),
977                     store->name(), configfile);
978                OK = false;
979             }
980          }
981       }
982
983       /* Loop over all counters, defining them in each database */
984       /* Set default value in all counters */
985       COUNTER *counter;
986       foreach_res(counter, R_COUNTER) {
987          /* Write to catalog? */
988          if (!counter->created && counter->Catalog == catalog) {
989             COUNTER_DBR cr;
990             bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter));
991             cr.MinValue = counter->MinValue;
992             cr.MaxValue = counter->MaxValue;
993             cr.CurrentValue = counter->MinValue;
994             if (counter->WrapCounter) {
995                bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter));
996             } else {
997                cr.WrapCounter[0] = 0;  /* empty string */
998             }
999             if (db_create_counter_record(NULL, db, &cr)) {
1000                counter->CurrentValue = cr.CurrentValue;
1001                counter->created = true;
1002                Dmsg2(100, "Create counter %s val=%d\n", counter->name(), counter->CurrentValue);
1003             }
1004          }
1005          if (!counter->created) {
1006             counter->CurrentValue = counter->MinValue;  /* default value */
1007          }
1008       }
1009       db_close_database(NULL, db);
1010    }
1011    /* Set type in global for debugging */
1012    set_db_type(db_get_type());
1013    return OK;
1014 }