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