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