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