From: Eric Bollengier Date: Wed, 21 Dec 2022 09:35:31 +0000 (+0100) Subject: Fix #9764 Abort a job if a PluginOptions is incorrect X-Git-Tag: Beta-15.0.0~298 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=176666f9c889e02b3dbc35f84d58c3297c0c2975;p=thirdparty%2Fbacula.git Fix #9764 Abort a job if a PluginOptions is incorrect If a plugin is not installed and is specified with the Job PluginOptions, the job simply terminated "Verify OK" With other plugins, like the vSphere plugin, if the plugin is not installed, but a Fileset calls it, we get a failed job and a warning about "command not found" or similar. The important part here is that if the plugin is missing, we end up with False negatives that a sysadmin should be notified about. --- diff --git a/bacula/src/filed/fd_plugins.c b/bacula/src/filed/fd_plugins.c index 37232fe0c..f45594efd 100644 --- a/bacula/src/filed/fd_plugins.c +++ b/bacula/src/filed/fd_plugins.c @@ -512,6 +512,39 @@ static void update_ff_pkt(FF_PKT *ff_pkt, struct save_pkt *sp) Dsm_check(999); } +/* Look if a given plugin can be used */ +bool is_plugin_loaded(JCR *jcr, char *cmd) +{ + Plugin *plugin; + bool found=false; + int len; + int i=0; + + bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list; + if (!b_plugin_list || !jcr->plugin_ctx_list || jcr->is_job_canceled()) { + goto bail_out; /* Return if no plugins loaded */ + } + + if (!get_plugin_name(jcr, cmd, &len)) { + goto bail_out; + } + + /* Note, we stop the loop on the first plugin that matches the name */ + foreach_alist_index(i, plugin, b_plugin_list) { + Dmsg4(dbglvl, "plugin=%s plen=%d cmd=%s len=%d\n", plugin->file, plugin->file_len, cmd, len); + if (!for_this_plugin(plugin, cmd, len)) { + continue; + } + if (is_plugin_disabled(&plugin_ctx_list[i])) { + goto bail_out; + } + found=true; + goto bail_out; + } /* end foreach loop */ +bail_out: + return found; +} + /* Ask to a Option Plugin what to do with the current file */ bRC plugin_option_handle_file(JCR *jcr, FF_PKT *ff_pkt, struct save_pkt *sp) { diff --git a/bacula/src/filed/fd_plugins.h b/bacula/src/filed/fd_plugins.h index d4a20bf32..232738864 100644 --- a/bacula/src/filed/fd_plugins.h +++ b/bacula/src/filed/fd_plugins.h @@ -503,7 +503,7 @@ int plugin_get_idx(JCR *jcr, char *plugin); bool plugin_send_restorefilelist(JCR *jcr, int plugin_index, char *path, char *lstat, char *checksum, int delta_seq); - +bool is_plugin_loaded(JCR *jcr, char *cmd); typedef struct { const char *plugin; const char *features; diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index db3bca625..20ee2293c 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -3653,19 +3653,28 @@ static int pluginoptions_cmd(JCR *jcr) { POOL_MEM buf(PM_MESSAGE); BSOCK *dir = jcr->dir_bsock; + bool ok = true; buf.check_size(dir->msglen+1); if (scan_string(dir->msg, "pluginoptions=%s", buf.c_str()) == 1) { unbash_spaces(buf.c_str()); if (!jcr->plugin_options_list) { jcr->plugin_options_list = New(alist(5, owned_by_alist)); } - jcr->plugin_options_list->append(bstrdup(buf.c_str())); + if (is_plugin_loaded(jcr, buf.c_str())) { + jcr->plugin_options_list->append(bstrdup(buf.c_str())); + } else { + ok = false; + } } else { dir->fsend(_("2992 Bad pluginoptions command\n")); return 0; } dir->fsend("2000 OK plugin options\n"); + if (!ok) { + Jmsg1(jcr, M_FATAL, 0, "Command plugin \"%s\" requested, but is not loaded.\n", + buf.c_str()); + } return 1; }