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