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