2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
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
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.
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
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.
31 * Kern Sibbald, March MM
42 #undef _POSIX_C_SOURCE
45 #include "lib/pythonlib.h"
47 /* Imported Functions */
48 extern PyObject *job_getattr(PyObject *self, char *attrname);
49 extern int job_setattr(PyObject *self, char *attrname, PyObject *value);
51 #endif /* HAVE_PYTHON */
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);
57 /* Forward referenced functions */
58 void terminate_filed(int sig);
59 static bool check_resources();
61 /* Exported variables */
62 CLIENT *me; /* my resource */
63 bool no_signals = false;
66 #define CONFIG_FILE "bacula-fd.conf" /* default config file */
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;
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"
85 " -s no signals (for debugging)\n"
86 " -t test configuration file and exit\n"
88 " -v verbose user messages\n"
89 " -? print this message.\n"
90 "\n"), 2000, VERSION, BDATE);
95 /*********************************************************************
97 * Main Bacula Unix Client Program
100 #if defined(HAVE_WIN32)
101 #define main BaculaMain
104 int main (int argc, char *argv[])
107 bool test_config = false;
111 init_python_interpreter_args python_args;
112 #endif /* HAVE_PYTHON */
114 start_heap = sbrk(0);
115 setlocale(LC_ALL, "");
116 bindtextdomain("bacula", LOCALEDIR);
117 textdomain("bacula");
120 my_name_is(argc, argv, "bacula-fd");
121 init_msg(NULL, NULL);
122 daemon_start_time = time(NULL);
124 while ((ch = getopt(argc, argv, "c:d:fg:stu:v?")) != -1) {
126 case 'c': /* configuration file */
127 if (configfile != NULL) {
130 configfile = bstrdup(optarg);
133 case 'd': /* debug level */
134 if (*optarg == 't') {
135 dbg_timestamp = true;
137 debug_level = atoi(optarg);
138 if (debug_level <= 0) {
144 case 'f': /* run in foreground */
148 case 'g': /* set group */
160 case 'u': /* set userid */
164 case 'v': /* verbose */
178 if (configfile != NULL)
180 configfile = bstrdup(*argv);
188 server_tid = pthread_self();
190 init_signals(terminate_filed);
192 /* This reduces the number of signals facilitating debugging */
193 watchdog_sleep_time = 120; /* long timeout for debugging */
196 if (configfile == NULL) {
197 configfile = bstrdup(CONFIG_FILE);
200 config = new_config_parser();
201 parse_fd_config(config, configfile, M_ERROR_TERM);
203 if (init_crypto() != 0) {
204 Emsg0(M_ERROR, 0, _("Cryptography library initialization failed.\n"));
208 if (!check_resources()) {
209 Emsg1(M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
213 set_working_directory(me->working_directory);
221 init_stack_dump(); /* set new pid */
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));
228 load_fd_plugins(me->plugin_directory);
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;
245 init_python_interpreter(&python_args);
246 #endif /* HAVE_PYTHON */
248 set_thread_concurrency(10);
251 start_watchdog(); /* start watchdog thread */
252 init_jcr_subsystem(); /* start JCR watchdogs etc. */
254 server_tid = pthread_self();
256 /* Become server, and handle requests */
258 foreach_dlist(p, me->FDaddrs) {
259 Dmsg1(10, "filed: listening on port %d\n", p->get_port_host_order());
261 bnet_thread_server(me->FDaddrs, me->MaxConcurrentJobs, &dir_workq, handle_client_request);
264 exit(0); /* should never get here */
267 void terminate_filed(int sig)
269 static bool already_here = false;
272 bmicrosleep(2, 0); /* yield */
273 exit(1); /* prevent loops */
276 debug_level = 0; /* turn off debug */
279 bnet_stop_thread_server(server_tid);
280 generate_daemon_event(NULL, "Exit");
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));
285 if (configfile != NULL) {
289 if (debug_level > 0) {
290 print_memory_pool_stats();
293 config->free_resources();
299 close_memory_pool(); /* release free memory in pool */
301 sm_dump(false); /* dump orphaned buffers */
306 * Make a quick check to see that we have all the
309 static bool check_resources()
317 me = (CLIENT *)GetNextRes(R_CLIENT, NULL);
319 Emsg1(M_FATAL, 0, _("No File daemon resource defined in %s\n"
320 "Without that I don't know who I am :-(\n"), configfile);
323 if (GetNextRes(R_CLIENT, (RES *) me) != NULL) {
324 Emsg1(M_FATAL, 0, _("Only one Client resource permitted in %s\n"),
328 my_name_is(0, NULL, me->hdr.name);
330 me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
332 Emsg1(M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
336 /* tls_require implies tls_enable */
337 if (me->tls_require) {
339 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
342 me->tls_enable = true;
345 need_tls = me->tls_enable || me->tls_authenticate;
347 if ((!me->tls_ca_certfile && !me->tls_ca_certdir) && need_tls) {
348 Emsg1(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
349 " or \"TLS CA Certificate Dir\" are defined for File daemon in %s.\n"),
354 /* If everything is well, attempt to initialize our per-resource TLS context */
355 if (OK && (need_tls || me->tls_require)) {
356 /* Initialize TLS context:
357 * Args: CA certfile, CA certdir, Certfile, Keyfile,
358 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
359 me->tls_ctx = new_tls_context(me->tls_ca_certfile,
360 me->tls_ca_certdir, me->tls_certfile, me->tls_keyfile,
361 NULL, NULL, NULL, true);
364 Emsg2(M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
365 me->hdr.name, configfile);
370 if (me->pki_encrypt || me->pki_sign) {
372 Jmsg(NULL, M_FATAL, 0, _("PKI encryption/signing enabled but not compiled into Bacula.\n"));
377 /* pki_encrypt implies pki_sign */
378 if (me->pki_encrypt) {
382 if ((me->pki_encrypt || me->pki_sign) && !me->pki_keypair_file) {
383 Emsg2(M_FATAL, 0, _("\"PKI Key Pair\" must be defined for File"
384 " daemon \"%s\" in %s if either \"PKI Sign\" or"
385 " \"PKI Encrypt\" are enabled.\n"), me->hdr.name, configfile);
389 /* If everything is well, attempt to initialize our public/private keys */
390 if (OK && (me->pki_encrypt || me->pki_sign)) {
392 /* Load our keypair */
393 me->pki_keypair = crypto_keypair_new();
394 if (!me->pki_keypair) {
395 Emsg0(M_FATAL, 0, _("Failed to allocate a new keypair object.\n"));
398 if (!crypto_keypair_load_cert(me->pki_keypair, me->pki_keypair_file)) {
399 Emsg2(M_FATAL, 0, _("Failed to load public certificate for File"
400 " daemon \"%s\" in %s.\n"), me->hdr.name, configfile);
404 if (!crypto_keypair_load_key(me->pki_keypair, me->pki_keypair_file, NULL, NULL)) {
405 Emsg2(M_FATAL, 0, _("Failed to load private key for File"
406 " daemon \"%s\" in %s.\n"), me->hdr.name, configfile);
412 * Trusted Signers. We're always trusted.
414 me->pki_signers = New(alist(10, not_owned_by_alist));
415 if (me->pki_keypair) {
416 me->pki_signers->append(crypto_keypair_dup(me->pki_keypair));
419 /* If additional signing public keys have been specified, load them up */
420 if (me->pki_signing_key_files) {
421 foreach_alist(filepath, me->pki_signing_key_files) {
422 X509_KEYPAIR *keypair;
424 keypair = crypto_keypair_new();
426 Emsg0(M_FATAL, 0, _("Failed to allocate a new keypair object.\n"));
429 if (crypto_keypair_load_cert(keypair, filepath)) {
430 me->pki_signers->append(keypair);
432 /* Attempt to load a private key, if available */
433 if (crypto_keypair_has_key(filepath)) {
434 if (!crypto_keypair_load_key(keypair, filepath, NULL, NULL)) {
435 Emsg3(M_FATAL, 0, _("Failed to load private key from file %s for File"
436 " daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile);
442 Emsg3(M_FATAL, 0, _("Failed to load trusted signer certificate"
443 " from file %s for File daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile);
451 * Crypto recipients. We're always included as a recipient.
452 * The symmetric session key will be encrypted for each of these readers.
454 me->pki_recipients = New(alist(10, not_owned_by_alist));
455 if (me->pki_keypair) {
456 me->pki_recipients->append(crypto_keypair_dup(me->pki_keypair));
460 /* If additional keys have been specified, load them up */
461 if (me->pki_master_key_files) {
462 foreach_alist(filepath, me->pki_master_key_files) {
463 X509_KEYPAIR *keypair;
465 keypair = crypto_keypair_new();
467 Emsg0(M_FATAL, 0, _("Failed to allocate a new keypair object.\n"));
470 if (crypto_keypair_load_cert(keypair, filepath)) {
471 me->pki_recipients->append(keypair);
473 Emsg3(M_FATAL, 0, _("Failed to load master key certificate"
474 " from file %s for File daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile);
484 /* Verify that a director record exists */
486 director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
489 Emsg1(M_FATAL, 0, _("No Director resource defined in %s\n"),
494 foreach_res(director, R_DIRECTOR) {
495 /* tls_require implies tls_enable */
496 if (director->tls_require) {
498 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
502 director->tls_enable = true;
505 need_tls = director->tls_enable || director->tls_authenticate;
507 if (!director->tls_certfile && need_tls) {
508 Emsg2(M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
509 director->hdr.name, configfile);
513 if (!director->tls_keyfile && need_tls) {
514 Emsg2(M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
515 director->hdr.name, configfile);
519 if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && need_tls && director->tls_verify_peer) {
520 Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
521 " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
522 " At least one CA certificate store is required"
523 " when using \"TLS Verify Peer\".\n"),
524 director->hdr.name, configfile);
528 /* If everything is well, attempt to initialize our per-resource TLS context */
529 if (OK && (need_tls || director->tls_require)) {
530 /* Initialize TLS context:
531 * Args: CA certfile, CA certdir, Certfile, Keyfile,
532 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
533 director->tls_ctx = new_tls_context(director->tls_ca_certfile,
534 director->tls_ca_certdir, director->tls_certfile,
535 director->tls_keyfile, NULL, NULL, director->tls_dhfile,
536 director->tls_verify_peer);
538 if (!director->tls_ctx) {
539 Emsg2(M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
540 director->hdr.name, configfile);
549 close_msg(NULL); /* close temp message handler */
550 init_msg(NULL, me->messages); /* open user specified message handler */