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