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