mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 08:03:04 +01:00
1) Restricted ALTER/DROP permissions to the object owners only. Now this applies to domains, charsets, collations, generators and exceptions. This fixes CORE-304: Metadata security hole - any user can alter/drop generators and exceptions.
2) Opened the gates to implement the standard USAGE privilege (CORE-2884). SQL support and validation logic are still to be developed. 3) Added the grant option to the owner permissions for packages, procedures and functions. 4) Misc cleanup and refactoring.
This commit is contained in:
parent
ea73eb8935
commit
e956e2e6c0
@ -749,7 +749,7 @@ bool DdlNode::deleteSecurityClass(thread_db* tdbb, jrd_tra* transaction,
|
||||
void DdlNode::executeDdlTrigger(thread_db* tdbb, jrd_tra* transaction, DdlTriggerWhen when,
|
||||
int action, const MetaName& objectName, const string& sqlText)
|
||||
{
|
||||
Attachment* attachment = transaction->tra_attachment;
|
||||
Attachment* const attachment = transaction->tra_attachment;
|
||||
|
||||
// do nothing if user doesn't want database triggers
|
||||
if (attachment->att_flags & ATT_no_db_triggers)
|
||||
@ -780,7 +780,8 @@ void DdlNode::executeDdlTrigger(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc
|
||||
void DdlNode::storeGlobalField(thread_db* tdbb, jrd_tra* transaction, MetaName& name,
|
||||
const TypeClause& field, const string& computedSource, const BlrWriter::BlrData& computedValue)
|
||||
{
|
||||
Attachment* attachment = transaction->tra_attachment;
|
||||
Attachment* const attachment = transaction->tra_attachment;
|
||||
const string& user_name = attachment->att_user->usr_user_name;
|
||||
|
||||
const dsql_nod* elements = field.legacyField->fld_ranges;
|
||||
const USHORT dims = elements ? elements->nod_count / 2 : 0;
|
||||
@ -803,6 +804,9 @@ void DdlNode::storeGlobalField(thread_db* tdbb, jrd_tra* transaction, MetaName&
|
||||
FLD.RDB$SYSTEM_FLAG = 0;
|
||||
strcpy(FLD.RDB$FIELD_NAME, name.c_str());
|
||||
|
||||
FLD.RDB$OWNER_NAME.NULL = FALSE;
|
||||
strcpy(FLD.RDB$OWNER_NAME, user_name.c_str());
|
||||
|
||||
FLD.RDB$COMPUTED_SOURCE.NULL = TRUE;
|
||||
FLD.RDB$COMPUTED_BLR.NULL = TRUE;
|
||||
FLD.RDB$DIMENSIONS.NULL = TRUE;
|
||||
@ -842,7 +846,7 @@ void DdlNode::storeGlobalField(thread_db* tdbb, jrd_tra* transaction, MetaName&
|
||||
|
||||
if (elements) // Is the type an array?
|
||||
{
|
||||
AutoCacheRequest request(tdbb, drq_s_fld_dym, DYN_REQUESTS);
|
||||
requestHandle.reset(tdbb, drq_s_fld_dym, DYN_REQUESTS);
|
||||
|
||||
SSHORT position = 0;
|
||||
const dsql_nod* const* ptr = elements->nod_arg;
|
||||
@ -860,7 +864,7 @@ void DdlNode::storeGlobalField(thread_db* tdbb, jrd_tra* transaction, MetaName&
|
||||
Arg::Gds(isc_dsql_arr_range_error));
|
||||
}
|
||||
|
||||
STORE (REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
STORE (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
|
||||
DIM IN RDB$FIELD_DIMENSIONS
|
||||
{
|
||||
strcpy(DIM.RDB$FIELD_NAME, name.c_str());
|
||||
@ -871,6 +875,21 @@ void DdlNode::storeGlobalField(thread_db* tdbb, jrd_tra* transaction, MetaName&
|
||||
END_STORE
|
||||
}
|
||||
}
|
||||
|
||||
requestHandle.reset(tdbb, drq_s_gfld_prvs, DYN_REQUESTS);
|
||||
|
||||
STORE (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
|
||||
X IN RDB$USER_PRIVILEGES
|
||||
{
|
||||
strcpy(X.RDB$RELATION_NAME, name.c_str());
|
||||
strcpy(X.RDB$USER, user_name.c_str());
|
||||
X.RDB$USER_TYPE = obj_user;
|
||||
X.RDB$OBJECT_TYPE = obj_field;
|
||||
X.RDB$PRIVILEGE[0] = USAGE_PRIVILEGE;
|
||||
X.RDB$PRIVILEGE[1] = 0;
|
||||
X.RDB$GRANT_OPTION = 1;
|
||||
}
|
||||
END_STORE
|
||||
}
|
||||
|
||||
|
||||
@ -1031,7 +1050,7 @@ void CommentOnNode::print(string& text, Array<dsql_nod*>& /*nodes*/) const
|
||||
void CommentOnNode::execute(thread_db* tdbb, DsqlCompilerScratch* /*dsqlScratch*/,
|
||||
jrd_tra* transaction)
|
||||
{
|
||||
Attachment* attachment = transaction->tra_attachment;
|
||||
Attachment* const attachment = transaction->tra_attachment;
|
||||
|
||||
const char* tableClause = NULL;
|
||||
const char* columnClause = NULL;
|
||||
@ -1402,7 +1421,8 @@ void CreateAlterFunctionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsql
|
||||
void CreateAlterFunctionNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
jrd_tra* transaction)
|
||||
{
|
||||
Attachment* attachment = transaction->getAttachment();
|
||||
Attachment* const attachment = transaction->getAttachment();
|
||||
const string& user_name = attachment->att_user->usr_user_name;
|
||||
|
||||
if (package.isEmpty())
|
||||
{
|
||||
@ -1450,7 +1470,7 @@ void CreateAlterFunctionNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch
|
||||
FUN.RDB$PRIVATE_FLAG.NULL = TRUE;
|
||||
|
||||
FUN.RDB$OWNER_NAME.NULL = FALSE;
|
||||
strcpy(FUN.RDB$OWNER_NAME, attachment->att_user->usr_user_name.c_str());
|
||||
strcpy(FUN.RDB$OWNER_NAME, user_name.c_str());
|
||||
}
|
||||
}
|
||||
END_STORE
|
||||
@ -1471,22 +1491,20 @@ void CreateAlterFunctionNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch
|
||||
|
||||
if (package.isEmpty())
|
||||
{
|
||||
for (const TEXT* p = ALL_PROC_PRIVILEGES; *p; p++)
|
||||
{
|
||||
requestHandle.reset(tdbb, drq_s_fun_usr_prvs, DYN_REQUESTS);
|
||||
requestHandle.reset(tdbb, drq_s_fun_usr_prvs, DYN_REQUESTS);
|
||||
|
||||
STORE (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
|
||||
X IN RDB$USER_PRIVILEGES
|
||||
{
|
||||
strcpy(X.RDB$RELATION_NAME, name.c_str());
|
||||
strcpy(X.RDB$USER, attachment->att_user->usr_user_name.c_str());
|
||||
X.RDB$USER_TYPE = obj_user;
|
||||
X.RDB$OBJECT_TYPE = obj_udf;
|
||||
X.RDB$PRIVILEGE[0] = *p;
|
||||
X.RDB$PRIVILEGE[1] = 0;
|
||||
}
|
||||
END_STORE
|
||||
STORE (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
|
||||
X IN RDB$USER_PRIVILEGES
|
||||
{
|
||||
strcpy(X.RDB$RELATION_NAME, name.c_str());
|
||||
strcpy(X.RDB$USER, user_name.c_str());
|
||||
X.RDB$USER_TYPE = obj_user;
|
||||
X.RDB$OBJECT_TYPE = obj_udf;
|
||||
X.RDB$PRIVILEGE[0] = EXEC_PRIVILEGE;
|
||||
X.RDB$PRIVILEGE[1] = 0;
|
||||
X.RDB$GRANT_OPTION = 1;
|
||||
}
|
||||
END_STORE
|
||||
}
|
||||
|
||||
executeAlter(tdbb, dsqlScratch, transaction, false, false);
|
||||
@ -1495,7 +1513,7 @@ void CreateAlterFunctionNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch
|
||||
bool CreateAlterFunctionNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
jrd_tra* transaction, bool secondPass, bool runTriggers)
|
||||
{
|
||||
Attachment* attachment = transaction->getAttachment();
|
||||
Attachment* const attachment = transaction->getAttachment();
|
||||
|
||||
bool modified = false;
|
||||
|
||||
@ -1708,7 +1726,7 @@ void CreateAlterFunctionNode::storeArgument(thread_db* tdbb, DsqlCompilerScratch
|
||||
jrd_tra* transaction, unsigned pos, const ParameterClause& parameter,
|
||||
const bid* comment)
|
||||
{
|
||||
Attachment* attachment = transaction->getAttachment();
|
||||
Attachment* const attachment = transaction->getAttachment();
|
||||
|
||||
AutoCacheRequest requestHandle(tdbb, drq_s_func_args2, DYN_REQUESTS);
|
||||
|
||||
@ -2353,7 +2371,8 @@ void CreateAlterProcedureNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsq
|
||||
void CreateAlterProcedureNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
jrd_tra* transaction)
|
||||
{
|
||||
Attachment* attachment = transaction->getAttachment();
|
||||
Attachment* const attachment = transaction->getAttachment();
|
||||
const string& user_name = attachment->att_user->usr_user_name;
|
||||
|
||||
if (package.isEmpty())
|
||||
{
|
||||
@ -2399,7 +2418,7 @@ void CreateAlterProcedureNode::executeCreate(thread_db* tdbb, DsqlCompilerScratc
|
||||
P.RDB$PACKAGE_NAME.NULL = TRUE;
|
||||
P.RDB$PRIVATE_FLAG.NULL = TRUE;
|
||||
|
||||
strcpy(P.RDB$OWNER_NAME, attachment->att_user->usr_user_name.c_str());
|
||||
strcpy(P.RDB$OWNER_NAME, user_name.c_str());
|
||||
}
|
||||
}
|
||||
END_STORE
|
||||
@ -2420,22 +2439,20 @@ void CreateAlterProcedureNode::executeCreate(thread_db* tdbb, DsqlCompilerScratc
|
||||
|
||||
if (package.isEmpty())
|
||||
{
|
||||
for (const TEXT* p = ALL_PROC_PRIVILEGES; *p; p++)
|
||||
{
|
||||
requestHandle.reset(tdbb, drq_s_prc_usr_prvs, DYN_REQUESTS);
|
||||
requestHandle.reset(tdbb, drq_s_prc_usr_prvs, DYN_REQUESTS);
|
||||
|
||||
STORE (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
|
||||
X IN RDB$USER_PRIVILEGES
|
||||
{
|
||||
strcpy(X.RDB$RELATION_NAME, name.c_str());
|
||||
strcpy(X.RDB$USER, attachment->att_user->usr_user_name.c_str());
|
||||
X.RDB$USER_TYPE = obj_user;
|
||||
X.RDB$OBJECT_TYPE = obj_procedure;
|
||||
X.RDB$PRIVILEGE[0] = *p;
|
||||
X.RDB$PRIVILEGE[1] = 0;
|
||||
}
|
||||
END_STORE
|
||||
STORE (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
|
||||
X IN RDB$USER_PRIVILEGES
|
||||
{
|
||||
strcpy(X.RDB$RELATION_NAME, name.c_str());
|
||||
strcpy(X.RDB$USER, user_name.c_str());
|
||||
X.RDB$USER_TYPE = obj_user;
|
||||
X.RDB$OBJECT_TYPE = obj_procedure;
|
||||
X.RDB$PRIVILEGE[0] = EXEC_PRIVILEGE;
|
||||
X.RDB$PRIVILEGE[1] = 0;
|
||||
X.RDB$GRANT_OPTION = 1;
|
||||
}
|
||||
END_STORE
|
||||
}
|
||||
|
||||
executeAlter(tdbb, dsqlScratch, transaction, false, false);
|
||||
@ -2444,7 +2461,7 @@ void CreateAlterProcedureNode::executeCreate(thread_db* tdbb, DsqlCompilerScratc
|
||||
bool CreateAlterProcedureNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
jrd_tra* transaction, bool secondPass, bool runTriggers)
|
||||
{
|
||||
Attachment* attachment = transaction->getAttachment();
|
||||
Attachment* const attachment = transaction->getAttachment();
|
||||
AutoCacheRequest requestHandle(tdbb, drq_m_prcs2, DYN_REQUESTS);
|
||||
bool modified = false;
|
||||
|
||||
@ -2604,7 +2621,7 @@ void CreateAlterProcedureNode::storeParameter(thread_db* tdbb, DsqlCompilerScrat
|
||||
jrd_tra* transaction, USHORT type, unsigned pos, const ParameterClause& parameter,
|
||||
const bid* comment)
|
||||
{
|
||||
Attachment* attachment = transaction->getAttachment();
|
||||
Attachment* const attachment = transaction->getAttachment();
|
||||
|
||||
AutoCacheRequest requestHandle(tdbb, drq_s_prms4, DYN_REQUESTS);
|
||||
|
||||
@ -2968,7 +2985,7 @@ void TriggerDefinition::store(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
bool TriggerDefinition::modify(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
jrd_tra* transaction)
|
||||
{
|
||||
Attachment* attachment = transaction->getAttachment();
|
||||
Attachment* const attachment = transaction->getAttachment();
|
||||
bool modified = false;
|
||||
|
||||
// ASF: Unregistered bug (2.0, 2.1, 2.5, 3.0): CREATE OR ALTER TRIGGER accepts different table
|
||||
@ -3121,7 +3138,7 @@ void CreateAlterTriggerNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlS
|
||||
{
|
||||
fb_assert(create || alter);
|
||||
|
||||
Attachment* attachment = transaction->getAttachment();
|
||||
Attachment* const attachment = transaction->getAttachment();
|
||||
|
||||
if (relationName.isEmpty() && !attachment->locksmith())
|
||||
status_exception::raise(Arg::Gds(isc_adm_task_denied));
|
||||
@ -3422,7 +3439,8 @@ void CreateCollationNode::print(string& text, Array<dsql_nod*>& /*nodes*/) const
|
||||
void CreateCollationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
jrd_tra* transaction)
|
||||
{
|
||||
Attachment* attachment = transaction->tra_attachment;
|
||||
Attachment* const attachment = transaction->tra_attachment;
|
||||
const string& user_name = attachment->att_user->usr_user_name;
|
||||
|
||||
// run all statements under savepoint control
|
||||
AutoSavePoint savePoint(tdbb, transaction);
|
||||
@ -3439,6 +3457,9 @@ void CreateCollationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
|
||||
strcpy(X.RDB$COLLATION_NAME, name.c_str());
|
||||
X.RDB$SYSTEM_FLAG = 0;
|
||||
|
||||
X.RDB$OWNER_NAME.NULL = FALSE;
|
||||
strcpy(X.RDB$OWNER_NAME, user_name.c_str());
|
||||
|
||||
X.RDB$SPECIFIC_ATTRIBUTES.NULL = TRUE;
|
||||
X.RDB$BASE_COLLATION_NAME.NULL = TRUE;
|
||||
|
||||
@ -3572,6 +3593,21 @@ void CreateCollationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
|
||||
}
|
||||
END_STORE
|
||||
|
||||
request.reset(tdbb, drq_s_coll_prvs, DYN_REQUESTS);
|
||||
|
||||
STORE (REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
X IN RDB$USER_PRIVILEGES
|
||||
{
|
||||
strcpy(X.RDB$RELATION_NAME, name.c_str());
|
||||
strcpy(X.RDB$USER, user_name.c_str());
|
||||
X.RDB$USER_TYPE = obj_user;
|
||||
X.RDB$OBJECT_TYPE = obj_collation;
|
||||
X.RDB$PRIVILEGE[0] = USAGE_PRIVILEGE;
|
||||
X.RDB$PRIVILEGE[1] = 0;
|
||||
X.RDB$GRANT_OPTION = 1;
|
||||
}
|
||||
END_STORE
|
||||
|
||||
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER,
|
||||
DDL_TRIGGER_CREATE_COLLATION, name);
|
||||
|
||||
@ -3732,6 +3768,19 @@ void DropCollationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc
|
||||
END_FOR
|
||||
|
||||
ERASE COLL;
|
||||
|
||||
if (!COLL.RDB$SECURITY_CLASS.NULL)
|
||||
deleteSecurityClass(tdbb, transaction, COLL.RDB$SECURITY_CLASS);
|
||||
}
|
||||
END_FOR
|
||||
|
||||
request.reset(tdbb, drq_e_coll_prvs, DYN_REQUESTS);
|
||||
|
||||
FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
PRIV IN RDB$USER_PRIVILEGES WITH PRIV.RDB$RELATION_NAME EQ name.c_str()
|
||||
AND PRIV.RDB$OBJECT_TYPE = obj_collation
|
||||
{
|
||||
ERASE PRIV;
|
||||
}
|
||||
END_FOR
|
||||
|
||||
@ -3764,7 +3813,7 @@ void CreateDomainNode::print(string& text, Array<dsql_nod*>& /*nodes*/) const
|
||||
void CreateDomainNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
jrd_tra* transaction)
|
||||
{
|
||||
Attachment* attachment = transaction->tra_attachment;
|
||||
Attachment* const attachment = transaction->tra_attachment;
|
||||
|
||||
if (fb_utils::implicit_domain(nameType.name.c_str()))
|
||||
{
|
||||
@ -4307,7 +4356,7 @@ void AlterDomainNode::print(string& text, Array<dsql_nod*>& /*nodes*/) const
|
||||
void AlterDomainNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
jrd_tra* transaction)
|
||||
{
|
||||
Attachment* attachment = transaction->tra_attachment;
|
||||
Attachment* const attachment = transaction->tra_attachment;
|
||||
|
||||
// run all statements under savepoint control
|
||||
AutoSavePoint savePoint(tdbb, transaction);
|
||||
@ -4639,10 +4688,23 @@ void DropDomainNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
|
||||
ERASE X;
|
||||
|
||||
if (!X.RDB$SECURITY_CLASS.NULL)
|
||||
deleteSecurityClass(tdbb, transaction, X.RDB$SECURITY_CLASS);
|
||||
|
||||
found = true;
|
||||
}
|
||||
END_FOR
|
||||
|
||||
request.reset(tdbb, drq_e_gfld_prvs, DYN_REQUESTS);
|
||||
|
||||
FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
PRIV IN RDB$USER_PRIVILEGES WITH PRIV.RDB$RELATION_NAME EQ name.c_str()
|
||||
AND PRIV.RDB$OBJECT_TYPE = obj_field
|
||||
{
|
||||
ERASE PRIV;
|
||||
}
|
||||
END_FOR
|
||||
|
||||
if (found)
|
||||
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_DROP_DOMAIN, name);
|
||||
else
|
||||
@ -4755,6 +4817,9 @@ void CreateAlterExceptionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsq
|
||||
void CreateAlterExceptionNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
jrd_tra* transaction)
|
||||
{
|
||||
Attachment* const attachment = transaction->getAttachment();
|
||||
const string& user_name = attachment->att_user->usr_user_name;
|
||||
|
||||
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
|
||||
DDL_TRIGGER_CREATE_EXCEPTION, name);
|
||||
|
||||
@ -4780,6 +4845,9 @@ void CreateAlterExceptionNode::executeCreate(thread_db* tdbb, DsqlCompilerScratc
|
||||
X.RDB$SYSTEM_FLAG = 0;
|
||||
strcpy(X.RDB$EXCEPTION_NAME, name.c_str());
|
||||
|
||||
X.RDB$OWNER_NAME.NULL = FALSE;
|
||||
strcpy(X.RDB$OWNER_NAME, user_name.c_str());
|
||||
|
||||
fb_assert(message.length() < sizeof(X.RDB$MESSAGE));
|
||||
strcpy(X.RDB$MESSAGE, message.c_str());
|
||||
}
|
||||
@ -4799,6 +4867,21 @@ void CreateAlterExceptionNode::executeCreate(thread_db* tdbb, DsqlCompilerScratc
|
||||
}
|
||||
}
|
||||
|
||||
request.reset(tdbb, drq_s_xcp_prvs, DYN_REQUESTS);
|
||||
|
||||
STORE (REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
X IN RDB$USER_PRIVILEGES
|
||||
{
|
||||
strcpy(X.RDB$RELATION_NAME, name.c_str());
|
||||
strcpy(X.RDB$USER, user_name.c_str());
|
||||
X.RDB$USER_TYPE = obj_user;
|
||||
X.RDB$OBJECT_TYPE = obj_exception;
|
||||
X.RDB$PRIVILEGE[0] = USAGE_PRIVILEGE;
|
||||
X.RDB$PRIVILEGE[1] = 0;
|
||||
X.RDB$GRANT_OPTION = 1;
|
||||
}
|
||||
END_STORE
|
||||
|
||||
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_CREATE_EXCEPTION, name);
|
||||
}
|
||||
|
||||
@ -4858,10 +4941,24 @@ void DropExceptionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc
|
||||
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
|
||||
DDL_TRIGGER_DROP_EXCEPTION, name);
|
||||
ERASE X;
|
||||
|
||||
if (!X.RDB$SECURITY_CLASS.NULL)
|
||||
deleteSecurityClass(tdbb, transaction, X.RDB$SECURITY_CLASS);
|
||||
|
||||
found = true;
|
||||
}
|
||||
END_FOR
|
||||
|
||||
request.reset(tdbb, drq_e_xcp_prvs, DYN_REQUESTS);
|
||||
|
||||
FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
PRIV IN RDB$USER_PRIVILEGES WITH PRIV.RDB$RELATION_NAME EQ name.c_str()
|
||||
AND PRIV.RDB$OBJECT_TYPE = obj_exception
|
||||
{
|
||||
ERASE PRIV;
|
||||
}
|
||||
END_FOR
|
||||
|
||||
if (found)
|
||||
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_DROP_EXCEPTION, name);
|
||||
else if (!silent)
|
||||
@ -4888,14 +4985,22 @@ void CreateSequenceNode::print(string& text, Array<dsql_nod*>& /*nodes*/) const
|
||||
void CreateSequenceNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
jrd_tra* transaction)
|
||||
{
|
||||
// run all statements under savepoint control
|
||||
AutoSavePoint savePoint(tdbb, transaction);
|
||||
|
||||
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_CREATE_SEQUENCE, name);
|
||||
store(tdbb, transaction, name, fb_sysflag_user);
|
||||
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_CREATE_SEQUENCE, name);
|
||||
|
||||
savePoint.release(); // everything is ok
|
||||
}
|
||||
|
||||
void CreateSequenceNode::store(thread_db* tdbb, jrd_tra* transaction, const MetaName& name,
|
||||
fb_sysflag sysFlag)
|
||||
{
|
||||
Attachment* const attachment = transaction->tra_attachment;
|
||||
const string& user_name = attachment->att_user->usr_user_name;
|
||||
|
||||
DYN_UTIL_check_unique_name(tdbb, transaction, name, obj_generator);
|
||||
|
||||
AutoCacheRequest request(tdbb, drq_s_gens, DYN_REQUESTS);
|
||||
@ -4917,6 +5022,9 @@ void CreateSequenceNode::store(thread_db* tdbb, jrd_tra* transaction, const Meta
|
||||
X.RDB$GENERATOR_ID = id;
|
||||
X.RDB$SYSTEM_FLAG = (SSHORT) sysFlag;
|
||||
strcpy(X.RDB$GENERATOR_NAME, name.c_str());
|
||||
|
||||
X.RDB$OWNER_NAME.NULL = FALSE;
|
||||
strcpy(X.RDB$OWNER_NAME, user_name.c_str());
|
||||
}
|
||||
END_STORE
|
||||
|
||||
@ -4933,6 +5041,21 @@ void CreateSequenceNode::store(thread_db* tdbb, jrd_tra* transaction, const Meta
|
||||
fb_utils::init_status(tdbb->tdbb_status_vector);
|
||||
}
|
||||
}
|
||||
|
||||
request.reset(tdbb, drq_s_gen_prvs, DYN_REQUESTS);
|
||||
|
||||
STORE (REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
X IN RDB$USER_PRIVILEGES
|
||||
{
|
||||
strcpy(X.RDB$RELATION_NAME, name.c_str());
|
||||
strcpy(X.RDB$USER, user_name.c_str());
|
||||
X.RDB$USER_TYPE = obj_user;
|
||||
X.RDB$OBJECT_TYPE = obj_generator;
|
||||
X.RDB$PRIVILEGE[0] = USAGE_PRIVILEGE;
|
||||
X.RDB$PRIVILEGE[1] = 0;
|
||||
X.RDB$GRANT_OPTION = 1;
|
||||
}
|
||||
END_STORE
|
||||
}
|
||||
|
||||
|
||||
@ -4948,6 +5071,9 @@ void DropSequenceNode::print(string& text, Array<dsql_nod*>& nodes) const
|
||||
|
||||
void DropSequenceNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction)
|
||||
{
|
||||
// run all statements under savepoint control
|
||||
AutoSavePoint savePoint(tdbb, transaction);
|
||||
|
||||
AutoCacheRequest request(tdbb, drq_e_gens, DYN_REQUESTS);
|
||||
bool found = false;
|
||||
|
||||
@ -4965,14 +5091,30 @@ void DropSequenceNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch
|
||||
DDL_TRIGGER_DROP_SEQUENCE, name);
|
||||
|
||||
ERASE GEN;
|
||||
|
||||
if (!GEN.RDB$SECURITY_CLASS.NULL)
|
||||
deleteSecurityClass(tdbb, transaction, GEN.RDB$SECURITY_CLASS);
|
||||
|
||||
found = true;
|
||||
}
|
||||
END_FOR
|
||||
|
||||
request.reset(tdbb, drq_e_gen_prvs, DYN_REQUESTS);
|
||||
|
||||
FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
PRIV IN RDB$USER_PRIVILEGES WITH PRIV.RDB$RELATION_NAME EQ name.c_str()
|
||||
AND PRIV.RDB$OBJECT_TYPE = obj_generator
|
||||
{
|
||||
ERASE PRIV;
|
||||
}
|
||||
END_FOR
|
||||
|
||||
if (found)
|
||||
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_DROP_SEQUENCE, name);
|
||||
else if (!silent)
|
||||
status_exception::raise(Arg::Gds(isc_gennotdef) << Arg::Str(name));
|
||||
|
||||
savePoint.release(); // everything is ok
|
||||
}
|
||||
|
||||
|
||||
@ -5074,7 +5216,7 @@ void RelationNode::FieldDefinition::modify(thread_db* tdbb, jrd_tra* transaction
|
||||
|
||||
void RelationNode::FieldDefinition::store(thread_db* tdbb, jrd_tra* transaction)
|
||||
{
|
||||
Attachment* attachment = transaction->tra_attachment;
|
||||
Attachment* const attachment = transaction->tra_attachment;
|
||||
|
||||
AutoCacheRequest request(tdbb, drq_s_lfields, DYN_REQUESTS);
|
||||
|
||||
@ -5328,7 +5470,8 @@ void RelationNode::deleteLocalField(thread_db* tdbb, jrd_tra* transaction,
|
||||
|
||||
void RelationNode::storePrivileges(thread_db* tdbb, jrd_tra* transaction)
|
||||
{
|
||||
Attachment* attachment = transaction->tra_attachment;
|
||||
Attachment* const attachment = transaction->tra_attachment;
|
||||
const string& user_name = attachment->att_user->usr_user_name;
|
||||
|
||||
AutoCacheRequest request(tdbb, drq_s_usr_prvs, DYN_REQUESTS);
|
||||
|
||||
@ -5338,7 +5481,7 @@ void RelationNode::storePrivileges(thread_db* tdbb, jrd_tra* transaction)
|
||||
X IN RDB$USER_PRIVILEGES
|
||||
{
|
||||
strcpy(X.RDB$RELATION_NAME, name.c_str());
|
||||
strcpy(X.RDB$USER, attachment->att_user->usr_user_name.c_str());
|
||||
strcpy(X.RDB$USER, user_name.c_str());
|
||||
X.RDB$USER_TYPE = obj_user;
|
||||
X.RDB$OBJECT_TYPE = obj_relation;
|
||||
X.RDB$PRIVILEGE[0] = *p;
|
||||
@ -6909,7 +7052,7 @@ void AlterRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc
|
||||
void AlterRelationNode::modifyField(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
jrd_tra* transaction, const dsql_nod* element)
|
||||
{
|
||||
Attachment* attachment = transaction->tra_attachment;
|
||||
Attachment* const attachment = transaction->tra_attachment;
|
||||
|
||||
dsql_fld* field = (dsql_fld*) element->nod_arg[Dsql::e_mod_fld_type_field];
|
||||
|
||||
@ -7529,7 +7672,8 @@ DdlNode* CreateAlterViewNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||
void CreateAlterViewNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
jrd_tra* transaction)
|
||||
{
|
||||
Attachment* attachment = transaction->tra_attachment;
|
||||
Attachment* const attachment = transaction->tra_attachment;
|
||||
const string& user_name = attachment->att_user->usr_user_name;
|
||||
|
||||
const dsql_rel* modifyingView = NULL;
|
||||
|
||||
@ -7702,7 +7846,7 @@ void CreateAlterViewNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
|
||||
// so I included a call to strip trailing blanks.
|
||||
fb_utils::exact_name_limit(PREL.RDB$OWNER_NAME, sizeof(PREL.RDB$OWNER_NAME));
|
||||
|
||||
if (attachment->att_user->usr_user_name != PREL.RDB$OWNER_NAME)
|
||||
if (user_name != PREL.RDB$OWNER_NAME)
|
||||
{
|
||||
SecurityClass::flags_t priv;
|
||||
|
||||
@ -8861,7 +9005,7 @@ void CreateIndexNode::print(string& text, Array<dsql_nod*>& /*nodes*/) const
|
||||
// Define an index.
|
||||
void CreateIndexNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction)
|
||||
{
|
||||
Attachment* attachment = transaction->tra_attachment;
|
||||
Attachment* const attachment = transaction->tra_attachment;
|
||||
|
||||
// run all statements under savepoint control
|
||||
AutoSavePoint savePoint(tdbb, transaction);
|
||||
@ -9556,7 +9700,7 @@ void AlterDatabaseNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc
|
||||
// run all statements under savepoint control
|
||||
AutoSavePoint savePoint(tdbb, transaction);
|
||||
|
||||
Attachment* attachment = transaction->tra_attachment;
|
||||
Attachment* const attachment = transaction->tra_attachment;
|
||||
SLONG dbAlloc = PageSpace::maxAlloc(tdbb->getDatabase());
|
||||
SLONG start = create ? createLength + 1 : 0;
|
||||
AutoCacheRequest request(tdbb, drq_m_database, DYN_REQUESTS);
|
||||
|
@ -497,6 +497,7 @@ void CreateAlterPackageNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch*
|
||||
jrd_tra* transaction)
|
||||
{
|
||||
Attachment* attachment = transaction->getAttachment();
|
||||
const string& user_name = attachment->att_user->usr_user_name;
|
||||
|
||||
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE,
|
||||
DDL_TRIGGER_CREATE_PACKAGE, name);
|
||||
@ -513,29 +514,27 @@ void CreateAlterPackageNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch*
|
||||
PKG.RDB$SYSTEM_FLAG = 0;
|
||||
|
||||
PKG.RDB$OWNER_NAME.NULL = FALSE;
|
||||
strcpy(PKG.RDB$OWNER_NAME, attachment->att_user->usr_user_name.c_str());
|
||||
strcpy(PKG.RDB$OWNER_NAME, user_name.c_str());
|
||||
|
||||
PKG.RDB$PACKAGE_HEADER_SOURCE.NULL = FALSE;
|
||||
attachment->storeMetaDataBlob(tdbb, transaction, &PKG.RDB$PACKAGE_HEADER_SOURCE, source);
|
||||
}
|
||||
END_STORE
|
||||
|
||||
for (const TEXT* p = ALL_PROC_PRIVILEGES; *p; p++)
|
||||
{
|
||||
requestHandle.reset(tdbb, drq_s_pkg_usr_prvs, DYN_REQUESTS);
|
||||
requestHandle.reset(tdbb, drq_s_pkg_usr_prvs, DYN_REQUESTS);
|
||||
|
||||
STORE (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
|
||||
X IN RDB$USER_PRIVILEGES
|
||||
{
|
||||
strcpy(X.RDB$RELATION_NAME, name.c_str());
|
||||
strcpy(X.RDB$USER, attachment->att_user->usr_user_name.c_str());
|
||||
X.RDB$USER_TYPE = obj_user;
|
||||
X.RDB$OBJECT_TYPE = obj_package_header;
|
||||
X.RDB$PRIVILEGE[0] = *p;
|
||||
X.RDB$PRIVILEGE[1] = 0;
|
||||
}
|
||||
END_STORE;
|
||||
STORE (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
|
||||
X IN RDB$USER_PRIVILEGES
|
||||
{
|
||||
strcpy(X.RDB$RELATION_NAME, name.c_str());
|
||||
strcpy(X.RDB$USER, user_name.c_str());
|
||||
X.RDB$USER_TYPE = obj_user;
|
||||
X.RDB$OBJECT_TYPE = obj_package_header;
|
||||
X.RDB$PRIVILEGE[0] = EXEC_PRIVILEGE;
|
||||
X.RDB$PRIVILEGE[1] = 0;
|
||||
X.RDB$GRANT_OPTION = 1;
|
||||
}
|
||||
END_STORE;
|
||||
|
||||
owner = attachment->att_user->usr_user_name;
|
||||
|
||||
|
@ -634,29 +634,6 @@ SSHORT CVT2_blob_compare(const dsc* arg1, const dsc* arg2)
|
||||
}
|
||||
|
||||
|
||||
void CVT2_get_name(const dsc* desc, TEXT* string)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* C V T 2 _ g e t _ n a m e
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Get a name (max length 31, NULL terminated) from a descriptor.
|
||||
*
|
||||
**************************************/
|
||||
VaryStr<MAX_SQL_IDENTIFIER_SIZE> temp; // 31 bytes + 1 NULL
|
||||
const char* p;
|
||||
|
||||
const USHORT length = CVT_make_string(desc, ttype_metadata, &p, &temp, sizeof(temp), ERR_post);
|
||||
|
||||
memcpy(string, p, length);
|
||||
string[length] = 0;
|
||||
fb_utils::exact_name(string);
|
||||
}
|
||||
|
||||
|
||||
USHORT CVT2_make_string2(const dsc* desc, USHORT to_interp, UCHAR** address, Jrd::MoveBuffer& temp)
|
||||
{
|
||||
/**************************************
|
||||
|
@ -28,7 +28,6 @@
|
||||
|
||||
SSHORT CVT2_compare(const dsc*, const dsc*);
|
||||
SSHORT CVT2_blob_compare(const dsc*, const dsc*);
|
||||
void CVT2_get_name(const dsc*, TEXT*);
|
||||
USHORT CVT2_make_string2(const dsc*, USHORT, UCHAR**, Jrd::MoveBuffer&);
|
||||
|
||||
#endif // JRD_CVT2_PROTO_H
|
||||
|
@ -231,6 +231,14 @@ enum drq_type_t
|
||||
drq_m_fld2, // alter domain
|
||||
drq_c_unq_nam2, // check for unique field names
|
||||
drq_s_rels2, // store relations
|
||||
drq_e_coll_prvs, // erase collation privileges
|
||||
drq_e_xcp_prvs, // erase exception privileges
|
||||
drq_e_gen_prvs, // erase generator privileges
|
||||
drq_e_gfld_prvs, // erase domain privileges
|
||||
drq_s_coll_prvs, // store collation privileges
|
||||
drq_s_xcp_prvs, // store exception privileges
|
||||
drq_s_gen_prvs, // store generator privileges
|
||||
drq_s_gfld_prvs, // store domain privileges
|
||||
|
||||
drq_MAX
|
||||
};
|
||||
|
@ -31,7 +31,9 @@
|
||||
#include "../common/dsc.h"
|
||||
|
||||
const char* const ALL_PRIVILEGES = "SIUDR"; // all applicable grant/revoke privileges
|
||||
const char* const ALL_PROC_PRIVILEGES = "X"; // all applicable grant/revoke privileges for a procedure
|
||||
const char EXEC_PRIVILEGE = 'X'; // execute privilege for procedures, functions and packages
|
||||
const char USAGE_PRIVILEGE = 'S'; // usage privilege, currently equal to the select one
|
||||
|
||||
const int DYN_MSG_FAC = 8;
|
||||
|
||||
|
||||
|
@ -60,9 +60,7 @@ using namespace Jrd;
|
||||
|
||||
// privileges given to the owner of a relation
|
||||
|
||||
const SecurityClass::flags_t OWNER_PRIVS = SCL_control | SCL_read | SCL_write | SCL_delete | SCL_protect;
|
||||
//const SecurityClass::flags_t VIEW_PRIVS = SCL_read | SCL_write | SCL_delete;
|
||||
//const ULONG ACL_BUFFER_SIZE = 4096;
|
||||
const SecurityClass::flags_t OWNER_PRIVS = SCL_control | SCL_read | SCL_write | SCL_delete | SCL_protect;
|
||||
|
||||
inline void CHECK_AND_MOVE(Acl& to, UCHAR from)
|
||||
{
|
||||
@ -73,11 +71,6 @@ DATABASE DB = STATIC "yachts.lnk";
|
||||
|
||||
static void define_default_class(thread_db*, const TEXT*, Firebird::MetaName&, const Acl&,
|
||||
jrd_tra*);
|
||||
#ifdef NOT_USED_OR_REPLACED
|
||||
static void delete_security_class(thread_db*, const TEXT*);
|
||||
static void grant_views(TEXT**, SecurityClass::flags_t);
|
||||
static void purge_default_class(TEXT*, SSHORT);
|
||||
#endif
|
||||
static void finish_security_class(Acl&, SecurityClass::flags_t);
|
||||
static void get_object_info(thread_db*, const TEXT*, SSHORT,
|
||||
Firebird::MetaName&, Firebird::MetaName&, Firebird::MetaName&, bool&);
|
||||
@ -112,7 +105,6 @@ void GRANT_privileges(thread_db* tdbb, const Firebird::string& name, USHORT id,
|
||||
|
||||
bool restrct = false;
|
||||
|
||||
//Database* dbb = tdbb->getDatabase();
|
||||
Firebird::MetaName s_class, owner, default_class;
|
||||
bool view; // unused after being retrieved.
|
||||
get_object_info(tdbb, name.c_str(), id, owner, s_class, default_class, view);
|
||||
@ -137,7 +129,7 @@ void GRANT_privileges(thread_db* tdbb, const Firebird::string& name, USHORT id,
|
||||
|
||||
grant_user(acl, owner, obj_user, priv);
|
||||
|
||||
// Pick up any relation-level privileges
|
||||
// Pick up core privileges
|
||||
|
||||
const SecurityClass::flags_t public_priv = get_public_privs(tdbb, name.c_str(), id);
|
||||
get_user_privs(tdbb, acl, name.c_str(), id, owner, public_priv);
|
||||
@ -155,12 +147,6 @@ void GRANT_privileges(thread_db* tdbb, const Firebird::string& name, USHORT id,
|
||||
save_field_privileges(tdbb, acl, name.c_str(), owner, public_priv,
|
||||
transaction);
|
||||
|
||||
// SQL tables don't need the 'all priviliges to all views' acl anymore.
|
||||
// This special acl was only generated for SQL.
|
||||
#ifdef NOT_USED_OR_REPLACED
|
||||
// grant_views (&acl, VIEW_PRIVS);
|
||||
#endif
|
||||
|
||||
// finish off and store the security class for the relation
|
||||
|
||||
finish_security_class(acl, aggregate_public);
|
||||
@ -394,6 +380,81 @@ static void get_object_info(thread_db* tdbb,
|
||||
}
|
||||
END_FOR
|
||||
}
|
||||
else if (obj_type == obj_charset)
|
||||
{
|
||||
AutoCacheRequest request(tdbb, irq_grant12, IRQ_REQUESTS);
|
||||
|
||||
FOR(REQUEST_HANDLE request)
|
||||
CS IN RDB$CHARACTER_SETS WITH
|
||||
CS.RDB$CHARACTER_SET_NAME EQ object_name
|
||||
{
|
||||
s_class = CS.RDB$SECURITY_CLASS;
|
||||
default_class = "";
|
||||
owner = CS.RDB$OWNER_NAME;
|
||||
view = false;
|
||||
}
|
||||
END_FOR
|
||||
}
|
||||
else if (obj_type == obj_collation)
|
||||
{
|
||||
AutoCacheRequest request(tdbb, irq_grant13, IRQ_REQUESTS);
|
||||
|
||||
FOR(REQUEST_HANDLE request)
|
||||
COLL IN RDB$COLLATIONS WITH
|
||||
COLL.RDB$COLLATION_NAME EQ object_name
|
||||
{
|
||||
s_class = COLL.RDB$SECURITY_CLASS;
|
||||
default_class = "";
|
||||
owner = COLL.RDB$OWNER_NAME;
|
||||
view = false;
|
||||
}
|
||||
END_FOR
|
||||
}
|
||||
else if (obj_type == obj_exception)
|
||||
{
|
||||
AutoCacheRequest request(tdbb, irq_grant14, IRQ_REQUESTS);
|
||||
|
||||
FOR(REQUEST_HANDLE request)
|
||||
XCP IN RDB$EXCEPTIONS WITH
|
||||
XCP.RDB$EXCEPTION_NAME EQ object_name
|
||||
{
|
||||
s_class = XCP.RDB$SECURITY_CLASS;
|
||||
default_class = "";
|
||||
owner = XCP.RDB$OWNER_NAME;
|
||||
view = false;
|
||||
}
|
||||
END_FOR
|
||||
}
|
||||
else if (obj_type == obj_generator)
|
||||
{
|
||||
AutoCacheRequest request(tdbb, irq_grant15, IRQ_REQUESTS);
|
||||
|
||||
FOR(REQUEST_HANDLE request)
|
||||
GEN IN RDB$GENERATORS WITH
|
||||
GEN.RDB$GENERATOR_NAME EQ object_name
|
||||
{
|
||||
s_class = GEN.RDB$SECURITY_CLASS;
|
||||
default_class = "";
|
||||
owner = GEN.RDB$OWNER_NAME;
|
||||
view = false;
|
||||
}
|
||||
END_FOR
|
||||
}
|
||||
else if (obj_type == obj_field)
|
||||
{
|
||||
AutoCacheRequest request(tdbb, irq_grant16, IRQ_REQUESTS);
|
||||
|
||||
FOR(REQUEST_HANDLE request)
|
||||
FLD IN RDB$FIELDS WITH
|
||||
FLD.RDB$FIELD_NAME EQ object_name
|
||||
{
|
||||
s_class = FLD.RDB$SECURITY_CLASS;
|
||||
default_class = "";
|
||||
owner = FLD.RDB$OWNER_NAME;
|
||||
view = false;
|
||||
}
|
||||
END_FOR
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -524,97 +585,6 @@ static void grant_user(Acl& acl,
|
||||
}
|
||||
|
||||
|
||||
#ifdef NOT_USED_OR_REPLACED
|
||||
static void delete_security_class( thread_db* tdbb, const TEXT* s_class)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* d e l e t e _ s e c u r i t y _ c l a s s
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Delete a security class.
|
||||
*
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
Database* dbb = tdbb->getDatabase();
|
||||
|
||||
AutoRequest handle;
|
||||
|
||||
FOR(REQUEST_HANDLE handle TRANSACTION_HANDLE transaction)
|
||||
CLS IN RDB$SECURITY_CLASSES
|
||||
WITH CLS.RDB$SECURITY_CLASS EQ s_class
|
||||
{
|
||||
ERASE CLS;
|
||||
}
|
||||
END_FOR
|
||||
}
|
||||
|
||||
|
||||
static void grant_views(Acl& acl, SecurityClass::flags_t privs)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* g r a n t _ v i e w s
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Grant privileges to all views.
|
||||
*
|
||||
**************************************/
|
||||
CHECK_AND_MOVE(acl, ACL_id_list);
|
||||
CHECK_AND_MOVE(acl, id_views);
|
||||
CHECK_AND_MOVE(acl, 0);
|
||||
SCL_move_priv(privs, acl);
|
||||
}
|
||||
|
||||
|
||||
static void purge_default_class( TEXT* object_name, SSHORT obj_type)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* p u r g e _ d e f a u l t _ c l a s s
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Get rid of any previously defined
|
||||
* default security class for this relation.
|
||||
*
|
||||
**************************************/
|
||||
thread_db* tdbb = JRD_get_thread_data();
|
||||
Database* dbb = tdbb->getDatabase();
|
||||
|
||||
AutoCacheRequest request(tdbb, irq_grant8, IRQ_REQUESTS);
|
||||
|
||||
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
REL IN RDB$RELATIONS
|
||||
WITH REL.RDB$RELATION_NAME EQ object_name
|
||||
AND REL.RDB$DEFAULT_CLASS NOT MISSING
|
||||
{
|
||||
fb_utils::exact_name_limit(REL.RDB$DEFAULT_CLASS, sizeof(REL.RDB$DEFAULT_CLASS));
|
||||
delete_security_class(tdbb, REL.RDB$DEFAULT_CLASS);
|
||||
|
||||
MODIFY REL USING
|
||||
REL.RDB$DEFAULT_CLASS.NULL = TRUE;
|
||||
END_MODIFY
|
||||
}
|
||||
END_FOR
|
||||
|
||||
dsc desc;
|
||||
desc.dsc_dtype = dtype_text;
|
||||
desc.dsc_sub_type = 0;
|
||||
desc.dsc_scale = 0;
|
||||
desc.dsc_ttype() = ttype_metadata;
|
||||
desc.dsc_address = (UCHAR *) object_name;
|
||||
desc.dsc_length = strlen(object_name);
|
||||
DFW_post_work(transaction, dfw_scan_relation, &desc, 0);
|
||||
}
|
||||
#endif // NOT_USED_OR_REPLACED
|
||||
|
||||
|
||||
static SecurityClass::flags_t save_field_privileges(thread_db* tdbb,
|
||||
Acl& relation_acl,
|
||||
const TEXT* relation_name,
|
||||
|
219
src/jrd/ini.epp
219
src/jrd/ini.epp
@ -55,6 +55,7 @@
|
||||
#include "../jrd/met_proto.h"
|
||||
#include "../jrd/obj.h"
|
||||
#include "../jrd/acl.h"
|
||||
#include "../jrd/dyn.h"
|
||||
#include "../jrd/irq.h"
|
||||
#include "../jrd/IntlManager.h"
|
||||
#include "../jrd/PreparedStatement.h"
|
||||
@ -70,11 +71,14 @@ const int FB_MAX_ACL_SIZE = 4096;
|
||||
|
||||
|
||||
static void add_index_set(thread_db*);
|
||||
static void add_security_to_sys_rel(thread_db*, const Firebird::MetaName&,
|
||||
const TEXT*, const UCHAR*, const SSHORT, const bool);
|
||||
static void store_generator(thread_db*, const gen*, AutoRequest&);
|
||||
static void store_global_field(thread_db*, const gfld*, AutoRequest&);
|
||||
static void store_intlnames(thread_db*);
|
||||
static void add_security_to_sys_obj(thread_db*, const MetaName&,
|
||||
USHORT, const MetaName&,
|
||||
USHORT = 0, const UCHAR* = NULL);
|
||||
static void add_security_to_sys_rel(thread_db*, const MetaName&,
|
||||
const TEXT*, const USHORT, const UCHAR*, const bool);
|
||||
static void store_generator(thread_db*, const gen*, AutoRequest&, const MetaName&);
|
||||
static void store_global_field(thread_db*, const gfld*, AutoRequest&, const MetaName&);
|
||||
static void store_intlnames(thread_db*, const MetaName&);
|
||||
static void store_message(thread_db*, const trigger_msg*, AutoRequest&);
|
||||
static void store_relation_field(thread_db*, const int*, const int*, int, AutoRequest&);
|
||||
static void store_trigger(thread_db*, const jrd_trg*, AutoRequest&);
|
||||
@ -242,7 +246,7 @@ static const trigger_msg trigger_messages[] =
|
||||
|
||||
|
||||
|
||||
void INI_format(const TEXT* owner, const TEXT* charset)
|
||||
void INI_format(const MetaName& owner, const MetaName& charset)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -259,13 +263,14 @@ void INI_format(const TEXT* owner, const TEXT* charset)
|
||||
thread_db* tdbb = JRD_get_thread_data();
|
||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
|
||||
fb_assert(owner.hasData());
|
||||
|
||||
// Uppercase owner name
|
||||
MetaName ownerName(owner ? owner : "");
|
||||
MetaName ownerName(owner);
|
||||
ownerName.upper7();
|
||||
|
||||
// Uppercase charset name
|
||||
MetaName rdbCharSetName(charset && strlen(charset) != 0 ?
|
||||
charset : DEFAULT_DB_CHARACTER_SET_NAME);
|
||||
MetaName rdbCharSetName(charset.hasData() ? charset.c_str() : DEFAULT_DB_CHARACTER_SET_NAME);
|
||||
rdbCharSetName.upper7();
|
||||
|
||||
const int* fld;
|
||||
@ -284,7 +289,7 @@ void INI_format(const TEXT* owner, const TEXT* charset)
|
||||
}
|
||||
|
||||
jrd_tra* transaction = attachment->getSysTransaction();
|
||||
|
||||
|
||||
// Store RELATIONS and RELATION_FIELDS
|
||||
|
||||
SLONG rdbRelationId;
|
||||
@ -323,7 +328,7 @@ void INI_format(const TEXT* owner, const TEXT* charset)
|
||||
// Store global FIELDS
|
||||
|
||||
for (const gfld* gfield = gfields; gfield->gfld_name; gfield++)
|
||||
store_global_field(tdbb, gfield, handle1);
|
||||
store_global_field(tdbb, gfield, handle1, ownerName);
|
||||
|
||||
// Store DATABASE record
|
||||
|
||||
@ -405,14 +410,14 @@ void INI_format(const TEXT* owner, const TEXT* charset)
|
||||
}
|
||||
|
||||
// Store symbols for international character sets & collations
|
||||
store_intlnames(tdbb);
|
||||
store_intlnames(tdbb, ownerName);
|
||||
|
||||
// Create generators to be used by system triggers
|
||||
|
||||
handle1.reset();
|
||||
|
||||
for (const gen* generator = generators; generator->gen_name; generator++)
|
||||
store_generator(tdbb, generator, handle1);
|
||||
store_generator(tdbb, generator, handle1, ownerName);
|
||||
|
||||
// Adjust the value of the hidden generator RDB$GENERATORS
|
||||
DPM_gen_id(tdbb, 0, true, FB_NELEM(generators) - 1);
|
||||
@ -433,7 +438,7 @@ void INI_format(const TEXT* owner, const TEXT* charset)
|
||||
|
||||
DFW_perform_system_work(tdbb);
|
||||
|
||||
// Add security on RDB$ROLES system table
|
||||
// Add security for the non-relation system metadata objects
|
||||
|
||||
UCHAR buffer[FB_MAX_ACL_SIZE];
|
||||
UCHAR* acl = buffer;
|
||||
@ -442,16 +447,11 @@ void INI_format(const TEXT* owner, const TEXT* charset)
|
||||
*acl++ = id_person;
|
||||
|
||||
USHORT length = ownerName.length();
|
||||
if (length > MAX_UCHAR)
|
||||
length = MAX_UCHAR;
|
||||
fb_assert(length <= MAX_UCHAR);
|
||||
*acl++ = (UCHAR) length;
|
||||
memcpy(acl, ownerName.c_str(), length);
|
||||
acl += length;
|
||||
|
||||
*acl++ = (UCHAR)length;
|
||||
if (length)
|
||||
{
|
||||
const TEXT* p_1 = ownerName.c_str();
|
||||
memcpy(acl, p_1, length);
|
||||
acl += length;
|
||||
}
|
||||
*acl++ = ACL_end;
|
||||
*acl++ = ACL_priv_list;
|
||||
*acl++ = priv_protect;
|
||||
@ -460,6 +460,31 @@ void INI_format(const TEXT* owner, const TEXT* charset)
|
||||
*acl++ = priv_write;
|
||||
*acl++ = priv_read;
|
||||
*acl++ = ACL_end;
|
||||
*acl++ = ACL_end;
|
||||
length = acl - buffer;
|
||||
|
||||
for (const gfld* gfield = gfields; gfield->gfld_name; gfield++)
|
||||
add_security_to_sys_obj(tdbb, ownerName, obj_field, names[(USHORT)gfield->gfld_name], length, buffer);
|
||||
|
||||
for (const gen* generator = generators; generator->gen_name; generator++)
|
||||
add_security_to_sys_obj(tdbb, ownerName, obj_generator, generator->gen_name, length, buffer);
|
||||
|
||||
for (const IntlManager::CharSetDefinition* charset = IntlManager::defaultCharSets;
|
||||
charset->name; ++charset)
|
||||
{
|
||||
add_security_to_sys_obj(tdbb, ownerName, obj_charset, charset->name, length, buffer);
|
||||
}
|
||||
|
||||
for (const IntlManager::CollationDefinition* collation = IntlManager::defaultCollations;
|
||||
collation->name; ++collation)
|
||||
{
|
||||
add_security_to_sys_obj(tdbb, ownerName, obj_collation, collation->name, length, buffer);
|
||||
}
|
||||
|
||||
// Add security on RDB$ROLES system table
|
||||
|
||||
acl--; // go before the last ACL_end, it's to be overwritten
|
||||
|
||||
*acl++ = ACL_id_list;
|
||||
*acl++ = ACL_end;
|
||||
*acl++ = ACL_priv_list;
|
||||
@ -468,10 +493,10 @@ void INI_format(const TEXT* owner, const TEXT* charset)
|
||||
*acl++ = ACL_end;
|
||||
length = acl - buffer;
|
||||
|
||||
add_security_to_sys_rel(tdbb, ownerName, "RDB$ROLES", buffer, length, true);
|
||||
add_security_to_sys_rel(tdbb, ownerName, "RDB$PAGES", buffer, length, true);
|
||||
add_security_to_sys_rel(tdbb, ownerName, "RDB$ROLES", length, buffer, true);
|
||||
add_security_to_sys_rel(tdbb, ownerName, "RDB$PAGES", length, buffer, true);
|
||||
// DFW writes here
|
||||
add_security_to_sys_rel(tdbb, ownerName, "RDB$FORMATS", buffer, length, true);
|
||||
add_security_to_sys_rel(tdbb, ownerName, "RDB$FORMATS", length, buffer, true);
|
||||
}
|
||||
|
||||
|
||||
@ -882,8 +907,8 @@ static void add_index_set(thread_db* tdbb)
|
||||
static void add_security_to_sys_rel(thread_db* tdbb,
|
||||
const Firebird::MetaName& user_name,
|
||||
const TEXT* rel_name,
|
||||
const USHORT acl_length,
|
||||
const UCHAR* acl,
|
||||
const SSHORT acl_length,
|
||||
const bool pub_select)
|
||||
{
|
||||
/**************************************
|
||||
@ -924,7 +949,7 @@ static void add_security_to_sys_rel(thread_db* tdbb,
|
||||
STORE(REQUEST_HANDLE handle1)
|
||||
CLS IN RDB$SECURITY_CLASSES
|
||||
{
|
||||
jrd_vtof(security_class.c_str(), CLS.RDB$SECURITY_CLASS, sizeof(CLS.RDB$SECURITY_CLASS));
|
||||
PAD(security_class.c_str(), CLS.RDB$SECURITY_CLASS);
|
||||
CLS.RDB$ACL = blob_id_1;
|
||||
}
|
||||
END_STORE
|
||||
@ -934,7 +959,7 @@ static void add_security_to_sys_rel(thread_db* tdbb,
|
||||
STORE(REQUEST_HANDLE handle1)
|
||||
CLS IN RDB$SECURITY_CLASSES
|
||||
{
|
||||
jrd_vtof(default_class.c_str(), CLS.RDB$SECURITY_CLASS, sizeof(CLS.RDB$SECURITY_CLASS));
|
||||
PAD(default_class.c_str(), CLS.RDB$SECURITY_CLASS);
|
||||
CLS.RDB$ACL = blob_id_2;
|
||||
}
|
||||
END_STORE
|
||||
@ -946,10 +971,10 @@ static void add_security_to_sys_rel(thread_db* tdbb,
|
||||
{
|
||||
MODIFY REL USING
|
||||
REL.RDB$SECURITY_CLASS.NULL = FALSE;
|
||||
jrd_vtof(security_class.c_str(), REL.RDB$SECURITY_CLASS, sizeof(REL.RDB$SECURITY_CLASS));
|
||||
PAD(security_class.c_str(), REL.RDB$SECURITY_CLASS);
|
||||
|
||||
REL.RDB$DEFAULT_CLASS.NULL = FALSE;
|
||||
jrd_vtof(default_class.c_str(), REL.RDB$DEFAULT_CLASS, sizeof(REL.RDB$DEFAULT_CLASS));
|
||||
PAD(default_class.c_str(), REL.RDB$DEFAULT_CLASS);
|
||||
END_MODIFY
|
||||
}
|
||||
END_FOR
|
||||
@ -1003,7 +1028,124 @@ static void add_security_to_sys_rel(thread_db* tdbb,
|
||||
}
|
||||
|
||||
|
||||
static void store_generator(thread_db* tdbb, const gen* generator, AutoRequest& handle)
|
||||
static void add_security_to_sys_obj(thread_db* tdbb,
|
||||
const MetaName& user_name,
|
||||
USHORT obj_type,
|
||||
const MetaName& obj_name,
|
||||
USHORT acl_length,
|
||||
const UCHAR* acl)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* a d d _ s e c u r i t y _ t o _ s y s _ o b j
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
*
|
||||
* Add security to system objects.
|
||||
*
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
Jrd::Attachment* const attachment = tdbb->getAttachment();
|
||||
|
||||
bid blob_id;
|
||||
attachment->storeBinaryBlob(tdbb, attachment->getSysTransaction(), &blob_id,
|
||||
ByteChunk(acl, acl_length));
|
||||
|
||||
Firebird::MetaName security_class;
|
||||
security_class.printf("%s%"SQUADFORMAT, SQL_SECCLASS_PREFIX,
|
||||
DPM_gen_id(tdbb, MET_lookup_generator(tdbb, SQL_SECCLASS_GENERATOR), false, 1));
|
||||
|
||||
AutoRequest handle;
|
||||
|
||||
STORE(REQUEST_HANDLE handle)
|
||||
CLS IN RDB$SECURITY_CLASSES
|
||||
{
|
||||
PAD(security_class.c_str(), CLS.RDB$SECURITY_CLASS);
|
||||
CLS.RDB$ACL = blob_id;
|
||||
}
|
||||
END_STORE
|
||||
|
||||
handle.reset();
|
||||
|
||||
if (obj_type == obj_field)
|
||||
{
|
||||
FOR(REQUEST_HANDLE handle) FLD IN RDB$FIELDS
|
||||
WITH FLD.RDB$FIELD_NAME EQ obj_name.c_str()
|
||||
{
|
||||
MODIFY FLD USING
|
||||
FLD.RDB$SECURITY_CLASS.NULL = FALSE;
|
||||
PAD(security_class.c_str(), FLD.RDB$SECURITY_CLASS);
|
||||
END_MODIFY
|
||||
}
|
||||
END_FOR
|
||||
}
|
||||
else if (obj_type == obj_charset)
|
||||
{
|
||||
FOR(REQUEST_HANDLE handle) CS IN RDB$CHARACTER_SETS
|
||||
WITH CS.RDB$CHARACTER_SET_NAME EQ obj_name.c_str()
|
||||
{
|
||||
MODIFY CS USING
|
||||
CS.RDB$SECURITY_CLASS.NULL = FALSE;
|
||||
PAD(security_class.c_str(), CS.RDB$SECURITY_CLASS);
|
||||
END_MODIFY
|
||||
}
|
||||
END_FOR
|
||||
}
|
||||
else if (obj_type == obj_collation)
|
||||
{
|
||||
FOR(REQUEST_HANDLE handle) COLL IN RDB$COLLATIONS
|
||||
WITH COLL.RDB$COLLATION_NAME EQ obj_name.c_str()
|
||||
{
|
||||
MODIFY COLL USING
|
||||
COLL.RDB$SECURITY_CLASS.NULL = FALSE;
|
||||
PAD(security_class.c_str(), COLL.RDB$SECURITY_CLASS);
|
||||
END_MODIFY
|
||||
}
|
||||
END_FOR
|
||||
}
|
||||
else if (obj_type == obj_exception)
|
||||
{
|
||||
FOR(REQUEST_HANDLE handle) XCP IN RDB$EXCEPTIONS
|
||||
WITH XCP.RDB$EXCEPTION_NAME EQ obj_name.c_str()
|
||||
{
|
||||
MODIFY XCP USING
|
||||
XCP.RDB$SECURITY_CLASS.NULL = FALSE;
|
||||
PAD(security_class.c_str(), XCP.RDB$SECURITY_CLASS);
|
||||
END_MODIFY
|
||||
}
|
||||
END_FOR
|
||||
}
|
||||
else if (obj_type == obj_generator)
|
||||
{
|
||||
FOR(REQUEST_HANDLE handle) GEN IN RDB$GENERATORS
|
||||
WITH GEN.RDB$GENERATOR_NAME EQ obj_name.c_str()
|
||||
{
|
||||
MODIFY GEN USING
|
||||
GEN.RDB$SECURITY_CLASS.NULL = FALSE;
|
||||
PAD(security_class.c_str(), GEN.RDB$SECURITY_CLASS);
|
||||
END_MODIFY
|
||||
}
|
||||
END_FOR
|
||||
}
|
||||
|
||||
handle.reset();
|
||||
|
||||
STORE(REQUEST_HANDLE handle) PRIV IN RDB$USER_PRIVILEGES
|
||||
PAD(user_name.c_str(), PRIV.RDB$USER);
|
||||
PAD(obj_name.c_str(), PRIV.RDB$RELATION_NAME);
|
||||
PRIV.RDB$PRIVILEGE[0] = USAGE_PRIVILEGE;
|
||||
PRIV.RDB$PRIVILEGE[1] = 0;
|
||||
PRIV.RDB$GRANT_OPTION = 1;
|
||||
PRIV.RDB$USER_TYPE = obj_user;
|
||||
PRIV.RDB$OBJECT_TYPE = obj_type;
|
||||
END_STORE
|
||||
}
|
||||
|
||||
|
||||
static void store_generator(thread_db* tdbb, const gen* generator, AutoRequest& handle,
|
||||
const MetaName& owner)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -1025,6 +1167,8 @@ static void store_generator(thread_db* tdbb, const gen* generator, AutoRequest&
|
||||
X.RDB$GENERATOR_ID = generator->gen_id;
|
||||
X.RDB$SYSTEM_FLAG = RDB_system;
|
||||
X.RDB$SYSTEM_FLAG.NULL = FALSE;
|
||||
PAD(owner.c_str(), X.RDB$OWNER_NAME);
|
||||
X.RDB$OWNER_NAME.NULL = FALSE;
|
||||
if (generator->gen_description)
|
||||
{
|
||||
attachment->storeMetaDataBlob(tdbb, attachment->getSysTransaction(), &X.RDB$DESCRIPTION,
|
||||
@ -1038,7 +1182,8 @@ static void store_generator(thread_db* tdbb, const gen* generator, AutoRequest&
|
||||
}
|
||||
|
||||
|
||||
static void store_global_field(thread_db* tdbb, const gfld* gfield, AutoRequest& handle)
|
||||
static void store_global_field(thread_db* tdbb, const gfld* gfield, AutoRequest& handle,
|
||||
const MetaName& owner)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -1062,6 +1207,8 @@ static void store_global_field(thread_db* tdbb, const gfld* gfield, AutoRequest&
|
||||
X.RDB$FIELD_SCALE = 0;
|
||||
X.RDB$SYSTEM_FLAG = RDB_system;
|
||||
X.RDB$SYSTEM_FLAG.NULL = FALSE;
|
||||
PAD(owner.c_str(), X.RDB$OWNER_NAME);
|
||||
X.RDB$OWNER_NAME.NULL = FALSE;
|
||||
X.RDB$FIELD_SUB_TYPE.NULL = TRUE;
|
||||
X.RDB$CHARACTER_SET_ID.NULL = TRUE;
|
||||
X.RDB$COLLATION_ID.NULL = TRUE;
|
||||
@ -1191,7 +1338,7 @@ static void store_global_field(thread_db* tdbb, const gfld* gfield, AutoRequest&
|
||||
}
|
||||
|
||||
|
||||
static void store_intlnames(thread_db* tdbb)
|
||||
static void store_intlnames(thread_db* tdbb, const MetaName& owner)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -1220,6 +1367,8 @@ static void store_intlnames(thread_db* tdbb)
|
||||
X.RDB$BYTES_PER_CHARACTER = charSet->maxBytes;
|
||||
X.RDB$SYSTEM_FLAG = RDB_system;
|
||||
X.RDB$SYSTEM_FLAG.NULL = FALSE;
|
||||
PAD(owner.c_str(), X.RDB$OWNER_NAME);
|
||||
X.RDB$OWNER_NAME.NULL = FALSE;
|
||||
}
|
||||
END_STORE
|
||||
}
|
||||
@ -1245,6 +1394,8 @@ static void store_intlnames(thread_db* tdbb)
|
||||
X.RDB$COLLATION_ID = collation->collationId;
|
||||
X.RDB$SYSTEM_FLAG = RDB_system;
|
||||
X.RDB$SYSTEM_FLAG.NULL = FALSE;
|
||||
PAD(owner.c_str(), X.RDB$OWNER_NAME);
|
||||
X.RDB$OWNER_NAME.NULL = FALSE;
|
||||
X.RDB$COLLATION_ATTRIBUTES = collation->attributes;
|
||||
|
||||
if (collation->specificAttributes)
|
||||
|
@ -29,7 +29,7 @@ namespace Jrd {
|
||||
class dsql_dbb;
|
||||
}
|
||||
|
||||
void INI_format(const TEXT*, const TEXT*);
|
||||
void INI_format(const Firebird::MetaName&, const Firebird::MetaName&);
|
||||
USHORT INI_get_trig_flags(const TEXT*);
|
||||
void INI_init(Jrd::thread_db*);
|
||||
void INI_init2(Jrd::thread_db*);
|
||||
|
@ -155,6 +155,16 @@ enum irq_type_t
|
||||
irq_fun_validate, // function blr validate
|
||||
irq_c_fun_dpd, // get function dependencies
|
||||
irq_grant11, // process grant option (functions)
|
||||
irq_cs_security, // verify security for character set
|
||||
irq_coll_security, // verify security for collation
|
||||
irq_exc_security, // verify security for exception
|
||||
irq_gen_security, // verify security for generator
|
||||
irq_gfld_security, // verify security for domain
|
||||
irq_grant12, // process grant option (charsets)
|
||||
irq_grant13, // process grant option (collations)
|
||||
irq_grant14, // process grant option (exceptions)
|
||||
irq_grant15, // process grant option (generators)
|
||||
irq_grant16, // process grant option (domains)
|
||||
|
||||
irq_MAX
|
||||
};
|
||||
|
@ -3380,9 +3380,9 @@ void MET_remove_procedure(thread_db* tdbb, int id, jrd_prc* procedure)
|
||||
|
||||
void MET_revoke(thread_db* tdbb,
|
||||
jrd_tra* transaction,
|
||||
const TEXT* relation,
|
||||
const TEXT* revokee,
|
||||
const TEXT* privilege)
|
||||
const MetaName& relation,
|
||||
const MetaName& revokee,
|
||||
const string& privilege)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -3405,9 +3405,9 @@ void MET_revoke(thread_db* tdbb,
|
||||
|
||||
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
FIRST 1 P IN RDB$USER_PRIVILEGES WITH
|
||||
P.RDB$RELATION_NAME EQ relation AND
|
||||
P.RDB$PRIVILEGE EQ privilege AND
|
||||
P.RDB$USER EQ revokee
|
||||
P.RDB$RELATION_NAME EQ relation.c_str() AND
|
||||
P.RDB$PRIVILEGE EQ privilege.c_str() AND
|
||||
P.RDB$USER EQ revokee.c_str()
|
||||
{
|
||||
++count;
|
||||
}
|
||||
@ -3422,9 +3422,9 @@ void MET_revoke(thread_db* tdbb,
|
||||
|
||||
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
P IN RDB$USER_PRIVILEGES WITH
|
||||
P.RDB$RELATION_NAME EQ relation AND
|
||||
P.RDB$PRIVILEGE EQ privilege AND
|
||||
P.RDB$GRANTOR EQ revokee
|
||||
P.RDB$RELATION_NAME EQ relation.c_str() AND
|
||||
P.RDB$PRIVILEGE EQ privilege.c_str() AND
|
||||
P.RDB$GRANTOR EQ revokee.c_str()
|
||||
{
|
||||
ERASE P;
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ void MET_verify_cache(Jrd::thread_db*);
|
||||
void MET_clear_cache(Jrd::thread_db*);
|
||||
bool MET_procedure_in_use(Jrd::thread_db*, Jrd::jrd_prc*);
|
||||
void MET_remove_procedure(Jrd::thread_db*, int, Jrd::jrd_prc*);
|
||||
void MET_revoke(Jrd::thread_db*, Jrd::jrd_tra*, const TEXT*, const TEXT*, const TEXT*);
|
||||
void MET_revoke(Jrd::thread_db*, Jrd::jrd_tra*, const Firebird::MetaName&, const Firebird::MetaName&, const Firebird::string&);
|
||||
void MET_scan_partners(Jrd::thread_db*, Jrd::jrd_rel*);
|
||||
void MET_scan_relation(Jrd::thread_db*, Jrd::jrd_rel*);
|
||||
void MET_trigger_msg(Jrd::thread_db*, Firebird::string&, const Firebird::MetaName&, USHORT);
|
||||
|
@ -193,53 +193,30 @@ SINT64 MOV_get_int64(const dsc* desc, SSHORT scale)
|
||||
}
|
||||
|
||||
|
||||
void MOV_get_metadata_str(const dsc* desc, TEXT* buffer, USHORT buffer_length)
|
||||
void MOV_get_metaname(const dsc* desc, MetaName& name)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* M O V _ g e t _ m e t a d a t a _ s t r
|
||||
* M O V _ g e t _ m e t a n a m e
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Copy string, which will afterward's
|
||||
* be treated as a metadata name value,
|
||||
* to the user-supplied buffer.
|
||||
* to the user-supplied object.
|
||||
*
|
||||
**************************************/
|
||||
USHORT dummy_type;
|
||||
UCHAR *ptr;
|
||||
USHORT ttype;
|
||||
UCHAR* ptr = NULL;
|
||||
|
||||
USHORT length = CVT_get_string_ptr(desc, &dummy_type, &ptr, NULL, 0);
|
||||
const USHORT length = CVT_get_string_ptr(desc, &ttype, &ptr, NULL, 0);
|
||||
|
||||
#ifdef DEV_BUILD
|
||||
if ((dummy_type != ttype_metadata) &&
|
||||
(dummy_type != ttype_none) && (dummy_type != ttype_ascii))
|
||||
{
|
||||
ERR_bugcheck_msg("Expected METADATA name");
|
||||
}
|
||||
#endif
|
||||
fb_assert(length && ptr);
|
||||
fb_assert(length <= MAX_SQL_IDENTIFIER_LEN);
|
||||
fb_assert(ttype == ttype_metadata);
|
||||
|
||||
length = ptr ? MIN(length, buffer_length - 1) : 0;
|
||||
memcpy(buffer, ptr, length);
|
||||
buffer[length] = 0;
|
||||
}
|
||||
|
||||
|
||||
void MOV_get_name(const dsc* desc, TEXT* string)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* M O V _ g e t _ n a m e
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Get a name (max length 31, blank terminated) from a descriptor.
|
||||
*
|
||||
**************************************/
|
||||
|
||||
CVT2_get_name(desc, string);
|
||||
name.assign(reinterpret_cast<char*>(ptr), length);
|
||||
}
|
||||
|
||||
|
||||
|
@ -37,8 +37,7 @@ void MOV_double_to_date(double, SLONG[2]);
|
||||
bool MOV_get_boolean(const dsc*);
|
||||
double MOV_get_double(const dsc*);
|
||||
SLONG MOV_get_long(const dsc*, SSHORT);
|
||||
void MOV_get_metadata_str(const dsc*, TEXT*, USHORT);
|
||||
void MOV_get_name(const dsc*, TEXT*);
|
||||
void MOV_get_metaname(const dsc*, Firebird::MetaName&);
|
||||
SQUAD MOV_get_quad(const dsc*, SSHORT);
|
||||
SINT64 MOV_get_int64(const dsc*, SSHORT);
|
||||
int MOV_get_string_ptr(const dsc*, USHORT*, UCHAR**, vary*,
|
||||
|
@ -38,7 +38,7 @@ const int obj_exception = 7;
|
||||
const int obj_user = 8;
|
||||
const int obj_field = 9;
|
||||
const int obj_index = 10;
|
||||
// const int obj_count = 11;
|
||||
const int obj_charset = 11;
|
||||
const int obj_user_group = 12;
|
||||
const int obj_sql_role = 13;
|
||||
const int obj_generator = 14;
|
||||
|
189
src/jrd/scl.epp
189
src/jrd/scl.epp
@ -103,12 +103,16 @@ namespace
|
||||
|
||||
// Database is never requested through CMP_post_access.
|
||||
const char* const object_str_database = "DATABASE";
|
||||
const char* const object_str_schema = "SCHEMA";
|
||||
const char* const object_str_table = "TABLE";
|
||||
const char* const object_str_package = "PACKAGE";
|
||||
const char* const object_str_procedure = "PROCEDURE";
|
||||
const char* const object_str_function = "FUNCTION";
|
||||
const char* const object_str_column = "COLUMN";
|
||||
const char* const object_str_charset = "CHARACTER SET";
|
||||
const char* const object_str_collation = "COLLATION";
|
||||
const char* const object_str_domain = "DOMAIN";
|
||||
const char* const object_str_exception = "EXCEPTION";
|
||||
const char* const object_str_generator = "GENERATOR";
|
||||
|
||||
|
||||
struct SecObjectNamePriority
|
||||
@ -120,12 +124,16 @@ namespace
|
||||
const SecObjectNamePriority priorities[] =
|
||||
{
|
||||
{object_str_database, SCL_object_database},
|
||||
{object_str_schema, SCL_object_schema},
|
||||
{object_str_table, SCL_object_table},
|
||||
{object_str_package, SCL_object_package},
|
||||
{object_str_procedure, SCL_object_procedure},
|
||||
{object_str_function, SCL_object_function},
|
||||
{object_str_column, SCL_object_column},
|
||||
{object_str_charset, SCL_object_charset},
|
||||
{object_str_collation, SCL_object_collation},
|
||||
{object_str_domain, SCL_object_domain},
|
||||
{object_str_exception, SCL_object_exception},
|
||||
{object_str_generator, SCL_object_generator},
|
||||
{"", 0}
|
||||
};
|
||||
|
||||
@ -245,7 +253,7 @@ void SCL_check_access(thread_db* tdbb,
|
||||
else
|
||||
{
|
||||
fb_assert(type != SCL_object_database);
|
||||
const char* typeAsStr = accTypeNumToStr(type);
|
||||
const char* const typeAsStr = accTypeNumToStr(type);
|
||||
const Firebird::string fullName = r_name.hasData() ?
|
||||
r_name.c_str() + Firebird::string(".") + name.c_str() : name.c_str();
|
||||
ERR_post(Arg::Gds(isc_no_priv) << Arg::Str(names->p_names_string) <<
|
||||
@ -255,6 +263,161 @@ void SCL_check_access(thread_db* tdbb,
|
||||
}
|
||||
|
||||
|
||||
void SCL_check_charset(thread_db* tdbb, const MetaName& name, SecurityClass::flags_t mask)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* S C L _ c h e c k _ c h a r s e t
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Given a character set name, check for a set of privileges.
|
||||
*
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
Jrd::Attachment* const attachment = tdbb->getAttachment();
|
||||
|
||||
const SecurityClass* s_class = NULL;
|
||||
AutoCacheRequest request(tdbb, irq_cs_security, IRQ_REQUESTS);
|
||||
|
||||
FOR (REQUEST_HANDLE request)
|
||||
CS IN RDB$CHARACTER_SETS
|
||||
WITH CS.RDB$CHARACTER_SET_NAME EQ name.c_str()
|
||||
{
|
||||
if (!CS.RDB$SECURITY_CLASS.NULL)
|
||||
s_class = SCL_get_class(tdbb, CS.RDB$SECURITY_CLASS);
|
||||
}
|
||||
END_FOR
|
||||
|
||||
SCL_check_access(tdbb, s_class, 0, id_charset, name, mask, SCL_object_charset, name);
|
||||
}
|
||||
|
||||
|
||||
void SCL_check_collation(thread_db* tdbb, const MetaName& name, SecurityClass::flags_t mask)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* S C L _ c h e c k _ c o l l a t i o n
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Given a collation name, check for a set of privileges.
|
||||
*
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
Jrd::Attachment* const attachment = tdbb->getAttachment();
|
||||
|
||||
const SecurityClass* s_class = NULL;
|
||||
AutoCacheRequest request(tdbb, irq_coll_security, IRQ_REQUESTS);
|
||||
|
||||
FOR (REQUEST_HANDLE request)
|
||||
COLL IN RDB$COLLATIONS
|
||||
WITH COLL.RDB$COLLATION_NAME EQ name.c_str()
|
||||
{
|
||||
if (!COLL.RDB$SECURITY_CLASS.NULL)
|
||||
s_class = SCL_get_class(tdbb, COLL.RDB$SECURITY_CLASS);
|
||||
}
|
||||
END_FOR
|
||||
|
||||
SCL_check_access(tdbb, s_class, 0, id_collation, name, mask, SCL_object_collation, name);
|
||||
}
|
||||
|
||||
|
||||
void SCL_check_domain(thread_db* tdbb, const MetaName& name, SecurityClass::flags_t mask)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* S C L _ c h e c k _ d o m a i n
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Given a domain name, check for a set of privileges.
|
||||
*
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
Jrd::Attachment* const attachment = tdbb->getAttachment();
|
||||
|
||||
const SecurityClass* s_class = NULL;
|
||||
AutoCacheRequest request(tdbb, irq_gfld_security, IRQ_REQUESTS);
|
||||
|
||||
FOR (REQUEST_HANDLE request)
|
||||
FLD IN RDB$FIELDS
|
||||
WITH FLD.RDB$FIELD_NAME EQ name.c_str()
|
||||
{
|
||||
if (!FLD.RDB$SECURITY_CLASS.NULL)
|
||||
s_class = SCL_get_class(tdbb, FLD.RDB$SECURITY_CLASS);
|
||||
}
|
||||
END_FOR
|
||||
|
||||
SCL_check_access(tdbb, s_class, 0, id_domain, name, mask, SCL_object_domain, name);
|
||||
}
|
||||
|
||||
|
||||
void SCL_check_exception(thread_db* tdbb, const MetaName& name, SecurityClass::flags_t mask)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* S C L _ c h e c k _ e x c e p t i o n
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Given an exception name, check for a set of privileges.
|
||||
*
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
Jrd::Attachment* const attachment = tdbb->getAttachment();
|
||||
|
||||
const SecurityClass* s_class = NULL;
|
||||
AutoCacheRequest request(tdbb, irq_exc_security, IRQ_REQUESTS);
|
||||
|
||||
FOR (REQUEST_HANDLE request)
|
||||
XCP IN RDB$EXCEPTIONS
|
||||
WITH XCP.RDB$EXCEPTION_NAME EQ name.c_str()
|
||||
{
|
||||
if (!XCP.RDB$SECURITY_CLASS.NULL)
|
||||
s_class = SCL_get_class(tdbb, XCP.RDB$SECURITY_CLASS);
|
||||
}
|
||||
END_FOR
|
||||
|
||||
SCL_check_access(tdbb, s_class, 0, id_exception, name, mask, SCL_object_exception, name);
|
||||
}
|
||||
|
||||
|
||||
void SCL_check_generator(thread_db* tdbb, const MetaName& name, SecurityClass::flags_t mask)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* S C L _ c h e c k _ g e n e r a t o r
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Given a generator name, check for a set of privileges.
|
||||
*
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
Jrd::Attachment* const attachment = tdbb->getAttachment();
|
||||
|
||||
const SecurityClass* s_class = NULL;
|
||||
AutoCacheRequest request(tdbb, irq_gen_security, IRQ_REQUESTS);
|
||||
|
||||
FOR (REQUEST_HANDLE request)
|
||||
GEN IN RDB$GENERATORS
|
||||
WITH GEN.RDB$GENERATOR_NAME EQ name.c_str()
|
||||
{
|
||||
if (!GEN.RDB$SECURITY_CLASS.NULL)
|
||||
s_class = SCL_get_class(tdbb, GEN.RDB$SECURITY_CLASS);
|
||||
}
|
||||
END_FOR
|
||||
|
||||
SCL_check_access(tdbb, s_class, 0, id_generator, name, mask, SCL_object_generator, name);
|
||||
}
|
||||
|
||||
|
||||
void SCL_check_index(thread_db* tdbb, const Firebird::MetaName& index_name, UCHAR index_id,
|
||||
SecurityClass::flags_t mask)
|
||||
{
|
||||
@ -276,7 +439,7 @@ void SCL_check_index(thread_db* tdbb, const Firebird::MetaName& index_name, UCHA
|
||||
*
|
||||
*******************************************************/
|
||||
SET_TDBB(tdbb);
|
||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
Jrd::Attachment* const attachment = tdbb->getAttachment();
|
||||
|
||||
const SecurityClass* s_class = NULL;
|
||||
const SecurityClass* default_s_class = NULL;
|
||||
@ -384,7 +547,7 @@ void SCL_check_package(thread_db* tdbb, const dsc* dsc_name, SecurityClass::flag
|
||||
const Firebird::MetaName name(reinterpret_cast<TEXT*>(dsc_name->dsc_address),
|
||||
dsc_name->dsc_length);
|
||||
|
||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
Jrd::Attachment* const attachment = tdbb->getAttachment();
|
||||
|
||||
const SecurityClass* s_class = NULL;
|
||||
AutoCacheRequest request(tdbb, irq_pkg_security, IRQ_REQUESTS);
|
||||
@ -423,7 +586,7 @@ void SCL_check_procedure(thread_db* tdbb, const dsc* dsc_name, SecurityClass::fl
|
||||
const Firebird::MetaName name(reinterpret_cast<TEXT*>(dsc_name->dsc_address),
|
||||
dsc_name->dsc_length);
|
||||
|
||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
Jrd::Attachment* const attachment = tdbb->getAttachment();
|
||||
|
||||
const SecurityClass* s_class = NULL;
|
||||
AutoCacheRequest request(tdbb, irq_p_security, IRQ_REQUESTS);
|
||||
@ -463,7 +626,7 @@ void SCL_check_function(thread_db* tdbb, const dsc* dsc_name, SecurityClass::fla
|
||||
const Firebird::MetaName name(reinterpret_cast<TEXT*>(dsc_name->dsc_address),
|
||||
dsc_name->dsc_length);
|
||||
|
||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
Jrd::Attachment* const attachment = tdbb->getAttachment();
|
||||
|
||||
const SecurityClass* s_class = NULL;
|
||||
AutoCacheRequest request(tdbb, irq_f_security, IRQ_REQUESTS);
|
||||
@ -503,7 +666,7 @@ void SCL_check_relation(thread_db* tdbb, const dsc* dsc_name, SecurityClass::fla
|
||||
const Firebird::MetaName name(reinterpret_cast<TEXT*>(dsc_name->dsc_address),
|
||||
dsc_name->dsc_length);
|
||||
|
||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
Jrd::Attachment* const attachment = tdbb->getAttachment();
|
||||
|
||||
const SecurityClass* s_class = NULL;
|
||||
AutoCacheRequest request(tdbb, irq_v_security, IRQ_REQUESTS);
|
||||
@ -550,7 +713,7 @@ SecurityClass* SCL_get_class(thread_db* tdbb, const TEXT* par_string)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
Jrd::Attachment* const attachment = tdbb->getAttachment();
|
||||
|
||||
// Look for the class already known
|
||||
|
||||
@ -597,7 +760,7 @@ SecurityClass::flags_t SCL_get_mask(thread_db* tdbb, const TEXT* relation_name,
|
||||
*
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
Jrd::Attachment* const attachment = tdbb->getAttachment();
|
||||
|
||||
// Start with database security class
|
||||
|
||||
@ -650,7 +813,7 @@ void SCL_init(thread_db* tdbb, bool create, const UserId& tempId)
|
||||
*
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
Jrd::Attachment* const attachment = tdbb->getAttachment();
|
||||
|
||||
const TEXT* sql_role = tempId.usr_sql_role_name.nullStr();
|
||||
Firebird::string loginName(tempId.usr_user_name);
|
||||
@ -1000,7 +1163,7 @@ static SecurityClass::flags_t compute_access(thread_db* tdbb,
|
||||
Acl acl;
|
||||
|
||||
SET_TDBB(tdbb);
|
||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
Jrd::Attachment* const attachment = tdbb->getAttachment();
|
||||
jrd_tra* sysTransaction = attachment->getSysTransaction();
|
||||
|
||||
SecurityClass::flags_t privileges = SCL_scanned;
|
||||
@ -1060,7 +1223,7 @@ static SecurityClass::flags_t walk_acl(thread_db* tdbb,
|
||||
*
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
Jrd::Attachment* const attachment = tdbb->getAttachment();
|
||||
|
||||
// Munch ACL. If we find a hit, eat up privileges.
|
||||
|
||||
|
@ -146,16 +146,19 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// Here, lower is more priority.
|
||||
// These numbers are arbitrary and only used at run-time. Can be changed if necessary at any moment.
|
||||
// We need to include here the new objects that accept ACLs.
|
||||
const SLONG SCL_object_database = 1;
|
||||
const SLONG SCL_object_schema = 2;
|
||||
const SLONG SCL_object_table = 3;
|
||||
const SLONG SCL_object_package = 4;
|
||||
const SLONG SCL_object_procedure = 5;
|
||||
const SLONG SCL_object_function = 6;
|
||||
const SLONG SCL_object_column = 7;
|
||||
const SLONG SCL_object_table = 2;
|
||||
const SLONG SCL_object_package = 3;
|
||||
const SLONG SCL_object_procedure = 4;
|
||||
const SLONG SCL_object_function = 5;
|
||||
const SLONG SCL_object_column = 6;
|
||||
const SLONG SCL_object_collation = 7;
|
||||
const SLONG SCL_object_exception = 8;
|
||||
const SLONG SCL_object_generator = 9;
|
||||
const SLONG SCL_object_charset = 10;
|
||||
const SLONG SCL_object_domain = 11;
|
||||
|
||||
} //namespace Jrd
|
||||
|
||||
|
@ -36,6 +36,11 @@ struct dsc;
|
||||
void SCL_check_access(Jrd::thread_db*, const Jrd::SecurityClass*, SLONG, SLONG, const Firebird::MetaName&,
|
||||
Jrd::SecurityClass::flags_t, SLONG type, const Firebird::MetaName&,
|
||||
const Firebird::MetaName& = "");
|
||||
void SCL_check_charset(Jrd::thread_db* tdbb, const Firebird::MetaName&, Jrd::SecurityClass::flags_t);
|
||||
void SCL_check_collation(Jrd::thread_db* tdbb, const Firebird::MetaName&, Jrd::SecurityClass::flags_t);
|
||||
void SCL_check_domain(Jrd::thread_db* tdbb, const Firebird::MetaName&, Jrd::SecurityClass::flags_t);
|
||||
void SCL_check_exception(Jrd::thread_db* tdbb, const Firebird::MetaName&, Jrd::SecurityClass::flags_t);
|
||||
void SCL_check_generator(Jrd::thread_db* tdbb, const Firebird::MetaName&, Jrd::SecurityClass::flags_t);
|
||||
void SCL_check_index(Jrd::thread_db*, const Firebird::MetaName&, UCHAR, Jrd::SecurityClass::flags_t);
|
||||
void SCL_check_package(Jrd::thread_db* tdbb, const dsc*, Jrd::SecurityClass::flags_t);
|
||||
void SCL_check_procedure(Jrd::thread_db* tdbb, const dsc*, Jrd::SecurityClass::flags_t);
|
||||
|
116
src/jrd/types.h
116
src/jrd/types.h
@ -39,8 +39,8 @@ TYPE("CSTRING", blr_cstring, nam_f_type)
|
||||
TYPE("BLOB_ID", blr_blob_id, nam_f_type)
|
||||
TYPE("DATE", blr_sql_date, nam_f_type)
|
||||
TYPE("TIME", blr_sql_time, nam_f_type)
|
||||
TYPE ("INT64", blr_int64, nam_f_type)
|
||||
TYPE ("BOOLEAN", blr_bool, nam_f_type)
|
||||
TYPE("INT64", blr_int64, nam_f_type)
|
||||
TYPE("BOOLEAN", blr_bool, nam_f_type)
|
||||
|
||||
TYPE("BINARY", 0, nam_f_sub_type)
|
||||
TYPE("TEXT", 1, nam_f_sub_type)
|
||||
@ -75,75 +75,75 @@ TYPE("TRANSACTION_START", 8194, nam_trg_type)
|
||||
TYPE("TRANSACTION_COMMIT", 8195, nam_trg_type)
|
||||
TYPE("TRANSACTION_ROLLBACK", 8196, nam_trg_type)
|
||||
|
||||
TYPE ("RELATION", obj_relation, nam_obj_type)
|
||||
TYPE ("VIEW", obj_view, nam_obj_type)
|
||||
TYPE ("TRIGGER", obj_trigger, nam_obj_type)
|
||||
TYPE ("COMPUTED_FIELD", obj_computed, nam_obj_type)
|
||||
TYPE ("VALIDATION", obj_validation, nam_obj_type)
|
||||
TYPE ("PROCEDURE", obj_procedure, nam_obj_type)
|
||||
TYPE ("EXPRESSION_INDEX", obj_expression_index, nam_obj_type)
|
||||
TYPE ("EXCEPTION", obj_exception, nam_obj_type)
|
||||
TYPE ("USER", obj_user, nam_obj_type)
|
||||
TYPE ("FIELD", obj_field, nam_obj_type)
|
||||
TYPE ("INDEX", obj_index, nam_obj_type)
|
||||
// TYPE ("DEPENDENT_COUNT", obj_count, nam_obj_type)
|
||||
TYPE ("USER_GROUP", obj_user_group, nam_obj_type)
|
||||
TYPE ("ROLE", obj_sql_role, nam_obj_type)
|
||||
TYPE ("GENERATOR", obj_generator, nam_obj_type)
|
||||
TYPE ("UDF", obj_udf, nam_obj_type)
|
||||
TYPE ("BLOB_FILTER", obj_blob_filter, nam_obj_type)
|
||||
TYPE ("COLLATION", obj_collation, nam_obj_type)
|
||||
TYPE ("PACKAGE", obj_package_header, nam_obj_type)
|
||||
TYPE ("PACKAGE BODY", obj_package_body, nam_obj_type)
|
||||
TYPE("RELATION", obj_relation, nam_obj_type)
|
||||
TYPE("VIEW", obj_view, nam_obj_type)
|
||||
TYPE("TRIGGER", obj_trigger, nam_obj_type)
|
||||
TYPE("COMPUTED_FIELD", obj_computed, nam_obj_type)
|
||||
TYPE("VALIDATION", obj_validation, nam_obj_type)
|
||||
TYPE("PROCEDURE", obj_procedure, nam_obj_type)
|
||||
TYPE("EXPRESSION_INDEX", obj_expression_index, nam_obj_type)
|
||||
TYPE("EXCEPTION", obj_exception, nam_obj_type)
|
||||
TYPE("USER", obj_user, nam_obj_type)
|
||||
TYPE("FIELD", obj_field, nam_obj_type)
|
||||
TYPE("INDEX", obj_index, nam_obj_type)
|
||||
TYPE("CHARACTER_SET", obj_charset, nam_obj_type)
|
||||
TYPE("USER_GROUP", obj_user_group, nam_obj_type)
|
||||
TYPE("ROLE", obj_sql_role, nam_obj_type)
|
||||
TYPE("GENERATOR", obj_generator, nam_obj_type)
|
||||
TYPE("UDF", obj_udf, nam_obj_type)
|
||||
TYPE("BLOB_FILTER", obj_blob_filter, nam_obj_type)
|
||||
TYPE("COLLATION", obj_collation, nam_obj_type)
|
||||
TYPE("PACKAGE", obj_package_header, nam_obj_type)
|
||||
TYPE("PACKAGE BODY", obj_package_body, nam_obj_type)
|
||||
|
||||
TYPE("LIMBO", 1, nam_trans_state)
|
||||
TYPE("COMMITTED", 2, nam_trans_state)
|
||||
TYPE("ROLLED_BACK", 3, nam_trans_state)
|
||||
|
||||
TYPE ("USER", 0, nam_sys_flag)
|
||||
TYPE ("SYSTEM", 1, nam_sys_flag)
|
||||
TYPE ("QLI", 2, nam_sys_flag)
|
||||
TYPE ("CHECK_CONSTRAINT", 3, nam_sys_flag)
|
||||
TYPE ("REFERENTIAL_CONSTRAINT", 4, nam_sys_flag)
|
||||
TYPE ("VIEW_CHECK", 5, nam_sys_flag)
|
||||
TYPE("USER", 0, nam_sys_flag)
|
||||
TYPE("SYSTEM", 1, nam_sys_flag)
|
||||
TYPE("QLI", 2, nam_sys_flag)
|
||||
TYPE("CHECK_CONSTRAINT", 3, nam_sys_flag)
|
||||
TYPE("REFERENTIAL_CONSTRAINT", 4, nam_sys_flag)
|
||||
TYPE("VIEW_CHECK", 5, nam_sys_flag)
|
||||
|
||||
TYPE ("PERSISTENT", rel_persistent, nam_r_type)
|
||||
TYPE ("VIEW", rel_view, nam_r_type)
|
||||
TYPE ("EXTERNAL", rel_external, nam_r_type)
|
||||
TYPE ("VIRTUAL", rel_virtual, nam_r_type)
|
||||
TYPE ("GLOBAL_TEMPORARY_PRESERVE", rel_global_temp_preserve, nam_r_type)
|
||||
TYPE ("GLOBAL_TEMPORARY_DELETE", rel_global_temp_delete, nam_r_type)
|
||||
TYPE("PERSISTENT", rel_persistent, nam_r_type)
|
||||
TYPE("VIEW", rel_view, nam_r_type)
|
||||
TYPE("EXTERNAL", rel_external, nam_r_type)
|
||||
TYPE("VIRTUAL", rel_virtual, nam_r_type)
|
||||
TYPE("GLOBAL_TEMPORARY_PRESERVE", rel_global_temp_preserve, nam_r_type)
|
||||
TYPE("GLOBAL_TEMPORARY_DELETE", rel_global_temp_delete, nam_r_type)
|
||||
|
||||
TYPE ("LEGACY", prc_legacy, nam_prc_type)
|
||||
TYPE ("SELECTABLE", prc_selectable, nam_prc_type)
|
||||
TYPE ("EXECUTABLE", prc_executable, nam_prc_type)
|
||||
TYPE("LEGACY", prc_legacy, nam_prc_type)
|
||||
TYPE("SELECTABLE", prc_selectable, nam_prc_type)
|
||||
TYPE("EXECUTABLE", prc_executable, nam_prc_type)
|
||||
|
||||
TYPE("NORMAL", prm_mech_normal, nam_prm_mechanism)
|
||||
TYPE("TYPE OF", prm_mech_type_of, nam_prm_mechanism)
|
||||
|
||||
TYPE ("IDLE", mon_state_idle, nam_mon_state)
|
||||
TYPE ("ACTIVE", mon_state_active, nam_mon_state)
|
||||
TYPE ("STALLED", mon_state_stalled, nam_mon_state)
|
||||
TYPE("IDLE", mon_state_idle, nam_mon_state)
|
||||
TYPE("ACTIVE", mon_state_active, nam_mon_state)
|
||||
TYPE("STALLED", mon_state_stalled, nam_mon_state)
|
||||
|
||||
TYPE ("ONLINE", shut_mode_online, nam_mon_shut_mode)
|
||||
TYPE ("MULTI_USER_SHUTDOWN", shut_mode_multi, nam_mon_shut_mode)
|
||||
TYPE ("SINGLE_USER_SHUTDOWN", shut_mode_single, nam_mon_shut_mode)
|
||||
TYPE ("FULL_SHUTDOWN", shut_mode_full, nam_mon_shut_mode)
|
||||
TYPE("ONLINE", shut_mode_online, nam_mon_shut_mode)
|
||||
TYPE("MULTI_USER_SHUTDOWN", shut_mode_multi, nam_mon_shut_mode)
|
||||
TYPE("SINGLE_USER_SHUTDOWN", shut_mode_single, nam_mon_shut_mode)
|
||||
TYPE("FULL_SHUTDOWN", shut_mode_full, nam_mon_shut_mode)
|
||||
|
||||
TYPE ("CONSISTENCY", iso_mode_consistency, nam_mon_iso_mode)
|
||||
TYPE ("CONCURRENCY", iso_mode_concurrency, nam_mon_iso_mode)
|
||||
TYPE ("READ_COMMITTED_VERSION", iso_mode_rc_version, nam_mon_iso_mode)
|
||||
TYPE ("READ_COMMITTED_NO_VERSION", iso_mode_rc_no_version, nam_mon_iso_mode)
|
||||
TYPE("CONSISTENCY", iso_mode_consistency, nam_mon_iso_mode)
|
||||
TYPE("CONCURRENCY", iso_mode_concurrency, nam_mon_iso_mode)
|
||||
TYPE("READ_COMMITTED_VERSION", iso_mode_rc_version, nam_mon_iso_mode)
|
||||
TYPE("READ_COMMITTED_NO_VERSION", iso_mode_rc_no_version, nam_mon_iso_mode)
|
||||
|
||||
TYPE ("NORMAL", backup_state_normal, nam_mon_backup_state)
|
||||
TYPE ("STALLED", backup_state_stalled, nam_mon_backup_state)
|
||||
TYPE ("MERGE", backup_state_merge, nam_mon_backup_state)
|
||||
TYPE("NORMAL", backup_state_normal, nam_mon_backup_state)
|
||||
TYPE("STALLED", backup_state_stalled, nam_mon_backup_state)
|
||||
TYPE("MERGE", backup_state_merge, nam_mon_backup_state)
|
||||
|
||||
TYPE ("DATABASE", stat_database, nam_mon_stat_group)
|
||||
TYPE ("ATTACHMENT", stat_attachment, nam_mon_stat_group)
|
||||
TYPE ("TRANSACTION", stat_transaction, nam_mon_stat_group)
|
||||
TYPE ("STATEMENT", stat_statement, nam_mon_stat_group)
|
||||
TYPE ("CALL", stat_call, nam_mon_stat_group)
|
||||
TYPE("DATABASE", stat_database, nam_mon_stat_group)
|
||||
TYPE("ATTACHMENT", stat_attachment, nam_mon_stat_group)
|
||||
TYPE("TRANSACTION", stat_transaction, nam_mon_stat_group)
|
||||
TYPE("STATEMENT", stat_statement, nam_mon_stat_group)
|
||||
TYPE("CALL", stat_call, nam_mon_stat_group)
|
||||
|
||||
TYPE ("ALWAYS", IDENT_TYPE_ALWAYS, nam_identity_type)
|
||||
TYPE ("BY DEFAULT", IDENT_TYPE_BY_DEFAULT, nam_identity_type)
|
||||
TYPE("ALWAYS", IDENT_TYPE_ALWAYS, nam_identity_type)
|
||||
TYPE("BY DEFAULT", IDENT_TYPE_BY_DEFAULT, nam_identity_type)
|
||||
|
195
src/jrd/vio.cpp
195
src/jrd/vio.cpp
@ -1267,9 +1267,7 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
* stub.
|
||||
*
|
||||
**************************************/
|
||||
|
||||
// Revokee is only 32 bytes. UserId would be truncated.
|
||||
SqlIdentifier relation_name, revokee, privilege, procedure_name, package_name;
|
||||
MetaName object_name, package_name;
|
||||
|
||||
SET_TDBB(tdbb);
|
||||
jrd_req* request = tdbb->getRequest();
|
||||
@ -1359,19 +1357,23 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
|
||||
if (EVL_field(0, rpb->rpb_record, f_prc_pkg_name, &desc2))
|
||||
{
|
||||
MOV_get_metadata_str(&desc2, package_name, sizeof(package_name));
|
||||
MOV_get_metaname(&desc2, package_name);
|
||||
SCL_check_package(tdbb, &desc2, SCL_delete);
|
||||
}
|
||||
else
|
||||
package_name[0] = '\0';
|
||||
|
||||
if (EVL_field(0, rpb->rpb_record, f_prc_name, &desc) && package_name[0] == '\0')
|
||||
if (EVL_field(0, rpb->rpb_record, f_prc_name, &desc) && package_name.isEmpty())
|
||||
SCL_check_procedure(tdbb, &desc, SCL_delete);
|
||||
|
||||
DFW_post_work(transaction, dfw_delete_procedure, &desc, id, package_name);
|
||||
MET_lookup_procedure_id(tdbb, id, false, true, 0);
|
||||
break;
|
||||
|
||||
case rel_charsets:
|
||||
EVL_field(0, rpb->rpb_record, f_cs_cs_name, &desc);
|
||||
MOV_get_metaname(&desc, object_name);
|
||||
SCL_check_charset(tdbb, object_name, SCL_delete);
|
||||
break;
|
||||
|
||||
case rel_collations:
|
||||
EVL_field(0, rpb->rpb_record, f_coll_cs_id, &desc2);
|
||||
id = MOV_get_long(&desc2, 0);
|
||||
@ -1380,16 +1382,22 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
id = INTL_CS_COLL_TO_TTYPE(id, MOV_get_long(&desc2, 0));
|
||||
|
||||
EVL_field(0, rpb->rpb_record, f_coll_name, &desc);
|
||||
MOV_get_metaname(&desc, object_name);
|
||||
SCL_check_collation(tdbb, object_name, SCL_delete);
|
||||
DFW_post_work(transaction, dfw_delete_collation, &desc, id);
|
||||
break;
|
||||
|
||||
case rel_exceptions:
|
||||
EVL_field(0, rpb->rpb_record, f_prc_name, &desc);
|
||||
EVL_field(0, rpb->rpb_record, f_xcp_name, &desc);
|
||||
MOV_get_metaname(&desc, object_name);
|
||||
SCL_check_exception(tdbb, object_name, SCL_delete);
|
||||
DFW_post_work(transaction, dfw_delete_exception, &desc, 0);
|
||||
break;
|
||||
|
||||
case rel_gens:
|
||||
EVL_field (0, rpb->rpb_record, f_gen_name, &desc);
|
||||
EVL_field(0, rpb->rpb_record, f_gen_name, &desc);
|
||||
MOV_get_metaname(&desc, object_name);
|
||||
SCL_check_generator(tdbb, object_name, SCL_delete);
|
||||
DFW_post_work(transaction, dfw_delete_generator, &desc, 0);
|
||||
break;
|
||||
|
||||
@ -1398,12 +1406,11 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
|
||||
if (EVL_field(0, rpb->rpb_record, f_fun_pkg_name, &desc2))
|
||||
{
|
||||
MOV_get_metadata_str(&desc2, package_name, sizeof(package_name));
|
||||
MOV_get_metaname(&desc2, package_name);
|
||||
SCL_check_package(tdbb, &desc2, SCL_delete);
|
||||
}
|
||||
else
|
||||
{
|
||||
package_name[0] = '\0';
|
||||
SCL_check_function(tdbb, &desc, SCL_delete);
|
||||
}
|
||||
|
||||
@ -1420,7 +1427,8 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
EVL_field(0, rpb->rpb_record, f_idx_id, &desc2);
|
||||
if ( (id = MOV_get_long(&desc2, 0)) )
|
||||
{
|
||||
MOV_get_metadata_str(&desc, relation_name, sizeof(relation_name));
|
||||
MetaName relation_name;
|
||||
MOV_get_metaname(&desc, relation_name);
|
||||
r2 = MET_lookup_relation(tdbb, relation_name);
|
||||
fb_assert(r2);
|
||||
|
||||
@ -1446,14 +1454,14 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
DSC desc3;
|
||||
EVL_field(0, rpb->rpb_record, f_idx_name, &desc3);
|
||||
|
||||
SqlIdentifier index_name;
|
||||
MOV_get_metadata_str(&desc3, index_name, sizeof(index_name));
|
||||
MetaName index_name;
|
||||
MOV_get_metaname(&desc3, index_name);
|
||||
|
||||
jrd_rel *partner;
|
||||
index_desc idx;
|
||||
|
||||
if ((BTR_lookup(tdbb, r2, id - 1, &idx, r2->getPages(tdbb)) == FB_SUCCESS) &&
|
||||
MET_lookup_partner(tdbb, r2, &idx, index_name) &&
|
||||
MET_lookup_partner(tdbb, r2, &idx, index_name.nullStr()) &&
|
||||
(partner = MET_lookup_relation_id(tdbb, idx.idx_primary_relation, false)) )
|
||||
{
|
||||
DFW_post_work_arg(transaction, work, 0, partner->rel_id,
|
||||
@ -1475,8 +1483,8 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
SCL_check_relation(tdbb, &desc, SCL_control);
|
||||
DFW_post_work(transaction, dfw_update_format, &desc, 0);
|
||||
EVL_field(0, rpb->rpb_record, f_rfr_fname, &desc2);
|
||||
MOV_get_metadata_str(&desc, relation_name, sizeof(relation_name));
|
||||
if ( (r2 = MET_lookup_relation(tdbb, relation_name)) )
|
||||
MOV_get_metaname(&desc, object_name);
|
||||
if ( (r2 = MET_lookup_relation(tdbb, object_name)) )
|
||||
{
|
||||
DFW_post_work(transaction, dfw_delete_rfr, &desc2, r2->rel_id);
|
||||
}
|
||||
@ -1487,13 +1495,12 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
case rel_args:
|
||||
if (EVL_field(0, rpb->rpb_record, f_arg_pkg_name, &desc2))
|
||||
{
|
||||
MOV_get_metadata_str(&desc2, package_name, sizeof(package_name));
|
||||
MOV_get_metaname(&desc2, package_name);
|
||||
SCL_check_package(tdbb, &desc2, SCL_control);
|
||||
}
|
||||
else
|
||||
{
|
||||
EVL_field(0, rpb->rpb_record, f_arg_fun_name, &desc);
|
||||
package_name[0] = '\0';
|
||||
SCL_check_function(tdbb, &desc, SCL_control);
|
||||
}
|
||||
break;
|
||||
@ -1503,20 +1510,19 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
|
||||
if (EVL_field(0, rpb->rpb_record, f_prm_pkg_name, &desc2))
|
||||
{
|
||||
MOV_get_metadata_str(&desc2, package_name, sizeof(package_name));
|
||||
MOV_get_metaname(&desc2, package_name);
|
||||
SCL_check_package(tdbb, &desc2, SCL_control);
|
||||
}
|
||||
else
|
||||
{
|
||||
package_name[0] = '\0';
|
||||
SCL_check_procedure(tdbb, &desc, SCL_control);
|
||||
}
|
||||
|
||||
EVL_field(0, rpb->rpb_record, f_prm_name, &desc2);
|
||||
MOV_get_metadata_str(&desc, procedure_name, sizeof(procedure_name));
|
||||
MOV_get_metaname(&desc, object_name);
|
||||
|
||||
if ((procedure = MET_lookup_procedure(tdbb,
|
||||
QualifiedName(procedure_name, package_name), true)))
|
||||
if ( (procedure = MET_lookup_procedure(tdbb,
|
||||
QualifiedName(object_name, package_name), true)) )
|
||||
{
|
||||
work = DFW_post_work(transaction, dfw_delete_prm, &desc2, procedure->getId(),
|
||||
package_name);
|
||||
@ -1529,8 +1535,9 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
break;
|
||||
|
||||
case rel_fields:
|
||||
check_control(tdbb);
|
||||
EVL_field(0, rpb->rpb_record, f_fld_name, &desc);
|
||||
MOV_get_metaname(&desc, object_name);
|
||||
SCL_check_domain(tdbb, object_name, SCL_delete);
|
||||
DFW_post_work(transaction, dfw_delete_field, &desc, 0);
|
||||
MET_change_fields(tdbb, transaction, &desc);
|
||||
break;
|
||||
@ -1666,15 +1673,16 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
if ((RIDS) relation->rel_id == rel_priv)
|
||||
{
|
||||
EVL_field(0, rpb->rpb_record, f_prv_rname, &desc);
|
||||
MOV_get_metadata_str(&desc, relation_name, sizeof(relation_name));
|
||||
MOV_get_metaname(&desc, object_name);
|
||||
EVL_field(0, rpb->rpb_record, f_prv_grant, &desc2);
|
||||
if (MOV_get_long(&desc2, 0))
|
||||
{
|
||||
EVL_field(0, rpb->rpb_record, f_prv_user, &desc2);
|
||||
MOV_get_metadata_str(&desc2, revokee, sizeof(revokee));
|
||||
MetaName revokee;
|
||||
MOV_get_metaname(&desc2, revokee);
|
||||
EVL_field(0, rpb->rpb_record, f_prv_priv, &desc2);
|
||||
MOV_get_metadata_str(&desc2, privilege, sizeof(privilege));
|
||||
MET_revoke(tdbb, transaction, relation_name, revokee, privilege);
|
||||
const string privilege = MOV_make_string2(tdbb, &desc2, ttype_ascii);
|
||||
MET_revoke(tdbb, transaction, object_name, revokee, privilege);
|
||||
}
|
||||
}
|
||||
if (!(transaction->tra_flags & TRA_system) &&
|
||||
@ -2321,6 +2329,8 @@ void VIO_modify(thread_db* tdbb, record_param* org_rpb, record_param* new_rpb, j
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
|
||||
MetaName object_name, package_name;
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES)
|
||||
{
|
||||
@ -2396,60 +2406,54 @@ void VIO_modify(thread_db* tdbb, record_param* org_rpb, record_param* new_rpb, j
|
||||
case rel_procedures:
|
||||
EVL_field(0, org_rpb->rpb_record, f_prc_name, &desc1);
|
||||
|
||||
{ // scope
|
||||
SqlIdentifier package_name;
|
||||
if (EVL_field(0, org_rpb->rpb_record, f_prc_pkg_name, &desc2))
|
||||
{
|
||||
MOV_get_metadata_str(&desc2, package_name, sizeof(package_name));
|
||||
SCL_check_package(tdbb, &desc2, SCL_protect);
|
||||
}
|
||||
else
|
||||
{
|
||||
package_name[0] = '\0';
|
||||
SCL_check_procedure(tdbb, &desc1, SCL_protect);
|
||||
}
|
||||
if (EVL_field(0, org_rpb->rpb_record, f_prc_pkg_name, &desc2))
|
||||
{
|
||||
MOV_get_metaname(&desc2, package_name);
|
||||
SCL_check_package(tdbb, &desc2, SCL_protect);
|
||||
}
|
||||
else
|
||||
{
|
||||
SCL_check_procedure(tdbb, &desc1, SCL_protect);
|
||||
}
|
||||
|
||||
check_class(tdbb, transaction, org_rpb, new_rpb, f_prc_class);
|
||||
check_class(tdbb, transaction, org_rpb, new_rpb, f_prc_class);
|
||||
|
||||
if (dfw_should_know(org_rpb, new_rpb, f_prc_desc, true))
|
||||
{
|
||||
EVL_field(0, org_rpb->rpb_record, f_prc_id, &desc2);
|
||||
const USHORT id = MOV_get_long(&desc2, 0);
|
||||
DFW_post_work(transaction, dfw_modify_procedure, &desc1, id, package_name);
|
||||
}
|
||||
} // scope
|
||||
if (dfw_should_know(org_rpb, new_rpb, f_prc_desc, true))
|
||||
{
|
||||
EVL_field(0, org_rpb->rpb_record, f_prc_id, &desc2);
|
||||
const USHORT id = MOV_get_long(&desc2, 0);
|
||||
DFW_post_work(transaction, dfw_modify_procedure, &desc1, id, package_name);
|
||||
}
|
||||
break;
|
||||
|
||||
case rel_funs:
|
||||
EVL_field(0, org_rpb->rpb_record, f_fun_name, &desc1);
|
||||
|
||||
{ // scope
|
||||
SqlIdentifier package_name;
|
||||
if (EVL_field(0, org_rpb->rpb_record, f_fun_pkg_name, &desc2))
|
||||
{
|
||||
MOV_get_metadata_str(&desc2, package_name, sizeof(package_name));
|
||||
SCL_check_package(tdbb, &desc2, SCL_protect);
|
||||
}
|
||||
else
|
||||
{
|
||||
package_name[0] = '\0';
|
||||
SCL_check_function(tdbb, &desc1, SCL_protect);
|
||||
}
|
||||
if (EVL_field(0, org_rpb->rpb_record, f_fun_pkg_name, &desc2))
|
||||
{
|
||||
MOV_get_metaname(&desc2, package_name);
|
||||
SCL_check_package(tdbb, &desc2, SCL_protect);
|
||||
}
|
||||
else
|
||||
{
|
||||
SCL_check_function(tdbb, &desc1, SCL_protect);
|
||||
}
|
||||
|
||||
check_class(tdbb, transaction, org_rpb, new_rpb, f_fun_class);
|
||||
check_class(tdbb, transaction, org_rpb, new_rpb, f_fun_class);
|
||||
|
||||
if (dfw_should_know(org_rpb, new_rpb, f_fun_desc, true))
|
||||
{
|
||||
EVL_field(0, org_rpb->rpb_record, f_fun_id, &desc2);
|
||||
const USHORT id = MOV_get_long(&desc2, 0);
|
||||
DFW_post_work(transaction, dfw_modify_function, &desc1, id, package_name);
|
||||
}
|
||||
} // scope
|
||||
if (dfw_should_know(org_rpb, new_rpb, f_fun_desc, true))
|
||||
{
|
||||
EVL_field(0, org_rpb->rpb_record, f_fun_id, &desc2);
|
||||
const USHORT id = MOV_get_long(&desc2, 0);
|
||||
DFW_post_work(transaction, dfw_modify_function, &desc1, id, package_name);
|
||||
}
|
||||
break;
|
||||
|
||||
case rel_gens:
|
||||
EVL_field(0, org_rpb->rpb_record, f_gen_name, &desc1);
|
||||
MOV_get_metaname(&desc1, object_name);
|
||||
SCL_check_generator(tdbb, object_name, SCL_protect);
|
||||
{
|
||||
EVL_field (0, org_rpb->rpb_record, f_gen_name, &desc1);
|
||||
// We won't accept modifying sys generators and for user gens,
|
||||
// only the description.
|
||||
// This is poor man's version of a trigger discovering changed fields.
|
||||
@ -2480,11 +2484,12 @@ void VIO_modify(thread_db* tdbb, record_param* org_rpb, record_param* new_rpb, j
|
||||
break;
|
||||
|
||||
case rel_fields:
|
||||
check_control(tdbb);
|
||||
EVL_field(0, org_rpb->rpb_record, f_fld_name, &desc1);
|
||||
MOV_get_metaname(&desc1, object_name);
|
||||
SCL_check_domain(tdbb, object_name, SCL_protect);
|
||||
|
||||
if (dfw_should_know(org_rpb, new_rpb, f_fld_desc, true))
|
||||
{
|
||||
EVL_field(0, org_rpb->rpb_record, f_fld_name, &desc1);
|
||||
MET_change_fields(tdbb, transaction, &desc1);
|
||||
EVL_field(0, new_rpb->rpb_record, f_fld_name, &desc2);
|
||||
DeferredWork* dw = MET_change_fields(tdbb, transaction, &desc2);
|
||||
@ -2583,6 +2588,24 @@ void VIO_modify(thread_db* tdbb, record_param* org_rpb, record_param* new_rpb, j
|
||||
}
|
||||
break;
|
||||
|
||||
case rel_charsets:
|
||||
EVL_field(0, new_rpb->rpb_record, fld_charset_name, &desc1);
|
||||
MOV_get_metaname(&desc1, object_name);
|
||||
SCL_check_charset(tdbb, object_name, SCL_protect);
|
||||
break;
|
||||
|
||||
case rel_collations:
|
||||
EVL_field(0, new_rpb->rpb_record, f_coll_name, &desc1);
|
||||
MOV_get_metaname(&desc1, object_name);
|
||||
SCL_check_collation(tdbb, object_name, SCL_protect);
|
||||
break;
|
||||
|
||||
case rel_exceptions:
|
||||
EVL_field(0, new_rpb->rpb_record, f_xcp_name, &desc1);
|
||||
MOV_get_metaname(&desc1, object_name);
|
||||
SCL_check_exception(tdbb, object_name, SCL_protect);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2934,11 +2957,9 @@ void VIO_store(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
case rel_procedures:
|
||||
EVL_field(0, rpb->rpb_record, f_prc_name, &desc);
|
||||
{ // scope
|
||||
SqlIdentifier package_name;
|
||||
MetaName package_name;
|
||||
if (EVL_field(0, rpb->rpb_record, f_prc_pkg_name, &desc2))
|
||||
MOV_get_metadata_str(&desc2, package_name, sizeof(package_name));
|
||||
else
|
||||
package_name[0] = '\0';
|
||||
MOV_get_metaname(&desc2, package_name);
|
||||
|
||||
EVL_field(0, rpb->rpb_record, f_prc_id, &desc2);
|
||||
const USHORT id = MOV_get_long(&desc2, 0);
|
||||
@ -2957,11 +2978,9 @@ void VIO_store(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
case rel_funs:
|
||||
EVL_field(0, rpb->rpb_record, f_fun_name, &desc);
|
||||
{ // scope
|
||||
SqlIdentifier package_name;
|
||||
MetaName package_name;
|
||||
if (EVL_field(0, rpb->rpb_record, f_fun_pkg_name, &desc2))
|
||||
MOV_get_metadata_str(&desc2, package_name, sizeof(package_name));
|
||||
else
|
||||
package_name[0] = '\0';
|
||||
MOV_get_metaname(&desc2, package_name);
|
||||
|
||||
const USHORT id =
|
||||
set_metadata_id(tdbb, rpb->rpb_record, f_fun_id, drq_g_nxt_fun_id, "RDB$FUNCTIONS");
|
||||
@ -3010,6 +3029,7 @@ void VIO_store(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
EVL_field(0, rpb->rpb_record, f_fld_name, &desc);
|
||||
DFW_post_work(transaction, dfw_create_field, &desc, 0);
|
||||
set_system_flag(tdbb, rpb->rpb_record, f_fld_sys_flag, 0);
|
||||
set_security_class(tdbb, rpb->rpb_record, f_fld_class);
|
||||
break;
|
||||
|
||||
case rel_files:
|
||||
@ -3099,6 +3119,19 @@ void VIO_store(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
transaction->getGenIdCache()->put(id, 0);
|
||||
DFW_post_work(transaction, dfw_create_generator, &desc, id);
|
||||
}
|
||||
set_security_class(tdbb, rpb->rpb_record, f_gen_class);
|
||||
break;
|
||||
|
||||
case rel_charsets:
|
||||
set_security_class(tdbb, rpb->rpb_record, f_cs_class);
|
||||
break;
|
||||
|
||||
case rel_collations:
|
||||
set_security_class(tdbb, rpb->rpb_record, f_coll_class);
|
||||
break;
|
||||
|
||||
case rel_exceptions:
|
||||
set_security_class(tdbb, rpb->rpb_record, f_xcp_class);
|
||||
break;
|
||||
|
||||
default: // Shut up compiler warnings
|
||||
@ -5443,7 +5476,7 @@ static void set_security_class(thread_db* tdbb, Record* record, USHORT field_id)
|
||||
{
|
||||
const SINT64 value = DYN_UTIL_gen_unique_id(tdbb, drq_g_nxt_sec_id, SQL_SECCLASS_GENERATOR);
|
||||
Firebird::MetaName name;
|
||||
name.printf("%s%d", SQL_SECCLASS_PREFIX, value);
|
||||
name.printf("%s%"SQUADFORMAT, SQL_SECCLASS_PREFIX, value);
|
||||
dsc desc2;
|
||||
desc2.makeText((USHORT) name.length(), CS_ASCII, (UCHAR*) name.c_str());
|
||||
MOV_move(tdbb, &desc2, &desc1);
|
||||
|
Loading…
Reference in New Issue
Block a user