From cfa08aa1e1519984716213a0903e40bc3566e8db Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sat, 23 Dec 2006 16:33:53 +0000 Subject: [PATCH] kes Add code in catreq.c to reject volumes not marked Enabled. kes Add a few more ACL access checks. kes Add \n in gnome2-console restore command so that output prints nicer -- i.e. lines do not run together. kes Fix autolabeling so that it will not mark a volume in error if the volume was not actually opened. This should fix bugs #737 and 738. kes Require tape drive to be open before autolabeling. kes Require explicit mount command on non-tapes before autolabeling. kes Implement an open_client_db() that searches the keywords for either a catolg or client, and opens the appropriate catalog. This makes Bacula adjust better to multiple catalogs. kes Use more name() methods for resources rather than hdr.name. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@3844 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/dird/catreq.c | 3 + bacula/src/dird/protos.h | 1 + bacula/src/dird/ua_cmds.c | 79 +++++++++++++-- bacula/src/dird/ua_dotcmds.c | 139 +++++++++++++------------- bacula/src/dird/ua_label.c | 4 +- bacula/src/dird/ua_output.c | 2 +- bacula/src/dird/ua_prune.c | 2 +- bacula/src/dird/ua_query.c | 4 +- bacula/src/dird/ua_restore.c | 4 +- bacula/src/dird/ua_run.c | 6 +- bacula/src/dird/ua_status.c | 13 ++- bacula/src/dird/ua_update.c | 2 +- bacula/src/gnome2-console/callbacks.c | 2 +- bacula/src/lib/parse_conf.h | 11 +- bacula/src/stored/mount.c | 19 ++-- bacula/src/version.h | 4 +- bacula/technotes-1.39 | 14 +++ 17 files changed, 205 insertions(+), 104 deletions(-) diff --git a/bacula/src/dird/catreq.c b/bacula/src/dird/catreq.c index 1d19a5a26f..eeae8ed4e5 100644 --- a/bacula/src/dird/catreq.c +++ b/bacula/src/dird/catreq.c @@ -189,6 +189,9 @@ void catalog_request(JCR *jcr, BSOCK *bs) check_if_volume_valid_or_recyclable(jcr, &mr, &reason); } } + if (!reason && mr.Enabled != 1) { + reason = _("is not Enabled"); + } if (reason == NULL) { /* * Send Find Media response to Storage daemon diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index ee7a4bd93c..31761cd19f 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -171,6 +171,7 @@ bool acl_access_ok(UAContext *ua, int acl, char *item, int len); int do_a_command(UAContext *ua, const char *cmd); int do_a_dot_command(UAContext *ua, const char *cmd); int qmessagescmd(UAContext *ua, const char *cmd); +bool open_client_db(UAContext *ua); bool open_db(UAContext *ua); void close_db(UAContext *ua); enum e_pool_op { diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 13cbccdc16..24e6d2ad4d 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -220,7 +220,7 @@ static int add_cmd(UAContext *ua, const char *cmd) "creates database records without labeling the Volumes.\n" "You probably want to use the \"label\" command.\n\n")); - if (!open_db(ua)) { + if (!open_client_db(ua)) { return 1; } @@ -384,7 +384,7 @@ static int cancel_cmd(UAContext *ua, const char *cmd) JCR *jcr = NULL; char JobName[MAX_NAME_LENGTH]; - if (!open_db(ua)) { + if (!open_client_db(ua)) { return 1; } @@ -556,7 +556,7 @@ static int create_cmd(UAContext *ua, const char *cmd) { POOL *pool; - if (!open_db(ua)) { + if (!open_client_db(ua)) { return 1; } @@ -824,7 +824,7 @@ static int setdebug_cmd(UAContext *ua, const char *cmd) int trace_flag = -1; int i; - if (!open_db(ua)) { + if (!open_client_db(ua)) { return 1; } Dmsg1(120, "setdebug:%s:\n", cmd); @@ -958,7 +958,7 @@ static int var_cmd(UAContext *ua, const char *cmd) POOLMEM *val = get_pool_memory(PM_FNAME); char *var; - if (!open_db(ua)) { + if (!open_client_db(ua)) { return 1; } for (var=ua->cmd; *var != ' '; ) { /* skip command */ @@ -995,12 +995,20 @@ static int estimate_cmd(UAContext *ua, const char *cmd) if (strcasecmp(ua->argk[i], NT_("job")) == 0) { if (ua->argv[i]) { job = (JOB *)GetResWithName(R_JOB, ua->argv[i]); + if (job && !acl_access_ok(ua, Job_ACL, job->name())) { + bsendmsg(ua, _("No authorization for Job \"%s\"\n"), job->name()); + return 1; + } continue; } } if (strcasecmp(ua->argk[i], NT_("fileset")) == 0) { if (ua->argv[i]) { fileset = (FILESET *)GetResWithName(R_FILESET, ua->argv[i]); + if (fileset && !acl_access_ok(ua, FileSet_ACL, fileset->name())) { + bsendmsg(ua, _("No authorization for FileSet \"%s\"\n"), fileset->name()); + return 1; + } continue; } } @@ -1026,6 +1034,10 @@ static int estimate_cmd(UAContext *ua, const char *cmd) bsendmsg(ua, _("No job specified.\n")); return 1; } + if (!acl_access_ok(ua, Job_ACL, job->name())) { + bsendmsg(ua, _("No authorization for Job \"%s\"\n"), job->name()); + return 1; + } } if (!client) { client = job->client; @@ -1131,7 +1143,7 @@ static int delete_cmd(UAContext *ua, const char *cmd) NT_("jobid"), NULL}; - if (!open_db(ua)) { + if (!open_client_db(ua)) { return 1; } @@ -1319,7 +1331,7 @@ static void do_mount_cmd(UAContext *ua, const char *command) int drive; int slot = -1; - if (!open_db(ua)) { + if (!open_client_db(ua)) { return; } Dmsg2(120, "%s: %s\n", command, ua->UA_sock->msg); @@ -1465,7 +1477,7 @@ int wait_cmd(UAContext *ua, const char *cmd) uint32_t jobid = 0 ; - if (!open_db(ua)) { + if (!open_client_db(ua)) { bsendmsg(ua, _("ERR: Can't open db\n")) ; return 1; } @@ -1602,6 +1614,56 @@ static int version_cmd(UAContext *ua, const char *cmd) return 1; } +/* + * This call explicitly checks for a catalog=xxx and + * if given, opens that catalog. It also checks for + * client=xxx and if found, opens the catalog + * corresponding to that client. + */ +bool open_client_db(UAContext *ua) +{ + int i; + CAT *catalog; + CLIENT *client; + + /* Try for catalog keyword */ + i = find_arg_with_value(ua, NT_("catalog")); + if (i >= 0) { + if (!acl_access_ok(ua, Catalog_ACL, ua->argv[i])) { + bsendmsg(ua, _("No authorization for catalog \"%s\"\n"), ua->argv[i]); + return false; + } + catalog = (CAT *)GetResWithName(R_CATALOG, ua->argv[i]); + if (catalog) { + if (ua->catalog && ua->catalog != catalog) { + close_db(ua); + } + ua->catalog = catalog; + return open_db(ua); + } + } + + /* Try for client keyword */ + i = find_arg_with_value(ua, NT_("client")); + if (i >= 0) { + if (!acl_access_ok(ua, Catalog_ACL, ua->argv[i])) { + bsendmsg(ua, _("No authorization for client \"%s\"\n"), ua->argv[i]); + return false; + } + client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]); + if (client) { + if (ua->catalog && ua->catalog != client->catalog) { + close_db(ua); + } + ua->catalog = client->catalog; + return open_db(ua); + } + } + return open_db(ua); +} + + + /* * Open the catalog database. @@ -1636,6 +1698,7 @@ bool open_db(UAContext *ua) return false; } ua->jcr->db = ua->db; + bsendmsg(ua, _("Using Catalog \"%s\"\n"), ua->catalog->name()); Dmsg1(150, "DB %s opened\n", ua->catalog->db_name); return true; } diff --git a/bacula/src/dird/ua_dotcmds.c b/bacula/src/dird/ua_dotcmds.c index 47a70898d4..04e87c0da9 100644 --- a/bacula/src/dird/ua_dotcmds.c +++ b/bacula/src/dird/ua_dotcmds.c @@ -152,8 +152,8 @@ static int jobscmd(UAContext *ua, const char *cmd) JOB *job = NULL; LockRes(); while ( (job = (JOB *)GetNextRes(R_JOB, (RES *)job)) ) { - if (acl_access_ok(ua, Job_ACL, job->hdr.name)) { - bsendmsg(ua, "%s\n", job->hdr.name); + if (acl_access_ok(ua, Job_ACL, job->name())) { + bsendmsg(ua, "%s\n", job->name()); } } UnlockRes(); @@ -165,8 +165,8 @@ static int filesetscmd(UAContext *ua, const char *cmd) FILESET *fs = NULL; LockRes(); while ( (fs = (FILESET *)GetNextRes(R_FILESET, (RES *)fs)) ) { - if (acl_access_ok(ua, FileSet_ACL, fs->hdr.name)) { - bsendmsg(ua, "%s\n", fs->hdr.name); + if (acl_access_ok(ua, FileSet_ACL, fs->name())) { + bsendmsg(ua, "%s\n", fs->name()); } } UnlockRes(); @@ -178,8 +178,8 @@ static int clientscmd(UAContext *ua, const char *cmd) CLIENT *client = NULL; LockRes(); while ( (client = (CLIENT *)GetNextRes(R_CLIENT, (RES *)client)) ) { - if (acl_access_ok(ua, Client_ACL, client->hdr.name)) { - bsendmsg(ua, "%s\n", client->hdr.name); + if (acl_access_ok(ua, Client_ACL, client->name())) { + bsendmsg(ua, "%s\n", client->name()); } } UnlockRes(); @@ -191,7 +191,7 @@ static int msgscmd(UAContext *ua, const char *cmd) MSGS *msgs = NULL; LockRes(); while ( (msgs = (MSGS *)GetNextRes(R_MSGS, (RES *)msgs)) ) { - bsendmsg(ua, "%s\n", msgs->hdr.name); + bsendmsg(ua, "%s\n", msgs->name()); } UnlockRes(); return 1; @@ -202,8 +202,8 @@ static int poolscmd(UAContext *ua, const char *cmd) POOL *pool = NULL; LockRes(); while ( (pool = (POOL *)GetNextRes(R_POOL, (RES *)pool)) ) { - if (acl_access_ok(ua, Pool_ACL, pool->hdr.name)) { - bsendmsg(ua, "%s\n", pool->hdr.name); + if (acl_access_ok(ua, Pool_ACL, pool->name())) { + bsendmsg(ua, "%s\n", pool->name()); } } UnlockRes(); @@ -215,8 +215,8 @@ static int storagecmd(UAContext *ua, const char *cmd) STORE *store = NULL; LockRes(); while ( (store = (STORE *)GetNextRes(R_STORAGE, (RES *)store)) ) { - if (acl_access_ok(ua, Storage_ACL, store->hdr.name)) { - bsendmsg(ua, "%s\n", store->hdr.name); + if (acl_access_ok(ua, Storage_ACL, store->name())) { + bsendmsg(ua, "%s\n", store->name()); } } UnlockRes(); @@ -244,7 +244,7 @@ static int client_backups_handler(void *ctx, int num_field, char **row) static int backupscmd(UAContext *ua, const char *cmd) { - if (!open_db(ua)) { + if (!open_client_db(ua)) { return 1; } if (ua->argc != 3 || strcmp(ua->argk[1], "client") != 0 || strcmp(ua->argk[2], "fileset") != 0) { @@ -296,78 +296,81 @@ static int defaultscmd(UAContext *ua, const char *cmd) job = (JOB *)GetResWithName(R_JOB, ua->argv[1]); if (job) { USTORE store; - bsendmsg(ua, "job=%s", job->hdr.name); - bsendmsg(ua, "pool=%s", job->pool->hdr.name); - bsendmsg(ua, "messages=%s", job->messages->hdr.name); - bsendmsg(ua, "client=%s", job->client->hdr.name); + bsendmsg(ua, "job=%s", job->name()); + bsendmsg(ua, "pool=%s", job->pool->name()); + bsendmsg(ua, "messages=%s", job->messages->name()); + bsendmsg(ua, "client=%s", job->client->name()); get_job_storage(&store, job, NULL); bsendmsg(ua, "storage=%s", store.store->name()); bsendmsg(ua, "where=%s", job->RestoreWhere?job->RestoreWhere:""); bsendmsg(ua, "level=%s", level_to_str(job->JobLevel)); bsendmsg(ua, "type=%s", job_type_to_str(job->JobType)); - bsendmsg(ua, "fileset=%s", job->fileset->hdr.name); + bsendmsg(ua, "fileset=%s", job->fileset->name()); bsendmsg(ua, "enabled=%d", job->enabled); + bsendmsg(ua, "catalog=%s", job->client->catalog->name()); } } /* Client defaults */ else if (strcmp(ua->argk[1], "client") == 0) { - if (!acl_access_ok(ua, Client_ACL, ua->argv[1])) { - return 1; - } - client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[1]); - if (client) { - bsendmsg(ua, "client=%s", client->hdr.name); - bsendmsg(ua, "address=%s", client->address); - bsendmsg(ua, "fdport=%d", client->FDport); - bsendmsg(ua, "file_retention=%d", client->FileRetention); - bsendmsg(ua, "job_retention=%d", client->JobRetention); - bsendmsg(ua, "autoprune=%d", client->AutoPrune); - } + if (!acl_access_ok(ua, Client_ACL, ua->argv[1])) { + return 1; + } + client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[1]); + if (client) { + bsendmsg(ua, "client=%s", client->name()); + bsendmsg(ua, "address=%s", client->address); + bsendmsg(ua, "fdport=%d", client->FDport); + bsendmsg(ua, "file_retention=%d", client->FileRetention); + bsendmsg(ua, "job_retention=%d", client->JobRetention); + bsendmsg(ua, "autoprune=%d", client->AutoPrune); + bsendmsg(ua, "catalog=%s", client->catalog->name()); + } } /* Storage defaults */ else if (strcmp(ua->argk[1], "storage") == 0) { - if (!acl_access_ok(ua, Storage_ACL, ua->argv[1])) { - return 1; - } - storage = (STORE *)GetResWithName(R_STORAGE, ua->argv[1]); - DEVICE *device; - if (storage) { - bsendmsg(ua, "storage=%s", storage->hdr.name); - bsendmsg(ua, "address=%s", storage->address); - bsendmsg(ua, "enabled=%d", storage->enabled); - bsendmsg(ua, "media_type=%s", storage->media_type); - bsendmsg(ua, "sdport=%d", storage->SDport); - device = (DEVICE *)storage->device->first(); - bsendmsg(ua, "device=%s", device->hdr.name); - if (storage->device->size() > 1) { - while ((device = (DEVICE *)storage->device->next())) - bsendmsg(ua, ",%s", device->hdr.name); - } - } + if (!acl_access_ok(ua, Storage_ACL, ua->argv[1])) { + return 1; + } + storage = (STORE *)GetResWithName(R_STORAGE, ua->argv[1]); + DEVICE *device; + if (storage) { + bsendmsg(ua, "storage=%s", storage->name()); + bsendmsg(ua, "address=%s", storage->address); + bsendmsg(ua, "enabled=%d", storage->enabled); + bsendmsg(ua, "media_type=%s", storage->media_type); + bsendmsg(ua, "sdport=%d", storage->SDport); + device = (DEVICE *)storage->device->first(); + bsendmsg(ua, "device=%s", device->name()); + if (storage->device->size() > 1) { + while ((device = (DEVICE *)storage->device->next())) { + bsendmsg(ua, ",%s", device->name()); + } + } + } } /* Pool defaults */ else if (strcmp(ua->argk[1], "pool") == 0) { - if (!acl_access_ok(ua, Pool_ACL, ua->argv[1])) { - return 1; - } - pool = (POOL *)GetResWithName(R_POOL, ua->argv[1]); - if (pool) { - bsendmsg(ua, "pool=%s", pool->hdr.name); - bsendmsg(ua, "pool_type=%s", pool->pool_type); - bsendmsg(ua, "label_format=%s", pool->label_format?pool->label_format:""); - bsendmsg(ua, "use_volume_once=%d", pool->use_volume_once); - bsendmsg(ua, "purge_oldest_volume=%d", pool->purge_oldest_volume); - bsendmsg(ua, "recycle_oldest_volume=%d", pool->recycle_oldest_volume); - bsendmsg(ua, "recycle_current_volume=%d", pool->recycle_current_volume); - bsendmsg(ua, "max_volumes=%d", pool->max_volumes); - bsendmsg(ua, "vol_retention=%d", pool->VolRetention); - bsendmsg(ua, "vol_use_duration=%d", pool->VolUseDuration); - bsendmsg(ua, "max_vol_jobs=%d", pool->MaxVolJobs); - bsendmsg(ua, "max_vol_files=%d", pool->MaxVolFiles); - bsendmsg(ua, "max_vol_bytes=%d", pool->MaxVolBytes); - bsendmsg(ua, "auto_prune=%d", pool->AutoPrune); - bsendmsg(ua, "recycle=%d", pool->Recycle); - } + if (!acl_access_ok(ua, Pool_ACL, ua->argv[1])) { + return 1; + } + pool = (POOL *)GetResWithName(R_POOL, ua->argv[1]); + if (pool) { + bsendmsg(ua, "pool=%s", pool->name()); + bsendmsg(ua, "pool_type=%s", pool->pool_type); + bsendmsg(ua, "label_format=%s", pool->label_format?pool->label_format:""); + bsendmsg(ua, "use_volume_once=%d", pool->use_volume_once); + bsendmsg(ua, "purge_oldest_volume=%d", pool->purge_oldest_volume); + bsendmsg(ua, "recycle_oldest_volume=%d", pool->recycle_oldest_volume); + bsendmsg(ua, "recycle_current_volume=%d", pool->recycle_current_volume); + bsendmsg(ua, "max_volumes=%d", pool->max_volumes); + bsendmsg(ua, "vol_retention=%d", pool->VolRetention); + bsendmsg(ua, "vol_use_duration=%d", pool->VolUseDuration); + bsendmsg(ua, "max_vol_jobs=%d", pool->MaxVolJobs); + bsendmsg(ua, "max_vol_files=%d", pool->MaxVolFiles); + bsendmsg(ua, "max_vol_bytes=%d", pool->MaxVolBytes); + bsendmsg(ua, "auto_prune=%d", pool->AutoPrune); + bsendmsg(ua, "recycle=%d", pool->Recycle); + } } return 1; } diff --git a/bacula/src/dird/ua_label.c b/bacula/src/dird/ua_label.c index fbd26f8e0b..e293b0abbb 100644 --- a/bacula/src/dird/ua_label.c +++ b/bacula/src/dird/ua_label.c @@ -174,7 +174,7 @@ void update_slots(UAContext *ua) int i; - if (!open_db(ua)) { + if (!open_client_db(ua)) { return; } store.store = get_storage_resource(ua, true/*arg is storage*/); @@ -329,7 +329,7 @@ static int do_label(UAContext *ua, const char *cmd, int relabel) memset(&pr, 0, sizeof(pr)); - if (!open_db(ua)) { + if (!open_client_db(ua)) { return 1; } diff --git a/bacula/src/dird/ua_output.c b/bacula/src/dird/ua_output.c index 231e64f0da..5f05046870 100644 --- a/bacula/src/dird/ua_output.c +++ b/bacula/src/dird/ua_output.c @@ -249,7 +249,7 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist) POOL_DBR pr; MEDIA_DBR mr; - if (!open_db(ua)) + if (!open_client_db(ua)) return 1; memset(&jr, 0, sizeof(jr)); diff --git a/bacula/src/dird/ua_prune.c b/bacula/src/dird/ua_prune.c index 1de851c8da..52fb760520 100644 --- a/bacula/src/dird/ua_prune.c +++ b/bacula/src/dird/ua_prune.c @@ -156,7 +156,7 @@ int prunecmd(UAContext *ua, const char *cmd) NT_("Volume"), NULL}; - if (!open_db(ua)) { + if (!open_client_db(ua)) { return false; } diff --git a/bacula/src/dird/ua_query.c b/bacula/src/dird/ua_query.c index def1a0a2ca..03c5f934d2 100644 --- a/bacula/src/dird/ua_query.c +++ b/bacula/src/dird/ua_query.c @@ -65,7 +65,7 @@ int querycmd(UAContext *ua, const char *cmd) int nprompt = 0;; char *query_file = director->query_file; - if (!open_db(ua)) { + if (!open_client_db(ua)) { goto bail_out; } if ((fd=fopen(query_file, "rb")) == NULL) { @@ -256,7 +256,7 @@ int sqlquerycmd(UAContext *ua, const char *cmd) int len; const char *msg; - if (!open_db(ua)) { + if (!open_client_db(ua)) { free_pool_memory(query); return 1; } diff --git a/bacula/src/dird/ua_restore.c b/bacula/src/dird/ua_restore.c index 7f8cf1db6b..420931d5f1 100644 --- a/bacula/src/dird/ua_restore.c +++ b/bacula/src/dird/ua_restore.c @@ -100,7 +100,7 @@ int restore_cmd(UAContext *ua, const char *cmd) } } - if (!open_db(ua)) { + if (!open_client_db(ua)) { goto bail_out; } @@ -179,7 +179,7 @@ int restore_cmd(UAContext *ua, const char *cmd) get_client_name(ua, &rx); if (!rx.ClientName) { - bsendmsg(ua, _("No Restore Job resource found!\n")); + bsendmsg(ua, _("No Client resource found!\n")); goto bail_out; } diff --git a/bacula/src/dird/ua_run.c b/bacula/src/dird/ua_run.c index 96944d393c..c5a271c84e 100644 --- a/bacula/src/dird/ua_run.c +++ b/bacula/src/dird/ua_run.c @@ -105,7 +105,7 @@ int run_cmd(UAContext *ua, const char *cmd) #define YES_POS 14 - if (!open_db(ua)) { + if (!open_client_db(ua)) { return 1; } @@ -322,6 +322,10 @@ int run_cmd(UAContext *ua, const char *cmd) bsendmsg(ua, _("Catalog \"%s\" not found\n"), catalog_name); return 0; } + if (!acl_access_ok(ua, Catalog_ACL, catalog->name())) { + bsendmsg(ua, _("No authorization. Catalog \"%s\".\n"), catalog->name()); + return 0; + } } Dmsg1(800, "Using catalog=%s\n", NPRT(catalog_name)); diff --git a/bacula/src/dird/ua_status.c b/bacula/src/dird/ua_status.c index fbc1628146..2da4d56a2e 100644 --- a/bacula/src/dird/ua_status.c +++ b/bacula/src/dird/ua_status.c @@ -58,9 +58,6 @@ int qstatus_cmd(UAContext *ua, const char *cmd) s_last_job* job; char ed1[50]; - if (!open_db(ua)) { - return 1; - } Dmsg1(20, "status:%s:\n", cmd); if ((ua->argc != 3) || (strcasecmp(ua->argk[1], "dir"))) { @@ -71,7 +68,7 @@ int qstatus_cmd(UAContext *ua, const char *cmd) if (strcasecmp(ua->argk[2], "current") == 0) { bsendmsg(ua, OKqstatus, ua->argk[2]); foreach_jcr(njcr) { - if (njcr->JobId != 0) { + if (njcr->JobId != 0 && acl_access_ok(ua, Job_ACL, njcr->job->name())) { bsendmsg(ua, DotStatusJob, edit_int64(njcr->JobId, ed1), njcr->JobStatus, njcr->JobErrors); } @@ -81,8 +78,10 @@ int qstatus_cmd(UAContext *ua, const char *cmd) bsendmsg(ua, OKqstatus, ua->argk[2]); if ((last_jobs) && (last_jobs->size() > 0)) { job = (s_last_job*)last_jobs->last(); - bsendmsg(ua, DotStatusJob, edit_int64(job->JobId, ed1), + if (acl_access_ok(ua, Job_ACL, job->Job)) { + bsendmsg(ua, DotStatusJob, edit_int64(job->JobId, ed1), job->JobStatus, job->Errors); + } } } else { bsendmsg(ua, "1900 Bad .status command, wrong argument.\n"); @@ -101,7 +100,7 @@ int status_cmd(UAContext *ua, const char *cmd) CLIENT *client; int item, i; - if (!open_db(ua)) { + if (!open_client_db(ua)) { return 1; } Dmsg1(20, "status:%s:\n", cmd); @@ -641,7 +640,7 @@ static void list_running_jobs(UAContext *ua) break; case JS_WaitFD: if (!pool_mem) { - emsg = (char *) get_pool_memory(PM_FNAME); + emsg = (char *)get_pool_memory(PM_FNAME); pool_mem = true; } Mmsg(emsg, _("is waiting for Client %s to connect to Storage %s"), diff --git a/bacula/src/dird/ua_update.c b/bacula/src/dird/ua_update.c index 6717138cc0..5e2688c38d 100644 --- a/bacula/src/dird/ua_update.c +++ b/bacula/src/dird/ua_update.c @@ -62,7 +62,7 @@ int update_cmd(UAContext *ua, const char *cmd) NT_("slots"), /* 3 */ NULL}; - if (!open_db(ua)) { + if (!open_client_db(ua)) { return 1; } diff --git a/bacula/src/gnome2-console/callbacks.c b/bacula/src/gnome2-console/callbacks.c index 85e430af70..9bd6cf0b68 100644 --- a/bacula/src/gnome2-console/callbacks.c +++ b/bacula/src/gnome2-console/callbacks.c @@ -545,7 +545,7 @@ on_select_files_button_clicked(GtkButton *button, gpointer user_data) bsnprintf(cmd, sizeof(cmd), "restore select current fileset=\"%s\" client=\"%s\" pool=\"%s\" " - "storage=\"%s\"", fileset, client, pool, storage); + "storage=\"%s\"\n", fileset, client, pool, storage); write_director(cmd); set_text(cmd, strlen(cmd)); gtk_widget_show(restore_file_selection); diff --git a/bacula/src/lib/parse_conf.h b/bacula/src/lib/parse_conf.h index 5833e0ad40..b8adffe25f 100644 --- a/bacula/src/lib/parse_conf.h +++ b/bacula/src/lib/parse_conf.h @@ -67,7 +67,8 @@ struct RES_ITEM { * at the beginning of every resource * record. */ -struct RES { +class RES { +public: RES *next; /* pointer to next resource of this type */ char *name; /* resource name */ char *desc; /* resource description */ @@ -97,14 +98,20 @@ struct RES_TABLE { #define ITEM_NO_EQUALS 0x4 /* Don't scan = after name */ /* Message Resource */ -struct MSGS { +class MSGS { +public: RES hdr; char *mail_cmd; /* mail command */ char *operator_cmd; /* Operator command */ DEST *dest_chain; /* chain of destinations */ char send_msg[nbytes_for_bits(M_MAX+1)]; /* bit array of types */ + + /* Methods */ + char *name() const; }; +inline char *MSGS::name() const { return hdr.name; } + /* Define the Union of all the above common * resource structure definitions. diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index 456bebb749..4dac477e24 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -39,7 +39,7 @@ #include "stored.h" /* pull in Storage Deamon headers */ static void mark_volume_not_inchanger(DCR *dcr); -static int try_autolabel(DCR *dcr); +static int try_autolabel(DCR *dcr, bool opened); enum { try_next_vol = 1, @@ -179,7 +179,7 @@ mount_next_vol: } /* Try autolabel if enabled */ if (dev->open(dcr, mode) < 0) { - try_autolabel(dcr); /* try to create a new volume label */ + try_autolabel(dcr, false); /* try to create a new volume label */ } while (dev->open(dcr, mode) < 0) { Dmsg1(150, "open_device failed: ERR=%s\n", dev->bstrerror()); @@ -200,7 +200,7 @@ mount_next_vol: dev->unmount(0); } } - if (try_autolabel(dcr) == try_read_vol) { + if (try_autolabel(dcr, false) == try_read_vol) { break; /* created a new volume label */ } /* If DVD, ignore the error, very often you cannot open the device @@ -319,7 +319,7 @@ read_volume: } /* Fall through wanted */ case VOL_NO_LABEL: - switch (try_autolabel(dcr)) { + switch (try_autolabel(dcr, true)) { case try_next_vol: goto mount_next_vol; case try_read_vol: @@ -475,12 +475,17 @@ read_volume: * try_error hard error (catalog update) * try_default I couldn't do anything */ -static int try_autolabel(DCR *dcr) +static int try_autolabel(DCR *dcr, bool opened) { DEVICE *dev = dcr->dev; + if (dev->poll && !dev->is_tape()) { return try_default; /* if polling, don't try to create new labels */ } + /* For a tape require it to be opened and read before labeling */ + if (!opened && dev->is_tape()) { + return try_default; + } if (dev->has_cap(CAP_LABEL) && (dcr->VolCatInfo.VolCatBytes == 0 || (!dev->is_tape() && strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0))) { @@ -489,7 +494,9 @@ static int try_autolabel(DCR *dcr) if (!write_new_volume_label_to_dev(dcr, dcr->VolumeName, dcr->pool_name, false, /* no relabel */ false /* defer DVD label */)) { Dmsg0(150, "!write_vol_label\n"); - mark_volume_in_error(dcr); + if (opened) { + mark_volume_in_error(dcr); + } return try_next_vol; } Dmsg0(150, "dir_update_vol_info. Set Append\n"); diff --git a/bacula/src/version.h b/bacula/src/version.h index 4d6863c131..4c7a6fb8b8 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -4,8 +4,8 @@ #undef VERSION #define VERSION "1.39.33" -#define BDATE "22 December 2006" -#define LSMDATE "22Dec06" +#define BDATE "23 December 2006" +#define LSMDATE "23Dec06" #define PROG_COPYRIGHT "Copyright (C) %d-2006 Free Software Foundation Europe e.V.\n" #define BYEAR "2006" /* year for copyright messages in progs */ diff --git a/bacula/technotes-1.39 b/bacula/technotes-1.39 index e247791827..aced453911 100644 --- a/bacula/technotes-1.39 +++ b/bacula/technotes-1.39 @@ -1,6 +1,20 @@ Technical notes on version 1.39 General: +23Dec06 +kes Add code in catreq.c to reject volumes not marked Enabled. +kes Add a few more ACL access checks. +kes Add \n in gnome2-console restore command so that output prints + nicer -- i.e. lines do not run together. +kes Fix autolabeling so that it will not mark a volume in error + if the volume was not actually opened. This should fix bugs + #737 and 738. +kes Require tape drive to be open before autolabeling. +kes Require explicit mount command on non-tapes before autolabeling. +kes Implement an open_client_db() that searches the keywords for + either a catolg or client, and opens the appropriate catalog. + This makes Bacula adjust better to multiple catalogs. +kes Use more name() methods for resources rather than hdr.name. 22Dec06 kes Fix code to check for two resources of same name. It forgot to check the last entry. Fixes bug #734. -- 2.39.5