From c6df8f44876d78c7267d1c36fbf07c15fde306d4 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Mon, 13 Jan 2020 17:30:01 +0300 Subject: [PATCH] Backported CORE-6208: Grant lost in security.db after backup/restore cycle --- src/burp/backup.epp | 63 +++++++++++++++++++++++++++++++++++ src/burp/burp.h | 11 +++++-- src/burp/restore.epp | 71 ++++++++++++++++++++++++++++++++++++++++ src/msgs/facilities2.sql | 2 +- src/msgs/messages2.sql | 26 +++++++++++++++ 5 files changed, 170 insertions(+), 3 deletions(-) diff --git a/src/burp/backup.epp b/src/burp/backup.epp index fd28489253..e8b24dadf5 100644 --- a/src/burp/backup.epp +++ b/src/burp/backup.epp @@ -134,6 +134,7 @@ void write_global_fields(); void write_generators(); void write_sql_roles(); void write_mapping(); +void write_db_creators(); void write_packages(); void write_procedures(); void write_procedure_prms(const GDS_NAME, const GDS_NAME); @@ -406,6 +407,11 @@ int BACKUP_backup(const TEXT* dbb_file, const TEXT* file_name) BURP_verbose(296); // msg 296 writing mapping write_mapping(); + + // Write database creators + BURP_verbose(391); + // msg 391 writing database creators + write_db_creators(); } // Finish up @@ -4153,6 +4159,63 @@ void write_mapping() } +void write_db_creators() +{ +/************************************** + * + * w r i t e _ d b _ c r e a t o r s + * + ************************************** + * + * Functional description + * write a record in the burp file for + * each grant to create database. + * + **************************************/ + isc_req_handle req_handle = 0; + TEXT temp[GDS_NAME_LEN]; + + BurpGlobals* tdgbl = BurpGlobals::getSpecific(); + + if (tdgbl->runtimeODS >= DB_VERSION_DDL12) + { + FOR (REQUEST_HANDLE req_handle) + C IN RDB$DB_CREATORS + + bool fl = true; + + if (!C.RDB$USER_TYPE.NULL) + { + put(tdgbl, rec_db_creator); + fl = false; + put_int32(att_dbc_type, C.RDB$USER_TYPE); + } + + if (!C.RDB$USER.NULL) + { + if (fl) + put(tdgbl, rec_db_creator); + fl = false; + const SSHORT l = PUT_TEXT(att_dbc_user, C.RDB$USER); + + MISC_terminate (C.RDB$USER, temp, l, sizeof(temp)); + BURP_verbose (392, temp); + // msg 392 writing db creator %s + } + + if (!fl) + put(tdgbl, att_end); + + END_FOR; + ON_ERROR + general_on_error(); + END_ERROR; + } + + MISC_release_request_silent(req_handle); +} + + void write_triggers() { /************************************** diff --git a/src/burp/burp.h b/src/burp/burp.h index f09c9c50ff..585151a4ca 100644 --- a/src/burp/burp.h +++ b/src/burp/burp.h @@ -100,7 +100,8 @@ enum rec_type { rec_collation, // Collations rec_sql_roles, // SQL roles rec_mapping, // Mapping of security names - rec_package // Package + rec_package, // Package + rec_db_creator // Database creator }; @@ -601,7 +602,11 @@ enum att_type { att_package_valid_body_flag, att_package_security_class, att_package_owner_name, - att_package_description + att_package_description, + + // Database creators + att_dbc_user = SERIES, + att_dbc_type }; @@ -1044,6 +1049,7 @@ public: isc_req_handle handles_get_security_class_req_handle1; isc_req_handle handles_get_sql_roles_req_handle1; isc_req_handle handles_get_mapping_req_handle1; + isc_req_handle handles_db_creators_req_handle1; isc_req_handle handles_get_trigger_message_req_handle1; isc_req_handle handles_get_trigger_message_req_handle2; isc_req_handle handles_get_trigger_old_req_handle1; @@ -1094,6 +1100,7 @@ public: ULONG verboseInterval; // How many records should be backed up or restored before we show this message bool flag_on_line; // indicates whether we will bring the database on-line bool firstMap; // this is the first time we entered get_mapping() + bool firstDbc; // this is the first time we entered get_db_creators() bool stdIoMode; // stdin or stdout is used as backup file Firebird::AutoPtr unicodeCollation; Firebird::AutoPtr > > skipDataMatcher; diff --git a/src/burp/restore.epp b/src/burp/restore.epp index 08ccfc16bd..57cbd2ef99 100644 --- a/src/burp/restore.epp +++ b/src/burp/restore.epp @@ -135,6 +135,7 @@ bool get_relation(BurpGlobals* tdgbl); bool get_relation_data(BurpGlobals* tdgbl); bool get_sql_roles(BurpGlobals* tdgbl); bool get_mapping(BurpGlobals* tdgbl); +bool get_db_creator(BurpGlobals* tdgbl); bool get_security_class(BurpGlobals* tdgbl); void get_source_blob(BurpGlobals* tdgbl, ISC_QUAD&, bool); USHORT get_text(BurpGlobals* tdgbl, TEXT*, ULONG); @@ -8088,6 +8089,70 @@ bool get_mapping(BurpGlobals* tdgbl) return true; } +bool get_db_creator(BurpGlobals* tdgbl) +{ +/************************************** + * + * g e t _ d b _ c r e a t o r + * + ************************************** + * + * Functional description + * Restore database creators + * + **************************************/ + att_type attribute; + scan_attr_t scan_next_attr; + TEXT temp[GDS_NAME_LEN]; + SSHORT l; + Firebird::string role; + + if (tdgbl->runtimeODS >= DB_VERSION_DDL12) + { + STORE (REQUEST_HANDLE tdgbl->handles_db_creators_req_handle1) + C IN RDB$DB_CREATORS + + C.RDB$USER.NULL = TRUE; + C.RDB$USER_TYPE.NULL = TRUE; + + skip_init(&scan_next_attr); + while (skip_scan(&scan_next_attr), get_attribute(&attribute, tdgbl) != att_end) + { + switch (attribute) + { + case att_dbc_user: + C.RDB$USER.NULL = FALSE; + GET_TEXT(C.RDB$USER); + if (tdgbl->firstDbc) + { + tdgbl->firstDbc = false; + BURP_verbose(394); + // msg 394 restoring database creators + } + BURP_verbose (393, C.RDB$USER); + break; + + case att_dbc_type: + C.RDB$USER_TYPE.NULL = FALSE; + C.RDB$USER_TYPE = (USHORT) get_int32(tdgbl); + break; + + default: + // msg 395 database creator + bad_attribute(scan_next_attr, attribute, 395); + break; + } + } + + END_STORE; + ON_ERROR + general_on_error (); + END_ERROR; + } + + return true; +} + bool is_ascii_name (const TEXT *name, const SSHORT len) { /************************************** @@ -10070,6 +10135,12 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam flag = true; break; + case rec_db_creator: + if (!get_db_creator(tdgbl)) + return false; + flag = true; + break; + default: BURP_error(43, true, SafeArg() << record); // msg 43 don't recognize record type %ld diff --git a/src/msgs/facilities2.sql b/src/msgs/facilities2.sql index 3754cb0bb9..b0e39e7686 100644 --- a/src/msgs/facilities2.sql +++ b/src/msgs/facilities2.sql @@ -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, 309) ('1996-11-07 13:39:40', 'INSTALL', 10, 1) ('1996-11-07 13:38:41', 'TEST', 11, 4) -('2015-07-23 14:20:00', 'GBAK', 12, 370) +('2020-01-13 17:17:30', 'GBAK', 12, 396) ('2015-08-05 12:40:00', 'SQLERR', 13, 1045) ('1996-11-07 13:38:42', 'SQLWARN', 14, 613) ('2006-09-10 03:04:31', 'JRD_BUGCHK', 15, 307) diff --git a/src/msgs/messages2.sql b/src/msgs/messages2.sql index b4d6a7ee65..de53eabe85 100644 --- a/src/msgs/messages2.sql +++ b/src/msgs/messages2.sql @@ -2369,6 +2369,32 @@ ERROR: Backup incomplete', NULL, NULL); ('gbak_wrong_perf', 'api_gbak/gbak', 'burp.cpp', NULL, 12, 367, NULL, 'wrong char "@1" at statistics parameter', NULL, NULL); ('gbak_too_long_perf', 'api_gbak/gbak', 'burp.cpp', NULL, 12, 368, NULL, 'too many chars at statistics parameter', 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); +(NULL, 'get_trigger', 'restore.epp', NULL, 12, 387, NULL, 'Skipped trigger @1 on system table @2', NULL, NULL); +(NULL, 'burp_usage', 'burp.c', NULL, 12, 388, NULL, ' @1INCLUDE(_DATA) backup data of table(s)', NULL, NULL); +(NULL, NULL, 'burp.cpp', NULL, 12, 389, NULL, 'missing regular expression to include tables', NULL, NULL); +(NULL, NULL, 'burp.cpp', NULL, 12, 390, NULL, 'regular expression to include tables was already set', NULL, NULL); +(NULL, 'BACKUP_backup', 'backup.epp', NULL, 12, 391, NULL, 'writing database create grants', NULL, NULL); +(NULL, 'write_db_creators', 'backup.epp', NULL, 12, 392, NULL, ' database create grant for @1', NULL, NULL); +(NULL, 'get_db_creators', 'restore.epp', NULL, 12, 393, NULL, ' restoring database create grant for @1', NULL, NULL); +(NULL, 'get_db_creators', 'restore.epp', NULL, 12, 394, NULL, 'restoring database create grants', NULL, NULL); +(NULL, 'get_db_creators', 'restore.epp', NULL, 12, 395, NULL, 'database create grant', 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);