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