Hello,
we've prepared patch to add option to disable RunScript functionality in Bacula File Daemon. The goal was that the user can't execute script on the client side for the security reasons. New configuration option has been called "AllowScripts" and if it is set to "yes" Bacula File Daemon is able to execute scripts. By default this option is set to "no" so when the user tries to execute script he'll get an error: "2999 Bad Executing scripts is not allowed".

We have also other idea of giving configurable restrictions in Bacula client for backup and restore. We would like to give opportunity of configure what directories will be accessible by server for making backup from. This can be achieved by adding option in Bacula client configuration file that will store regular expression describing what paths can be backed up. We would like to add this configuration option also for restore. To let restore backups only in certain paths described by regular expressions. Those changes are very useful in our environment where we would like to integrate Bacula client. We won't let backup internal system files, only user data can be backed up. Also restore should be possible only in space separated for user. We also think that this changes are useful for any Bacula user because it is possible to restrict access to certain files on client machine and don't allow restore to places where it shouldn't be done. For example user can restrict restore only to specified path and make sure that some system files won't be changed during restore.

--
Best regards
Arkadiusz Bubała
Open-E Poland Sp. z o.o.
www.open-e.com

diff -rup bacula-5.2.13/src/filed/filed_conf.c bacula-5.2.13-mod/src/filed/filed_conf.c
--- bacula-5.2.13/src/filed/filed_conf.c	2013-02-19 20:21:35.000000000 +0100
+++ bacula-5.2.13-mod/src/filed/filed_conf.c	2013-08-08 11:55:08.237639283 +0200
@@ -103,6 +103,7 @@ static RES_ITEM cli_items[] = {
    {"sdconnecttimeout", store_time,ITEM(res_client.SDConnectTimeout), 0, ITEM_DEFAULT, 60 * 30},
    {"heartbeatinterval", store_time, ITEM(res_client.heartbeat_interval), 0, ITEM_DEFAULT, 0},
    {"maximumnetworkbuffersize", store_pint32, ITEM(res_client.max_network_buffer_size), 0, 0, 0},
+   {"allowscripts", store_bool, ITEM(res_client.allow_scripts), 0, ITEM_DEFAULT, 0},
 #ifdef DATA_ENCRYPTION
    {"pkisignatures",         store_bool,    ITEM(res_client.pki_sign), 0, ITEM_DEFAULT, 0},
    {"pkiencryption",         store_bool,    ITEM(res_client.pki_encrypt), 0, ITEM_DEFAULT, 0},
diff -rup bacula-5.2.13/src/filed/filed_conf.h bacula-5.2.13-mod/src/filed/filed_conf.h
--- bacula-5.2.13/src/filed/filed_conf.h	2013-02-19 20:21:35.000000000 +0100
+++ bacula-5.2.13-mod/src/filed/filed_conf.h	2013-08-08 11:52:25.705640653 +0200
@@ -98,7 +98,8 @@ struct CLIENT {
    char *tls_ca_certdir;              /* TLS CA Certificate Directory */
    char *tls_certfile;                /* TLS Client Certificate File */
    char *tls_keyfile;                 /* TLS Client Key File */
-
+   bool allow_scripts;  /* Allow user script to run on clients side */
+   
    X509_KEYPAIR *pki_keypair;         /* Shared PKI Public/Private Keypair */
    alist *pki_signers;                /* Shared PKI Trusted Signers */
    alist *pki_recipients;             /* Shared PKI Recipients */
diff -rup bacula-5.2.13/src/filed/job.c bacula-5.2.13-mod/src/filed/job.c
--- bacula-5.2.13/src/filed/job.c	2013-02-19 20:21:35.000000000 +0100
+++ bacula-5.2.13-mod/src/filed/job.c	2013-08-08 16:32:30.689499049 +0200
@@ -177,6 +177,7 @@ static char OKRunBefore[] = "2000 OK Run
 static char OKRunBeforeNow[] = "2000 OK RunBeforeNow\n";
 static char OKRunAfter[]  = "2000 OK RunAfter\n";
 static char OKRunScript[] = "2000 OK RunScript\n";
+static char BADRunScript[]= "2999 Bad Executing scripts is not allowed\n";
 static char BADcmd[]      = "2902 Bad %s\n";
 static char OKRestoreObject[] = "2000 OK ObjectRestored\n";
 
@@ -304,7 +305,10 @@ void *handle_client_request(void *dirp)
    }
 
    /* Run the after job */
-   run_scripts(jcr, jcr->RunScripts, "ClientAfterJob");
+   if (me->allow_scripts)
+   {	   
+	   run_scripts(jcr, jcr->RunScripts, "ClientAfterJob");
+   }
 
    if (jcr->JobId) {            /* send EndJob if running a job */
       char ed1[50], ed2[50];
@@ -569,9 +573,16 @@ static int runbefore_cmd(JCR *jcr)
 {
    bool ok;
    BSOCK *dir = jcr->dir_bsock;
-   POOLMEM *cmd = get_memory(dir->msglen+1);
+   POOLMEM *cmd;
    RUNSCRIPT *script;
-
+   
+   if (!me->allow_scripts)
+   {
+	   dir->fsend(BADRunScript);
+	   return 0;
+   }
+   
+   cmd = get_memory(dir->msglen+1);
    Dmsg1(100, "runbefore_cmd: %s", dir->msg);
    if (sscanf(dir->msg, runbefore, cmd) != 1) {
       pm_strcpy(jcr->errmsg, dir->msg);
@@ -603,7 +614,13 @@ static int runbefore_cmd(JCR *jcr)
 static int runbeforenow_cmd(JCR *jcr)
 {
    BSOCK *dir = jcr->dir_bsock;
-
+   
+   if (!me->allow_scripts)
+   {
+	   dir->fsend(BADRunScript);
+	   return 0;
+   }
+   
    run_scripts(jcr, jcr->RunScripts, "ClientBeforeJob");
    if (job_canceled(jcr)) {
       dir->fsend(_("2905 Bad RunBeforeNow command.\n"));
@@ -619,9 +636,16 @@ static int runbeforenow_cmd(JCR *jcr)
 static int runafter_cmd(JCR *jcr)
 {
    BSOCK *dir = jcr->dir_bsock;
-   POOLMEM *msg = get_memory(dir->msglen+1);
+   POOLMEM *msg; 
    RUNSCRIPT *cmd;
 
+   if (!me->allow_scripts)
+   {
+	   dir->fsend(BADRunScript);
+	   return 0;
+   }
+   
+   msg = get_memory(dir->msglen+1);
    Dmsg1(100, "runafter_cmd: %s", dir->msg);
    if (sscanf(dir->msg, runafter, msg) != 1) {
       pm_strcpy(jcr->errmsg, dir->msg);
@@ -648,10 +672,18 @@ static int runafter_cmd(JCR *jcr)
 static int runscript_cmd(JCR *jcr)
 {
    BSOCK *dir = jcr->dir_bsock;
-   POOLMEM *msg = get_memory(dir->msglen+1);
+   POOLMEM *msg;
    int on_success, on_failure, fail_on_error;
 
-   RUNSCRIPT *cmd = new_runscript() ;
+   RUNSCRIPT *cmd;
+   if (!me->allow_scripts)
+   {
+	   dir->fsend(BADRunScript);
+	   return 0;
+   }
+      
+   cmd = new_runscript();
+   msg = get_memory(dir->msglen+1);
    cmd->set_job_code_callback(job_code_callback_filed);
 
    Dmsg1(100, "runscript_cmd: '%s'\n", dir->msg);
@@ -1934,7 +1965,10 @@ static int backup_cmd(JCR *jcr)
          Jmsg(jcr, M_FATAL, 0, _("VSS was not initialized properly. ERR=%s\n"),
             be.bstrerror());
       } 
-      run_scripts(jcr, jcr->RunScripts, "ClientAfterVSS");
+	  if (me->allow_scripts)
+      {
+	      run_scripts(jcr, jcr->RunScripts, "ClientAfterVSS");
+      }   
    }
 #endif
 
@@ -2207,7 +2241,10 @@ static int restore_cmd(JCR *jcr)
          Jmsg(jcr, M_WARNING, 0, _("VSS was not initialized properly. VSS support is disabled. ERR=%s\n"), be.bstrerror());
       }
       //free_and_null_pool_memory(jcr->job_metadata);
-      run_scripts(jcr, jcr->RunScripts, "ClientAfterVSS");
+	  if (me->allow_scripts)
+      {
+	      run_scripts(jcr, jcr->RunScripts, "ClientAfterVSS");
+      }      
    }
 #endif
 
------------------------------------------------------------------------------
Get 100% visibility into Java/.NET code with AppDynamics Lite!
It's a free troubleshooting tool designed for production.
Get down to code-level detail for bottlenecks, with <2% overhead. 
Download for free and get started troubleshooting in minutes. 
http://pubads.g.doubleclick.net/gampad/clk?id=48897031&iu=/4140/ostg.clktrk
_______________________________________________
Bacula-devel mailing list
Bacula-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bacula-devel

Reply via email to