X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Ffiled%2Ffiled.c;h=be146bbb96f97c6515de24b0af66bc307006369c;hb=10cfd798ced2d27f61ead2de6fe9b1bcc8e3468d;hp=9a893f929f88bf69372dfb1f482cc20175acf2a9;hpb=c61c6525d92d0324770fa76f2a802f55235ac752;p=bacula%2Fbacula diff --git a/bacula/src/filed/filed.c b/bacula/src/filed/filed.c index 9a893f929f..be146bbb96 100644 --- a/bacula/src/filed/filed.c +++ b/bacula/src/filed/filed.c @@ -1,93 +1,78 @@ /* - Bacula® - The Network Backup Solution - - Copyright (C) 2000-2009 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 two of the GNU 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 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(R) - The Network Backup Solution + + Copyright (C) 2000-2017 Kern Sibbald + + The original author of Bacula is Kern Sibbald, with contributions + from many others, a complete list can be found in the file AUTHORS. + + You may use this file and others of this release according to the + license defined in the LICENSE file, which includes the Affero General + Public License, v3.0 ("AGPLv3") and some additional permissions and + terms pursuant to its AGPLv3 Section 7. + + This notice must be preserved when any source code is + conveyed and/or propagated. + + Bacula(R) is a registered trademark of Kern Sibbald. */ /* * Bacula File Daemon * * Kern Sibbald, March MM - * */ #include "bacula.h" #include "filed.h" -#ifdef HAVE_PYTHON - -#undef _POSIX_C_SOURCE -#include - -#include "lib/pythonlib.h" - -/* Imported Functions */ -extern PyObject *job_getattr(PyObject *self, char *attrname); -extern int job_setattr(PyObject *self, char *attrname, PyObject *value); - -#endif /* HAVE_PYTHON */ - /* Imported Functions */ -extern void *handle_client_request(void *dir_sock); +extern void *handle_connection_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 bool check_resources(); /* Exported variables */ CLIENT *me; /* my resource */ bool no_signals = false; void *start_heap; +extern struct s_cmds cmds[]; -#define CONFIG_FILE "bacula-fd.conf" /* default config file */ +#ifndef CONFIG_FILE /* Might be overwritten */ + #define CONFIG_FILE "bacula-fd.conf" /* default config file */ + #define PROG_NAME "bacula-fd" +#endif char *configfile = NULL; +static bool test_config = false; static bool foreground = false; +static bool make_pid_file = true; /* create pid file */ static workq_t dir_workq; /* queue of work from Director */ static pthread_t server_tid; static CONFIG *config; static void usage() { - Pmsg3(-1, _( -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" -" -d set debug level to \n" -" -dt print a timestamp in debug output\n" -" -f run in foreground (for debugging)\n" -" -g groupid\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"), 2000, VERSION, BDATE); + 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" + " -d [,] set debug level to , debug tags to \n" + " -dt print a timestamp in debug output\n" + " -f run in foreground (for debugging)\n" + " -g groupid\n" + " -k keep readall capabilities\n" + " -m print kaboom output (for debugging)\n" + " -P do not create pid file\n" + " -s no signals (for debugging)\n" + " -t test configuration file and exit\n" + " -T set trace on\n" + " -u userid\n" + " -v verbose user messages\n" + " -? print this message.\n" + "\n"), 2000, VERSION, BDATE); + exit(1); } @@ -101,16 +86,12 @@ PROG_COPYRIGHT #define main BaculaMain #endif -int main (int argc, char *argv[]) +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, ""); @@ -118,11 +99,12 @@ int main (int argc, char *argv[]) textdomain("bacula"); init_stack_dump(); - my_name_is(argc, argv, "bacula-fd"); + my_name_is(argc, argv, PROG_NAME); init_msg(NULL, NULL); daemon_start_time = time(NULL); + setup_daemon_message_queue(); - while ((ch = getopt(argc, argv, "c:d:fg:kmstu:v?")) != -1) { + while ((ch = getopt(argc, argv, "c:d:fg:kmPstTu:v?D:")) != -1) { switch (ch) { case 'c': /* configuration file */ if (configfile != NULL) { @@ -135,10 +117,18 @@ int main (int argc, char *argv[]) if (*optarg == 't') { dbg_timestamp = true; } else { + char *p; + /* We probably find a tag list -d 10,sql,bvfs */ + if ((p = strchr(optarg, ',')) != NULL) { + *p = 0; + } debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } + if (p) { + debug_parse_tags(p+1, &debug_level_tags); + } } break; @@ -158,6 +148,10 @@ int main (int argc, char *argv[]) prt_kaboom = true; break; + case 'P': + make_pid_file = false; + break; + case 's': no_signals = true; break; @@ -166,6 +160,10 @@ int main (int argc, char *argv[]) test_config = true; break; + case 'T': + set_trace(true); + break; + case 'u': /* set userid */ uid = optarg; break; @@ -199,6 +197,16 @@ int main (int argc, char *argv[]) } server_tid = pthread_self(); + + if (configfile == NULL) { + configfile = bstrdup(CONFIG_FILE); + } + + if (!foreground && !test_config) { + daemon_start(); + init_stack_dump(); /* set new pid */ + } + if (!no_signals) { init_signals(terminate_filed); } else { @@ -206,11 +214,7 @@ int main (int argc, char *argv[]) watchdog_sleep_time = 120; /* long timeout for debugging */ } - if (configfile == NULL) { - configfile = bstrdup(CONFIG_FILE); - } - - config = new_config_parser(); + config = New(CONFIG()); parse_fd_config(config, configfile, M_ERROR_TERM); if (init_crypto() != 0) { @@ -229,18 +233,15 @@ int main (int argc, char *argv[]) terminate_filed(0); } - 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", + if (make_pid_file) { + create_pid_file(me->pid_directory, PROG_NAME, + get_first_port_host_order(me->FDaddrs)); + } + read_state_file(me->working_directory, PROG_NAME, get_first_port_host_order(me->FDaddrs)); load_fd_plugins(me->plugin_directory); @@ -251,17 +252,10 @@ int main (int argc, char *argv[]) me += 1000000; #endif -#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; - - init_python_interpreter(&python_args); -#endif /* HAVE_PYTHON */ + /* Setup default value for the the snapshot handler */ + if (!me->snapshot_command) { + me->snapshot_command = snapshot_get_command(); + } if (!no_signals) { start_watchdog(); /* start watchdog thread */ @@ -274,7 +268,8 @@ int main (int argc, char *argv[]) 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); + bnet_thread_server(me->FDaddrs, me->MaxConcurrentJobs, &dir_workq, + handle_connection_request); terminate_filed(0); exit(0); /* should never get here */ @@ -295,8 +290,17 @@ void terminate_filed(int sig) 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)); + + free_daemon_message_queue(); + + if (!test_config) { + write_state_file(me->working_directory, + "bacula-fd", get_first_port_host_order(me->FDaddrs)); + if (make_pid_file) { + delete_pid_file(me->pid_directory, + "bacula-fd", get_first_port_host_order(me->FDaddrs)); + } + } if (configfile != NULL) { free(configfile); @@ -305,13 +309,15 @@ void terminate_filed(int sig) if (debug_level > 0) { print_memory_pool_stats(); } + if (config) { - config->free_resources(); - free(config); + delete config; config = NULL; } term_msg(); cleanup_crypto(); + free(res_head); + res_head = NULL; close_memory_pool(); /* release free memory in pool */ lmgr_cleanup_main(); sm_dump(false); /* dump orphaned buffers */ @@ -324,6 +330,9 @@ void terminate_filed(int sig) */ static bool check_resources() { + int i; + bool found; + char *cmd; bool OK = true; DIRRES *director; bool need_tls; @@ -349,6 +358,37 @@ static bool check_resources() OK = false; } } + + /* Construct disabled command array */ + for (i=0; cmds[i].cmd; i++) { } /* Count commands */ + if (me->disable_cmds) { + me->disabled_cmds_array = (bool *)malloc(i); + memset(me->disabled_cmds_array, 0, i); + foreach_alist(cmd, me->disable_cmds) { + found = false; + for (i=0; cmds[i].cmd; i++) { + if (strncasecmp(cmds[i].cmd, cmd, strlen(cmd)) == 0) { + me->disabled_cmds_array[i] = true; + found = true; + break; + } + } + if (!found) { + Jmsg(NULL, M_FATAL, 0, _("Disable Command \"%s\" not found.\n"), + cmd); + OK = false; + } + } + } +#ifdef xxxDEBUG + for (i=0; cmds[i].cmd; i++) { } /* Count commands */ + while (i-- >= 0) { + if (me->disabled_cmds_array[i]) { + Dmsg1(050, "Command: %s disabled.\n", cmds[i].cmd); + } + } +#endif + /* tls_require implies tls_enable */ if (me->tls_require) { #ifndef HAVE_TLS @@ -376,7 +416,7 @@ static bool check_resources() me->tls_ca_certdir, me->tls_certfile, me->tls_keyfile, NULL, NULL, NULL, true); - if (!me->tls_ctx) { + if (!me->tls_ctx) { Emsg2(M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"), me->hdr.name, configfile); OK = false; @@ -472,6 +512,15 @@ static bool check_resources() me->pki_recipients->append(crypto_keypair_dup(me->pki_keypair)); } + /* Put a default cipher (not possible in the filed_conf.c structure */ + if (!me->pki_cipher) { + me->pki_cipher = CRYPTO_CIPHER_AES_128_CBC; + } + + /* Put a default digest (not possible in the filed_conf.c structure */ + if (!me->pki_digest) { + me->pki_digest = CRYPTO_DIGEST_DEFAULT; + } /* If additional keys have been specified, load them up */ if (me->pki_master_key_files) { @@ -507,7 +556,39 @@ static bool check_resources() OK = false; } - foreach_res(director, R_DIRECTOR) { + foreach_res(director, R_DIRECTOR) { + + /* Construct disabled command array */ + for (i=0; cmds[i].cmd; i++) { } /* Count commands */ + if (director->disable_cmds) { + director->disabled_cmds_array = (bool *)malloc(i); + memset(director->disabled_cmds_array, 0, i); + foreach_alist(cmd, director->disable_cmds) { + found = false; + for (i=0; cmds[i].cmd; i++) { + if (strncasecmp(cmds[i].cmd, cmd, strlen(cmd)) == 0) { + director->disabled_cmds_array[i] = true; + found = true; + break; + } + } + if (!found) { + Jmsg(NULL, M_FATAL, 0, _("Disable Command \"%s\" not found.\n"), + cmd); + OK = false; + } + } + } + +#ifdef xxxDEBUG + for (i=0; cmds[i].cmd; i++) { } /* Count commands */ + while (i-- >= 0) { + if (director->disabled_cmds_array[i]) { + Dmsg1(050, "Command: %s disabled for Director.\n", cmds[i].cmd); + } + } +#endif + /* tls_require implies tls_enable */ if (director->tls_require) { #ifndef HAVE_TLS @@ -551,7 +632,7 @@ static bool check_resources() director->tls_keyfile, NULL, NULL, director->tls_dhfile, director->tls_verify_peer); - if (!director->tls_ctx) { + if (!director->tls_ctx) { Emsg2(M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"), director->hdr.name, configfile); OK = false; @@ -559,6 +640,60 @@ static bool check_resources() } } + CONSRES *console; + foreach_res(console, R_CONSOLE) { + /* tls_require implies tls_enable */ + if (console->tls_require) { +#ifndef HAVE_TLS + Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n")); + OK = false; + continue; +#else + console->tls_enable = true; +#endif + } + need_tls = console->tls_enable || console->tls_authenticate; + + if (!console->tls_certfile && need_tls) { + Emsg2(M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"), + console->hdr.name, configfile); + OK = false; + } + + if (!console->tls_keyfile && need_tls) { + Emsg2(M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"), + console->hdr.name, configfile); + OK = false; + } + + if ((!console->tls_ca_certfile && !console->tls_ca_certdir) && need_tls && console->tls_verify_peer) { + Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\"" + " or \"TLS CA Certificate Dir\" are defined for Console \"%s\" in %s." + " At least one CA certificate store is required" + " when using \"TLS Verify Peer\".\n"), + console->hdr.name, configfile); + OK = false; + } + + /* If everything is well, attempt to initialize our per-resource TLS context */ + if (OK && (need_tls || console->tls_require)) { + /* Initialize TLS context: + * Args: CA certfile, CA certdir, Certfile, Keyfile, + * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */ + console->tls_ctx = new_tls_context(console->tls_ca_certfile, + console->tls_ca_certdir, console->tls_certfile, + console->tls_keyfile, NULL, NULL, console->tls_dhfile, + console->tls_verify_peer); + + if (!console->tls_ctx) { + Emsg2(M_FATAL, 0, _("Failed to initialize TLS context for Console \"%s\" in %s.\n"), + console->hdr.name, configfile); + OK = false; + } + } + + } + UnlockRes(); if (OK) {