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