X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Ffiled%2Ffiled.c;h=79dd1928aad3b5c31e0018d9ffac80753e2219d9;hb=25f607f9bd00610e4cf7b72dd1808cbb23fc3632;hp=5145735a1cab7b41c4428a31f52d59b018b55302;hpb=8e1a4eeb2bdc80c9ab45a822a8da1cfa0ece1a6d;p=bacula%2Fbacula diff --git a/bacula/src/filed/filed.c b/bacula/src/filed/filed.c index 5145735a1c..79dd1928aa 100644 --- a/bacula/src/filed/filed.c +++ b/bacula/src/filed/filed.c @@ -1,70 +1,93 @@ +/* + Bacula® - The Network Backup Solution + + Copyright (C) 2000-2010 Free Software Foundation Europe e.V. + + The main author of Bacula is Kern Sibbald, with contributions from + many others, a complete list can be found in the file AUTHORS. + This program is Free Software; you can redistribute it and/or + modify it under the terms of version three of the GNU Affero General Public + License as published by the Free Software Foundation and included + in the file LICENSE. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + + Bacula® is a registered trademark of Kern Sibbald. + The licensor of Bacula is the Free Software Foundation Europe + (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, + Switzerland, email:ftf@fsfeurope.org. +*/ /* * Bacula File Daemon * * Kern Sibbald, March MM * - * Version $Id$ - * */ -/* - Copyright (C) 2000-2006 Kern Sibbald - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as amended with additional clauses defined in the - file LICENSE in the main source directory. +#include "bacula.h" +#include "filed.h" - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - the file LICENSE for additional details. +#ifdef HAVE_PYTHON - */ +#undef _POSIX_C_SOURCE +#include -#include "bacula.h" -#include "filed.h" +#include "lib/pythonlib.h" /* Imported Functions */ -extern void *handle_client_request(void *dir_sock); +extern PyObject *job_getattr(PyObject *self, char *attrname); +extern int job_setattr(PyObject *self, char *attrname, PyObject *value); -/* Imported Variables */ -extern time_t watchdog_sleep_time; +#endif /* HAVE_PYTHON */ + +/* Imported Functions */ +extern void *handle_client_request(void *dir_sock); +extern bool parse_fd_config(CONFIG *config, const char *configfile, int exit_code); /* Forward referenced functions */ -void terminate_filed(int sig); -static int check_resources(); +static bool check_resources(); /* Exported variables */ CLIENT *me; /* my resource */ bool no_signals = false; +void *start_heap; - -#define CONFIG_FILE "./bacula-fd.conf" /* default config file */ +#define CONFIG_FILE "bacula-fd.conf" /* default config file */ char *configfile = NULL; static bool foreground = false; -static bool inetd_request = false; static workq_t dir_workq; /* queue of work from Director */ static pthread_t server_tid; - +static CONFIG *config; static void usage() { - Pmsg2(-1, _( -"Copyright (C) 2000-2005 Kern Sibbald\n" + fprintf(stderr, _( +PROG_COPYRIGHT "\nVersion: %s (%s)\n\n" "Usage: bacula-fd [-f -s] [-c config_file] [-d debug_level]\n" " -c use as configuration file\n" -" -dnn set debug level to nn\n" +" -d set debug level to \n" +" -dt print a timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" -" -i inetd request\n" +" -k keep readall capabilities\n" +" -m print kaboom output (for debugging)\n" " -s no signals (for debugging)\n" " -t test configuration file and exit\n" " -u userid\n" " -v verbose user messages\n" " -? print this message.\n" -"\n"), VERSION, BDATE); +"\n"), 2000, VERSION, BDATE); + exit(1); } @@ -82,9 +105,14 @@ int main (int argc, char *argv[]) { int ch; bool test_config = false; + bool keep_readall_caps = false; char *uid = NULL; char *gid = NULL; +#ifdef HAVE_PYTHON + init_python_interpreter_args python_args; +#endif /* HAVE_PYTHON */ + start_heap = sbrk(0); setlocale(LC_ALL, ""); bindtextdomain("bacula", LOCALEDIR); textdomain("bacula"); @@ -94,7 +122,7 @@ int main (int argc, char *argv[]) init_msg(NULL, NULL); daemon_start_time = time(NULL); - while ((ch = getopt(argc, argv, "c:d:fg:istu:v?")) != -1) { + while ((ch = getopt(argc, argv, "c:d:fg:kmstu:v?")) != -1) { switch (ch) { case 'c': /* configuration file */ if (configfile != NULL) { @@ -104,9 +132,13 @@ int main (int argc, char *argv[]) break; case 'd': /* debug level */ - debug_level = atoi(optarg); - if (debug_level <= 0) { - debug_level = 1; + if (*optarg == 't') { + dbg_timestamp = true; + } else { + debug_level = atoi(optarg); + if (debug_level <= 0) { + debug_level = 1; + } } break; @@ -118,9 +150,14 @@ int main (int argc, char *argv[]) gid = optarg; break; - case 'i': - inetd_request = true; + case 'k': + keep_readall_caps = true; break; + + case 'm': /* print kaboom output */ + prt_kaboom = true; + break; + case 's': no_signals = true; break; @@ -157,6 +194,10 @@ int main (int argc, char *argv[]) usage(); } + if (!uid && keep_readall_caps) { + Emsg0(M_ERROR_TERM, 0, _("-k option has no meaning without -u option.\n")); + } + server_tid = pthread_self(); if (!no_signals) { init_signals(terminate_filed); @@ -169,7 +210,8 @@ int main (int argc, char *argv[]) configfile = bstrdup(CONFIG_FILE); } - parse_config(configfile); + config = new_config_parser(); + parse_fd_config(config, configfile, M_ERROR_TERM); if (init_crypto() != 0) { Emsg0(M_ERROR, 0, _("Cryptography library initialization failed.\n")); @@ -187,24 +229,39 @@ int main (int argc, char *argv[]) terminate_filed(0); } - if (!foreground &&!inetd_request) { + if (!foreground) { daemon_start(); init_stack_dump(); /* set new pid */ } + set_thread_concurrency(me->MaxConcurrentJobs + 10); + lmgr_init_thread(); /* initialize the lockmanager stack */ + /* Maximum 1 daemon at a time */ - create_pid_file(me->pid_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs)); - read_state_file(me->working_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs)); + create_pid_file(me->pid_directory, "bacula-fd", + get_first_port_host_order(me->FDaddrs)); + read_state_file(me->working_directory, "bacula-fd", + get_first_port_host_order(me->FDaddrs)); + + load_fd_plugins(me->plugin_directory); - drop(uid, gid); + drop(uid, gid, keep_readall_caps); #ifdef BOMB me += 1000000; #endif - init_python_interpreter(me->hdr.name, me->scripts_directory, "FDStartUp"); +#ifdef HAVE_PYTHON + python_args.progname = me->hdr.name; + python_args.scriptdir = me->scripts_directory; + python_args.modulename = "FDStartUp"; + python_args.configfile = configfile; + python_args.workingdir = me->working_directory; + python_args.job_getattr = job_getattr; + python_args.job_setattr = job_setattr; - set_thread_concurrency(10); + init_python_interpreter(&python_args); +#endif /* HAVE_PYTHON */ if (!no_signals) { start_watchdog(); /* start watchdog thread */ @@ -212,25 +269,12 @@ int main (int argc, char *argv[]) } server_tid = pthread_self(); - if (inetd_request) { - /* Socket is on fd 0 */ - struct sockaddr client_addr; - int port = -1; - socklen_t client_addr_len = sizeof(client_addr); - if (getsockname(0, &client_addr, &client_addr_len) == 0) { - /* MA BUG 6 remove ifdefs */ - port = sockaddr_get_port_net_order(&client_addr); - } - BSOCK *bs = init_bsock(NULL, 0, "client", "unknown client", port, &client_addr); - handle_client_request((void *)bs); - } else { - /* Become server, and handle requests */ - IPADDR *p; - foreach_dlist(p, me->FDaddrs) { - Dmsg1(10, "filed: listening on port %d\n", p->get_port_host_order()); - } - bnet_thread_server(me->FDaddrs, me->MaxConcurrentJobs, &dir_workq, handle_client_request); + /* Become server, and handle requests */ + IPADDR *p; + foreach_dlist(p, me->FDaddrs) { + Dmsg1(10, "filed: listening on port %d\n", p->get_port_host_order()); } + bnet_thread_server(me->FDaddrs, me->MaxConcurrentJobs, &dir_workq, handle_client_request); terminate_filed(0); exit(0); /* should never get here */ @@ -238,22 +282,38 @@ int main (int argc, char *argv[]) void terminate_filed(int sig) { + static bool already_here = false; + + if (already_here) { + bmicrosleep(2, 0); /* yield */ + exit(1); /* prevent loops */ + } + already_here = true; + debug_level = 0; /* turn off debug */ + stop_watchdog(); + bnet_stop_thread_server(server_tid); generate_daemon_event(NULL, "Exit"); + unload_plugins(); write_state_file(me->working_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs)); delete_pid_file(me->pid_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs)); if (configfile != NULL) { free(configfile); } + if (debug_level > 0) { print_memory_pool_stats(); } - free_config_resources(); + if (config) { + config->free_resources(); + free(config); + config = NULL; + } term_msg(); - stop_watchdog(); cleanup_crypto(); close_memory_pool(); /* release free memory in pool */ + lmgr_cleanup_main(); sm_dump(false); /* dump orphaned buffers */ exit(sig); } @@ -262,10 +322,11 @@ void terminate_filed(int sig) * Make a quick check to see that we have all the * resources needed. */ -static int check_resources() +static bool check_resources() { bool OK = true; DIRRES *director; + bool need_tls; LockRes(); @@ -297,8 +358,9 @@ static int check_resources() me->tls_enable = true; #endif } + need_tls = me->tls_enable || me->tls_authenticate; - if ((!me->tls_ca_certfile && !me->tls_ca_certdir) && me->tls_enable) { + if ((!me->tls_ca_certfile && !me->tls_ca_certdir) && need_tls) { Emsg1(M_FATAL, 0, _("Neither \"TLS CA Certificate\"" " or \"TLS CA Certificate Dir\" are defined for File daemon in %s.\n"), configfile); @@ -306,7 +368,7 @@ static int check_resources() } /* If everything is well, attempt to initialize our per-resource TLS context */ - if (OK && (me->tls_enable || me->tls_require)) { + if (OK && (need_tls || me->tls_require)) { /* Initialize TLS context: * Args: CA certfile, CA certdir, Certfile, Keyfile, * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */ @@ -423,16 +485,6 @@ static int check_resources() } else { if (crypto_keypair_load_cert(keypair, filepath)) { me->pki_recipients->append(keypair); - - /* Attempt to load a private key, if available */ - if (crypto_keypair_has_key(filepath)) { - if (!crypto_keypair_load_key(keypair, filepath, NULL, NULL)) { - Emsg3(M_FATAL, 0, _("Failed to load private key from file %s for File" - " daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile); - OK = false; - } - } - } else { Emsg3(M_FATAL, 0, _("Failed to load master key certificate" " from file %s for File daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile); @@ -466,20 +518,21 @@ static int check_resources() director->tls_enable = true; #endif } + need_tls = director->tls_enable || director->tls_authenticate; - if (!director->tls_certfile && director->tls_enable) { + if (!director->tls_certfile && need_tls) { Emsg2(M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"), director->hdr.name, configfile); OK = false; } - if (!director->tls_keyfile && director->tls_enable) { + if (!director->tls_keyfile && need_tls) { Emsg2(M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"), director->hdr.name, configfile); OK = false; } - if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable && director->tls_verify_peer) { + if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && need_tls && director->tls_verify_peer) { Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\"" " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s." " At least one CA certificate store is required" @@ -489,7 +542,7 @@ static int check_resources() } /* If everything is well, attempt to initialize our per-resource TLS context */ - if (OK && (director->tls_enable || director->tls_require)) { + if (OK && (need_tls || director->tls_require)) { /* Initialize TLS context: * Args: CA certfile, CA certdir, Certfile, Keyfile, * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */