]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/filed.c
Merge the Bacula Encryption branch to HEAD.
[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. me->pki_keypair
376           * will be deallocated when me->pki_signers is deallocated.
377           */
378          me->pki_signers = New(alist(10, not_owned_by_alist));
379          me->pki_signers->append(me->pki_keypair);
380
381          /* If additional trusted keys have been specified, load them up */
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
402
403    /* Verify that a director record exists */
404    LockRes();
405    director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
406    UnlockRes();
407    if (!director) {
408       Emsg1(M_FATAL, 0, _("No Director resource defined in %s\n"),
409             configfile);
410       OK = false;
411    }
412
413    foreach_res(director, R_DIRECTOR) { 
414       /* tls_require implies tls_enable */
415       if (director->tls_require) {
416 #ifndef HAVE_TLS
417          Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
418          OK = false;
419          continue;
420 #else
421          director->tls_enable = true;
422 #endif
423       }
424
425       if (!director->tls_certfile && director->tls_enable) {
426          Emsg2(M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"),
427                director->hdr.name, configfile);
428          OK = false;
429       }
430
431       if (!director->tls_keyfile && director->tls_enable) {
432          Emsg2(M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"),
433                director->hdr.name, configfile);
434          OK = false;
435       }
436
437       if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable && director->tls_verify_peer) {
438          Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
439                              " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
440                              " At least one CA certificate store is required"
441                              " when using \"TLS Verify Peer\".\n"),
442                              director->hdr.name, configfile);
443          OK = false;
444       }
445
446       /* If everything is well, attempt to initialize our per-resource TLS context */
447       if (OK && (director->tls_enable || director->tls_require)) {
448          /* Initialize TLS context:
449           * Args: CA certfile, CA certdir, Certfile, Keyfile,
450           * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
451          director->tls_ctx = new_tls_context(director->tls_ca_certfile,
452             director->tls_ca_certdir, director->tls_certfile,
453             director->tls_keyfile, NULL, NULL, director->tls_dhfile,
454             director->tls_verify_peer);
455
456          if (!director->tls_ctx) { 
457             Emsg2(M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"),
458                                 director->hdr.name, configfile);
459             OK = false;
460          }
461       }
462    }
463
464    UnlockRes();
465
466    if (OK) {
467       close_msg(NULL);                /* close temp message handler */
468       init_msg(NULL, me->messages);   /* open user specified message handler */
469    }
470
471    return OK;
472 }