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