]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/filed.c
kes Add code to help Dan debug 2drive-incremental-2disk test.
[bacula/bacula] / bacula / src / filed / filed.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of John Walker.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  *  Bacula File Daemon
30  *
31  *    Kern Sibbald, March MM
32  *
33  *   Version $Id$
34  *
35  */
36
37 #include "bacula.h"
38 #include "filed.h"
39
40 /* Imported Functions */
41 extern void *handle_client_request(void *dir_sock);
42
43 /* Forward referenced functions */
44 void terminate_filed(int sig);
45 static bool check_resources();
46
47 /* Exported variables */
48 CLIENT *me;                           /* my resource */
49 bool no_signals = false;
50 void *start_heap;
51
52
53 #define CONFIG_FILE "bacula-fd.conf" /* default config file */
54
55 char *configfile = NULL;
56 static bool foreground = false;
57 static workq_t dir_workq;             /* queue of work from Director */
58 static pthread_t server_tid;
59
60
61 static void usage()
62 {
63    Pmsg3(-1, _(
64 PROG_COPYRIGHT
65 "\nVersion: %s (%s)\n\n"
66 "Usage: bacula-fd [-f -s] [-c config_file] [-d debug_level]\n"
67 "        -c <file>   use <file> as configuration file\n"
68 "        -dnn        set debug level to nn\n"
69 "        -f          run in foreground (for debugging)\n"
70 "        -g          groupid\n"
71 "        -s          no signals (for debugging)\n"
72 "        -t          test configuration file and exit\n"
73 "        -u          userid\n"
74 "        -v          verbose user messages\n"
75 "        -?          print this message.\n"
76 "\n"), 2000, VERSION, BDATE);
77    exit(1);
78 }
79
80
81 /*********************************************************************
82  *
83  *  Main Bacula Unix Client Program
84  *
85  */
86 #if defined(HAVE_WIN32)
87 #define main BaculaMain
88 #endif
89
90 int main (int argc, char *argv[])
91 {
92    int ch;
93    bool test_config = false;
94    char *uid = NULL;
95    char *gid = NULL;
96
97    start_heap = sbrk(0);
98    setlocale(LC_ALL, "");
99    bindtextdomain("bacula", LOCALEDIR);
100    textdomain("bacula");
101
102    init_stack_dump();
103    my_name_is(argc, argv, "bacula-fd");
104    init_msg(NULL, NULL);
105    daemon_start_time = time(NULL);
106
107    while ((ch = getopt(argc, argv, "c:d:fg:stu:v?")) != -1) {
108       switch (ch) {
109       case 'c':                    /* configuration file */
110          if (configfile != NULL) {
111             free(configfile);
112          }
113          configfile = bstrdup(optarg);
114          break;
115
116       case 'd':                    /* debug level */
117          debug_level = atoi(optarg);
118          if (debug_level <= 0) {
119             debug_level = 1;
120          }
121          break;
122
123       case 'f':                    /* run in foreground */
124          foreground = true;
125          break;
126
127       case 'g':                    /* set group */
128          gid = optarg;
129          break;
130
131       case 's':
132          no_signals = true;
133          break;
134
135       case 't':
136          test_config = true;
137          break;
138
139       case 'u':                    /* set userid */
140          uid = optarg;
141          break;
142
143       case 'v':                    /* verbose */
144          verbose++;
145          break;
146
147       case '?':
148       default:
149          usage();
150
151       }
152    }
153    argc -= optind;
154    argv += optind;
155
156    if (argc) {
157       if (configfile != NULL)
158          free(configfile);
159       configfile = bstrdup(*argv);
160       argc--;
161       argv++;
162    }
163    if (argc) {
164       usage();
165    }
166
167    server_tid = pthread_self();
168    if (!no_signals) {
169       init_signals(terminate_filed);
170    } else {
171       /* This reduces the number of signals facilitating debugging */
172       watchdog_sleep_time = 120;      /* long timeout for debugging */
173    }
174
175    if (configfile == NULL) {
176       configfile = bstrdup(CONFIG_FILE);
177    }
178
179    parse_config(configfile);
180
181    if (init_crypto() != 0) {
182       Emsg0(M_ERROR, 0, _("Cryptography library initialization failed.\n"));
183       terminate_filed(1);
184    }
185
186    if (!check_resources()) {
187       Emsg1(M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
188       terminate_filed(1);
189    }
190
191    set_working_directory(me->working_directory);
192
193    if (test_config) {
194       terminate_filed(0);
195    }
196
197    if (!foreground) {
198       daemon_start();
199       init_stack_dump();              /* set new pid */
200    }
201
202    /* Maximum 1 daemon at a time */
203    create_pid_file(me->pid_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
204    read_state_file(me->working_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
205
206    drop(uid, gid);
207
208 #ifdef BOMB
209    me += 1000000;
210 #endif
211
212    init_python_interpreter(me->hdr.name, me->scripts_directory, "FDStartUp");
213
214    set_thread_concurrency(10);
215
216    if (!no_signals) {
217       start_watchdog();               /* start watchdog thread */
218       init_jcr_subsystem();           /* start JCR watchdogs etc. */
219    }
220    server_tid = pthread_self();
221
222    /* Become server, and handle requests */
223    IPADDR *p;
224    foreach_dlist(p, me->FDaddrs) {
225       Dmsg1(10, "filed: listening on port %d\n", p->get_port_host_order());
226    }
227    bnet_thread_server(me->FDaddrs, me->MaxConcurrentJobs, &dir_workq, handle_client_request);
228
229    terminate_filed(0);
230    exit(0);                           /* should never get here */
231 }
232
233 void terminate_filed(int sig)
234 {
235    static bool already_here = false;
236
237    if (already_here) {
238       bmicrosleep(2, 0);              /* yield */
239       exit(1);                        /* prevent loops */
240    }
241    already_here = true;
242    stop_watchdog();
243
244    bnet_stop_thread_server(server_tid);
245    generate_daemon_event(NULL, "Exit");
246    write_state_file(me->working_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
247    delete_pid_file(me->pid_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
248
249    if (configfile != NULL) {
250       free(configfile);
251    }
252
253    if (debug_level > 0) {
254       print_memory_pool_stats();
255    }
256    term_msg();
257    free_config_resources();
258    cleanup_crypto();
259    close_memory_pool();               /* release free memory in pool */
260    sm_dump(false);                    /* dump orphaned buffers */
261    exit(sig);
262 }
263
264 /*
265 * Make a quick check to see that we have all the
266 * resources needed.
267 */
268 static bool check_resources()
269 {
270    bool OK = true;
271    DIRRES *director;
272
273    LockRes();
274
275    me = (CLIENT *)GetNextRes(R_CLIENT, NULL);
276    if (!me) {
277       Emsg1(M_FATAL, 0, _("No File daemon resource defined in %s\n"
278             "Without that I don't know who I am :-(\n"), configfile);
279       OK = false;
280    } else {
281       if (GetNextRes(R_CLIENT, (RES *) me) != NULL) {
282          Emsg1(M_FATAL, 0, _("Only one Client resource permitted in %s\n"),
283               configfile);
284          OK = false;
285       }
286       my_name_is(0, NULL, me->hdr.name);
287       if (!me->messages) {
288          me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
289          if (!me->messages) {
290              Emsg1(M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
291              OK = false;
292          }
293       }
294       /* tls_require implies tls_enable */
295       if (me->tls_require) {
296 #ifndef HAVE_TLS
297          Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
298          OK = false;
299 #else
300          me->tls_enable = true;
301 #endif
302       }
303
304       if ((!me->tls_ca_certfile && !me->tls_ca_certdir) && me->tls_enable) {
305          Emsg1(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
306             " or \"TLS CA Certificate Dir\" are defined for File daemon in %s.\n"),
307                             configfile);
308         OK = false;
309       }
310
311       /* If everything is well, attempt to initialize our per-resource TLS context */
312       if (OK && (me->tls_enable || me->tls_require)) {
313          /* Initialize TLS context:
314           * Args: CA certfile, CA certdir, Certfile, Keyfile,
315           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
316          me->tls_ctx = new_tls_context(me->tls_ca_certfile,
317             me->tls_ca_certdir, me->tls_certfile, me->tls_keyfile,
318             NULL, NULL, NULL, true);
319
320          if (!me->tls_ctx) { 
321             Emsg2(M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
322                                 me->hdr.name, configfile);
323             OK = false;
324          }
325       }
326
327       if (me->pki_encrypt || me->pki_sign) {
328 #ifndef HAVE_CRYPTO
329          Jmsg(NULL, M_FATAL, 0, _("PKI encryption/signing enabled but not compiled into Bacula.\n"));
330          OK = false;
331 #endif
332       }
333
334       /* pki_encrypt implies pki_sign */
335       if (me->pki_encrypt) {
336          me->pki_sign = true;
337       }
338
339       if ((me->pki_encrypt || me->pki_sign) && !me->pki_keypair_file) {
340          Emsg2(M_FATAL, 0, _("\"PKI Key Pair\" must be defined for File"
341             " daemon \"%s\" in %s if either \"PKI Sign\" or"
342             " \"PKI Encrypt\" are enabled.\n"), me->hdr.name, configfile);
343          OK = false;
344       }
345
346       /* If everything is well, attempt to initialize our public/private keys */
347       if (OK && (me->pki_encrypt || me->pki_sign)) {
348          char *filepath;
349          /* Load our keypair */
350          me->pki_keypair = crypto_keypair_new();
351          if (!me->pki_keypair) {
352             Emsg0(M_FATAL, 0, _("Failed to allocate a new keypair object.\n"));
353             OK = false;
354          } else {
355             if (!crypto_keypair_load_cert(me->pki_keypair, me->pki_keypair_file)) {
356                Emsg2(M_FATAL, 0, _("Failed to load public certificate for File"
357                      " daemon \"%s\" in %s.\n"), me->hdr.name, configfile);
358                OK = false;
359             }
360
361             if (!crypto_keypair_load_key(me->pki_keypair, me->pki_keypair_file, NULL, NULL)) {
362                Emsg2(M_FATAL, 0, _("Failed to load private key for File"
363                      " daemon \"%s\" in %s.\n"), me->hdr.name, configfile);
364                OK = false;
365             }
366          }
367
368          /*
369           * Trusted Signers. We're always trusted.
370           */
371          me->pki_signers = New(alist(10, not_owned_by_alist));
372          if (me->pki_keypair) {
373             me->pki_signers->append(crypto_keypair_dup(me->pki_keypair));
374          }
375
376          /* If additional signing public keys have been specified, load them up */
377          if (me->pki_signing_key_files) {
378             foreach_alist(filepath, me->pki_signing_key_files) {
379                X509_KEYPAIR *keypair;
380
381                keypair = crypto_keypair_new();
382                if (!keypair) {
383                   Emsg0(M_FATAL, 0, _("Failed to allocate a new keypair object.\n"));
384                   OK = false;
385                } else {
386                   if (crypto_keypair_load_cert(keypair, filepath)) {
387                      me->pki_signers->append(keypair);
388
389                      /* Attempt to load a private key, if available */
390                      if (crypto_keypair_has_key(filepath)) {
391                         if (!crypto_keypair_load_key(keypair, filepath, NULL, NULL)) {
392                            Emsg3(M_FATAL, 0, _("Failed to load private key from file %s for File"
393                               " daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile);
394                            OK = false;
395                         }
396                      }
397
398                   } else {
399                      Emsg3(M_FATAL, 0, _("Failed to load trusted signer certificate"
400                         " from file %s for File daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile);
401                      OK = false;
402                   }
403                }
404             }
405          }
406
407          /*
408           * Crypto recipients. We're always included as a recipient.
409           * The symmetric session key will be encrypted for each of these readers.
410           */
411          me->pki_recipients = New(alist(10, not_owned_by_alist));
412          if (me->pki_keypair) {
413             me->pki_recipients->append(crypto_keypair_dup(me->pki_keypair));
414          }
415
416
417          /* If additional keys have been specified, load them up */
418          if (me->pki_master_key_files) {
419             foreach_alist(filepath, me->pki_master_key_files) {
420                X509_KEYPAIR *keypair;
421
422                keypair = crypto_keypair_new();
423                if (!keypair) {
424                   Emsg0(M_FATAL, 0, _("Failed to allocate a new keypair object.\n"));
425                   OK = false;
426                } else {
427                   if (crypto_keypair_load_cert(keypair, filepath)) {
428                      me->pki_recipients->append(keypair);
429                   } else {
430                      Emsg3(M_FATAL, 0, _("Failed to load master key certificate"
431                         " from file %s for File daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile);
432                      OK = false;
433                   }
434                }
435             }
436          }
437       }
438    }
439
440
441    /* Verify that a director record exists */
442    LockRes();
443    director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
444    UnlockRes();
445    if (!director) {
446       Emsg1(M_FATAL, 0, _("No Director resource defined in %s\n"),
447             configfile);
448       OK = false;
449    }
450
451    foreach_res(director, R_DIRECTOR) { 
452       /* tls_require implies tls_enable */
453       if (director->tls_require) {
454 #ifndef HAVE_TLS
455          Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
456          OK = false;
457          continue;
458 #else
459          director->tls_enable = true;
460 #endif
461       }
462
463       if (!director->tls_certfile && director->tls_enable) {
464          Emsg2(M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
465                director->hdr.name, configfile);
466          OK = false;
467       }
468
469       if (!director->tls_keyfile && director->tls_enable) {
470          Emsg2(M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
471                director->hdr.name, configfile);
472          OK = false;
473       }
474
475       if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable && director->tls_verify_peer) {
476          Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
477                              " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
478                              " At least one CA certificate store is required"
479                              " when using \"TLS Verify Peer\".\n"),
480                              director->hdr.name, configfile);
481          OK = false;
482       }
483
484       /* If everything is well, attempt to initialize our per-resource TLS context */
485       if (OK && (director->tls_enable || director->tls_require)) {
486          /* Initialize TLS context:
487           * Args: CA certfile, CA certdir, Certfile, Keyfile,
488           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
489          director->tls_ctx = new_tls_context(director->tls_ca_certfile,
490             director->tls_ca_certdir, director->tls_certfile,
491             director->tls_keyfile, NULL, NULL, director->tls_dhfile,
492             director->tls_verify_peer);
493
494          if (!director->tls_ctx) { 
495             Emsg2(M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
496                                 director->hdr.name, configfile);
497             OK = false;
498          }
499       }
500    }
501
502    UnlockRes();
503
504    if (OK) {
505       close_msg(NULL);                /* close temp message handler */
506       init_msg(NULL, me->messages);   /* open user specified message handler */
507    }
508
509    return OK;
510 }