]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Fix #9764 Abort a job if a PluginOptions is incorrect
authorEric Bollengier <eric@baculasystems.com>
Wed, 21 Dec 2022 09:35:31 +0000 (10:35 +0100)
committerEric Bollengier <eric@baculasystems.com>
Thu, 14 Sep 2023 11:57:00 +0000 (13:57 +0200)
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.

bacula/src/filed/fd_plugins.c
bacula/src/filed/fd_plugins.h
bacula/src/filed/job.c

index 37232fe0cf4f16dac0e359eb6ba23aa2c80e9013..f45594efda00aebde2900fb77d7429026189a1d4 100644 (file)
@@ -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)
 {
index d4a20bf328354ea9703ee2f2df217e3ea16ef511..23273886450739b34a5f6ff5877a44963b637b13 100644 (file)
@@ -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;
index db3bca625cd3ed1cc90d4099bcf9b68ec9f19006..20ee2293c599a50eabd63154da7eb6204562dc3a 100644 (file)
@@ -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;
 }