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