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