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