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