mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 20:03:02 +01:00
parent
332334ab3d
commit
aa6cb5d05f
@ -1820,6 +1820,8 @@ C --
|
||||
PARAMETER (GDS__vld_plugins = 335545203)
|
||||
INTEGER*4 GDS__db_crypt_key
|
||||
PARAMETER (GDS__db_crypt_key = 335545204)
|
||||
INTEGER*4 GDS__no_keyholder_plugin
|
||||
PARAMETER (GDS__no_keyholder_plugin = 335545205)
|
||||
INTEGER*4 GDS__gfix_db_name
|
||||
PARAMETER (GDS__gfix_db_name = 335740929)
|
||||
INTEGER*4 GDS__gfix_invalid_sw
|
||||
|
@ -1815,6 +1815,8 @@ const
|
||||
gds_vld_plugins = 335545203;
|
||||
isc_db_crypt_key = 335545204;
|
||||
gds_db_crypt_key = 335545204;
|
||||
isc_no_keyholder_plugin = 335545205;
|
||||
gds_no_keyholder_plugin = 335545205;
|
||||
isc_gfix_db_name = 335740929;
|
||||
gds_gfix_db_name = 335740929;
|
||||
isc_gfix_invalid_sw = 335740930;
|
||||
|
@ -88,18 +88,12 @@ namespace // unnamed, private
|
||||
|
||||
inline void put(BurpGlobals* tdgbl, const UCHAR c)
|
||||
{
|
||||
if (--(tdgbl->io_cnt) >= 0)
|
||||
*(tdgbl->io_ptr)++ = c;
|
||||
else
|
||||
MVOL_write(c, &tdgbl->io_cnt, &tdgbl->io_ptr);
|
||||
tdgbl->put(c);
|
||||
}
|
||||
|
||||
inline void put(BurpGlobals* tdgbl, const att_type c)
|
||||
{
|
||||
if (--tdgbl->io_cnt >= 0)
|
||||
*(tdgbl->io_ptr)++ = UCHAR(c);
|
||||
else
|
||||
MVOL_write(UCHAR(c), &tdgbl->io_cnt, &tdgbl->io_ptr);
|
||||
put(tdgbl, UCHAR(c));
|
||||
}
|
||||
|
||||
inline const UCHAR* put_block(BurpGlobals* tdgbl, const UCHAR* p, ULONG n)
|
||||
@ -221,11 +215,6 @@ int BACKUP_backup(const TEXT* dbb_file, const TEXT* file_name)
|
||||
|
||||
tdgbl->gbl_database_file_name = dbb_file;
|
||||
|
||||
tdgbl->io_ptr = NULL;
|
||||
tdgbl->io_cnt = 0;
|
||||
tdgbl->relations = NULL;
|
||||
tdgbl->runtimeODS = 0;
|
||||
|
||||
gds_trans = 0;
|
||||
|
||||
BURP_verbose(130);
|
||||
@ -280,7 +269,7 @@ int BACKUP_backup(const TEXT* dbb_file, const TEXT* file_name)
|
||||
tdgbl->action->act_file = tdgbl->gbl_sw_files;
|
||||
}
|
||||
|
||||
MVOL_init_write(file_name, &tdgbl->io_cnt, &tdgbl->io_ptr);
|
||||
MVOL_init_write(file_name);
|
||||
|
||||
// Write database record
|
||||
|
||||
@ -416,7 +405,7 @@ int BACKUP_backup(const TEXT* dbb_file, const TEXT* file_name)
|
||||
// Finish up
|
||||
|
||||
put(tdgbl, (UCHAR) rec_end);
|
||||
FB_UINT64 cumul_count = MVOL_fini_write(&tdgbl->io_cnt, &tdgbl->io_ptr);
|
||||
FB_UINT64 cumul_count = MVOL_fini_write();
|
||||
tdgbl->action->act_action = ACT_backup_fini;
|
||||
BURP_verbose(176, SafeArg() << cumul_count);
|
||||
// msg 176 closing file, committing, and finishing. %ld bytes written
|
||||
|
@ -726,6 +726,41 @@ int gbak(Firebird::UtilSvc* uSvc)
|
||||
}
|
||||
tdgbl->gbl_sw_sql_role = argv[itr];
|
||||
break;
|
||||
case IN_SW_BURP_KEYHOLD:
|
||||
if (++itr >= argc)
|
||||
{
|
||||
BURP_error(381, true);
|
||||
// KeyHolder parameter missing
|
||||
}
|
||||
if (tdgbl->gbl_sw_keyholder)
|
||||
BURP_error(334, true, SafeArg() << in_sw_tab->in_sw_name);
|
||||
tdgbl->gbl_sw_keyholder = argv[itr];
|
||||
break;
|
||||
case IN_SW_BURP_CRYPT:
|
||||
if (++itr >= argc)
|
||||
{
|
||||
BURP_error(377, true);
|
||||
// CryptPlugin parameter missing
|
||||
}
|
||||
if (tdgbl->gbl_sw_crypt)
|
||||
BURP_error(334, true, SafeArg() << in_sw_tab->in_sw_name);
|
||||
tdgbl->gbl_sw_crypt = argv[itr];
|
||||
break;
|
||||
case IN_SW_BURP_KEYNAME:
|
||||
if (++itr >= argc)
|
||||
{
|
||||
BURP_error(375, true);
|
||||
// Key name parameter missing
|
||||
}
|
||||
if (tdgbl->gbl_sw_keyname)
|
||||
BURP_error(334, true, SafeArg() << in_sw_tab->in_sw_name);
|
||||
tdgbl->gbl_sw_keyname = argv[itr];
|
||||
break;
|
||||
case IN_SW_BURP_ZIP:
|
||||
if (tdgbl->gbl_sw_zip)
|
||||
BURP_error(334, true, SafeArg() << in_sw_tab->in_sw_name);
|
||||
tdgbl->gbl_sw_zip = true;
|
||||
break;
|
||||
case IN_SW_BURP_FA:
|
||||
if (tdgbl->gbl_sw_blk_factor)
|
||||
BURP_error(333, true, SafeArg() << in_sw_tab->in_sw_name << tdgbl->gbl_sw_blk_factor);
|
||||
@ -1202,6 +1237,8 @@ int gbak(Firebird::UtilSvc* uSvc)
|
||||
}
|
||||
else if (tdgbl->gbl_sw_old_descriptions)
|
||||
errNum = IN_SW_BURP_OL;
|
||||
else if (tdgbl->gbl_sw_zip)
|
||||
errNum = IN_SW_BURP_ZIP;
|
||||
|
||||
if (errNum != IN_SW_BURP_0)
|
||||
{
|
||||
@ -1815,14 +1852,28 @@ static gbak_action open_files(const TEXT* file1,
|
||||
*
|
||||
**************************************/
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
FbLocalStatus temp_status;
|
||||
Firebird::CheckStatusWrapper* status_vector = &temp_status;
|
||||
FbLocalStatus status_vector;
|
||||
|
||||
// try to attach the database using the first file_name
|
||||
|
||||
if (sw_replace != IN_SW_BURP_C && sw_replace != IN_SW_BURP_R)
|
||||
{
|
||||
tdgbl->db_handle = Firebird::DispatcherPtr()->attachDatabase(status_vector, file1,
|
||||
Firebird::DispatcherPtr provider;
|
||||
|
||||
// provide crypt key(s) for engine
|
||||
|
||||
if (tdgbl->gbl_sw_keyholder)
|
||||
{
|
||||
tdgbl->gbl_database_file_name = file1;
|
||||
provider->setDbCryptCallback(&status_vector, MVOL_get_crypt(tdgbl));
|
||||
if (!status_vector.isSuccess())
|
||||
{
|
||||
BURP_print_status(true, &status_vector);
|
||||
return QUIT;
|
||||
}
|
||||
}
|
||||
|
||||
tdgbl->db_handle = provider->attachDatabase(&status_vector, file1,
|
||||
dpb.getBufferLength(), dpb.getBuffer());
|
||||
|
||||
if (!(status_vector->getState() & Firebird::IStatus::STATE_ERRORS))
|
||||
@ -1831,10 +1882,10 @@ static gbak_action open_files(const TEXT* file1,
|
||||
{
|
||||
// msg 13 REPLACE specified, but the first file %s is a database
|
||||
BURP_error(13, true, file1);
|
||||
tdgbl->db_handle->detach(status_vector);
|
||||
tdgbl->db_handle->detach(&status_vector);
|
||||
|
||||
if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
BURP_print_status(true, status_vector);
|
||||
BURP_print_status(true, &status_vector);
|
||||
else
|
||||
tdgbl->db_handle = NULL;
|
||||
|
||||
@ -1845,14 +1896,58 @@ static gbak_action open_files(const TEXT* file1,
|
||||
// msg 139 Version(s) for database "%s"
|
||||
BURP_print(false, 139, file1);
|
||||
OutputVersion outputVersion("\t%s\n");
|
||||
Firebird::UtilInterfacePtr()->getFbVersion(status_vector, tdgbl->db_handle, &outputVersion);
|
||||
Firebird::UtilInterfacePtr()->getFbVersion(&status_vector, tdgbl->db_handle, &outputVersion);
|
||||
}
|
||||
BURP_verbose(166, file1); // msg 166: readied database %s for backup
|
||||
|
||||
if (tdgbl->gbl_sw_keyholder)
|
||||
{
|
||||
unsigned char info[] = {fb_info_crypt_key, fb_info_crypt_plugin};
|
||||
unsigned char buffer[(1 + 2 + MAX_SQL_IDENTIFIER_SIZE) * 2 + 2];
|
||||
unsigned int len;
|
||||
|
||||
tdgbl->db_handle->getInfo(&status_vector, sizeof(info), info, sizeof(buffer), buffer);
|
||||
|
||||
UCHAR* p = buffer;
|
||||
while(p)
|
||||
{
|
||||
switch(*p++)
|
||||
{
|
||||
case fb_info_crypt_key:
|
||||
len = gds__vax_integer(p, 2);
|
||||
if (len < sizeof(tdgbl->gbl_hdr_keybuffer))
|
||||
{
|
||||
memcpy(tdgbl->gbl_hdr_keybuffer, p + 2, len);
|
||||
tdgbl->gbl_hdr_keybuffer[len] = 0;
|
||||
if (!tdgbl->gbl_sw_keyname)
|
||||
tdgbl->gbl_sw_keyname = tdgbl->gbl_hdr_keybuffer;
|
||||
}
|
||||
break;
|
||||
|
||||
case fb_info_crypt_plugin:
|
||||
len = gds__vax_integer(p, 2);
|
||||
if (len < sizeof(tdgbl->gbl_hdr_cryptbuffer))
|
||||
{
|
||||
memcpy(tdgbl->gbl_hdr_cryptbuffer, p + 2, len);
|
||||
tdgbl->gbl_hdr_cryptbuffer[len] = 0;
|
||||
if (!tdgbl->gbl_sw_crypt)
|
||||
tdgbl->gbl_sw_crypt = tdgbl->gbl_hdr_cryptbuffer;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
p = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
p += (2 + len);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sw_replace == IN_SW_BURP_B ||
|
||||
(status_vector->getErrors()[1] != isc_io_error && status_vector->getErrors()[1] != isc_bad_db_format))
|
||||
{
|
||||
BURP_print_status(true, status_vector);
|
||||
BURP_print_status(true, &status_vector);
|
||||
return QUIT;
|
||||
}
|
||||
}
|
||||
@ -1928,7 +2023,7 @@ static gbak_action open_files(const TEXT* file1,
|
||||
{
|
||||
Firebird::string nm = tdgbl->toSystem(fil->fil_name);
|
||||
#ifdef WIN_NT
|
||||
if ((fil->fil_fd = MVOL_open(nm.c_str(), MODE_WRITE, CREATE_ALWAYS)) ==
|
||||
if ((fil->fil_fd = NT_tape_open(nm.c_str(), MODE_WRITE, CREATE_ALWAYS)) ==
|
||||
INVALID_HANDLE_VALUE)
|
||||
#else
|
||||
if ((fil->fil_fd = os_utils::open(nm.c_str(), MODE_WRITE, open_mask)) == -1)
|
||||
@ -1974,10 +2069,10 @@ static gbak_action open_files(const TEXT* file1,
|
||||
}
|
||||
else
|
||||
{
|
||||
tdgbl->db_handle->detach(status_vector);
|
||||
tdgbl->db_handle->detach(&status_vector);
|
||||
|
||||
if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
BURP_print_status(true, status_vector);
|
||||
BURP_print_status(true, &status_vector);
|
||||
else
|
||||
tdgbl->db_handle = NULL;
|
||||
}
|
||||
@ -2038,7 +2133,7 @@ static gbak_action open_files(const TEXT* file1,
|
||||
// open first file
|
||||
Firebird::string nm = tdgbl->toSystem(fil->fil_name);
|
||||
#ifdef WIN_NT
|
||||
if ((fil->fil_fd = MVOL_open(nm.c_str(), MODE_READ, OPEN_EXISTING)) ==
|
||||
if ((fil->fil_fd = NT_tape_open(nm.c_str(), MODE_READ, OPEN_EXISTING)) ==
|
||||
INVALID_HANDLE_VALUE)
|
||||
#else
|
||||
if ((fil->fil_fd = os_utils::open(nm.c_str(), MODE_READ)) == INVALID_HANDLE_VALUE)
|
||||
@ -2084,7 +2179,7 @@ static gbak_action open_files(const TEXT* file1,
|
||||
tdgbl->action->act_file = fil;
|
||||
Firebird::string nm = tdgbl->toSystem(fil->fil_name);
|
||||
#ifdef WIN_NT
|
||||
if ((fil->fil_fd = MVOL_open(nm.c_str(), MODE_READ, OPEN_EXISTING)) ==
|
||||
if ((fil->fil_fd = NT_tape_open(nm.c_str(), MODE_READ, OPEN_EXISTING)) ==
|
||||
INVALID_HANDLE_VALUE)
|
||||
#else
|
||||
if ((fil->fil_fd = os_utils::open(nm.c_str(), MODE_READ)) == INVALID_HANDLE_VALUE)
|
||||
@ -2152,17 +2247,32 @@ static gbak_action open_files(const TEXT* file1,
|
||||
|
||||
if (sw_replace == IN_SW_BURP_C || sw_replace == IN_SW_BURP_R)
|
||||
{
|
||||
tdgbl->db_handle = Firebird::DispatcherPtr()->attachDatabase(status_vector, *file2,
|
||||
Firebird::DispatcherPtr provider;
|
||||
|
||||
// provide crypt key(s) for engine
|
||||
|
||||
if (tdgbl->gbl_sw_keyholder)
|
||||
{
|
||||
tdgbl->gbl_database_file_name = *file2;
|
||||
provider->setDbCryptCallback(&status_vector, MVOL_get_crypt(tdgbl));
|
||||
if (!status_vector.isSuccess())
|
||||
{
|
||||
BURP_print_status(true, &status_vector);
|
||||
return QUIT;
|
||||
}
|
||||
}
|
||||
|
||||
tdgbl->db_handle = provider->attachDatabase(&status_vector, *file2,
|
||||
dpb.getBufferLength(), dpb.getBuffer());
|
||||
|
||||
if (!(status_vector->getState() & Firebird::IStatus::STATE_ERRORS))
|
||||
{
|
||||
if (sw_replace == IN_SW_BURP_C)
|
||||
{
|
||||
tdgbl->db_handle->detach(status_vector);
|
||||
tdgbl->db_handle->detach(&status_vector);
|
||||
|
||||
if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
BURP_print_status(true, status_vector);
|
||||
BURP_print_status(true, &status_vector);
|
||||
else
|
||||
tdgbl->db_handle = NULL;
|
||||
|
||||
@ -2171,7 +2281,7 @@ static gbak_action open_files(const TEXT* file1,
|
||||
}
|
||||
else
|
||||
{
|
||||
tdgbl->db_handle->dropDatabase(status_vector);
|
||||
tdgbl->db_handle->dropDatabase(&status_vector);
|
||||
|
||||
if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
{
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "firebird/Message.h"
|
||||
#include "../common/dsc.h"
|
||||
#include "../burp/misc_proto.h"
|
||||
#include "../burp/mvol_proto.h"
|
||||
#include "../yvalve/gds_proto.h"
|
||||
#include "../common/ThreadData.h"
|
||||
#include "../common/UtilSvc.h"
|
||||
@ -43,6 +44,7 @@
|
||||
#include "../common/classes/MetaName.h"
|
||||
#include "../../jrd/SimilarToMatcher.h"
|
||||
#include "../common/status.h"
|
||||
#include "../common/sha.h"
|
||||
#include "../common/classes/ImplementHelper.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
@ -53,6 +55,14 @@
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ZLIB_H)
|
||||
#define WIRE_COMPRESS_SUPPORT 1
|
||||
#endif
|
||||
|
||||
#ifdef WIRE_COMPRESS_SUPPORT
|
||||
#include <zlib.h>
|
||||
//#define COMPRESS_DEBUG 1
|
||||
#endif // WIRE_COMPRESS_SUPPORT
|
||||
|
||||
static inline UCHAR* BURP_alloc(ULONG size)
|
||||
{
|
||||
@ -208,10 +218,6 @@ Version 11: FB4.0.
|
||||
|
||||
const int ATT_BACKUP_FORMAT = 11;
|
||||
|
||||
// format version number for ranges for arrays
|
||||
|
||||
//const int GDS_NDA_VERSION = 1; // Not used
|
||||
|
||||
// max array dimension
|
||||
|
||||
const int MAX_DIMENSION = 16;
|
||||
@ -234,6 +240,10 @@ enum att_type {
|
||||
att_backup_blksize, // backup block size
|
||||
att_backup_file, // database file name
|
||||
att_backup_volume, // backup volume number
|
||||
att_backup_keyname, // name of crypt key
|
||||
att_backup_zip, // zipped backup file
|
||||
att_backup_hash, // hash of crypt key
|
||||
att_backup_crypt, // name of crypt plugin
|
||||
|
||||
// Database attributes
|
||||
|
||||
@ -921,6 +931,8 @@ public:
|
||||
|
||||
// Global switches and data
|
||||
|
||||
struct BurpCrypt;
|
||||
|
||||
class BurpGlobals : public Firebird::ThreadData
|
||||
{
|
||||
public:
|
||||
@ -973,6 +985,12 @@ public:
|
||||
bool gbl_sw_mode;
|
||||
bool gbl_sw_mode_val;
|
||||
bool gbl_sw_overwrite;
|
||||
bool gbl_sw_zip;
|
||||
const SCHAR* gbl_sw_keyholder;
|
||||
const SCHAR* gbl_sw_crypt;
|
||||
const SCHAR* gbl_sw_keyname;
|
||||
SCHAR gbl_hdr_keybuffer[MAX_SQL_IDENTIFIER_SIZE + 1];
|
||||
SCHAR gbl_hdr_cryptbuffer[MAX_SQL_IDENTIFIER_SIZE + 1];
|
||||
const SCHAR* gbl_sw_sql_role;
|
||||
const SCHAR* gbl_sw_user;
|
||||
const SCHAR* gbl_sw_password;
|
||||
@ -983,11 +1001,42 @@ public:
|
||||
gfld* gbl_global_fields;
|
||||
unsigned gbl_network_protocol;
|
||||
burp_act* action;
|
||||
BurpCrypt* gbl_crypt;
|
||||
ULONG io_buffer_size;
|
||||
redirect_vals sw_redirect;
|
||||
bool burp_throw;
|
||||
UCHAR* io_ptr;
|
||||
int io_cnt;
|
||||
|
||||
UCHAR* blk_io_ptr;
|
||||
int blk_io_cnt;
|
||||
|
||||
void put(const UCHAR c)
|
||||
{
|
||||
if (gbl_io_cnt <= 0)
|
||||
MVOL_write(this);
|
||||
|
||||
--gbl_io_cnt;
|
||||
*gbl_io_ptr++ = c;
|
||||
}
|
||||
|
||||
UCHAR get()
|
||||
{
|
||||
if (gbl_io_cnt <= 0)
|
||||
MVOL_read(this);
|
||||
|
||||
--gbl_io_cnt;
|
||||
return *gbl_io_ptr++;
|
||||
}
|
||||
|
||||
#ifdef WIRE_COMPRESS_SUPPORT
|
||||
z_stream gbl_stream;
|
||||
#endif
|
||||
UCHAR* gbl_io_ptr;
|
||||
int gbl_io_cnt;
|
||||
UCHAR* gbl_compress_buffer;
|
||||
UCHAR* gbl_crypt_buffer;
|
||||
ULONG gbl_crypt_left;
|
||||
UCHAR* gbl_decompress;
|
||||
|
||||
burp_rel* relations;
|
||||
burp_pkg* packages;
|
||||
burp_prc* procedures;
|
||||
@ -1010,6 +1059,11 @@ public:
|
||||
SCHAR mvol_old_file [MAX_FILE_NAME_SIZE];
|
||||
int mvol_volume_count;
|
||||
bool mvol_empty_file;
|
||||
TEXT mvol_keyname_buffer[MAX_FILE_NAME_SIZE];
|
||||
const TEXT* mvol_keyname;
|
||||
TEXT mvol_crypt_buffer[MAX_FILE_NAME_SIZE];
|
||||
const TEXT* mvol_crypt;
|
||||
TEXT gbl_key_hash[(Firebird::Sha1::HASH_SIZE + 1) * 4 / 3 + 1]; // take into an account base64
|
||||
Firebird::IAttachment* db_handle;
|
||||
Firebird::ITransaction* tr_handle;
|
||||
Firebird::ITransaction* global_trans;
|
||||
|
@ -91,8 +91,12 @@ const int IN_SW_BURP_FETCHPASS = 45; // fetch default password from file to us
|
||||
const int IN_SW_BURP_VERBINT = 46; // verbose but with specific interval
|
||||
const int IN_SW_BURP_STATS = 47; // print statistics
|
||||
|
||||
const int IN_SW_BURP_ZIP = 48; // backup file in .zip format
|
||||
const int IN_SW_BURP_KEYHOLD = 49; // name of KeyHolder plugin
|
||||
const int IN_SW_BURP_KEYNAME = 50; // name of crypt key
|
||||
const int IN_SW_BURP_CRYPT = 51; // name of crypt plugin
|
||||
|
||||
/**************************************************************************/
|
||||
// used 0BCDEFGILMNOPRSTUVYZ available AHJQWX
|
||||
|
||||
static const char* const BURP_SW_MODE_RO = "READ_ONLY";
|
||||
static const char* const BURP_SW_MODE_RW = "READ_WRITE";
|
||||
@ -111,6 +115,8 @@ static const Switches::in_sw_tab_t reference_burp_in_sw_table[] =
|
||||
// msg 73: @1CREATE_DATABASE create database from backup file
|
||||
{IN_SW_BURP_CO, isc_spb_bkp_convert, "CONVERT", 0, 0, 0, false, true, 254, 2, NULL, boBackup},
|
||||
// msg 254: @1CO(NVERT) backup external files as tables
|
||||
{IN_SW_BURP_CRYPT, isc_spb_bkp_crypt, "CRYPT", 0, 0, 0, false, false, 373, 3, NULL, boGeneral},
|
||||
// msg 373:@1CRY(PT) plugin name
|
||||
{IN_SW_BURP_E, isc_spb_bkp_expand, "EXPAND", 0, 0, 0, false, true, 97, 1, NULL, boBackup},
|
||||
// msg 97: @1EXPAND no data compression
|
||||
{IN_SW_BURP_FA, isc_spb_bkp_factor, "FACTOR", 0, 0, 0, false, false, 181, 2, NULL, boBackup},
|
||||
@ -125,10 +131,14 @@ static const Switches::in_sw_tab_t reference_burp_in_sw_table[] =
|
||||
// msg 303: @1FIX_FSS_METADATA fix malformed UNICODE_FSS metadata
|
||||
{IN_SW_BURP_G, isc_spb_bkp_no_garbage_collect, "GARBAGE_COLLECT", 0, 0, 0, false, true, 177, 1, NULL, boBackup},
|
||||
// msg 177:@1GARBAGE_COLLECT inhibit garbage collection
|
||||
{IN_SW_BURP_I, isc_spb_res_deactivate_idx, "INACTIVE", 0, 0, 0, false, true, 78, 1, NULL, boRestore},
|
||||
{IN_SW_BURP_I, isc_spb_res_deactivate_idx, "INACTIVE", 0, 0, 0, false, true, 78, 1, NULL, boRestore},
|
||||
// msg 78:@1INACTIVE deactivate indexes during restore
|
||||
{IN_SW_BURP_IG, isc_spb_bkp_ignore_checksums, "IGNORE", 0, 0, 0, false, true, 178, 2, NULL, boBackup},
|
||||
{IN_SW_BURP_IG, isc_spb_bkp_ignore_checksums, "IGNORE", 0, 0, 0, false, true, 178, 2, NULL, boBackup},
|
||||
// msg 178:@1IGNORE ignore bad checksums
|
||||
{IN_SW_BURP_KEYHOLD, isc_spb_bkp_keyholder, "KEYHOLDER", 0, 0, 0, false, false, 382, 4, NULL, boGeneral},
|
||||
// msg 382:@1KEYHOLDER name of a key holder plugin
|
||||
{IN_SW_BURP_KEYNAME, isc_spb_bkp_keyname, "KEYNAME", 0, 0, 0, false, false, 372, 4, NULL, boGeneral},
|
||||
// msg 372:@1KEYNAME name of a key to be used for encryption
|
||||
{IN_SW_BURP_K, isc_spb_res_no_shadow, "KILL", 0, 0, 0, false, true, 172, 1, NULL, boRestore},
|
||||
// msg 172:@1KILL restore without creating shadows
|
||||
{IN_SW_BURP_L, isc_spb_bkp_ignore_limbo, "LIMBO", 0, 0, 0, false, true, 98, 1, NULL, boBackup},
|
||||
@ -167,13 +177,13 @@ static const Switches::in_sw_tab_t reference_burp_in_sw_table[] =
|
||||
// msg 355: @1SKIP_DATA skip data for table
|
||||
{IN_SW_BURP_STATS, isc_spb_bkp_stat, "STATISTICS", 0, 0, 0, false, false, 361, 2, NULL, boGeneral},
|
||||
// msg 361: @1ST(ATISTICS) TDRW show statistics:
|
||||
{-1, 0, " ", 0, 0, 0, false, false, 362, 0, NULL, boGeneral},
|
||||
{-1, 0, " ", 0, 0, 0, false, false, 362, 0, NULL, boGeneral},
|
||||
// msg 362: T time from start
|
||||
{-1, 0, " ", 0, 0, 0, false, false, 363, 0, NULL, boGeneral},
|
||||
{-1, 0, " ", 0, 0, 0, false, false, 363, 0, NULL, boGeneral},
|
||||
// msg 363: D delta time
|
||||
{-1, 0, " ", 0, 0, 0, false, false, 364, 0, NULL, boGeneral},
|
||||
{-1, 0, " ", 0, 0, 0, false, false, 364, 0, NULL, boGeneral},
|
||||
// msg 364: R page reads
|
||||
{-1, 0, " ", 0, 0, 0, false, false, 365, 0, NULL, boGeneral},
|
||||
{-1, 0, " ", 0, 0, 0, false, false, 365, 0, NULL, boGeneral},
|
||||
// msg 365: W page writes
|
||||
{IN_SW_BURP_T, 0, "TRANSPORTABLE", 0, 0, 0, false, false, 175, 1, NULL, boBackup},
|
||||
// msg 175: @1TRANSPORTABLE transportable backup -- data in XDR format
|
||||
@ -197,6 +207,8 @@ static const Switches::in_sw_tab_t reference_burp_in_sw_table[] =
|
||||
// msg 109: @1Y redirect/suppress output (file path or OUTPUT_SUPPRESS)
|
||||
{IN_SW_BURP_Z, 0, "Z", 0, 0, 0, false, false, 104, 1, NULL, boGeneral},
|
||||
// msg 104: @1Z print version number
|
||||
{IN_SW_BURP_ZIP, isc_spb_bkp_zip, "ZIP", 0, 0, 0, false, true, 374, 3, NULL, boBackup},
|
||||
// msg 104: @1ZIP backup file is in zip compressed format
|
||||
/**************************************************************************/
|
||||
// The next two 'virtual' switches are hidden from user and are needed
|
||||
// for services API
|
||||
|
@ -42,11 +42,11 @@
|
||||
#include "../common/xdr_proto.h"
|
||||
#include "../common/gdsassert.h"
|
||||
#include "../common/StatusHolder.h"
|
||||
#include "../common/status.h"
|
||||
#include "fb_types.h"
|
||||
|
||||
// TMN: Currently we can't include remote/remote.h because we'd get
|
||||
// conflicting blk_t definitions (we are gonna fix this, in due time).
|
||||
|
||||
using Firebird::FbLocalStatus;
|
||||
|
||||
static bool_t burp_getbytes(XDR*, SCHAR *, u_int);
|
||||
static bool_t burp_putbytes(XDR*, const SCHAR*, u_int);
|
||||
@ -426,8 +426,7 @@ static bool_t xdr_slice(XDR* xdrs, lstring* slice, /*USHORT sdl_length,*/ const
|
||||
|
||||
sdl_info info;
|
||||
{
|
||||
Firebird::LocalStatus ls;
|
||||
Firebird::CheckStatusWrapper s(&ls);
|
||||
FbLocalStatus s;
|
||||
if (SDL_info(&s, sdl, &info, 0))
|
||||
return FALSE;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -24,24 +24,27 @@
|
||||
#ifndef BURP_MVOL_PROTO_H
|
||||
#define BURP_MVOL_PROTO_H
|
||||
|
||||
#include "../burp/burp.h"
|
||||
#include "firebird/Interface.h"
|
||||
#include "std_desc.h"
|
||||
|
||||
class BurpGlobals;
|
||||
|
||||
FB_UINT64 MVOL_fini_read();
|
||||
FB_UINT64 MVOL_fini_write(int*, UCHAR**);
|
||||
FB_UINT64 MVOL_fini_write();
|
||||
void MVOL_init(ULONG);
|
||||
void MVOL_init_read(const char*, USHORT*, int*, UCHAR**);
|
||||
void MVOL_init_write(const char*, int*, UCHAR**);
|
||||
void MVOL_init_read(const char*, USHORT*);
|
||||
void MVOL_init_write(const char*);
|
||||
bool MVOL_split_hdr_write();
|
||||
bool MVOL_split_hdr_read();
|
||||
int MVOL_read(int*, UCHAR**);
|
||||
void MVOL_read(BurpGlobals*);
|
||||
UCHAR* MVOL_read_block(BurpGlobals*, UCHAR*, ULONG);
|
||||
void MVOL_skip_block(BurpGlobals*, ULONG);
|
||||
UCHAR MVOL_write(const UCHAR, int*, UCHAR**);
|
||||
void MVOL_write(BurpGlobals*);
|
||||
const UCHAR* MVOL_write_block(BurpGlobals*, const UCHAR*, ULONG);
|
||||
Firebird::ICryptKeyCallback* MVOL_get_crypt(BurpGlobals*);
|
||||
|
||||
#if defined WIN_NT
|
||||
DESC MVOL_open(const char*, ULONG, ULONG);
|
||||
DESC NT_tape_open(const char*, ULONG, ULONG);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "../burp/OdsDetection.h"
|
||||
#include "../auth/trusted/AuthSspi.h"
|
||||
#include "../common/dsc_proto.h"
|
||||
#include "../common/ThreadStart.h"
|
||||
|
||||
using MsgFormat::SafeArg;
|
||||
using Firebird::FbLocalStatus;
|
||||
@ -104,7 +105,7 @@ enum scan_attr_t
|
||||
void add_access_dpb(BurpGlobals* tdgbl, Firebird::ClumpletWriter& dpb);
|
||||
void add_files(BurpGlobals* tdgbl, const char*);
|
||||
void bad_attribute(scan_attr_t, att_type, USHORT);
|
||||
void create_database(BurpGlobals* tdgbl, const TEXT*);
|
||||
void create_database(BurpGlobals* tdgbl, Firebird::IProvider*, const TEXT*);
|
||||
void decompress(BurpGlobals* tdgbl, UCHAR*, ULONG);
|
||||
void eat_blob(BurpGlobals* tdgbl);
|
||||
void eat_text(BurpGlobals* tdgbl);
|
||||
@ -163,7 +164,7 @@ void realign(BurpGlobals* tdgbl, UCHAR*, const burp_rel*);
|
||||
#ifdef sparc
|
||||
USHORT recompute_length(BurpGlobals* tdgbl, burp_rel*);
|
||||
#endif
|
||||
bool restore(BurpGlobals* tdgbl, const TEXT*, const TEXT*);
|
||||
bool restore(BurpGlobals* tdgbl, Firebird::IProvider*, const TEXT*, const TEXT*);
|
||||
void restore_security_class(BurpGlobals* tdgbl, const TEXT*, const TEXT*);
|
||||
USHORT get_view_base_relation_count(BurpGlobals* tdgbl, const TEXT*, USHORT, bool* error);
|
||||
void store_blr_gen_id(BurpGlobals* tdgbl, const TEXT* gen_name, SINT64 value, SINT64 initial_value,
|
||||
@ -184,13 +185,9 @@ const SSHORT old_sparcs[] =
|
||||
{0, 0, 0, 2, 0, 0, 0, 0, 2, 4, 4, 4, 8, 8, 0, 0, 8, 8, 8};
|
||||
#endif
|
||||
|
||||
//MVOL_read returns int
|
||||
static inline int get(BurpGlobals* tdgbl)
|
||||
static inline UCHAR get(BurpGlobals* tdgbl)
|
||||
{
|
||||
if (--(tdgbl->io_cnt) >= 0)
|
||||
return *(tdgbl->io_ptr)++;
|
||||
|
||||
return MVOL_read(&tdgbl->io_cnt, &tdgbl->io_ptr);
|
||||
return tdgbl->get();
|
||||
}
|
||||
|
||||
static inline FB_BOOLEAN get_boolean(BurpGlobals* tdgbl)
|
||||
@ -283,22 +280,11 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name)
|
||||
Firebird::IRequest* req_handle5 = nullptr;
|
||||
BASED_ON RDB$INDICES.RDB$INDEX_NAME index_name;
|
||||
|
||||
Firebird::DispatcherPtr provider;
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
tdgbl->io_ptr = NULL;
|
||||
tdgbl->io_cnt = 0;
|
||||
|
||||
tdgbl->relations = NULL;
|
||||
tdgbl->packages = NULL;
|
||||
tdgbl->procedures = NULL;
|
||||
tdgbl->miss_privs = NULL;
|
||||
tdgbl->RESTORE_format = 0;
|
||||
tdgbl->runtimeODS = 0;
|
||||
tdgbl->global_trans = 0;
|
||||
|
||||
tdgbl->gbl_sw_transportable = tdgbl->gbl_sw_compress = false;
|
||||
|
||||
if (!restore(tdgbl, file_name, database_name))
|
||||
if (!restore(tdgbl, provider, file_name, database_name))
|
||||
return FINI_ERROR;
|
||||
|
||||
BURP_verbose (76);
|
||||
@ -580,7 +566,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name)
|
||||
// set forced writes to the value which was in the header
|
||||
dpb.insertByte(isc_dpb_force_write, tdgbl->hdr_forced_writes ? 1 : 0);
|
||||
|
||||
Firebird::IAttachment* db_handle = Firebird::DispatcherPtr()->attachDatabase(&tdgbl->status_vector, database_name,
|
||||
Firebird::IAttachment* db_handle = provider->attachDatabase(&tdgbl->status_vector, database_name,
|
||||
dpb.getBufferLength(), dpb.getBuffer());
|
||||
if (tdgbl->status_vector->hasData())
|
||||
general_on_error();
|
||||
@ -608,7 +594,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name)
|
||||
|
||||
dpb.insertByte(isc_dpb_set_db_readonly, 1);
|
||||
|
||||
db_handle = Firebird::DispatcherPtr()->attachDatabase(&tdgbl->status_vector, database_name,
|
||||
db_handle = provider->attachDatabase(&tdgbl->status_vector, database_name,
|
||||
dpb.getBufferLength(), dpb.getBuffer());
|
||||
if (tdgbl->status_vector->hasData())
|
||||
general_on_error();
|
||||
@ -807,9 +793,32 @@ private:
|
||||
unsigned* version;
|
||||
};
|
||||
|
||||
class EngineVersion :
|
||||
public Firebird::AutoIface<Firebird::IVersionCallbackImpl<EngineVersion, Firebird::CheckStatusWrapper> >
|
||||
{
|
||||
public:
|
||||
EngineVersion(char* v)
|
||||
: version(v)
|
||||
{
|
||||
version[0] = 0;
|
||||
}
|
||||
|
||||
// IVersionCallback implementation
|
||||
void callback(Firebird::CheckStatusWrapper*, const char* text)
|
||||
{
|
||||
if (!version[0])
|
||||
strcpy(version, text);
|
||||
}
|
||||
|
||||
private:
|
||||
char* version;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void create_database(BurpGlobals* tdgbl, const TEXT* file_name)
|
||||
|
||||
|
||||
void create_database(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TEXT* file_name)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -836,6 +845,8 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name)
|
||||
ULONG page_buffers = 0;
|
||||
USHORT SQL_dialect = 0;
|
||||
|
||||
tdgbl->gbl_database_file_name = file_name;
|
||||
|
||||
att_type attribute;
|
||||
rec_type record;
|
||||
if (get_record(&record, tdgbl) == rec_physical_db)
|
||||
@ -974,7 +985,9 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name)
|
||||
|
||||
// start database up shut down,
|
||||
// use single-user mode to avoid conflicts during restore process
|
||||
dpb.insertByte(isc_dpb_shutdown, isc_dpb_shut_attachment | isc_dpb_shut_single);
|
||||
// when crypt thread to run use multi-DBO mode
|
||||
dpb.insertByte(isc_dpb_shutdown, isc_dpb_shut_attachment |
|
||||
(tdgbl->gbl_sw_keyholder ? isc_dpb_shut_multi : isc_dpb_shut_single));
|
||||
dpb.insertInt(isc_dpb_shutdown_delay, 0);
|
||||
dpb.insertInt(isc_dpb_overwrite, tdgbl->gbl_sw_overwrite);
|
||||
|
||||
@ -988,8 +1001,19 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name)
|
||||
fb_strlen(tdgbl->gbl_sw_fix_fss_metadata));
|
||||
}
|
||||
|
||||
DB = Firebird::DispatcherPtr()->createDatabase(&status_vector, file_name,
|
||||
dpb.getBufferLength(), dpb.getBuffer());
|
||||
// provide crypt key(s) for engine
|
||||
|
||||
if (tdgbl->gbl_sw_keyholder)
|
||||
{
|
||||
provider->setDbCryptCallback(&status_vector, MVOL_get_crypt(tdgbl));
|
||||
if (!status_vector.isSuccess())
|
||||
{
|
||||
BURP_print_status(true, &status_vector);
|
||||
BURP_exit_local(FINI_ERROR, tdgbl);
|
||||
}
|
||||
}
|
||||
|
||||
DB = provider->createDatabase(&status_vector, file_name, dpb.getBufferLength(), dpb.getBuffer());
|
||||
if (status_vector->hasData())
|
||||
{
|
||||
BURP_error_redirect(&status_vector, 33, SafeArg() << file_name);
|
||||
@ -1017,6 +1041,100 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name)
|
||||
|
||||
BURP_verbose (74, SafeArg() << file_name << page_size);
|
||||
// msg 74 created database %s, page_size %ld bytes
|
||||
|
||||
if (tdgbl->gbl_sw_keyholder)
|
||||
{
|
||||
// check server version
|
||||
char buf[256];
|
||||
EngineVersion ev(buf);
|
||||
Firebird::UtilInterfacePtr()->getFbVersion(&status_vector, DB, &ev);
|
||||
|
||||
const char* ptr = strstr(buf, "version \"");
|
||||
int v = 0;
|
||||
int c = 1;
|
||||
if (ptr)
|
||||
{
|
||||
while(ptr && *ptr)
|
||||
{
|
||||
if (*ptr >='0' && *ptr <= '9')
|
||||
{
|
||||
v *= 100;
|
||||
v += atoi(ptr);
|
||||
if (c >= 3)
|
||||
{
|
||||
if (v < 30004)
|
||||
ptr = NULL;
|
||||
break;
|
||||
}
|
||||
++c;
|
||||
ptr = strchr(ptr, '.');
|
||||
}
|
||||
else
|
||||
++ptr;
|
||||
}
|
||||
}
|
||||
if (!(ptr && *ptr))
|
||||
{
|
||||
Firebird::string x;
|
||||
x.printf("Undefined or too small server version: %s, need at least 3.0.4", buf);
|
||||
(Firebird::Arg::Gds(isc_random) << x).raise();
|
||||
}
|
||||
|
||||
EXEC SQL SET TRANSACTION;
|
||||
if (gds_status->hasData())
|
||||
general_on_error ();
|
||||
|
||||
if (!tdgbl->gbl_sw_crypt)
|
||||
{
|
||||
BURP_error(true, 378);
|
||||
// Unknown crypt plugin name - use -CRYPT switch
|
||||
}
|
||||
|
||||
Firebird::string sql;
|
||||
sql.printf("ALTER DATABASE ENCRYPT WITH \"%s\"", tdgbl->gbl_sw_crypt);
|
||||
if (tdgbl->gbl_sw_keyname)
|
||||
{
|
||||
sql += " KEY ";
|
||||
sql += tdgbl->gbl_sw_keyname;
|
||||
}
|
||||
tdgbl->db_handle->execute(gds_status, tdgbl->tr_handle, sql.length(), sql.c_str(), 3,
|
||||
nullptr, nullptr, nullptr, nullptr);
|
||||
if (gds_status->hasData())
|
||||
general_on_error ();
|
||||
|
||||
COMMIT
|
||||
ON_ERROR
|
||||
general_on_error ();
|
||||
END_ERROR;
|
||||
|
||||
UCHAR buffer[100];
|
||||
UCHAR item = fb_info_crypt_state;
|
||||
bool complete = false;
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
Thread::sleep(100);
|
||||
|
||||
tdgbl->db_handle->getInfo(gds_status, sizeof(item), &item, sizeof(buffer), buffer);
|
||||
if (gds_status->hasData())
|
||||
general_on_error ();
|
||||
|
||||
const UCHAR* d = buffer;
|
||||
if (*d++ != fb_info_crypt_state)
|
||||
BURP_error(385, true);
|
||||
|
||||
const int length = gds__vax_integer(d, 2);
|
||||
d += 2;
|
||||
const int value = gds__vax_integer(d, length);
|
||||
if (value & fb_info_crypt_encrypted && !(value & fb_info_crypt_process))
|
||||
{
|
||||
complete = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!complete)
|
||||
BURP_error(386, true);
|
||||
}
|
||||
}
|
||||
|
||||
void decompress(BurpGlobals* tdgbl, UCHAR* buffer, ULONG length)
|
||||
@ -10348,7 +10466,7 @@ USHORT recompute_length(BurpGlobals* tdgbl, burp_rel* relation)
|
||||
}
|
||||
#endif
|
||||
|
||||
bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_name)
|
||||
bool restore(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TEXT* file_name, const TEXT* database_name)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -10363,7 +10481,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam
|
||||
|
||||
// Read burp record first
|
||||
|
||||
MVOL_init_read (file_name, &tdgbl->RESTORE_format, &tdgbl->io_cnt, &tdgbl->io_ptr);
|
||||
MVOL_init_read (file_name, &tdgbl->RESTORE_format);
|
||||
|
||||
if (tdgbl->gbl_sw_transportable)
|
||||
BURP_verbose (133);
|
||||
@ -10383,7 +10501,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam
|
||||
|
||||
BURP_verbose(349, SafeArg() << tdgbl->RESTORE_format); // backup version is @1
|
||||
|
||||
create_database(tdgbl, database_name);
|
||||
create_database(tdgbl, provider, database_name);
|
||||
|
||||
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
|
||||
if (gds_status->hasData())
|
||||
|
@ -145,6 +145,7 @@ public:
|
||||
virtual bool finished() { return false; }
|
||||
virtual void initStatus() { }
|
||||
virtual bool utf8FileNames() { return false; }
|
||||
virtual Firebird::ICryptKeyCallback* getCryptCallback() { return NULL; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -30,6 +30,8 @@
|
||||
#ifndef FB_UTILFACE
|
||||
#define FB_UTILFACE
|
||||
|
||||
#include "firebird/Interface.h"
|
||||
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "../common/classes/array.h"
|
||||
#include "../common/classes/fb_string.h"
|
||||
@ -74,6 +76,7 @@ public:
|
||||
virtual bool finished() = 0;
|
||||
virtual unsigned int getAuthBlock(const unsigned char** bytes) = 0;
|
||||
virtual bool utf8FileNames() = 0;
|
||||
virtual Firebird::ICryptKeyCallback* getCryptCallback() = 0;
|
||||
|
||||
void setDataMode(bool value)
|
||||
{
|
||||
|
@ -334,7 +334,9 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const
|
||||
case isc_spb_res_fix_fss_metadata:
|
||||
case isc_spb_bkp_stat:
|
||||
case isc_spb_bkp_skip_data:
|
||||
//case isc_spb_res_skip_data: // same value
|
||||
case isc_spb_bkp_keyholder:
|
||||
case isc_spb_bkp_keyname:
|
||||
case isc_spb_bkp_crypt:
|
||||
return StringSpb;
|
||||
case isc_spb_bkp_factor:
|
||||
case isc_spb_bkp_length:
|
||||
|
@ -30,6 +30,7 @@
|
||||
#define FB_COMMON_CLASSES_GET_PLUGINS
|
||||
|
||||
#include "../common/classes/ImplementHelper.h"
|
||||
#include "../common/classes/auto.h"
|
||||
#include "../common/config/config.h"
|
||||
#include "../common/StatusHolder.h"
|
||||
|
||||
|
@ -130,6 +130,13 @@ namespace Firebird
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void moveFrom(RefPtr& r)
|
||||
{
|
||||
assign(NULL);
|
||||
ptr = r.ptr;
|
||||
r.ptr = NULL;
|
||||
}
|
||||
|
||||
T* operator=(T* p)
|
||||
{
|
||||
return assign(p);
|
||||
|
@ -393,6 +393,9 @@
|
||||
#define isc_spb_bkp_length 7
|
||||
#define isc_spb_bkp_skip_data 8
|
||||
#define isc_spb_bkp_stat 15
|
||||
#define isc_spb_bkp_keyholder 16
|
||||
#define isc_spb_bkp_keyname 17
|
||||
#define isc_spb_bkp_crypt 18
|
||||
#define isc_spb_bkp_ignore_checksums 0x01
|
||||
#define isc_spb_bkp_ignore_limbo 0x02
|
||||
#define isc_spb_bkp_metadata_only 0x04
|
||||
@ -402,6 +405,7 @@
|
||||
#define isc_spb_bkp_convert 0x40
|
||||
#define isc_spb_bkp_expand 0x80
|
||||
#define isc_spb_bkp_no_triggers 0x8000
|
||||
#define isc_spb_bkp_zip 0x010000
|
||||
|
||||
/********************************************
|
||||
* Parameters for isc_action_svc_properties *
|
||||
@ -505,6 +509,9 @@
|
||||
#define isc_spb_res_access_mode 12
|
||||
#define isc_spb_res_fix_fss_data 13
|
||||
#define isc_spb_res_fix_fss_metadata 14
|
||||
#define isc_spb_res_keyholder isc_spb_bkp_keyholder
|
||||
#define isc_spb_res_keyname isc_spb_bkp_keyname
|
||||
#define isc_spb_res_crypt isc_spb_bkp_crypt
|
||||
#define isc_spb_res_stat isc_spb_bkp_stat
|
||||
#define isc_spb_res_metadata_only isc_spb_bkp_metadata_only
|
||||
#define isc_spb_res_deactivate_idx 0x0100
|
||||
|
@ -906,6 +906,7 @@ static const struct {
|
||||
{"hdr_overflow", 335545202},
|
||||
{"vld_plugins", 335545203},
|
||||
{"db_crypt_key", 335545204},
|
||||
{"no_keyholder_plugin", 335545205},
|
||||
{"gfix_db_name", 335740929},
|
||||
{"gfix_invalid_sw", 335740930},
|
||||
{"gfix_incmp_sw", 335740932},
|
||||
|
@ -940,6 +940,7 @@ const ISC_STATUS isc_map_overflow = 335545201L;
|
||||
const ISC_STATUS isc_hdr_overflow = 335545202L;
|
||||
const ISC_STATUS isc_vld_plugins = 335545203L;
|
||||
const ISC_STATUS isc_db_crypt_key = 335545204L;
|
||||
const ISC_STATUS isc_no_keyholder_plugin = 335545205L;
|
||||
const ISC_STATUS isc_gfix_db_name = 335740929L;
|
||||
const ISC_STATUS isc_gfix_invalid_sw = 335740930L;
|
||||
const ISC_STATUS isc_gfix_incmp_sw = 335740932L;
|
||||
@ -1414,7 +1415,7 @@ const ISC_STATUS isc_trace_switch_user_only = 337182757L;
|
||||
const ISC_STATUS isc_trace_switch_param_miss = 337182758L;
|
||||
const ISC_STATUS isc_trace_param_act_notcompat = 337182759L;
|
||||
const ISC_STATUS isc_trace_mandatory_switch_miss = 337182760L;
|
||||
const ISC_STATUS isc_err_max = 1358;
|
||||
const ISC_STATUS isc_err_max = 1359;
|
||||
|
||||
#else /* c definitions */
|
||||
|
||||
@ -2324,6 +2325,7 @@ const ISC_STATUS isc_err_max = 1358;
|
||||
#define isc_hdr_overflow 335545202L
|
||||
#define isc_vld_plugins 335545203L
|
||||
#define isc_db_crypt_key 335545204L
|
||||
#define isc_no_keyholder_plugin 335545205L
|
||||
#define isc_gfix_db_name 335740929L
|
||||
#define isc_gfix_invalid_sw 335740930L
|
||||
#define isc_gfix_incmp_sw 335740932L
|
||||
@ -2798,7 +2800,7 @@ const ISC_STATUS isc_err_max = 1358;
|
||||
#define isc_trace_switch_param_miss 337182758L
|
||||
#define isc_trace_param_act_notcompat 337182759L
|
||||
#define isc_trace_mandatory_switch_miss 337182760L
|
||||
#define isc_err_max 1358
|
||||
#define isc_err_max 1359
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -909,6 +909,7 @@ Data source : @4"}, /* eds_statement */
|
||||
{335545202, "Header page overflow - too many clumplets on it"}, /* hdr_overflow */
|
||||
{335545203, "No matching client/server authentication plugins configured for execute statement in embedded datasource"}, /* vld_plugins */
|
||||
{335545204, "Missing database encryption key for your attachment"}, /* db_crypt_key */
|
||||
{335545205, "Key holder plugin @1 failed to load"}, /* no_keyholder_plugin */
|
||||
{335740929, "data base file name (@1) already given"}, /* gfix_db_name */
|
||||
{335740930, "invalid switch @1"}, /* gfix_invalid_sw */
|
||||
{335740932, "incompatible switch combination"}, /* gfix_incmp_sw */
|
||||
|
@ -905,6 +905,7 @@ static const struct {
|
||||
{335545202, -901}, /* 882 hdr_overflow */
|
||||
{335545203, -901}, /* 883 vld_plugins */
|
||||
{335545204, -902}, /* 884 db_crypt_key */
|
||||
{335545205, -104}, /* 885 no_keyholder_plugin */
|
||||
{335740929, -901}, /* 1 gfix_db_name */
|
||||
{335740930, -901}, /* 2 gfix_invalid_sw */
|
||||
{335740932, -901}, /* 4 gfix_incmp_sw */
|
||||
|
@ -905,6 +905,7 @@ static const struct {
|
||||
{335545202, "54000"}, // 882 hdr_overflow
|
||||
{335545203, "28000"}, // 883 vld_plugins
|
||||
{335545204, "08004"}, // 884 db_crypt_key
|
||||
{335545205, "HY024"}, // 885 no_keyholder_plugin
|
||||
{335740929, "00000"}, // 1 gfix_db_name
|
||||
{335740930, "00000"}, // 2 gfix_invalid_sw
|
||||
{335740932, "00000"}, // 4 gfix_incmp_sw
|
||||
|
@ -265,6 +265,7 @@ namespace Jrd {
|
||||
: PermanentStorage(*tdbb->getDatabase()->dbb_permanent),
|
||||
sync(this),
|
||||
keyName(getPool()),
|
||||
pluginName(getPool()),
|
||||
keyProviders(getPool()),
|
||||
keyConsumers(getPool()),
|
||||
hash(getPool()),
|
||||
@ -366,6 +367,7 @@ namespace Jrd {
|
||||
keyName = "";
|
||||
|
||||
loadPlugin(tdbb, hdr->hdr_crypt_plugin);
|
||||
pluginName = hdr->hdr_crypt_plugin;
|
||||
|
||||
string valid;
|
||||
calcValidation(valid, cryptPlugin);
|
||||
@ -395,7 +397,7 @@ namespace Jrd {
|
||||
}
|
||||
}
|
||||
|
||||
void CryptoManager::loadPlugin(thread_db* tdbb, const char* pluginName)
|
||||
void CryptoManager::loadPlugin(thread_db* tdbb, const char* plugName)
|
||||
{
|
||||
if (cryptPlugin)
|
||||
{
|
||||
@ -408,10 +410,10 @@ namespace Jrd {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoPtr<Factory> cryptControl(FB_NEW Factory(IPluginManager::TYPE_DB_CRYPT, dbb.dbb_config, pluginName));
|
||||
AutoPtr<Factory> cryptControl(FB_NEW Factory(IPluginManager::TYPE_DB_CRYPT, dbb.dbb_config, plugName));
|
||||
if (!cryptControl->hasData())
|
||||
{
|
||||
(Arg::Gds(isc_no_crypt_plugin) << pluginName).raise();
|
||||
(Arg::Gds(isc_no_crypt_plugin) << plugName).raise();
|
||||
}
|
||||
|
||||
// do not assign cryptPlugin directly before key init complete
|
||||
@ -461,6 +463,7 @@ namespace Jrd {
|
||||
|
||||
cryptPlugin = p;
|
||||
cryptPlugin->addRef();
|
||||
pluginName = plugName;
|
||||
|
||||
// remove old factory if present
|
||||
delete checkFactory;
|
||||
@ -1326,6 +1329,11 @@ namespace Jrd {
|
||||
return keyName.c_str();
|
||||
}
|
||||
|
||||
const char* CryptoManager::getPluginName() const
|
||||
{
|
||||
return pluginName.c_str();
|
||||
}
|
||||
|
||||
void CryptoManager::addClumplet(string& signature, ClumpletReader& block, UCHAR tag)
|
||||
{
|
||||
if (block.find(tag))
|
||||
|
@ -304,6 +304,7 @@ public:
|
||||
ULONG getCurrentPage() const;
|
||||
UCHAR getCurrentState() const;
|
||||
const char* getKeyName() const;
|
||||
const char* getPluginName() const;
|
||||
|
||||
private:
|
||||
enum IoResult {SUCCESS_ALL, FAILED_CRYPT, FAILED_IO};
|
||||
@ -383,7 +384,7 @@ private:
|
||||
void checkDigitalSignature(thread_db* tdbb, const class Header& hdr);
|
||||
|
||||
BarSync sync;
|
||||
Firebird::MetaName keyName;
|
||||
Firebird::MetaName keyName, pluginName;
|
||||
ULONG currentPage;
|
||||
Firebird::Mutex pluginLoadMtx, cryptThreadMtx, holdersMutex;
|
||||
AttVector keyProviders, keyConsumers;
|
||||
|
@ -62,7 +62,7 @@ SYSTEM_PRIVILEGE(USE_GRANTED_BY_CLAUSE)
|
||||
SYSTEM_PRIVILEGE(GRANT_REVOKE_ON_ANY_OBJECT)
|
||||
SYSTEM_PRIVILEGE(GRANT_REVOKE_ANY_DDL_RIGHT)
|
||||
SYSTEM_PRIVILEGE(CREATE_PRIVILEGED_ROLES)
|
||||
SYSTEM_PRIVILEGE(GET_DBCRYPT_KEY_NAME)
|
||||
SYSTEM_PRIVILEGE(GET_DBCRYPT_INFO)
|
||||
|
||||
#ifdef FB_JRD_SYSTEM_PRIVILEGES_TMP
|
||||
maxSystemPrivilege
|
||||
|
@ -770,7 +770,7 @@ void INF_database_info(thread_db* tdbb,
|
||||
break;
|
||||
|
||||
case fb_info_crypt_key:
|
||||
if (tdbb->getAttachment()->locksmith(tdbb, GET_DBCRYPT_KEY_NAME))
|
||||
if (tdbb->getAttachment()->locksmith(tdbb, GET_DBCRYPT_INFO))
|
||||
{
|
||||
const char* key = dbb->dbb_crypto_manager->getKeyName();
|
||||
if (!(info = INF_put_item(item, static_cast<USHORT>(strlen(key)), key, info, end)))
|
||||
@ -788,6 +788,25 @@ void INF_database_info(thread_db* tdbb,
|
||||
length = 1 + INF_convert(isc_adm_task_denied, buffer + 1);
|
||||
break;
|
||||
|
||||
case fb_info_crypt_plugin:
|
||||
if (tdbb->getAttachment()->locksmith(tdbb, GET_DBCRYPT_INFO))
|
||||
{
|
||||
const char* key = dbb->dbb_crypto_manager->getPluginName();
|
||||
if (!(info = INF_put_item(item, static_cast<USHORT>(strlen(key)), key, info, end)))
|
||||
{
|
||||
if (transaction)
|
||||
TRA_commit(tdbb, transaction, false);
|
||||
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
buffer[0] = item;
|
||||
item = isc_info_error;
|
||||
length = 1 + INF_convert(isc_adm_task_denied, buffer + 1);
|
||||
break;
|
||||
|
||||
case fb_info_conn_flags:
|
||||
length = INF_convert(tdbb->getAttachment()->att_remote_flags, buffer);
|
||||
break;
|
||||
|
@ -148,7 +148,6 @@ enum db_info_types
|
||||
fb_info_ses_idle_timeout_run = 131,
|
||||
|
||||
fb_info_conn_flags = 132,
|
||||
fb_info_protocol_version = 133,
|
||||
|
||||
fb_info_crypt_key = 133,
|
||||
fb_info_crypt_state = 134,
|
||||
@ -156,6 +155,9 @@ enum db_info_types
|
||||
fb_info_statement_timeout_db = 135,
|
||||
fb_info_statement_timeout_att = 136,
|
||||
|
||||
fb_info_protocol_version = 137,
|
||||
fb_info_crypt_plugin = 138,
|
||||
|
||||
isc_info_db_last_value /* Leave this LAST! */
|
||||
};
|
||||
|
||||
|
@ -647,6 +647,11 @@ bool Service::utf8FileNames()
|
||||
return svc_utf8;
|
||||
}
|
||||
|
||||
Firebird::ICryptKeyCallback* Service::getCryptCallback()
|
||||
{
|
||||
return svc_crypt_callback;
|
||||
}
|
||||
|
||||
void Service::need_admin_privs(Arg::StatusVector& status, const char* message)
|
||||
{
|
||||
status << Arg::Gds(isc_insufficient_svc_privileges) << Arg::Str(message);
|
||||
@ -2933,6 +2938,9 @@ bool Service::process_switches(ClumpletReader& spb, string& switches)
|
||||
case isc_spb_res_fix_fss_metadata:
|
||||
case isc_spb_bkp_stat:
|
||||
case isc_spb_bkp_skip_data:
|
||||
case isc_spb_bkp_keyholder:
|
||||
case isc_spb_bkp_keyname:
|
||||
case isc_spb_bkp_crypt:
|
||||
if (!get_action_svc_parameter(spb.getClumpTag(), reference_burp_in_sw_table, switches))
|
||||
{
|
||||
return false;
|
||||
|
@ -141,6 +141,8 @@ public: // utilities interface with service
|
||||
virtual void fillDpb(Firebird::ClumpletWriter& dpb);
|
||||
// encoding for string parameters passed to utility
|
||||
virtual bool utf8FileNames();
|
||||
// get database encryption key transfer callback routine
|
||||
virtual Firebird::ICryptKeyCallback* getCryptCallback();
|
||||
|
||||
virtual TraceManager* getTraceManager()
|
||||
{
|
||||
@ -196,7 +198,6 @@ public: // external interface with service
|
||||
const Firebird::string& getRemoteProcess() const { return svc_remote_process; }
|
||||
int getRemotePID() const { return svc_remote_pid; }
|
||||
const Firebird::PathName& getExpectedDb() const { return svc_expected_db; }
|
||||
Firebird::ICryptKeyCallback* getCryptCallback() { return svc_crypt_callback; }
|
||||
|
||||
private:
|
||||
// Service must have private destructor, called from finish
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* MAX_NUMBER is the next number to be used, always one more than the highest message number. */
|
||||
set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUMBER) VALUES (?, ?, ?, ?);
|
||||
--
|
||||
('2018-02-01 17:40:00', 'JRD', 0, 885)
|
||||
('2018-05-05 16:40:00', 'JRD', 0, 886)
|
||||
('2015-03-17 18:33:00', 'QLI', 1, 533)
|
||||
('2015-01-07 18:01:51', 'GFIX', 3, 134)
|
||||
('1996-11-07 13:39:40', 'GPRE', 4, 1)
|
||||
@ -9,7 +9,7 @@ set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUM
|
||||
('2018-01-15 00:15:00', 'DYN', 8, 299)
|
||||
('1996-11-07 13:39:40', 'INSTALL', 10, 1)
|
||||
('1996-11-07 13:38:41', 'TEST', 11, 4)
|
||||
('2018-02-19 19:40:00', 'GBAK', 12, 372)
|
||||
('2018-04-26 20:40:00', 'GBAK', 12, 387)
|
||||
('2015-08-05 12:40:00', 'SQLERR', 13, 1045)
|
||||
('1996-11-07 13:38:42', 'SQLWARN', 14, 613)
|
||||
('2018-02-27 14:50:31', 'JRD_BUGCHK', 15, 308)
|
||||
|
@ -992,6 +992,7 @@ Data source : @4', NULL, NULL)
|
||||
('hdr_overflow', NULL, 'CryptoManager.cpp', NULL, 0, 882, NULL, 'Header page overflow - too many clumplets on it', NULL, NULL);
|
||||
('vld_plugins', NULL, 'ValidatePassword.cpp', NULL, 0, 883, NULL, 'No matching client/server authentication plugins configured for execute statement in embedded datasource', NULL, NULL);
|
||||
('db_crypt_key', NULL, 'CryptoManager.cpp', NULL, 0, 884, NULL, 'Missing database encryption key for your attachment', NULL, NULL);
|
||||
('no_keyholder_plugin', NULL, 'mvol.cpp', NULL, 0, 885, NULL, 'Key holder plugin @1 failed to load', NULL, NULL);
|
||||
-- QLI
|
||||
(NULL, NULL, NULL, NULL, 1, 0, NULL, 'expected type', NULL, NULL);
|
||||
(NULL, NULL, NULL, NULL, 1, 1, NULL, 'bad block type', NULL, NULL);
|
||||
@ -2464,6 +2465,21 @@ ERROR: Backup incomplete', NULL, NULL);
|
||||
(NULL, 'api_gbak/gbak', 'burp.cpp', NULL, 12, 369, NULL, 'total statistics', NULL, NULL);
|
||||
(NULL, 'get_blob', 'restore.epp', NULL, 12, 370, NULL, 'could not append BLOB data to batch', NULL, NULL);
|
||||
(NULL, 'get_data', 'restore.epp', NULL, 12, 371, NULL, 'could not start batch when restoring table @1, trying old way', NULL, NULL);
|
||||
(NULL, 'burp_usage', 'burp.cpp', NULL, 12, 372, NULL, ' @1KEYNAME name of a key to be used for encryption', NULL, NULL);
|
||||
(NULL, 'burp_usage', 'burp.cpp', NULL, 12, 373, NULL, ' @1CRYPT crypt plugin name', NULL, NULL);
|
||||
(NULL, 'burp_usage', 'burp.cpp', NULL, 12, 374, NULL, ' @1ZIP backup file is in zip compressed format', NULL, NULL);
|
||||
(NULL, 'gbak', 'burp.cpp', NULL, 12, 375, NULL, 'Keyname parameter missing', NULL, NULL);
|
||||
(NULL, 'gbak', 'burp.cpp', NULL, 12, 376, NULL, 'Key holder parameter missing but backup file is encrypted', NULL, NULL);
|
||||
(NULL, 'gbak', 'mvol.cpp', NULL, 12, 377, NULL, 'CryptPlugin parameter missing', NULL, NULL);
|
||||
(NULL, 'gbak', 'burp.cpp', NULL, 12, 378, NULL, 'Unknown crypt plugin name - use -CRYPT switch', NULL, NULL);
|
||||
(NULL, NULL, 'mvol.cpp', NULL, 12, 379, NULL, 'Inflate error @1', NULL, NULL);
|
||||
(NULL, NULL, 'mvol.cpp', NULL, 12, 380, NULL, 'Deflate error @1', NULL, NULL);
|
||||
(NULL, 'gbak', 'burp.cpp', NULL, 12, 381, NULL, 'Key holder parameter missing', NULL, NULL);
|
||||
(NULL, 'burp_usage', 'burp.cpp', NULL, 12, 382, NULL, ' @1KEYHOLDER name of a key holder plugin', NULL, NULL);
|
||||
(NULL, NULL, 'mvol.cpp', NULL, 12, 383, NULL, 'Decompression stream init error @1', NULL, NULL);
|
||||
(NULL, NULL, 'mvol.cpp', NULL, 12, 384, NULL, 'Compression stream init error @1', NULL, NULL);
|
||||
(NULL, NULL, 'restore.epp', NULL, 12, 385, NULL, 'Invalid reply from getInfo() when waiting for DB encryption', NULL, NULL);
|
||||
(NULL, NULL, 'restore.epp', NULL, 12, 386, NULL, 'Problems with just created database encryption', NULL, NULL);
|
||||
-- SQLERR
|
||||
(NULL, NULL, NULL, NULL, 13, 1, NULL, 'Firebird error', NULL, NULL);
|
||||
(NULL, NULL, NULL, NULL, 13, 74, NULL, 'Rollback not performed', NULL, NULL);
|
||||
|
@ -891,6 +891,7 @@ set bulk_insert INSERT INTO SYSTEM_ERRORS (SQL_CODE, SQL_CLASS, SQL_SUBCLASS, FA
|
||||
(-901, '54', '000', 0, 882, 'hdr_overflow', NULL, NULL)
|
||||
(-901, '28', '000', 0, 883, 'vld_plugins', NULL, NULL)
|
||||
(-902, '08', '004', 0, 884, 'db_crypt_key', NULL, NULL)
|
||||
(-104, 'HY', '024', 0, 885, 'no_keyholder_plugin', NULL, NULL)
|
||||
-- GFIX
|
||||
(-901, '00', '000', 3, 1, 'gfix_db_name', NULL, NULL)
|
||||
(-901, '00', '000', 3, 2, 'gfix_invalid_sw', NULL, NULL)
|
||||
|
@ -41,7 +41,9 @@
|
||||
#include "../common/classes/timestamp.h"
|
||||
#include "../common/utils_proto.h"
|
||||
#include "../common/classes/MsgPrint.h"
|
||||
#include "../common/classes/GetPlugins.h"
|
||||
#include "../common/StatusArg.h"
|
||||
#include "../common/status.h"
|
||||
#include "../common/os/os_utils.h"
|
||||
#include "../jrd/license.h"
|
||||
|
||||
@ -108,6 +110,32 @@ bool putStringArgument(char**& av, ClumpletWriter& spb, unsigned int tag)
|
||||
return true;
|
||||
}
|
||||
|
||||
// add callback to named KeyHolderPlugin
|
||||
IKeyHolderPlugin* keyHolder = NULL;
|
||||
|
||||
bool putCallback(char**& av, ClumpletWriter&, unsigned int)
|
||||
{
|
||||
if (! *av)
|
||||
return false;
|
||||
|
||||
char* x = *av++;
|
||||
GetPlugins<IKeyHolderPlugin> keyControl(IPluginManager::TYPE_KEY_HOLDER, x);
|
||||
if (!keyControl.hasData())
|
||||
(Firebird::Arg::Gds(isc_no_keyholder_plugin) << x).raise();
|
||||
keyHolder = keyControl.plugin();
|
||||
keyHolder->addRef(); // Leak memory, OK for utility
|
||||
|
||||
FbLocalStatus st;
|
||||
ICryptKeyCallback* cb = keyHolder->chainHandle(&st);
|
||||
check(&st);
|
||||
|
||||
ISC_STATUS_ARRAY status;
|
||||
if (fb_database_crypt_callback(status, cb) != 0)
|
||||
status_exception::raise(status);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// add string tag from file (fetch password)
|
||||
|
||||
bool putFileArgument(char**& av, ClumpletWriter& spb, unsigned int tag)
|
||||
@ -341,6 +369,7 @@ const SvcSwitches attSwitch[] =
|
||||
{"fetch_password", putFileArgument, 0, isc_spb_password, 0},
|
||||
{"trusted_auth", putSingleTag, 0, isc_spb_trusted_auth, 0},
|
||||
{"expected_db", putStringArgument, 0, isc_spb_expected_db, 0},
|
||||
{"key_holder", putCallback, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@ -376,6 +405,10 @@ const SvcSwitches backupOptions[] =
|
||||
{"verbint", putIntArgument, 0, isc_spb_verbint, 0},
|
||||
{"bkp_skip_data", putStringArgument, 0, isc_spb_bkp_skip_data, 0},
|
||||
{"bkp_stat", putStringArgument, 0, isc_spb_bkp_stat, 0 },
|
||||
{"bkp_keyholder", putStringArgument, 0, isc_spb_bkp_keyholder, 0 },
|
||||
{"bkp_keyname", putStringArgument, 0, isc_spb_bkp_keyname, 0 },
|
||||
{"bkp_crypt", putStringArgument, 0, isc_spb_bkp_crypt, 0 },
|
||||
{"bkp_zip", putOption, 0, isc_spb_bkp_zip, 0 },
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@ -401,6 +434,9 @@ const SvcSwitches restoreOptions[] =
|
||||
{"verbint", putIntArgument, 0, isc_spb_verbint, 0},
|
||||
{"res_skip_data", putStringArgument, 0, isc_spb_res_skip_data, 0},
|
||||
{"res_stat", putStringArgument, 0, isc_spb_res_stat, 0 },
|
||||
{"res_keyholder", putStringArgument, 0, isc_spb_res_keyholder, 0 },
|
||||
{"res_keyname", putStringArgument, 0, isc_spb_res_keyname, 0 },
|
||||
{"res_crypt", putStringArgument, 0, isc_spb_res_crypt, 0 },
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@ -961,6 +997,7 @@ struct TypeText
|
||||
{ putBigIntArgument, "int64 value", "456" },
|
||||
{ putOption, NULL, "" },
|
||||
{ putSingleTag, NULL, "" },
|
||||
{ putCallback, "key holder plugin name", NULL },
|
||||
{ NULL, NULL , NULL }
|
||||
};
|
||||
|
||||
@ -1003,6 +1040,9 @@ void testSvc(isc_svc_handle* h, ClumpletWriter& spb, const SvcSwitches* sw)
|
||||
{
|
||||
if (sw->populate == tt->populate)
|
||||
{
|
||||
if (!tt->testArg)
|
||||
break;
|
||||
|
||||
// some tricks to emulate 'char* argv[]'
|
||||
char x[100];
|
||||
strcpy(x, tt->testArg);
|
||||
|
Loading…
Reference in New Issue
Block a user