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