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