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 " -k keep readall capabilities\n"
86 " -s no signals (for debugging)\n"
87 " -t test configuration file and exit\n"
89 " -v verbose user messages\n"
90 " -? print this message.\n"
91 "\n"), 2000, VERSION, BDATE);
96 /*********************************************************************
98 * Main Bacula Unix Client Program
101 #if defined(HAVE_WIN32)
102 #define main BaculaMain
105 int main (int argc, char *argv[])
108 bool test_config = false;
109 bool keep_readall_caps = false;
113 init_python_interpreter_args python_args;
114 #endif /* HAVE_PYTHON */
116 start_heap = sbrk(0);
117 setlocale(LC_ALL, "");
118 bindtextdomain("bacula", LOCALEDIR);
119 textdomain("bacula");
122 my_name_is(argc, argv, "bacula-fd");
123 init_msg(NULL, NULL);
124 daemon_start_time = time(NULL);
126 while ((ch = getopt(argc, argv, "c:d:fg:kstu:v?")) != -1) {
128 case 'c': /* configuration file */
129 if (configfile != NULL) {
132 configfile = bstrdup(optarg);
135 case 'd': /* debug level */
136 if (*optarg == 't') {
137 dbg_timestamp = true;
139 debug_level = atoi(optarg);
140 if (debug_level <= 0) {
146 case 'f': /* run in foreground */
150 case 'g': /* set group */
155 keep_readall_caps = true;
166 case 'u': /* set userid */
170 case 'v': /* verbose */
184 if (configfile != NULL)
186 configfile = bstrdup(*argv);
194 if (!uid && keep_readall_caps) {
195 Emsg0(M_ERROR_TERM, 0, _("-k option has no meaning without -u option.\n"));
198 server_tid = pthread_self();
200 init_signals(terminate_filed);
202 /* This reduces the number of signals facilitating debugging */
203 watchdog_sleep_time = 120; /* long timeout for debugging */
206 if (configfile == NULL) {
207 configfile = bstrdup(CONFIG_FILE);
210 config = new_config_parser();
211 parse_fd_config(config, configfile, M_ERROR_TERM);
213 if (init_crypto() != 0) {
214 Emsg0(M_ERROR, 0, _("Cryptography library initialization failed.\n"));
218 if (!check_resources()) {
219 Emsg1(M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
223 set_working_directory(me->working_directory);
231 init_stack_dump(); /* set new pid */
234 /* Maximum 1 daemon at a time */
235 create_pid_file(me->pid_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
236 read_state_file(me->working_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
238 load_fd_plugins(me->plugin_directory);
240 drop(uid, gid, keep_readall_caps);
247 python_args.progname = me->hdr.name;
248 python_args.scriptdir = me->scripts_directory;
249 python_args.modulename = "FDStartUp";
250 python_args.configfile = configfile;
251 python_args.workingdir = me->working_directory;
252 python_args.job_getattr = job_getattr;
253 python_args.job_setattr = job_setattr;
255 init_python_interpreter(&python_args);
256 #endif /* HAVE_PYTHON */
258 set_thread_concurrency(10);
261 start_watchdog(); /* start watchdog thread */
262 init_jcr_subsystem(); /* start JCR watchdogs etc. */
264 server_tid = pthread_self();
266 /* Become server, and handle requests */
268 foreach_dlist(p, me->FDaddrs) {
269 Dmsg1(10, "filed: listening on port %d\n", p->get_port_host_order());
271 bnet_thread_server(me->FDaddrs, me->MaxConcurrentJobs, &dir_workq, handle_client_request);
274 exit(0); /* should never get here */
277 void terminate_filed(int sig)
279 static bool already_here = false;
282 bmicrosleep(2, 0); /* yield */
283 exit(1); /* prevent loops */
286 debug_level = 0; /* turn off debug */
289 bnet_stop_thread_server(server_tid);
290 generate_daemon_event(NULL, "Exit");
292 write_state_file(me->working_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
293 delete_pid_file(me->pid_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
295 if (configfile != NULL) {
299 if (debug_level > 0) {
300 print_memory_pool_stats();
303 config->free_resources();
309 close_memory_pool(); /* release free memory in pool */
311 sm_dump(false); /* dump orphaned buffers */
316 * Make a quick check to see that we have all the
319 static bool check_resources()
327 me = (CLIENT *)GetNextRes(R_CLIENT, NULL);
329 Emsg1(M_FATAL, 0, _("No File daemon resource defined in %s\n"
330 "Without that I don't know who I am :-(\n"), configfile);
333 if (GetNextRes(R_CLIENT, (RES *) me) != NULL) {
334 Emsg1(M_FATAL, 0, _("Only one Client resource permitted in %s\n"),
338 my_name_is(0, NULL, me->hdr.name);
340 me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
342 Emsg1(M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
346 /* tls_require implies tls_enable */
347 if (me->tls_require) {
349 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
352 me->tls_enable = true;
355 need_tls = me->tls_enable || me->tls_authenticate;
357 if ((!me->tls_ca_certfile && !me->tls_ca_certdir) && need_tls) {
358 Emsg1(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
359 " or \"TLS CA Certificate Dir\" are defined for File daemon in %s.\n"),
364 /* If everything is well, attempt to initialize our per-resource TLS context */
365 if (OK && (need_tls || me->tls_require)) {
366 /* Initialize TLS context:
367 * Args: CA certfile, CA certdir, Certfile, Keyfile,
368 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
369 me->tls_ctx = new_tls_context(me->tls_ca_certfile,
370 me->tls_ca_certdir, me->tls_certfile, me->tls_keyfile,
371 NULL, NULL, NULL, true);
374 Emsg2(M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"),
375 me->hdr.name, configfile);
380 if (me->pki_encrypt || me->pki_sign) {
382 Jmsg(NULL, M_FATAL, 0, _("PKI encryption/signing enabled but not compiled into Bacula.\n"));
387 /* pki_encrypt implies pki_sign */
388 if (me->pki_encrypt) {
392 if ((me->pki_encrypt || me->pki_sign) && !me->pki_keypair_file) {
393 Emsg2(M_FATAL, 0, _("\"PKI Key Pair\" must be defined for File"
394 " daemon \"%s\" in %s if either \"PKI Sign\" or"
395 " \"PKI Encrypt\" are enabled.\n"), me->hdr.name, configfile);
399 /* If everything is well, attempt to initialize our public/private keys */
400 if (OK && (me->pki_encrypt || me->pki_sign)) {
402 /* Load our keypair */
403 me->pki_keypair = crypto_keypair_new();
404 if (!me->pki_keypair) {
405 Emsg0(M_FATAL, 0, _("Failed to allocate a new keypair object.\n"));
408 if (!crypto_keypair_load_cert(me->pki_keypair, me->pki_keypair_file)) {
409 Emsg2(M_FATAL, 0, _("Failed to load public certificate for File"
410 " daemon \"%s\" in %s.\n"), me->hdr.name, configfile);
414 if (!crypto_keypair_load_key(me->pki_keypair, me->pki_keypair_file, NULL, NULL)) {
415 Emsg2(M_FATAL, 0, _("Failed to load private key for File"
416 " daemon \"%s\" in %s.\n"), me->hdr.name, configfile);
422 * Trusted Signers. We're always trusted.
424 me->pki_signers = New(alist(10, not_owned_by_alist));
425 if (me->pki_keypair) {
426 me->pki_signers->append(crypto_keypair_dup(me->pki_keypair));
429 /* If additional signing public keys have been specified, load them up */
430 if (me->pki_signing_key_files) {
431 foreach_alist(filepath, me->pki_signing_key_files) {
432 X509_KEYPAIR *keypair;
434 keypair = crypto_keypair_new();
436 Emsg0(M_FATAL, 0, _("Failed to allocate a new keypair object.\n"));
439 if (crypto_keypair_load_cert(keypair, filepath)) {
440 me->pki_signers->append(keypair);
442 /* Attempt to load a private key, if available */
443 if (crypto_keypair_has_key(filepath)) {
444 if (!crypto_keypair_load_key(keypair, filepath, NULL, NULL)) {
445 Emsg3(M_FATAL, 0, _("Failed to load private key from file %s for File"
446 " daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile);
452 Emsg3(M_FATAL, 0, _("Failed to load trusted signer certificate"
453 " from file %s for File daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile);
461 * Crypto recipients. We're always included as a recipient.
462 * The symmetric session key will be encrypted for each of these readers.
464 me->pki_recipients = New(alist(10, not_owned_by_alist));
465 if (me->pki_keypair) {
466 me->pki_recipients->append(crypto_keypair_dup(me->pki_keypair));
470 /* If additional keys have been specified, load them up */
471 if (me->pki_master_key_files) {
472 foreach_alist(filepath, me->pki_master_key_files) {
473 X509_KEYPAIR *keypair;
475 keypair = crypto_keypair_new();
477 Emsg0(M_FATAL, 0, _("Failed to allocate a new keypair object.\n"));
480 if (crypto_keypair_load_cert(keypair, filepath)) {
481 me->pki_recipients->append(keypair);
483 Emsg3(M_FATAL, 0, _("Failed to load master key certificate"
484 " from file %s for File daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile);
494 /* Verify that a director record exists */
496 director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
499 Emsg1(M_FATAL, 0, _("No Director resource defined in %s\n"),
504 foreach_res(director, R_DIRECTOR) {
505 /* tls_require implies tls_enable */
506 if (director->tls_require) {
508 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
512 director->tls_enable = true;
515 need_tls = director->tls_enable || director->tls_authenticate;
517 if (!director->tls_certfile && need_tls) {
518 Emsg2(M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
519 director->hdr.name, configfile);
523 if (!director->tls_keyfile && need_tls) {
524 Emsg2(M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
525 director->hdr.name, configfile);
529 if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && need_tls && director->tls_verify_peer) {
530 Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
531 " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
532 " At least one CA certificate store is required"
533 " when using \"TLS Verify Peer\".\n"),
534 director->hdr.name, configfile);
538 /* If everything is well, attempt to initialize our per-resource TLS context */
539 if (OK && (need_tls || director->tls_require)) {
540 /* Initialize TLS context:
541 * Args: CA certfile, CA certdir, Certfile, Keyfile,
542 * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
543 director->tls_ctx = new_tls_context(director->tls_ca_certfile,
544 director->tls_ca_certdir, director->tls_certfile,
545 director->tls_keyfile, NULL, NULL, director->tls_dhfile,
546 director->tls_verify_peer);
548 if (!director->tls_ctx) {
549 Emsg2(M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
550 director->hdr.name, configfile);
559 close_msg(NULL); /* close temp message handler */
560 init_msg(NULL, me->messages); /* open user specified message handler */