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