From: Alain Spineux Date: Mon, 7 Nov 2022 11:07:18 +0000 (+0100) Subject: Add VolumeEncrypted field to the catalog X-Git-Tag: Beta-15.0.0~361 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e38c34790dba9be9ac7c87d62028549da5749241;p=thirdparty%2Fbacula.git Add VolumeEncrypted field to the catalog - the goal is to not append encrypted data to volumes that that are not encryption ready ( that are BB02 or have not been label with an "encrypted" capable label ) --- diff --git a/bacula/src/baconfig.h b/bacula/src/baconfig.h index 0431d7b42..00da234d6 100644 --- a/bacula/src/baconfig.h +++ b/bacula/src/baconfig.h @@ -489,6 +489,7 @@ void b_memset(const char *file, int line, void *mem, int val, size_t num); #define Pmsg12(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) p_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) #define Pmsg13(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13) p_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13) #define Pmsg14(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14) p_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14) +#define Pmsg15(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) p_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) /** Daemon Error Messages that are delivered according to the message resource */ diff --git a/bacula/src/cats/cats.h b/bacula/src/cats/cats.h index 2bdbfcff4..241fa8ddd 100644 --- a/bacula/src/cats/cats.h +++ b/bacula/src/cats/cats.h @@ -458,8 +458,9 @@ public: uint32_t MaxVolJobs; /* Max Jobs on Volume */ uint32_t MaxVolFiles; /* Max files on Volume */ int32_t Recycle; /* recycle yes/no */ - int32_t Protected; /* Protected yes/no */ + int32_t Protected; /* Protected yes/no */ int32_t UseProtect; /* Use Protected feature yes/no */ + int32_t VolEncrypted; /* Volume is encrypted */ int32_t Slot; /* slot in changer */ int32_t Enabled; /* 0=disabled, 1=enabled, 2=archived */ int32_t InChanger; /* Volume currently in changer */ diff --git a/bacula/src/cats/make_mysql_tables.in b/bacula/src/cats/make_mysql_tables.in index d54c04ad9..5b29d08c5 100644 --- a/bacula/src/cats/make_mysql_tables.in +++ b/bacula/src/cats/make_mysql_tables.in @@ -481,6 +481,7 @@ CREATE TABLE Media ( Comment BLOB, Protected TINYINT DEFAULT 0, UseProtect TINYINT DEFAULT 0, + VolEncrypted TINYINT DEFAULT 0, PRIMARY KEY(MediaId), UNIQUE (VolumeName(128)), INDEX (PoolId), diff --git a/bacula/src/cats/make_postgresql_tables.in b/bacula/src/cats/make_postgresql_tables.in index ac26f4479..21d185502 100644 --- a/bacula/src/cats/make_postgresql_tables.in +++ b/bacula/src/cats/make_postgresql_tables.in @@ -420,6 +420,7 @@ CREATE TABLE media comment text, protected smallint default 0, useprotect smallint default 0, + volencrypted smallint default 0, primary key (mediaid) ); diff --git a/bacula/src/cats/make_sqlite3_tables.in b/bacula/src/cats/make_sqlite3_tables.in index 8962799f7..5987d18d4 100644 --- a/bacula/src/cats/make_sqlite3_tables.in +++ b/bacula/src/cats/make_sqlite3_tables.in @@ -427,6 +427,7 @@ CREATE TABLE Media ( Comment TEXT, Protected TINYINT DEFAULT 0, UseProtect TINYINT DEFAULT 0, + VolEncrypted TINYINT DEFAULT 0, PRIMARY KEY(MediaId) ); diff --git a/bacula/src/cats/sql_create.c b/bacula/src/cats/sql_create.c index f0d32219f..4b7b8e0ea 100644 --- a/bacula/src/cats/sql_create.c +++ b/bacula/src/cats/sql_create.c @@ -442,9 +442,10 @@ int BDB::bdb_create_media_record(JCR *jcr, MEDIA_DBR *mr) "VolStatus,Slot,VolBytes,InChanger,VolReadTime,VolWriteTime,VolType," "VolParts,VolCloudParts,LastPartBytes," "EndFile,EndBlock,LabelType,StorageId,DeviceId,LocationId," -"ScratchPoolId,RecyclePoolId,Enabled,ActionOnPurge,CacheRetention,UseProtect,Protected)" +"ScratchPoolId,RecyclePoolId,Enabled,ActionOnPurge,CacheRetention,UseProtect," +"Protected,VolEncrypted)" "VALUES ('%s','%s',0,%lu,%s,%s,%ld,%s,%s,%lu,%lu,'%s',%ld,%s,%ld,%s,%s,%ld," - "%ld,%ld,'%s',%ld,%ld,%ld,%s,%s,%s,%s,%s,%ld,%ld,%s,%ld,%ld)", + "%ld,%ld,'%s',%ld,%ld,%ld,%s,%s,%s,%s,%s,%ld,%ld,%s,%ld,%ld,%ld)", esc_name, esc_mtype, mr->PoolId, edit_uint64(mr->MaxVolBytes,ed1), @@ -472,11 +473,12 @@ int BDB::bdb_create_media_record(JCR *jcr, MEDIA_DBR *mr) edit_int64(mr->LocationId, ed11), edit_int64(mr->ScratchPoolId, ed12), edit_int64(mr->RecyclePoolId, ed13), - mr->Enabled, + mr->Enabled, mr->ActionOnPurge, edit_uint64(mr->CacheRetention, ed14), mr->UseProtect, - mr->Protected + mr->Protected, + mr->VolEncrypted ); diff --git a/bacula/src/cats/sql_find.c b/bacula/src/cats/sql_find.c index ebe5e9835..5173d88ec 100644 --- a/bacula/src/cats/sql_find.c +++ b/bacula/src/cats/sql_find.c @@ -426,11 +426,13 @@ int BDB::bdb_find_next_volume(JCR *jcr, int item, bool InChanger, MEDIA_DBR *mr) "LabelType,LabelDate,StorageId," "Enabled,LocationId,RecycleCount,InitialWrite," "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime,ActionOnPurge,CacheRetention " + "VolEncrypted " "FROM Media WHERE PoolId=%s AND MediaType='%s' " " AND (VolStatus IN ('Full', 'Append', 'Used') OR (VolStatus IN ('Recycle', 'Purged', 'Used') AND Recycle=1)) " " AND Enabled=1 " + " AND VolEncrypted=%d " "ORDER BY LastWritten LIMIT 1", - edit_int64(mr->PoolId, ed1), esc_type); + edit_int64(mr->PoolId, ed1), esc_type, mr->VolEncrypted); item = 1; } else { POOL_MEM changer(PM_FNAME); @@ -483,15 +485,17 @@ int BDB::bdb_find_next_volume(JCR *jcr, int item, bool InChanger, MEDIA_DBR *mr) "EndFile,EndBlock,VolType,VolParts,VolCloudParts,LastPartBytes," "LabelType,LabelDate,StorageId," "Enabled,LocationId,RecycleCount,InitialWrite," - "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime,ActionOnPurge,CacheRetention " + "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime,ActionOnPurge,CacheRetention," + "VolEncrypted " "FROM Media WHERE PoolId=%s AND MediaType='%s' AND Enabled=1 " "AND VolStatus='%s' " + "AND VolEncrypted=%d " "%s " "%s " "%s " "%s LIMIT %d", edit_int64(mr->PoolId, ed1), esc_type, - esc_status, + esc_status, mr->VolEncrypted, voltype.c_str(), changer.c_str(), exclude.c_str(), order, item); } @@ -573,6 +577,7 @@ int BDB::bdb_find_next_volume(JCR *jcr, int item, bool InChanger, MEDIA_DBR *mr) mr->VolWriteTime = str_to_int64(row[39]); mr->ActionOnPurge = str_to_int64(row[40]); mr->CacheRetention = str_to_int64(row[41]); + mr->VolEncrypted = str_to_int64(row[42]); sql_free_result(); diff --git a/bacula/src/cats/sql_get.c b/bacula/src/cats/sql_get.c index 2380ae6ab..767a929f8 100644 --- a/bacula/src/cats/sql_get.c +++ b/bacula/src/cats/sql_get.c @@ -1370,8 +1370,9 @@ bool BDB::bdb_get_media_record(JCR *jcr, MEDIA_DBR *mr) "EndFile,EndBlock,VolType,VolParts,VolCloudParts,LastPartBytes," "LabelType,LabelDate,StorageId," "Enabled,LocationId,RecycleCount,InitialWrite," - "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime,ActionOnPurge,CacheRetention,Pool.Name,Protected,UseProtect " - "FROM Media JOIN Pool USING (PoolId) WHERE MediaId=%s", + "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime,ActionOnPurge," + "CacheRetention,Pool.Name,Protected,UseProtect,VolEncrypted " + "FROM Media WHERE MediaId=%s", edit_int64(mr->MediaId, ed1)); } else { /* find by name */ bdb_escape_string(jcr, esc, mr->VolumeName, strlen(mr->VolumeName)); @@ -1383,8 +1384,9 @@ bool BDB::bdb_get_media_record(JCR *jcr, MEDIA_DBR *mr) "EndFile,EndBlock,VolType,VolParts,VolCloudParts,LastPartBytes," "LabelType,LabelDate,StorageId," "Enabled,LocationId,RecycleCount,InitialWrite," - "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime,ActionOnPurge,CacheRetention,Pool.Name,Protected,UseProtect " - "FROM Media JOIN Pool USING (PoolId) WHERE VolumeName='%s'", esc); + "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime,ActionOnPurge," + "CacheRetention,Pool.Name,Protected,UseProtect,VolEncrypted " + "FROM Media WHERE VolumeName='%s'", esc); } if (QueryDB(jcr, cmd)) { @@ -1449,8 +1451,9 @@ bool BDB::bdb_get_media_record(JCR *jcr, MEDIA_DBR *mr) mr->ActionOnPurge = str_to_int32(row[43]); mr->CacheRetention = str_to_int64(row[44]); bstrncpy(mr->Pool, row[45], sizeof(mr->Pool)); - mr->Protected = str_to_int64(row[45]); - mr->UseProtect = str_to_int64(row[46]); + mr->Protected = str_to_int64(row[46]); + mr->UseProtect = str_to_int64(row[47]); + mr->VolEncrypted = str_to_int64(row[48]); ok = true; } diff --git a/bacula/src/cats/sql_list.c b/bacula/src/cats/sql_list.c index 552d046ef..b834fa637 100644 --- a/bacula/src/cats/sql_list.c +++ b/bacula/src/cats/sql_list.c @@ -490,7 +490,7 @@ void BDB::bdb_list_media_records(JCR *jcr, MEDIA_DBR *mdbr, "EndFile,EndBlock,VolType,Media.LabelType,StorageId,DeviceId," "MediaAddressing,VolReadTime,VolWriteTime," "LocationId,RecycleCount,InitialWrite,Media.ScratchPoolId,Media.RecyclePoolId, " - "Media.ActionOnPurge,%s AS ExpiresIn, Comment, Protected, UseProtect" + "Media.ActionOnPurge,%s AS ExpiresIn, Comment, Protected, UseProtect, VolEncrypted" " FROM Media %s WHERE Media.VolumeName='%s' %s", expiresin, join, @@ -508,7 +508,7 @@ void BDB::bdb_list_media_records(JCR *jcr, MEDIA_DBR *mdbr, "EndFile,EndBlock,VolType,Media.LabelType,StorageId,DeviceId," "MediaAddressing,VolReadTime,VolWriteTime," "LocationId,RecycleCount,InitialWrite,Media.ScratchPoolId,Media.RecyclePoolId, " - "Media.ActionOnPurge,%s AS ExpiresIn, Comment, Protected, UseProtect" + "Media.ActionOnPurge,%s AS ExpiresIn, Comment, Protected, UseProtect, VolEncrypted" " FROM Media %s WHERE Media.PoolId=%s %s ORDER BY MediaId", expiresin, join, diff --git a/bacula/src/cats/sql_update.c b/bacula/src/cats/sql_update.c index 2ec63537c..2b7f1d5ac 100644 --- a/bacula/src/cats/sql_update.c +++ b/bacula/src/cats/sql_update.c @@ -408,7 +408,8 @@ int BDB::bdb_update_media_record(JCR *jcr, MEDIA_DBR *mr) "LabelType=%d,StorageId=%s,PoolId=%s,VolRetention=%s,VolUseDuration=%s," "MaxVolJobs=%d,MaxVolFiles=%d,Enabled=%d,LocationId=%s," "ScratchPoolId=%s,RecyclePoolId=%s,RecycleCount=%d,Recycle=%d," - "ActionOnPurge=%d,CacheRetention=%s,EndBlock=%u,Protected=%d,UseProtect=%d" + "ActionOnPurge=%d,CacheRetention=%s,EndBlock=%u,Protected=%d," + "UseProtect=%d,VolEncrypted=%d" " WHERE VolumeName='%s'", mr->VolJobs, mr->VolFiles, mr->VolBlocks, edit_uint64(mr->VolBytes, ed1), @@ -435,7 +436,7 @@ int BDB::bdb_update_media_record(JCR *jcr, MEDIA_DBR *mr) edit_uint64(mr->RecyclePoolId, ed15), mr->RecycleCount,mr->Recycle, mr->ActionOnPurge, edit_uint64(mr->CacheRetention, ed16), - mr->EndBlock,mr->Protected,mr->UseProtect, + mr->EndBlock, mr->Protected, mr->UseProtect, mr->VolEncrypted, esc_name); Dmsg1(dbglevel1, "%s\n", cmd); diff --git a/bacula/src/cats/update_mysql_tables.in b/bacula/src/cats/update_mysql_tables.in index c166d5a14..32ac4d3af 100644 --- a/bacula/src/cats/update_mysql_tables.in +++ b/bacula/src/cats/update_mysql_tables.in @@ -707,7 +707,8 @@ CREATE INDEX meta_attachmentemailid ON MetaAttachment (AttachmentEmailId(255)); ALTER TABLE Media MODIFY COLUMN Protected TINYINT DEFAULT 0, - MODIFY COLUMN UseProtect TINYINT DEFAULT 0; + MODIFY COLUMN UseProtect TINYINT DEFAULT 0, + MODIFY COLUMN VolEncrypted TINYINT DEFAULT 0; ALTER TABLE Object ADD COLUMN FileIndex integer not null default 0, diff --git a/bacula/src/cats/update_postgresql_tables.in b/bacula/src/cats/update_postgresql_tables.in index 4e71cd1f8..320fbf5ec 100644 --- a/bacula/src/cats/update_postgresql_tables.in +++ b/bacula/src/cats/update_postgresql_tables.in @@ -758,8 +758,9 @@ ALTER TABLE Job ADD COLUMN WriteDevice text default '' ALTER TABLE Job ADD COLUMN StatusInfo text default ''; ATLER TABLE Job ADD COLUMN Encrypted int default 0; -ALTER TABLE Media ADD COLUMN Protected smallint default 0; -ALTER TABLE Media ADD COLUMN IsProtect smallint default 0; +ALTER TABLE Media ADD COLUMN Protected smallint default 0; +ALTER TABLE Media ADD COLUMN UseProtect smallint default 0; +ALTER TABLE Media ADD COLUMN VolEncrypted smallint default 0; INSERT INTO Events (EventsCode, EventsType, EventsTime, EventsDaemon, EventsSource, EventsRef, EventsText) VALUES ('DU0001', 'catalog_update', NOW(), '*SHELL*', 'update_bacula_tables', 'pid$$', 'Catalog schema was updated to 1026'); diff --git a/bacula/src/dird/catreq.c b/bacula/src/dird/catreq.c index 8d54068a7..7c9710378 100644 --- a/bacula/src/dird/catreq.c +++ b/bacula/src/dird/catreq.c @@ -38,7 +38,7 @@ */ /* Requests from the Storage daemon */ -static char Find_media[] = "CatReq JobId=%ld FindMedia=%d pool_name=%127s media_type=%127s vol_type=%d create=%d use_protect=%d\n"; +static char Find_media[] = "CatReq JobId=%ld FindMedia=%d pool_name=%127s media_type=%127s vol_type=%d create=%d use_protect=%d vol_encrypted=%d\n"; static char Get_Vol_Info[] = "CatReq JobId=%ld GetVolInfo VolName=%127s write=%d\n"; static char Update_media[] = "CatReq JobId=%ld UpdateMedia VolName=%s" @@ -47,7 +47,7 @@ static char Update_media[] = "CatReq JobId=%ld UpdateMedia VolName=%s" " VolErrors=%u VolWrites=%lld MaxVolBytes=%lld EndTime=%lld VolStatus=%10s" " Slot=%d relabel=%d InChanger=%d VolReadTime=%llu VolWriteTime=%llu" " VolFirstWritten=%lld VolType=%u VolParts=%d VolCloudParts=%d" - " LastPartBytes=%lld Enabled=%d Recycle=%d Protected=%d UseProtect=%d\n"; + " LastPartBytes=%lld Enabled=%d Recycle=%d Protected=%d UseProtect=%d VolEncrypted=%d\n"; static char FileEvent_add[] = "%c %d %127s %127s 0"; /* Full format when coming from the Verify Job */ @@ -67,7 +67,8 @@ static char OK_media[] = "1000 OK VolName=%s VolJobs=%u VolFiles=%u" " MaxVolJobs=%u MaxVolFiles=%u InChanger=%d VolReadTime=%s" " VolWriteTime=%s EndFile=%u EndBlock=%u VolType=%u LabelType=%d" " MediaId=%s ScratchPoolId=%s VolParts=%d VolCloudParts=%d" - " LastPartBytes=%lld Enabled=%d MaxPoolBytes=%s PoolBytes=%s Recycle=%d Protected=%d UseProtect=%d\n"; + " LastPartBytes=%lld Enabled=%d MaxPoolBytes=%s PoolBytes=%s Recycle=%d" + " Protected=%d UseProtect=%d VolEncrypted=%d\n"; static char OK_create[] = "1000 OK CreateJobMedia\n"; @@ -120,7 +121,7 @@ static int send_volume_info_to_storage_daemon(JCR *jcr, BSOCK *sd, MEDIA_DBR *mr mr->Enabled, edit_uint64(pr.MaxPoolBytes, ed11), edit_uint64(pr.PoolBytes, ed12), - mr->Recycle, mr->Protected, mr->UseProtect); + mr->Recycle, mr->Protected, mr->UseProtect, mr->VolEncrypted); unbash_spaces(mr->VolumeName); Dmsg2(100, "Vol Info for %s: %s", jcr->Job, sd->msg); return stat; @@ -187,8 +188,8 @@ void catalog_request(JCR *jcr, BSOCK *bs) utime_t VolFirstWritten; utime_t VolLastWritten; int n; - int can_create=0, use_protect=0; - int Enabled, Recycle, Protected, UseProtect; + int can_create=0, use_protect=0, vol_encrypted; + int Enabled, Recycle, Protected, UseProtect, VolEncrypted; JobId_t JobId = 0; STORE *wstore = jcr->store_mngr->get_wstore(); @@ -212,8 +213,9 @@ void catalog_request(JCR *jcr, BSOCK *bs) /* * Find next appendable medium for SD */ - n = sscanf(bs->msg, Find_media, &JobId, &index, &pool_name, &mr.MediaType, &mr.VolType, &can_create, &use_protect); - if (n == 7) { + n = sscanf(bs->msg, Find_media, &JobId, &index, &pool_name, &mr.MediaType, + &mr.VolType, &can_create, &use_protect, &vol_encrypted); + if (n == 8) { POOL_MEM errmsg; POOL_DBR pr; bstrncpy(pr.Name, pool_name, sizeof(pr.Name)); @@ -225,7 +227,7 @@ void catalog_request(JCR *jcr, BSOCK *bs) mr.ScratchPoolId = pr.ScratchPoolId; ok = find_next_volume_for_append(jcr, &mr, index, can_create?fnv_create_vol : fnv_no_create_vol, - fnv_prune, use_protect, errmsg); + fnv_prune, use_protect, vol_encrypted, errmsg); Dmsg3(050, "find_media ok=%d idx=%d vol=%s\n", ok, index, mr.VolumeName); } else { /* Report problem finding pool */ @@ -316,8 +318,8 @@ void catalog_request(JCR *jcr, BSOCK *bs) &VolLastWritten, &sdmr.VolStatus, &sdmr.Slot, &label, &sdmr.InChanger, &sdmr.VolReadTime, &sdmr.VolWriteTime, &VolFirstWritten, &sdmr.VolType, &sdmr.VolParts, &sdmr.VolCloudParts, - &sdmr.LastPartBytes, &Enabled, &Recycle, &Protected, &UseProtect); - if (n == 29) { + &sdmr.LastPartBytes, &Enabled, &Recycle, &Protected, &UseProtect, &VolEncrypted); + if (n == 30) { db_lock(jcr->db); Dmsg3(400, "Update media %s oldStat=%s newStat=%s\n", sdmr.VolumeName, mr.VolStatus, sdmr.VolStatus); @@ -401,10 +403,11 @@ void catalog_request(JCR *jcr, BSOCK *bs) mr.VolParts = sdmr.VolParts; mr.VolCloudParts = sdmr.VolCloudParts; mr.LastPartBytes = sdmr.LastPartBytes; - mr.Enabled = Enabled; /* byte assignment */ - mr.Recycle = Recycle; /* byte assignment */ - mr.Protected = Protected; /* byte assignment */ - mr.UseProtect = UseProtect; /* byte assignment */ + mr.Enabled = Enabled; /* byte assignment */ + mr.Recycle = Recycle; /* byte assignment */ + mr.Protected = Protected; /* byte assignment */ + mr.UseProtect = UseProtect; /* byte assignment */ + mr.VolEncrypted = VolEncrypted; /* byte assignment */ bstrncpy(mr.VolStatus, sdmr.VolStatus, sizeof(mr.VolStatus)); mr.VolReadTime = sdmr.VolReadTime; mr.VolWriteTime = sdmr.VolWriteTime; diff --git a/bacula/src/dird/next_vol.c b/bacula/src/dird/next_vol.c index 2762a2945..3d8e06bc5 100644 --- a/bacula/src/dird/next_vol.c +++ b/bacula/src/dird/next_vol.c @@ -100,7 +100,8 @@ static void set_volume_to_exclude_list(JCR *jcr, int index, MEDIA_DBR *mr) * use_protect -- whether or not the device will mark the volume as protected (0 no, -1 don't know, 1 yes) */ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, - bool create, bool prune, int use_protect, POOL_MEM &errmsg) + bool create, bool prune, int use_protect, + int vol_encrypted, POOL_MEM &errmsg) { int retry = 0; bool ok; @@ -108,9 +109,9 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, STORE *store = jcr->store_mngr->get_wstore(); bstrncpy(mr->MediaType, store->media_type, sizeof(mr->MediaType)); - Dmsg7(dbglvl, "find_next_vol_for_append: JobId=%u PoolId=%d, MediaType=%s index=%d create=%d prune=%d protect=%d\n", + Dmsg8(dbglvl, "find_next_vol_for_append: JobId=%u PoolId=%d, MediaType=%s index=%d create=%d prune=%d protect=%d vol_encrypted=%d\n", (uint32_t)jcr->JobId, (int)mr->PoolId, mr->MediaType, index, - create, prune, use_protect); + create, prune, use_protect, vol_encrypted); /* * If we are using an Autochanger, restrict Volume * search to the Autochanger on the first pass @@ -120,6 +121,12 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, /* Make sure we don't send two times the same volume in the same session */ set_volume_to_exclude_list(jcr, index, mr); + if (vol_encrypted == 1) { + mr->VolEncrypted = 1; + } else { + mr->VolEncrypted = 0; + } + /* * Find the Next Volume for Append */ diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index 5714651b6..046686fec 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -186,7 +186,8 @@ bool has_quota_reached(JCR *jcr, MEDIA_DBR *mr); bool has_quota_reached(JCR *jcr); void set_storageid_in_mr(STORE *store, MEDIA_DBR *mr); int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, - bool create, bool purge, int use_worm, POOL_MEM &errmsg); + bool create, bool purge, int use_protect, + int vol_encrypted, POOL_MEM &errmsg); bool has_volume_expired(JCR *jcr, MEDIA_DBR *mr); void check_if_volume_valid_or_recyclable(JCR *jcr, MEDIA_DBR *mr, const char **reason); bool get_scratch_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr, diff --git a/bacula/src/dird/ua_label.c b/bacula/src/dird/ua_label.c index d12191814..a57244448 100644 --- a/bacula/src/dird/ua_label.c +++ b/bacula/src/dird/ua_label.c @@ -682,6 +682,7 @@ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, uint64_t VolABytes = 0; uint32_t VolType = 0; int UseProtect = 0; + int VolEncrypted = 0; STORE *wstore = ua->jcr->store_mngr->get_wstore(); if (!(sd=open_sd_bsock(ua))) { @@ -713,8 +714,8 @@ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, while (bget_dirmsg(ua->jcr, sd, BSOCK_TYPE_SD) >= 0) { ua->send_msg("%s", sd->msg); - if (sscanf(sd->msg, "3000 OK label. VolBytes=%llu VolABytes=%lld VolType=%ld UseProtect=%d", - &VolBytes, &VolABytes, &VolType, &UseProtect) == 4) { + if (sscanf(sd->msg, "3000 OK label. VolBytes=%llu VolABytes=%lld VolType=%ld UseProtect=%d VolEncrypted=%d", + &VolBytes, &VolABytes, &VolType, &UseProtect, &VolEncrypted) == 5) { ok = true; if (media_record_exists) { /* we update it */ mr->VolBytes = VolBytes; @@ -722,6 +723,7 @@ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, mr->VolType = VolType; mr->InChanger = mr->Slot > 0; /* if slot give assume in changer */ mr->UseProtect = UseProtect; + mr->VolEncrypted = VolEncrypted; set_storageid_in_mr(wstore, mr); if (!db_update_media_record(ua->jcr, ua->db, mr)) { ua->error_msg("%s", db_strerror(ua->db)); @@ -735,6 +737,7 @@ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, mr->InChanger = mr->Slot > 0; /* if slot give assume in changer */ mr->Enabled = 1; mr->UseProtect = UseProtect; + mr->VolEncrypted = VolEncrypted; set_storageid_in_mr(wstore, mr); if (db_create_media_record(ua->jcr, ua->db, mr)) { ua->info_msg(_("Catalog record for Volume \"%s\", Slot %d successfully created.\n"), diff --git a/bacula/src/dird/ua_output.c b/bacula/src/dird/ua_output.c index 5a1c51376..d5d61cf7f 100644 --- a/bacula/src/dird/ua_output.c +++ b/bacula/src/dird/ua_output.c @@ -1198,7 +1198,8 @@ static bool list_nextvol(UAContext *ua, int ndays) get_job_storage(&store, job, run); set_storageid_in_mr(store.store, &mr); /* no need to set ScratchPoolId, since we use fnv_no_create_vol */ - if (!find_next_volume_for_append(jcr, &mr, 1, fnv_no_create_vol, fnv_prune, -1 /* no worm */, errmsg)) { + if (!find_next_volume_for_append(jcr, &mr, 1, fnv_no_create_vol, fnv_prune, + -1 /* no protect */, -1 /* vol_encrypted*/, errmsg)) { ua->error_msg(_("Could not find next Volume for Job %s (Pool=%s, Level=%s).%s\n"), job->name(), pr.Name, level_to_str(edl, sizeof(edl), run->level), errmsg.c_str()); } else { diff --git a/bacula/src/dird/ua_status.c b/bacula/src/dird/ua_status.c index 41cb4012b..924e402af 100644 --- a/bacula/src/dird/ua_status.c +++ b/bacula/src/dird/ua_status.c @@ -778,7 +778,7 @@ static void prt_runtime(UAContext *ua, sched_pkt *sp, int novolume, OutputWriter } else { Dmsg0(250, "call find_next_volume_for_append\n"); /* no need to set ScratchPoolId, since we use fnv_no_create_vol */ - ok = find_next_volume_for_append(jcr, &mr, 1, fnv_no_create_vol, fnv_no_prune, -1, tmp); + ok = find_next_volume_for_append(jcr, &mr, 1, fnv_no_create_vol, fnv_no_prune, -1, -1, tmp); } } if (!ok) { diff --git a/bacula/src/stored/askdir.c b/bacula/src/stored/askdir.c index 6312e6903..31c8f2ebe 100644 --- a/bacula/src/stored/askdir.c +++ b/bacula/src/stored/askdir.c @@ -29,7 +29,7 @@ static const int dbglvl = 200; /* Requests sent to the Director */ -static char Find_media[] = "CatReq JobId=%ld FindMedia=%d pool_name=%s media_type=%s vol_type=%d create=%d use_protect=%d\n"; +static char Find_media[] = "CatReq JobId=%ld FindMedia=%d pool_name=%s media_type=%s vol_type=%d create=%d use_protect=%d vol_encrypted=%d\n"; static char Get_Vol_Info[] = "CatReq JobId=%ld GetVolInfo VolName=%s write=%d\n"; static char Update_media[] = "CatReq JobId=%ld UpdateMedia VolName=%s" " VolJobs=%u VolFiles=%u VolBlocks=%u VolBytes=%s VolABytes=%s" @@ -37,7 +37,7 @@ static char Update_media[] = "CatReq JobId=%ld UpdateMedia VolName=%s" " VolErrors=%u VolWrites=%u MaxVolBytes=%s EndTime=%s VolStatus=%s" " Slot=%d relabel=%d InChanger=%d VolReadTime=%s VolWriteTime=%s" " VolFirstWritten=%s VolType=%u VolParts=%d VolCloudParts=%d" - " LastPartBytes=%lld Enabled=%d Recycle=%d Protected=%d UseProtect=%d\n"; + " LastPartBytes=%lld Enabled=%d Recycle=%d Protected=%d UseProtect=%d VolEncrypted=%d\n"; static char Create_jobmedia[] = "CatReq JobId=%ld CreateJobMedia\n"; static char FileAttributes[] = "UpdCat JobId=%ld FileAttributes "; @@ -51,7 +51,7 @@ static char OK_media[] = "1000 OK VolName=%127s VolJobs=%u VolFiles=%lu" " VolReadTime=%lld VolWriteTime=%lld EndFile=%lu EndBlock=%lu" " VolType=%lu LabelType=%ld MediaId=%lld ScratchPoolId=%lld" " VolParts=%d VolCloudParts=%d LastPartBytes=%lld Enabled=%d MaxPoolBytes=%lld PoolBytes=%lld Recycle=%d" - " Protected=%d UseProtect=%d\n"; + " Protected=%d UseProtect=%d VolEncrypted=%d\n"; static char OK_create[] = "1000 OK CreateJobMedia\n"; @@ -200,7 +200,7 @@ static bool do_get_volume_info(DCR *dcr) BSOCK *dir = jcr->dir_bsock; VOLUME_CAT_INFO vol; int n; - int32_t Enabled, Recycle, Protected, UseProtect; + int32_t Enabled, Recycle, Protected, UseProtect, VolEncrypted; int32_t InChanger; dcr->setVolCatInfo(false); @@ -222,9 +222,10 @@ static bool do_get_volume_info(DCR *dcr) &vol.EndFile, &vol.EndBlock, &vol.VolCatType, &vol.LabelType, &vol.VolMediaId, &vol.VolScratchPoolId, &vol.VolCatParts, &vol.VolCatCloudParts, - &vol.VolLastPartBytes, &Enabled, &vol.MaxPoolBytes, &vol.PoolBytes, &Recycle, &Protected, &UseProtect); + &vol.VolLastPartBytes, &Enabled, &vol.MaxPoolBytes, + &vol.PoolBytes, &Recycle, &Protected, &UseProtect, &VolEncrypted); Dmsg2(dbglvl, "msg); - if (n != 35) { + if (n != 36) { Dmsg1(dbglvl, "get_volume_info failed: ERR=%s", dir->msg); /* * Note, we can get an error here either because there is @@ -240,6 +241,7 @@ static bool do_get_volume_info(DCR *dcr) vol.VolRecycle = Recycle; /* bool in structure */ vol.Protected = Protected; /* bool in structure */ vol.UseProtect = UseProtect; /* bool in structure */ + vol.VolEncrypted = VolEncrypted; /* bool in structure */ vol.is_valid = true; vol.VolCatBytes = vol.VolCatAmetaBytes + vol.VolCatAdataBytes; unbash_spaces(vol.VolCatName); @@ -340,7 +342,8 @@ bool dir_find_next_appendable_volume(DCR *dcr) bash_spaces(dcr->media_type); bash_spaces(dcr->pool_name); dir->fsend(Find_media, jcr->JobId, vol_index, dcr->pool_name, dcr->media_type, - dcr->dev->dev_type, can_create, dcr->dev->use_protect()); + dcr->dev->dev_type, can_create, dcr->dev->use_protect(), + dcr->dev->use_volume_encryption()); unbash_spaces(dcr->media_type); unbash_spaces(dcr->pool_name); Dmsg1(dbglvl, ">dird %s", dir->msg); @@ -526,7 +529,8 @@ bool dir_update_volume_info(DCR *dcr, bool label, bool update_LastWritten, Enabled, Recycle, vol.Protected, - dev->use_protect() + dev->use_protect(), + vol.VolEncrypted ); Dmsg1(100, ">dird %s", dir->msg); /* diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 148a8a660..43306cfed 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -1173,6 +1173,11 @@ bool DEVICE::get_tape_worm(DCR *dcr) return false; } +int DEVICE::use_volume_encryption() +{ + return device->volume_encryption != ET_NONE; +}; + bool DEVICE::load_encryption_key(DCR *dcr, const char *operation, const char *volume_name, uint32_t *enc_cipher_key_size, unsigned char *enc_cipher_key, @@ -1180,23 +1185,24 @@ bool DEVICE::load_encryption_key(DCR *dcr, const char *operation, { enum { op_none, op_label, op_read }; bool ok = true; // No error - if (!device->volume_encryption) { + Dmsg4(0, "load_encryption_key %s %s enc=%ld ver=%d\n", operation, volume_name, device->volume_encryption, VolHdr.BlockVer); + int op = op_none; + if (0 == strcmp(operation, "LABEL")) { + op = op_label; + } else if (0 == strcmp(operation, "READ")) { + op = op_read; + } + /* don't use encryption if volume encryption is not enable or we are reading + * (aka not recycling) a BB02 volume */ + if (device->volume_encryption == ET_NONE || (op != op_label && VolHdr.BlockVer <= 2)) { return ok; } JCR *jcr = dcr->jcr; -// char *edit_device_codes(DCR *dcr, char *omsg, const char *imsg, const char *cmd) POOLMEM *encrypt_program = get_pool_memory(PM_FNAME); POOL_MEM results(PM_MESSAGE); POOL_MEM err_msg(PM_MESSAGE); POOL_MEM envv; - int op = op_none; - if (0 == strcmp(operation, "LABEL")) { - op = op_label; - } else if (0 == strcmp(operation, "READ")) { - op = op_read; - } - edit_device_codes(dcr, &encrypt_program, me->encryption_command, "load"); char *envp[5]; Mmsg(envv, "OPERATION=%s", operation); diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index c85eb6347..6acf154d0 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -235,6 +235,7 @@ struct VOLUME_CAT_INFO { bool InChanger; /* Set if vol in current magazine */ bool Protected; /* Set if the vol is Readonly, worm or immutable */ bool UseProtect; /* Set if the device can set the volume Readonly, worm or immutable */ + bool VolEncrypted; /* Set if the volume is encrypted */ bool is_valid; /* set if this data is valid */ bool VolEnabled; /* set if volume enabled */ bool VolRecycle; /* set if volume can be recycled */ @@ -617,6 +618,7 @@ public: virtual int set_readonly(int fd, const char *vol_name) { errno=ENOSYS; return -1;}; virtual int set_atime(int fd, const char *vol_name, btime_t val) { errno=ENOSYS; return -1;}; virtual int use_protect() { return 0; }; + virtual int use_volume_encryption(); virtual const char *print_type() = 0; /* in dev.c */ virtual const char *print_driver_type() { return "";}; virtual const char *print_full_type() { return print_type();}; diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 5e8680360..cca993583 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -1105,9 +1105,10 @@ static void label_volume_if_ok(DCR *dcr, char *oldname, } else { type = 0; } - dir->fsend("3000 OK label. VolBytes=%lld VolABytes=%lld VolType=%d UseProtect=%d Volume=\"%s\" Device=%s\n", + dir->fsend("3000 OK label. VolBytes=%lld VolABytes=%lld VolType=%d UseProtect=%d VolEncrypted=%d Volume=\"%s\" Device=%s\n", volCatBytes, dev->VolCatInfo.VolCatAdataBytes, - type, dev->use_protect(), newname, dev->print_name()); + type, dev->use_protect(), dev->use_volume_encryption(), + newname, dev->print_name()); break; case VOL_TYPE_ERROR: dir->fsend(_("3917 Failed to label Volume: ERR=%s\n"), dcr->jcr->errmsg); diff --git a/bacula/src/stored/label.c b/bacula/src/stored/label.c index 6b49caedf..06c843320 100644 --- a/bacula/src/stored/label.c +++ b/bacula/src/stored/label.c @@ -659,6 +659,7 @@ bool DEVICE::rewrite_volume_label(DCR *dcr, bool recycle) VolCatInfo.VolLastPartBytes = 0; VolCatInfo.VolCatType = 0; /* Will be set by dir_update_volume_info() */ VolCatInfo.UseProtect = use_protect(); + VolCatInfo.VolEncrypted = use_volume_encryption(); if (recycle) { VolCatInfo.VolCatMounts++; VolCatInfo.VolCatRecycles++; @@ -809,7 +810,7 @@ void create_volume_header(DEVICE *dev, const char *VolName, Enter(130); ASSERT2(dev != NULL, "dev ptr is NULL"); - + dev->VolHdr.BlockVer = BLOCK_VER; if (dev->is_aligned()) { bstrncpy(dev->VolHdr.Id, BaculaMetaDataId, sizeof(dev->VolHdr.Id)); dev->VolHdr.VerNum = BaculaMetaDataVersion; @@ -1035,7 +1036,7 @@ bool unser_volume_label(DEVICE *dev, DEV_RECORD *rec) dev->VolHdr.LabelType = rec->FileIndex; dev->VolHdr.LabelSize = rec->data_len; - + dev->VolHdr.BlockVer = rec->BlockVer; /* Unserialize the record into the Volume Header */ Dmsg2(100, "reclen=%d recdata=%s", rec->data_len, rec->data); @@ -1180,7 +1181,7 @@ void DEVICE::dump_volume_label() break; } - Pmsg14(-1, _("\nVolume Label:\n" + Pmsg15(-1, _("\nVolume Label:\n" "Adata : %d\n" "Id : %s" "VerNo : %d\n" @@ -1193,6 +1194,7 @@ void DEVICE::dump_volume_label() "MediaType : %s\n" "PoolType : %s\n" "HostName : %s\n" +"BlockVer : BB%02%d\n" "EncCypherKeySize : %ld\n" "MasterKeyIdSize : %ld\n" ""), @@ -1202,7 +1204,7 @@ void DEVICE::dump_volume_label() File, LabelType, VolHdr.LabelSize, VolHdr.PoolName, VolHdr.MediaType, VolHdr.PoolType, VolHdr.HostName, - VolHdr.EncCypherKeySize, VolHdr.MasterKeyIdSize); + VolHdr.BlockVer, VolHdr.EncCypherKeySize, VolHdr.MasterKeyIdSize); if (VolHdr.VerNum >= 11) { char dt[50]; diff --git a/bacula/src/stored/record.h b/bacula/src/stored/record.h index 50d82174c..dfb74ec3e 100644 --- a/bacula/src/stored/record.h +++ b/bacula/src/stored/record.h @@ -172,7 +172,7 @@ struct Volume_Label { char Id[32]; /* Bacula Immortal ... */ uint32_t VerNum; /* Label version number */ - + int BlockVer; /* 1, 2 or .. from BB01, BB02 from the FIRST block */ /* VerNum <= 10 */ float64_t label_date; /* Date tape labeled */ float64_t label_time; /* Time tape labeled */