]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/filed.c
kes Correctly detect Ubuntu systems, and add ubuntu platform directory.
[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    debug_level = 0;                   /* turn off debug */
250    stop_watchdog();
251
252    bnet_stop_thread_server(server_tid);
253    generate_daemon_event(NULL, "Exit");
254    unload_plugins();
255    write_state_file(me->working_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
256    delete_pid_file(me->pid_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
257
258    if (configfile != NULL) {
259       free(configfile);
260    }
261
262    if (debug_level > 0) {
263       print_memory_pool_stats();
264    }
265    term_msg();
266    free_config_resources();
267    cleanup_crypto();
268    close_memory_pool();               /* release free memory in pool */
269    sm_dump(false);                    /* dump orphaned buffers */
270    exit(sig);
271 }
272
273 /*
274 * Make a quick check to see that we have all the
275 * resources needed.
276 */
277 static bool check_resources()
278 {
279    bool OK = true;
280    DIRRES *director;
281    bool need_tls;
282
283    LockRes();
284
285    me = (CLIENT *)GetNextRes(R_CLIENT, NULL);
286    if (!me) {
287       Emsg1(M_FATAL, 0, _("No File daemon resource defined in %s\n"
288             "Without that I don't know who I am :-(\n"), configfile);
289       OK = false;
290    } else {
291       if (GetNextRes(R_CLIENT, (RES *) me) != NULL) {
292          Emsg1(M_FATAL, 0, _("Only one Client resource permitted in %s\n"),
293               configfile);
294          OK = false;
295       }
296       my_name_is(0, NULL, me->hdr.name);
297       if (!me->messages) {
298          me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
299          if (!me->messages) {
300              Emsg1(M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
301              OK = false;
302          }
303       }
304       /* tls_require implies tls_enable */
305       if (me->tls_require) {
306 #ifndef HAVE_TLS
307          Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
308          OK = false;
309 #else
310          me->tls_enable = true;
311 #endif
312       }
313       need_tls = me->tls_enable || me->tls_authenticate;
314
315       if ((!me->tls_ca_certfile && !me->tls_ca_certdir) && need_tls) {
316          Emsg1(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
317             " or \"TLS CA Certificate Dir\" are defined for File daemon in %s.\n"),
318                             configfile);
319         OK = false;
320       }
321
322       /* If everything is well, attempt to initialize our per-resource TLS context */
323       if (OK && (need_tls || me->tls_require)) {
324          /* Initialize TLS context:
325           * Args: CA certfile, CA certdir, Certfile, Keyfile,
326           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
327          me->tls_ctx = new_tls_context(me->tls_ca_certfile,
328             me->tls_ca_certdir, me->tls_certfile, me->tls_keyfile,
329             NULL, NULL, NULL, true);
330
331          if (!me->tls_ctx) { 
332             Emsg2(M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
333                                 me->hdr.name, configfile);
334             OK = false;
335          }
336       }
337
338       if (me->pki_encrypt || me->pki_sign) {
339 #ifndef HAVE_CRYPTO
340          Jmsg(NULL, M_FATAL, 0, _("PKI encryption/signing enabled but not compiled into Bacula.\n"));
341          OK = false;
342 #endif
343       }
344
345       /* pki_encrypt implies pki_sign */
346       if (me->pki_encrypt) {
347          me->pki_sign = true;
348       }
349
350       if ((me->pki_encrypt || me->pki_sign) && !me->pki_keypair_file) {
351          Emsg2(M_FATAL, 0, _("\"PKI Key Pair\" must be defined for File"
352             " daemon \"%s\" in %s if either \"PKI Sign\" or"
353             " \"PKI Encrypt\" are enabled.\n"), me->hdr.name, configfile);
354          OK = false;
355       }
356
357       /* If everything is well, attempt to initialize our public/private keys */
358       if (OK && (me->pki_encrypt || me->pki_sign)) {
359          char *filepath;
360          /* Load our keypair */
361          me->pki_keypair = crypto_keypair_new();
362          if (!me->pki_keypair) {
363             Emsg0(M_FATAL, 0, _("Failed to allocate a new keypair object.\n"));
364             OK = false;
365          } else {
366             if (!crypto_keypair_load_cert(me->pki_keypair, me->pki_keypair_file)) {
367                Emsg2(M_FATAL, 0, _("Failed to load public certificate for File"
368                      " daemon \"%s\" in %s.\n"), me->hdr.name, configfile);
369                OK = false;
370             }
371
372             if (!crypto_keypair_load_key(me->pki_keypair, me->pki_keypair_file, NULL, NULL)) {
373                Emsg2(M_FATAL, 0, _("Failed to load private key for File"
374                      " daemon \"%s\" in %s.\n"), me->hdr.name, configfile);
375                OK = false;
376             }
377          }
378
379          /*
380           * Trusted Signers. We're always trusted.
381           */
382          me->pki_signers = New(alist(10, not_owned_by_alist));
383          if (me->pki_keypair) {
384             me->pki_signers->append(crypto_keypair_dup(me->pki_keypair));
385          }
386
387          /* If additional signing public keys have been specified, load them up */
388          if (me->pki_signing_key_files) {
389             foreach_alist(filepath, me->pki_signing_key_files) {
390                X509_KEYPAIR *keypair;
391
392                keypair = crypto_keypair_new();
393                if (!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(keypair, filepath)) {
398                      me->pki_signers->append(keypair);
399
400                      /* Attempt to load a private key, if available */
401                      if (crypto_keypair_has_key(filepath)) {
402                         if (!crypto_keypair_load_key(keypair, filepath, NULL, NULL)) {
403                            Emsg3(M_FATAL, 0, _("Failed to load private key from file %s for File"
404                               " daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile);
405                            OK = false;
406                         }
407                      }
408
409                   } else {
410                      Emsg3(M_FATAL, 0, _("Failed to load trusted signer certificate"
411                         " from file %s for File daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile);
412                      OK = false;
413                   }
414                }
415             }
416          }
417
418          /*
419           * Crypto recipients. We're always included as a recipient.
420           * The symmetric session key will be encrypted for each of these readers.
421           */
422          me->pki_recipients = New(alist(10, not_owned_by_alist));
423          if (me->pki_keypair) {
424             me->pki_recipients->append(crypto_keypair_dup(me->pki_keypair));
425          }
426
427
428          /* If additional keys have been specified, load them up */
429          if (me->pki_master_key_files) {
430             foreach_alist(filepath, me->pki_master_key_files) {
431                X509_KEYPAIR *keypair;
432
433                keypair = crypto_keypair_new();
434                if (!keypair) {
435                   Emsg0(M_FATAL, 0, _("Failed to allocate a new keypair object.\n"));
436                   OK = false;
437                } else {
438                   if (crypto_keypair_load_cert(keypair, filepath)) {
439                      me->pki_recipients->append(keypair);
440                   } else {
441                      Emsg3(M_FATAL, 0, _("Failed to load master key 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
451
452    /* Verify that a director record exists */
453    LockRes();
454    director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
455    UnlockRes();
456    if (!director) {
457       Emsg1(M_FATAL, 0, _("No Director resource defined in %s\n"),
458             configfile);
459       OK = false;
460    }
461
462    foreach_res(director, R_DIRECTOR) { 
463       /* tls_require implies tls_enable */
464       if (director->tls_require) {
465 #ifndef HAVE_TLS
466          Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
467          OK = false;
468          continue;
469 #else
470          director->tls_enable = true;
471 #endif
472       }
473       need_tls = director->tls_enable || director->tls_authenticate;
474
475       if (!director->tls_certfile && need_tls) {
476          Emsg2(M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
477                director->hdr.name, configfile);
478          OK = false;
479       }
480
481       if (!director->tls_keyfile && need_tls) {
482          Emsg2(M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
483                director->hdr.name, configfile);
484          OK = false;
485       }
486
487       if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && need_tls && director->tls_verify_peer) {
488          Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
489                              " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
490                              " At least one CA certificate store is required"
491                              " when using \"TLS Verify Peer\".\n"),
492                              director->hdr.name, configfile);
493          OK = false;
494       }
495
496       /* If everything is well, attempt to initialize our per-resource TLS context */
497       if (OK && (need_tls || director->tls_require)) {
498          /* Initialize TLS context:
499           * Args: CA certfile, CA certdir, Certfile, Keyfile,
500           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
501          director->tls_ctx = new_tls_context(director->tls_ca_certfile,
502             director->tls_ca_certdir, director->tls_certfile,
503             director->tls_keyfile, NULL, NULL, director->tls_dhfile,
504             director->tls_verify_peer);
505
506          if (!director->tls_ctx) { 
507             Emsg2(M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
508                                 director->hdr.name, configfile);
509             OK = false;
510          }
511       }
512    }
513
514    UnlockRes();
515
516    if (OK) {
517       close_msg(NULL);                /* close temp message handler */
518       init_msg(NULL, me->messages);   /* open user specified message handler */
519    }
520
521    return OK;
522 }