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
[email protected]
https://lists.sourceforge.net/lists/listinfo/bacula-devel