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