Skip to content

Commit

Permalink
Add some safeguards.
Browse files Browse the repository at this point in the history
Add some safeguards against running a Native Backup Job on NDMP client
or storage.

Fixes #329: Add some safeguards against running a Native Backup Job on
            NDMP client or storage.
  • Loading branch information
Marco van Wieringen committed Aug 30, 2014
1 parent 4d007be commit 246223e
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 5 deletions.
48 changes: 43 additions & 5 deletions src/dird/backup.c
Expand Up @@ -55,9 +55,38 @@ static char EndJob[] =
"ReadBytes=%llu JobBytes=%llu Errors=%u "
"VSS=%d Encrypt=%d\n";

static inline bool validate_client(JCR *jcr)
{
switch (jcr->res.client->Protocol) {
case APT_NATIVE:
return true;
default:
Jmsg(jcr, M_FATAL, 0, _("Client %s has illegal backup protocol %s for Native backup\n"),
jcr->res.client->name(), auth_protocol_to_str(jcr->res.client->Protocol));
return false;
}
}

static inline bool validate_storage(JCR *jcr)
{
STORERES *store;

foreach_alist(store, jcr->wstorage) {
switch (store->Protocol) {
case APT_NATIVE:
continue;
default:
Jmsg(jcr, M_FATAL, 0, _("Storage %s has illegal backup protocol %s for Native backup\n"),
store->name(), auth_protocol_to_str(store->Protocol));
return false;
}
}

return true;
}

/*
* Called here before the job is run to do the job
* specific setup.
* Called here before the job is run to do the job specific setup.
*/
bool do_native_backup_init(JCR *jcr)
{
Expand All @@ -72,21 +101,30 @@ bool do_native_backup_init(JCR *jcr)
return false;
}

/* If pool storage specified, use it instead of job storage */
/*
* If pool storage specified, use it instead of job storage
*/
copy_wstorage(jcr, jcr->res.pool->storage, _("Pool resource"));

if (!jcr->wstorage) {
Jmsg(jcr, M_FATAL, 0, _("No Storage specification found in Job or Pool.\n"));
return false;
}

/*
* Validate that we have a native client and storage(s).
*/
if (!validate_client(jcr) || !validate_storage(jcr)) {
return false;
}

create_clones(jcr); /* run any clone jobs */

return true;
}

/* Take all base jobs from job resource and find the
* last L_BASE jobid.
/*
* Take all base jobs from job resource and find the last L_BASE jobid.
*/
static bool get_base_jobids(JCR *jcr, db_list_ctx *jobids)
{
Expand Down
12 changes: 12 additions & 0 deletions src/dird/dird_conf.c
Expand Up @@ -1422,6 +1422,17 @@ bool FILESETRES::print_config(POOL_MEM &buff)
return true;
}

const char *auth_protocol_to_str(uint32_t auth_protocol)
{
for (int i = 0; authprotocols[i].name; i++) {
if (authprotocols[i].token == auth_protocol) {
return authprotocols[i].name;
}
}

return "Unknown";
}

const char *level_to_str(int level)
{
static char level_no[30];
Expand All @@ -1434,6 +1445,7 @@ const char *level_to_str(int level)
break;
}
}

return str;
}

Expand Down
72 changes: 72 additions & 0 deletions src/dird/ndmp_dma.c
Expand Up @@ -492,6 +492,60 @@ static inline N_TREE_NODE *find_tree_node(N_TREE_ROOT *root, uint32_t inode)
return (N_TREE_NODE *)NULL;
}

static inline bool validate_client(JCR *jcr)
{
switch (jcr->res.client->Protocol) {
case APT_NDMPV2:
case APT_NDMPV3:
case APT_NDMPV4:
break;
default:
Jmsg(jcr, M_FATAL, 0,
_("Client %s, with backup protocol %s not compatible for running NDMP backup.\n"),
jcr->res.client->name(), auth_protocol_to_str(jcr->res.client->Protocol));
return false;
}

return true;
}

static inline bool validate_storage(JCR *jcr, STORERES *store)
{
switch (store->Protocol) {
case APT_NDMPV2:
case APT_NDMPV3:
case APT_NDMPV4:
break;
default:
Jmsg(jcr, M_FATAL, 0, _("Storage %s has illegal backup protocol %s for NDMP backup\n"),
store->name(), auth_protocol_to_str(store->Protocol));
return false;
}

return true;
}

static inline bool validate_storage(JCR *jcr)
{
STORERES *store;

if (jcr->wstorage) {
foreach_alist(store, jcr->wstorage) {
if (!validate_storage(jcr, store)) {
return false;
}
}
} else {
foreach_alist(store, jcr->rstorage) {
if (!validate_storage(jcr, store)) {
return false;
}
}
}

return true;
}

/*
* Fill a ndmagent structure with the correct info. Instead of calling ndmagent_from_str
* we fill the structure ourself from info provides in a resource.
Expand Down Expand Up @@ -1860,6 +1914,17 @@ bool do_ndmp_backup_init(JCR *jcr)
return false;
}

/*
* Validate the Job to have a NDMP client and NDMP storage.
*/
if (!validate_client(jcr)) {
return false;
}

if (!validate_storage(jcr)) {
return false;
}

/*
* For now we only allow NDMP backups to bareos SD's
* so we need a paired storage definition.
Expand Down Expand Up @@ -2669,6 +2734,13 @@ bool do_ndmp_restore(JCR *jcr)

Dmsg1(20, "RestoreJobId=%d\n", jcr->res.job->RestoreJobId);

/*
* Validate the Job to have a NDMP client.
*/
if (!validate_client(jcr)) {
return false;
}

if (!jcr->RestoreBootstrap) {
Jmsg(jcr, M_FATAL, 0, _("Cannot restore without a bootstrap file.\n"
"You probably ran a restore job directly. All restore jobs must\n"
Expand Down
1 change: 1 addition & 0 deletions src/dird/protos.h
Expand Up @@ -83,6 +83,7 @@ void catalog_update(JCR *jcr, BSOCK *bs);
bool despool_attributes_from_file(JCR *jcr, const char *file);

/* dird_conf.c */
const char *auth_protocol_to_str(uint32_t auth_protocol);
const char *level_to_str(int level);
extern "C" char *job_code_callback_director(JCR *jcr, const char*);
bool populate_jobdefs();
Expand Down

0 comments on commit 246223e

Please sign in to comment.