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