mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-02-02 10:00:38 +01:00
Make DDL object type constants stable and extendable (#7125)
Add shift to DDL object type while restoring backup of prior version. Rework DDL access checks. Remove unneeded constants, duplicating code. Rename some functions to suit their purpose. Provide a way to extent object type constants in future not changing existing ones.
This commit is contained in:
parent
13bda0c1b6
commit
b4be5b9ae2
@ -10239,6 +10239,8 @@ bool get_user_privilege(BurpGlobals* tdgbl)
|
||||
case att_priv_obj_type:
|
||||
flags |= USER_PRIV_OBJECT_TYPE;
|
||||
object_type = (USHORT) get_int32(tdgbl);
|
||||
if ( (tdgbl->RESTORE_format < 11) && (object_type > 19) ) // FB 4 has a shift :(
|
||||
object_type++;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -10310,9 +10312,6 @@ bool get_user_privilege(BurpGlobals* tdgbl)
|
||||
}
|
||||
break;
|
||||
|
||||
case obj_database:
|
||||
break;
|
||||
|
||||
default:
|
||||
exists = true;
|
||||
break;
|
||||
|
@ -1354,7 +1354,6 @@ void CommentOnNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
|
||||
switch (objType)
|
||||
{
|
||||
case obj_schema:
|
||||
case obj_database:
|
||||
SCL_check_database(tdbb, SCL_alter);
|
||||
break;
|
||||
@ -1577,12 +1576,6 @@ void CommentOnNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
status << Arg::Gds(isc_dyn_package_not_found) << Arg::Str(objNameStr);
|
||||
break;
|
||||
|
||||
case obj_schema:
|
||||
tableClause = "rdb$schemas";
|
||||
columnClause = "rdb$schema_name";
|
||||
status << Arg::Gds(isc_dyn_schema_not_found) << Arg::Str(objNameStr);
|
||||
break;
|
||||
|
||||
default:
|
||||
fb_assert(false);
|
||||
return;
|
||||
@ -1741,7 +1734,7 @@ void CreateAlterFunctionNode::checkPermission(thread_db* tdbb, jrd_tra* transact
|
||||
return;
|
||||
}
|
||||
|
||||
SCL_check_create_access(tdbb, SCL_object_function);
|
||||
SCL_check_create_access(tdbb, obj_functions);
|
||||
}
|
||||
|
||||
void CreateAlterFunctionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
@ -2749,7 +2742,7 @@ void CreateAlterProcedureNode::checkPermission(thread_db* tdbb, jrd_tra* transac
|
||||
return;
|
||||
}
|
||||
|
||||
SCL_check_create_access(tdbb, SCL_object_procedure);
|
||||
SCL_check_create_access(tdbb, obj_procedures);
|
||||
}
|
||||
|
||||
void CreateAlterProcedureNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
@ -3950,7 +3943,7 @@ string CreateCollationNode::internalPrint(NodePrinter& printer) const
|
||||
|
||||
void CreateCollationNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
{
|
||||
SCL_check_create_access(tdbb, SCL_object_collation);
|
||||
SCL_check_create_access(tdbb, obj_collations);
|
||||
}
|
||||
|
||||
void CreateCollationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
@ -4318,7 +4311,7 @@ string CreateDomainNode::internalPrint(NodePrinter& printer) const
|
||||
|
||||
void CreateDomainNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
{
|
||||
SCL_check_create_access(tdbb, SCL_object_domain);
|
||||
SCL_check_create_access(tdbb, obj_domains);
|
||||
}
|
||||
|
||||
void CreateDomainNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
@ -5456,7 +5449,7 @@ void CreateAlterExceptionNode::checkPermission(thread_db* tdbb, jrd_tra* transac
|
||||
return;
|
||||
}
|
||||
|
||||
SCL_check_create_access(tdbb, SCL_object_exception);
|
||||
SCL_check_create_access(tdbb, obj_exceptions);
|
||||
}
|
||||
|
||||
void CreateAlterExceptionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
@ -5663,7 +5656,7 @@ void CreateAlterSequenceNode::checkPermission(thread_db* tdbb, jrd_tra* transact
|
||||
return;
|
||||
}
|
||||
|
||||
SCL_check_create_access(tdbb, SCL_object_generator);
|
||||
SCL_check_create_access(tdbb, obj_generators);
|
||||
}
|
||||
|
||||
void CreateAlterSequenceNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
@ -7396,7 +7389,7 @@ string CreateRelationNode::internalPrint(NodePrinter& printer) const
|
||||
|
||||
void CreateRelationNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
{
|
||||
SCL_check_create_access(tdbb, SCL_object_table);
|
||||
SCL_check_create_access(tdbb, obj_relations);
|
||||
}
|
||||
|
||||
void CreateRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
@ -8676,7 +8669,7 @@ void CreateAlterViewNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
return;
|
||||
}
|
||||
|
||||
SCL_check_create_access(tdbb, SCL_object_view);
|
||||
SCL_check_create_access(tdbb, obj_views);
|
||||
}
|
||||
|
||||
void CreateAlterViewNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
@ -10098,7 +10091,7 @@ string CreateFilterNode::internalPrint(NodePrinter& printer) const
|
||||
|
||||
void CreateFilterNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
{
|
||||
SCL_check_create_access(tdbb, SCL_object_filter);
|
||||
SCL_check_create_access(tdbb, obj_filters);
|
||||
}
|
||||
|
||||
// Define a blob filter.
|
||||
@ -10354,7 +10347,7 @@ string CreateAlterRoleNode::internalPrint(NodePrinter& printer) const
|
||||
void CreateAlterRoleNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
{
|
||||
if (createFlag)
|
||||
SCL_check_create_access(tdbb, SCL_object_role);
|
||||
SCL_check_create_access(tdbb, obj_roles);
|
||||
else
|
||||
SCL_check_role(tdbb, name, SCL_alter);
|
||||
}
|
||||
@ -11520,10 +11513,10 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
||||
const GranteeClause* userNod, const char* privs,
|
||||
MetaName field, int options)
|
||||
{
|
||||
SSHORT userType = userNod->first;
|
||||
ObjectType userType = userNod->first;
|
||||
MetaName user(userNod->second);
|
||||
MetaName dummyName;
|
||||
const SSHORT objType = object ? object->first : obj_type_MAX;
|
||||
const ObjectType objType = object ? object->first : obj_type_MAX;
|
||||
const MetaName objName(object ? object->second : "");
|
||||
bool crdb = false;
|
||||
|
||||
@ -11675,7 +11668,7 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
||||
break;
|
||||
|
||||
default:
|
||||
fb_assert(object == NULL || objType >= obj_database);
|
||||
fb_assert(object == NULL || isDdlObject(objType));
|
||||
}
|
||||
|
||||
if (options == 1) // with grant option
|
||||
@ -11879,10 +11872,8 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
||||
}
|
||||
|
||||
default:
|
||||
if (objType >= obj_database)
|
||||
{
|
||||
if (isDdlObject(objType))
|
||||
checkGrantorCanGrantDdl(tdbb, transaction, currentUser.c_str(), priv, objName);
|
||||
}
|
||||
else
|
||||
fb_assert(false);
|
||||
}
|
||||
@ -12304,12 +12295,16 @@ void GrantRevokeNode::checkGrantorCanGrantDdl(thread_db* tdbb, jrd_tra* transact
|
||||
WITH ((PRV.RDB$USER = UPPERCASE(grantor.c_str()) AND
|
||||
PRV.RDB$USER_TYPE = obj_user) OR (PRV.RDB$USER_TYPE = obj_sql_role)) AND
|
||||
PRV.RDB$RELATION_NAME EQ objName.c_str() AND
|
||||
PRV.RDB$OBJECT_TYPE >= obj_database AND
|
||||
PRV.RDB$OBJECT_TYPE >= obj_database AND // it might be deleted but I believe it's more efficient
|
||||
PRV.RDB$PRIVILEGE EQ privilege
|
||||
{
|
||||
if ( (PRV.RDB$USER_TYPE == obj_sql_role) && !attachment->att_user->roleInUse(tdbb, PRV.RDB$USER))
|
||||
continue;
|
||||
|
||||
// Double check if the object is DDL one.
|
||||
if (!isDdlObject(PRV.RDB$OBJECT_TYPE))
|
||||
continue;
|
||||
|
||||
if (PRV.RDB$GRANT_OPTION == WITH_GRANT_OPTION)
|
||||
{
|
||||
grantable = true;
|
||||
|
@ -2279,7 +2279,7 @@ typedef RecreateNode<CreateAlterUserNode, DropUserNode, isc_dsql_recreate_user_f
|
||||
|
||||
|
||||
typedef Firebird::Pair<Firebird::NonPooled<char, ValueListNode*> > PrivilegeClause;
|
||||
typedef Firebird::Pair<Firebird::NonPooled<SSHORT, MetaName> > GranteeClause;
|
||||
typedef Firebird::Pair<Firebird::NonPooled<ObjectType, MetaName> > GranteeClause;
|
||||
|
||||
class GrantRevokeNode : public PrivilegesNode, private ExecInSecurityDb
|
||||
{
|
||||
|
@ -6624,14 +6624,14 @@ ValueExprNode* FieldNode::pass1(thread_db* tdbb, CompilerScratch* csb)
|
||||
tail->csb_view->rel_id : (csb->csb_view ? csb->csb_view->rel_id : 0);
|
||||
|
||||
CMP_post_access(tdbb, csb, relation->rel_security_name, ssRelationId,
|
||||
privilege, SCL_object_table, relation->rel_name);
|
||||
privilege, obj_relations, relation->rel_name);
|
||||
|
||||
// Field-level privilege access is posted for every operation except DELETE
|
||||
|
||||
if (privilege != SCL_delete)
|
||||
{
|
||||
CMP_post_access(tdbb, csb, field->fld_security_name, ssRelationId,
|
||||
privilege, SCL_object_column, field->fld_name, relation->rel_name);
|
||||
privilege, obj_column, field->fld_name, relation->rel_name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7039,7 +7039,7 @@ ValueExprNode* GenIdNode::pass1(thread_db* tdbb, CompilerScratch* csb)
|
||||
if (!identity)
|
||||
{
|
||||
CMP_post_access(tdbb, csb, generator.secName, 0,
|
||||
SCL_usage, SCL_object_generator, generator.name);
|
||||
SCL_usage, obj_generators, generator.name);
|
||||
}
|
||||
|
||||
return this;
|
||||
@ -12919,13 +12919,13 @@ ValueExprNode* UdfCallNode::pass1(thread_db* tdbb, CompilerScratch* csb)
|
||||
}
|
||||
|
||||
CMP_post_access(tdbb, csb, function->getSecurityName(), ssRelationId,
|
||||
SCL_execute, SCL_object_function, function->getName().identifier);
|
||||
SCL_execute, obj_functions, function->getName().identifier);
|
||||
}
|
||||
else
|
||||
{
|
||||
CMP_post_access(tdbb, csb, function->getSecurityName(),
|
||||
(csb->csb_view ? csb->csb_view->rel_id : 0),
|
||||
SCL_execute, SCL_object_package, function->getName().package);
|
||||
SCL_execute, obj_packages, function->getName().package);
|
||||
}
|
||||
|
||||
ExternalAccess temp(ExternalAccess::exa_function, function->getId());
|
||||
|
@ -297,7 +297,7 @@ void CreateAlterPackageNode::checkPermission(thread_db* tdbb, jrd_tra* transacti
|
||||
return;
|
||||
}
|
||||
|
||||
SCL_check_create_access(tdbb, SCL_object_package);
|
||||
SCL_check_create_access(tdbb, obj_packages);
|
||||
}
|
||||
|
||||
|
||||
@ -699,7 +699,7 @@ DdlNode* CreatePackageBodyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||
|
||||
void CreatePackageBodyNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
{
|
||||
SCL_check_create_access(tdbb, SCL_object_package);
|
||||
SCL_check_create_access(tdbb, obj_packages);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4671,7 +4671,7 @@ ExceptionNode* ExceptionNode::pass1(thread_db* tdbb, CompilerScratch* csb)
|
||||
if (exception)
|
||||
{
|
||||
CMP_post_access(tdbb, csb, exception->secName, 0,
|
||||
SCL_usage, SCL_object_exception, exception->name);
|
||||
SCL_usage, obj_exceptions, exception->name);
|
||||
}
|
||||
|
||||
return this;
|
||||
@ -8421,7 +8421,7 @@ SetGeneratorNode* SetGeneratorNode::pass1(thread_db* tdbb, CompilerScratch* csb)
|
||||
doPass1(tdbb, csb, value.getAddress());
|
||||
|
||||
CMP_post_access(tdbb, csb, generator.secName, 0,
|
||||
SCL_usage, SCL_object_generator, generator.name);
|
||||
SCL_usage, obj_generators, generator.name);
|
||||
|
||||
return this;
|
||||
}
|
||||
@ -10625,7 +10625,7 @@ static RelationSourceNode* pass1Update(thread_db* tdbb, CompilerScratch* csb, jr
|
||||
// unless this is an internal request, check access permission
|
||||
|
||||
CMP_post_access(tdbb, csb, relation->rel_security_name, (view ? view->rel_id : 0),
|
||||
priv, SCL_object_table, relation->rel_name);
|
||||
priv, obj_relations, relation->rel_name);
|
||||
|
||||
// ensure that the view is set for the input streams,
|
||||
// so that access to views can be checked at the field level
|
||||
|
@ -1009,7 +1009,7 @@ grant0($node)
|
||||
| db_ddl_privileges(NOTRIAL(&$node->privileges)) DATABASE
|
||||
TO non_role_grantee_list(NOTRIAL(&$node->users)) grant_option granted_by
|
||||
{
|
||||
$node->object = newNode<GranteeClause>(obj_database, get_object_name(obj_database));
|
||||
$node->object = newNode<GranteeClause>(obj_database, getSecurityClassName(obj_database));
|
||||
$node->grantAdminOption = $5;
|
||||
$node->grantor = $6;
|
||||
$node->isDdl = true;
|
||||
@ -1025,31 +1025,31 @@ grant0($node)
|
||||
%type <granteeClause> object
|
||||
object
|
||||
: TABLE
|
||||
{ $$ = newNode<GranteeClause>(obj_relations, get_object_name(obj_relations)); }
|
||||
{ $$ = newNode<GranteeClause>(obj_relations, getSecurityClassName(obj_relations)); }
|
||||
| VIEW
|
||||
{ $$ = newNode<GranteeClause>(obj_views, get_object_name(obj_views)); }
|
||||
{ $$ = newNode<GranteeClause>(obj_views, getSecurityClassName(obj_views)); }
|
||||
| PROCEDURE
|
||||
{ $$ = newNode<GranteeClause>(obj_procedures, get_object_name(obj_procedures)); }
|
||||
{ $$ = newNode<GranteeClause>(obj_procedures, getSecurityClassName(obj_procedures)); }
|
||||
| FUNCTION
|
||||
{ $$ = newNode<GranteeClause>(obj_functions, get_object_name(obj_functions)); }
|
||||
{ $$ = newNode<GranteeClause>(obj_functions, getSecurityClassName(obj_functions)); }
|
||||
| PACKAGE
|
||||
{ $$ = newNode<GranteeClause>(obj_packages, get_object_name(obj_packages)); }
|
||||
{ $$ = newNode<GranteeClause>(obj_packages, getSecurityClassName(obj_packages)); }
|
||||
| GENERATOR
|
||||
{ $$ = newNode<GranteeClause>(obj_generators, get_object_name(obj_generators)); }
|
||||
{ $$ = newNode<GranteeClause>(obj_generators, getSecurityClassName(obj_generators)); }
|
||||
| SEQUENCE
|
||||
{ $$ = newNode<GranteeClause>(obj_generators, get_object_name(obj_generators)); }
|
||||
{ $$ = newNode<GranteeClause>(obj_generators, getSecurityClassName(obj_generators)); }
|
||||
| DOMAIN
|
||||
{ $$ = newNode<GranteeClause>(obj_domains, get_object_name(obj_domains)); }
|
||||
{ $$ = newNode<GranteeClause>(obj_domains, getSecurityClassName(obj_domains)); }
|
||||
| EXCEPTION
|
||||
{ $$ = newNode<GranteeClause>(obj_exceptions, get_object_name(obj_exceptions)); }
|
||||
{ $$ = newNode<GranteeClause>(obj_exceptions, getSecurityClassName(obj_exceptions)); }
|
||||
| ROLE
|
||||
{ $$ = newNode<GranteeClause>(obj_roles, get_object_name(obj_roles)); }
|
||||
{ $$ = newNode<GranteeClause>(obj_roles, getSecurityClassName(obj_roles)); }
|
||||
| CHARACTER SET
|
||||
{ $$ = newNode<GranteeClause>(obj_charsets, get_object_name(obj_charsets)); }
|
||||
{ $$ = newNode<GranteeClause>(obj_charsets, getSecurityClassName(obj_charsets)); }
|
||||
| COLLATION
|
||||
{ $$ = newNode<GranteeClause>(obj_collations, get_object_name(obj_collations)); }
|
||||
{ $$ = newNode<GranteeClause>(obj_collations, getSecurityClassName(obj_collations)); }
|
||||
| FILTER
|
||||
{ $$ = newNode<GranteeClause>(obj_filters, get_object_name(obj_filters)); }
|
||||
{ $$ = newNode<GranteeClause>(obj_filters, getSecurityClassName(obj_filters)); }
|
||||
;
|
||||
|
||||
table_noise
|
||||
@ -1266,7 +1266,7 @@ revoke0($node)
|
||||
| rev_grant_option db_ddl_privileges(NOTRIAL(&$node->privileges)) DATABASE
|
||||
FROM non_role_grantee_list(NOTRIAL(&$node->users)) granted_by
|
||||
{
|
||||
$node->object = newNode<GranteeClause>(obj_database, get_object_name(obj_database));
|
||||
$node->object = newNode<GranteeClause>(obj_database, getSecurityClassName(obj_database));
|
||||
$node->grantAdminOption = $1;
|
||||
$node->grantor = $6;
|
||||
$node->isDdl = true;
|
||||
|
@ -1404,10 +1404,13 @@ static processing_state list_all_grants2(bool show_role_list, const SCHAR* termi
|
||||
***/
|
||||
|
||||
// Process DDL permissions
|
||||
for (int i = obj_database; i < obj_type_MAX; i++)
|
||||
for (SSHORT obj = obj_database; obj < obj_type_MAX; obj++)
|
||||
{
|
||||
if (!isDdlObject(obj))
|
||||
continue;
|
||||
|
||||
const processing_state rc =
|
||||
SHOW_grants2(get_object_name(i), terminator, i, first ? banner : 0, mangle);
|
||||
SHOW_grants2(getSecurityClassName(obj), terminator, obj, first ? banner : 0, mangle);
|
||||
if (rc == SKIP)
|
||||
first = false;
|
||||
}
|
||||
|
@ -655,7 +655,7 @@ bool SHOW_dbb_parameters(Firebird::IAttachment* db_handle,
|
||||
}
|
||||
|
||||
|
||||
processing_state SHOW_grants(const SCHAR* object, const SCHAR* terminator, USHORT obj_type)
|
||||
processing_state SHOW_grants(const SCHAR* object, const SCHAR* terminator, ObjectType obj_type)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -786,7 +786,7 @@ static void set_grantee(int user_type, const char* SQL_identifier, char* user_st
|
||||
|
||||
processing_state SHOW_grants2 (const SCHAR* object,
|
||||
const SCHAR* terminator,
|
||||
USHORT obj_type,
|
||||
ObjectType obj_type,
|
||||
const TEXT* optional_msg,
|
||||
bool mangle)
|
||||
{
|
||||
@ -837,7 +837,7 @@ processing_state SHOW_grants2 (const SCHAR* object,
|
||||
USHORT priv_flags = 0;
|
||||
SSHORT prev_field_null = -1;
|
||||
|
||||
if (obj_type == obj_relation || obj_type == 255)
|
||||
if (obj_type == obj_relation || obj_type == obj_any)
|
||||
{
|
||||
// Find the user specified relation and show its privileges
|
||||
|
||||
@ -1020,7 +1020,7 @@ processing_state SHOW_grants2 (const SCHAR* object,
|
||||
}
|
||||
|
||||
// No relation called "object" was found, try procedure "object"
|
||||
if (obj_type == obj_procedure || obj_type == 255)
|
||||
if (obj_type == obj_procedure || obj_type == obj_any)
|
||||
{
|
||||
FOR FIRST 1 P IN RDB$PROCEDURES WITH
|
||||
P.RDB$PROCEDURE_NAME EQ object AND
|
||||
@ -1099,7 +1099,7 @@ processing_state SHOW_grants2 (const SCHAR* object,
|
||||
// No procedure called "object" was found, try role "object"
|
||||
SCHAR role_name[BUFFER_LENGTH256];
|
||||
|
||||
if (obj_type == obj_sql_role || obj_type == 255)
|
||||
if (obj_type == obj_sql_role || obj_type == obj_any)
|
||||
{
|
||||
// No procedure called "object" was found, try role "object"
|
||||
// CVC: This code could be superseded by SHOW_grant_roles() below
|
||||
@ -1164,7 +1164,7 @@ processing_state SHOW_grants2 (const SCHAR* object,
|
||||
return (SKIP);
|
||||
}
|
||||
|
||||
if (obj_type == obj_package_header || obj_type == 255)
|
||||
if (obj_type == obj_package_header || obj_type == obj_any)
|
||||
{
|
||||
if (isqlGlob.major_ods >= ODS_VERSION12)
|
||||
{
|
||||
@ -1238,7 +1238,7 @@ processing_state SHOW_grants2 (const SCHAR* object,
|
||||
}
|
||||
}
|
||||
|
||||
if (obj_type == obj_udf || obj_type == 255)
|
||||
if (obj_type == obj_udf || obj_type == obj_any)
|
||||
{
|
||||
if (isqlGlob.major_ods >= ODS_VERSION12)
|
||||
{
|
||||
@ -1316,7 +1316,7 @@ processing_state SHOW_grants2 (const SCHAR* object,
|
||||
}
|
||||
}
|
||||
|
||||
if (obj_type == obj_generator || obj_type == 255)
|
||||
if (obj_type == obj_generator || obj_type == obj_any)
|
||||
{
|
||||
if (isqlGlob.major_ods >= ODS_VERSION12)
|
||||
{
|
||||
@ -1390,7 +1390,7 @@ processing_state SHOW_grants2 (const SCHAR* object,
|
||||
}
|
||||
}
|
||||
|
||||
if (obj_type == obj_exception || obj_type == 255)
|
||||
if (obj_type == obj_exception || obj_type == obj_any)
|
||||
{
|
||||
if (isqlGlob.major_ods >= ODS_VERSION12)
|
||||
{
|
||||
@ -1688,7 +1688,7 @@ processing_state SHOW_grants2 (const SCHAR* object,
|
||||
}
|
||||
***/
|
||||
|
||||
if (obj_type >= obj_database || obj_type == 255)
|
||||
if (isDdlObject(obj_type) || obj_type == obj_any)
|
||||
{
|
||||
if (isqlGlob.major_ods >= ODS_VERSION12)
|
||||
{
|
||||
@ -1698,6 +1698,10 @@ processing_state SHOW_grants2 (const SCHAR* object,
|
||||
PRV.RDB$RELATION_NAME EQ object
|
||||
SORTED BY PRV.RDB$USER, PRV.RDB$GRANT_OPTION
|
||||
|
||||
// Double check if the object is DDL one.
|
||||
if (!isDdlObject(PRV.RDB$OBJECT_TYPE))
|
||||
continue;
|
||||
|
||||
if (first && optional_msg)
|
||||
isqlGlob.prints(optional_msg);
|
||||
|
||||
@ -1753,60 +1757,7 @@ processing_state SHOW_grants2 (const SCHAR* object,
|
||||
|
||||
set_grantee(PRV.RDB$USER_TYPE, SQL_identifier, user_string);
|
||||
|
||||
switch (PRV.RDB$OBJECT_TYPE)
|
||||
{
|
||||
case obj_database:
|
||||
strcpy(obj_string, "DATABASE");
|
||||
break;
|
||||
|
||||
case obj_relations:
|
||||
strcpy(obj_string, "TABLE");
|
||||
break;
|
||||
|
||||
case obj_views:
|
||||
strcpy(obj_string, "VIEW");
|
||||
break;
|
||||
|
||||
case obj_procedures:
|
||||
strcpy(obj_string, "PROCEDURE");
|
||||
break;
|
||||
|
||||
case obj_functions:
|
||||
strcpy(obj_string, "FUNCTION");
|
||||
break;
|
||||
|
||||
case obj_packages:
|
||||
strcpy(obj_string, "PACKAGE");
|
||||
break;
|
||||
|
||||
case obj_generators:
|
||||
strcpy(obj_string, "GENERATOR");
|
||||
break;
|
||||
|
||||
case obj_domains:
|
||||
strcpy(obj_string, "DOMAIN");
|
||||
break;
|
||||
|
||||
case obj_exceptions:
|
||||
strcpy(obj_string, "EXCEPTION");
|
||||
break;
|
||||
|
||||
case obj_roles:
|
||||
strcpy(obj_string, "ROLE");
|
||||
break;
|
||||
|
||||
case obj_charsets:
|
||||
strcpy(obj_string, "CHARACTER SET");
|
||||
break;
|
||||
|
||||
case obj_collations:
|
||||
strcpy(obj_string, "COLLATION");
|
||||
break;
|
||||
|
||||
case obj_filters:
|
||||
strcpy(obj_string, "FILTER");
|
||||
break;
|
||||
}
|
||||
strcpy(obj_string, getDdlObjectName(PRV.RDB$OBJECT_TYPE));
|
||||
|
||||
if (PRV.RDB$GRANT_OPTION)
|
||||
strcpy(with_option, " WITH GRANT OPTION");
|
||||
@ -1824,7 +1775,7 @@ processing_state SHOW_grants2 (const SCHAR* object,
|
||||
return ps_ERR;
|
||||
END_ERROR
|
||||
|
||||
if (obj_type == obj_database || obj_type == 255)
|
||||
if (obj_type == obj_database || obj_type == obj_any)
|
||||
{
|
||||
FOR PRV IN SEC$DB_CREATORS
|
||||
SORTED BY PRV.SEC$USER_TYPE, PRV.SEC$USER
|
||||
@ -2448,7 +2399,7 @@ processing_state SHOW_metadata(const SCHAR* const* cmd, SCHAR** lcmd)
|
||||
}
|
||||
else
|
||||
strcpy(SQL_id_for_grant, cmd[2]);
|
||||
ret = SHOW_grants(SQL_id_for_grant, "", 255);
|
||||
ret = SHOW_grants(SQL_id_for_grant, "", obj_any);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -26,11 +26,12 @@
|
||||
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include <firebird/Interface.h>
|
||||
#include "../jrd/obj.h"
|
||||
|
||||
void SHOW_comments(bool force);
|
||||
bool SHOW_dbb_parameters (Firebird::IAttachment*, SCHAR*, const UCHAR*, unsigned, bool, const char*);
|
||||
processing_state SHOW_grants (const SCHAR*, const SCHAR*, USHORT);
|
||||
processing_state SHOW_grants2 (const SCHAR*, const SCHAR*, USHORT, const TEXT*, bool);
|
||||
processing_state SHOW_grants (const SCHAR*, const SCHAR*, ObjectType);
|
||||
processing_state SHOW_grants2 (const SCHAR*, const SCHAR*, ObjectType, const TEXT*, bool);
|
||||
void SHOW_grant_roles (const SCHAR*, bool*);
|
||||
void SHOW_grant_roles2 (const SCHAR*, bool*, const TEXT*, bool);
|
||||
void SHOW_print_metadata_text_blob(FILE*, ISC_QUAD*, bool escape_squote = false,
|
||||
|
@ -65,7 +65,7 @@ namespace Jrd
|
||||
|
||||
virtual SLONG getSclType() const
|
||||
{
|
||||
return SCL_object_function;
|
||||
return obj_functions;
|
||||
}
|
||||
|
||||
virtual bool checkCache(thread_db* tdbb) const;
|
||||
|
@ -724,7 +724,7 @@ RecordSourceNode* RelationSourceNode::pass1(thread_db* tdbb, CompilerScratch* cs
|
||||
const SLONG ssRelationId = tail->csb_view ? tail->csb_view->rel_id :
|
||||
view ? view->rel_id : csb->csb_view ? csb->csb_view->rel_id : 0;
|
||||
CMP_post_access(tdbb, csb, relation->rel_security_name, ssRelationId,
|
||||
SCL_select, SCL_object_table, relation->rel_name);
|
||||
SCL_select, obj_relations, relation->rel_name);
|
||||
}
|
||||
|
||||
return this;
|
||||
|
@ -708,12 +708,12 @@ void Statement::verifyTriggerAccess(thread_db* tdbb, jrd_rel* ownerRelation,
|
||||
|
||||
if (!(ownerRelation->rel_flags & REL_system))
|
||||
{
|
||||
if (access->acc_type == SCL_object_table &&
|
||||
if (access->acc_type == obj_relations &&
|
||||
(ownerRelation->rel_name == access->acc_name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (access->acc_type == SCL_object_column &&
|
||||
if (access->acc_type == obj_column &&
|
||||
(ownerRelation->rel_name == access->acc_r_name))
|
||||
{
|
||||
continue;
|
||||
|
@ -327,7 +327,7 @@ void CMP_post_access(thread_db* tdbb,
|
||||
const MetaName& security_name,
|
||||
SLONG ssRelationId, // SQL SECURITY relation in which context permissions should be check
|
||||
SecurityClass::flags_t mask,
|
||||
SLONG type_name,
|
||||
ObjectType obj_type,
|
||||
const MetaName& name,
|
||||
const MetaName& r_name)
|
||||
{
|
||||
@ -353,7 +353,7 @@ void CMP_post_access(thread_db* tdbb,
|
||||
|
||||
SET_TDBB(tdbb);
|
||||
|
||||
AccessItem access(security_name, ssRelationId, name, type_name, mask, r_name);
|
||||
AccessItem access(security_name, ssRelationId, name, obj_type, mask, r_name);
|
||||
|
||||
FB_SIZE_T i;
|
||||
|
||||
@ -487,13 +487,13 @@ void CMP_post_procedure_access(thread_db* tdbb, CompilerScratch* csb, jrd_prc* p
|
||||
{
|
||||
CMP_post_access(tdbb, csb, procedure->getSecurityName(),
|
||||
(csb->csb_view ? csb->csb_view->rel_id : 0),
|
||||
SCL_execute, SCL_object_procedure, procedure->getName().identifier);
|
||||
SCL_execute, obj_procedures, procedure->getName().identifier);
|
||||
}
|
||||
else
|
||||
{
|
||||
CMP_post_access(tdbb, csb, procedure->getSecurityName(),
|
||||
(csb->csb_view ? csb->csb_view->rel_id : 0),
|
||||
SCL_execute, SCL_object_package, procedure->getName().package);
|
||||
SCL_execute, obj_packages, procedure->getName().package);
|
||||
}
|
||||
|
||||
// Add the procedure to list of external objects accessed
|
||||
|
@ -47,7 +47,7 @@ Jrd::jrd_req* CMP_make_request(Jrd::thread_db*, Jrd::CompilerScratch*, bool);
|
||||
Jrd::ItemInfo* CMP_pass2_validation(Jrd::thread_db*, Jrd::CompilerScratch*, const Jrd::Item&);
|
||||
|
||||
void CMP_post_access(Jrd::thread_db*, Jrd::CompilerScratch*, const Jrd::MetaName&, SLONG ssRelationId,
|
||||
Jrd::SecurityClass::flags_t, SLONG type_name, const Jrd::MetaName&,
|
||||
Jrd::SecurityClass::flags_t, ObjectType obj_type, const Jrd::MetaName&,
|
||||
const Jrd::MetaName& = "");
|
||||
|
||||
void CMP_post_procedure_access(Jrd::thread_db*, Jrd::CompilerScratch*, Jrd::jrd_prc*);
|
||||
|
@ -187,9 +187,10 @@ typedef Firebird::SortedArray<Resource, Firebird::EmptyStorage<Resource>,
|
||||
struct AccessItem
|
||||
{
|
||||
MetaName acc_security_name;
|
||||
SLONG acc_ss_rel_id; // Relation Id which owner will be used to check permissions
|
||||
MetaName acc_name, acc_r_name;
|
||||
SLONG acc_type;
|
||||
SLONG acc_ss_rel_id; // Relation Id which owner will be used to check permissions
|
||||
MetaName acc_name;
|
||||
MetaName acc_r_name;
|
||||
ObjectType acc_type;
|
||||
SecurityClass::flags_t acc_mask;
|
||||
|
||||
static bool greaterThan(const AccessItem& i1, const AccessItem& i2)
|
||||
@ -224,7 +225,7 @@ struct AccessItem
|
||||
}
|
||||
|
||||
AccessItem(const MetaName& security_name, SLONG view_id,
|
||||
const MetaName& name, SLONG type,
|
||||
const MetaName& name, ObjectType type,
|
||||
SecurityClass::flags_t mask, const MetaName& relName)
|
||||
: acc_security_name(security_name), acc_ss_rel_id(view_id), acc_name(name),
|
||||
acc_r_name(relName), acc_type(type), acc_mask(mask)
|
||||
|
@ -71,7 +71,7 @@ DATABASE DB = STATIC "yachts.lnk";
|
||||
static void define_default_class(thread_db*, const TEXT*, MetaName&, const Acl&,
|
||||
jrd_tra*);
|
||||
static void finish_security_class(Acl&, SecurityClass::flags_t);
|
||||
static void get_object_info(thread_db*, const TEXT*, SSHORT,
|
||||
static void get_object_info(thread_db*, const TEXT*, ObjectType,
|
||||
MetaName&, MetaName&, MetaName&, bool&);
|
||||
static SecurityClass::flags_t get_public_privs(thread_db*, const TEXT*, SSHORT);
|
||||
static void get_user_privs(thread_db*, Acl&, const TEXT*, SSHORT, const MetaName&,
|
||||
@ -85,7 +85,7 @@ static SecurityClass::flags_t squeeze_acl(Acl&, const MetaName&, SSHORT);
|
||||
static bool check_string(const UCHAR*, const MetaName&);
|
||||
|
||||
|
||||
void GRANT_privileges(thread_db* tdbb, const Firebird::string& name, USHORT id, jrd_tra* transaction)
|
||||
void GRANT_privileges(thread_db* tdbb, const Firebird::string& name, ObjectType id, jrd_tra* transaction)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -142,7 +142,7 @@ void GRANT_privileges(thread_db* tdbb, const Firebird::string& name, USHORT id,
|
||||
break;
|
||||
|
||||
default:
|
||||
if (id >= obj_database && id < obj_type_MAX)
|
||||
if (isDdlObject(id))
|
||||
priv = OWNER_PRIVS;
|
||||
break;
|
||||
}
|
||||
@ -314,7 +314,7 @@ static SecurityClass::flags_t get_public_privs(thread_db* tdbb,
|
||||
|
||||
static void get_object_info(thread_db* tdbb,
|
||||
const TEXT* object_name,
|
||||
SSHORT obj_type,
|
||||
ObjectType obj_type,
|
||||
MetaName& owner,
|
||||
MetaName& s_class,
|
||||
MetaName& default_class,
|
||||
@ -521,7 +521,7 @@ static void get_object_info(thread_db* tdbb,
|
||||
}
|
||||
else
|
||||
{
|
||||
s_class = get_object_name(obj_type);
|
||||
s_class = getSecurityClassName(obj_type);
|
||||
default_class = "";
|
||||
owner = tdbb->getDatabase()->dbb_owner;
|
||||
view = false;
|
||||
|
@ -25,12 +25,13 @@
|
||||
#define JRD_GRANT_PROTO_H
|
||||
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../jrd/obj.h"
|
||||
|
||||
namespace Jrd
|
||||
{
|
||||
class DeferredWork;
|
||||
}
|
||||
|
||||
void GRANT_privileges(Jrd::thread_db*, const Firebird::string&, USHORT, Jrd::jrd_tra*);
|
||||
void GRANT_privileges(Jrd::thread_db*, const Firebird::string&, ObjectType, Jrd::jrd_tra*);
|
||||
|
||||
#endif // JRD_GRANT_PROTO_H
|
||||
|
@ -167,11 +167,11 @@ void IDX_check_access(thread_db* tdbb, CompilerScratch* csb, jrd_rel* view, jrd_
|
||||
CMP_post_access(tdbb, csb,
|
||||
referenced_relation->rel_security_name,
|
||||
(view ? view->rel_id : 0),
|
||||
SCL_references, SCL_object_table,
|
||||
SCL_references, obj_relations,
|
||||
referenced_relation->rel_name);
|
||||
CMP_post_access(tdbb, csb,
|
||||
referenced_field->fld_security_name, 0,
|
||||
SCL_references, SCL_object_column,
|
||||
SCL_references, obj_column,
|
||||
referenced_field->fld_name, referenced_relation->rel_name);
|
||||
}
|
||||
|
||||
|
@ -524,9 +524,10 @@ void INI_format(const char* owner, const char* charset)
|
||||
|
||||
length = acl - buffer;
|
||||
|
||||
for (int ddl_obj = obj_database + 1; ddl_obj < obj_type_MAX; ++ddl_obj)
|
||||
for (int obj = obj_database + 1; obj < obj_type_MAX; obj++)
|
||||
{
|
||||
add_security_class(tdbb, reqAddSC, get_object_name(ddl_obj), length, buffer);
|
||||
if (isDdlObject(obj))
|
||||
add_security_class(tdbb, reqAddSC, getSecurityClassName(obj), length, buffer);
|
||||
}
|
||||
|
||||
{ // scope
|
||||
|
@ -248,7 +248,7 @@ public:
|
||||
|
||||
virtual SLONG getSclType() const
|
||||
{
|
||||
return SCL_object_procedure;
|
||||
return obj_procedures;
|
||||
}
|
||||
|
||||
virtual void releaseFormat()
|
||||
|
154
src/jrd/obj.h
154
src/jrd/obj.h
@ -24,56 +24,88 @@
|
||||
#ifndef JRD_OBJ_H
|
||||
#define JRD_OBJ_H
|
||||
|
||||
// Object types used in RDB$DEPENDENCIES and RDB$USER_PRIVILEGES
|
||||
// Object types used in RDB$DEPENDENCIES and RDB$USER_PRIVILEGES and stored in backup.
|
||||
// Note: some values are hard coded in grant.gdl
|
||||
// Keep existing constants unchanged.
|
||||
|
||||
const int obj_relation = 0;
|
||||
const int obj_view = 1;
|
||||
const int obj_trigger = 2;
|
||||
const int obj_computed = 3;
|
||||
const int obj_validation = 4;
|
||||
const int obj_procedure = 5;
|
||||
const int obj_expression_index = 6;
|
||||
const int obj_exception = 7;
|
||||
const int obj_user = 8;
|
||||
const int obj_field = 9;
|
||||
const int obj_index = 10;
|
||||
const int obj_charset = 11;
|
||||
const int obj_user_group = 12;
|
||||
const int obj_sql_role = 13;
|
||||
const int obj_generator = 14;
|
||||
const int obj_udf = 15;
|
||||
const int obj_blob_filter = 16;
|
||||
const int obj_collation = 17;
|
||||
const int obj_package_header = 18;
|
||||
const int obj_package_body = 19;
|
||||
const int obj_privilege = 20;
|
||||
typedef SSHORT ObjectType;
|
||||
|
||||
const int obj_last_non_ddl = 20; // keep in sync!!!
|
||||
const ObjectType obj_relation = 0;
|
||||
const ObjectType obj_view = 1;
|
||||
const ObjectType obj_trigger = 2;
|
||||
const ObjectType obj_computed = 3;
|
||||
const ObjectType obj_validation = 4;
|
||||
const ObjectType obj_procedure = 5;
|
||||
const ObjectType obj_expression_index = 6;
|
||||
const ObjectType obj_exception = 7;
|
||||
const ObjectType obj_user = 8;
|
||||
const ObjectType obj_field = 9;
|
||||
const ObjectType obj_index = 10;
|
||||
const ObjectType obj_charset = 11;
|
||||
const ObjectType obj_user_group = 12;
|
||||
const ObjectType obj_sql_role = 13;
|
||||
const ObjectType obj_generator = 14;
|
||||
const ObjectType obj_udf = 15;
|
||||
const ObjectType obj_blob_filter = 16;
|
||||
const ObjectType obj_collation = 17;
|
||||
const ObjectType obj_package_header = 18;
|
||||
const ObjectType obj_package_body = 19;
|
||||
const ObjectType obj_privilege = 20;
|
||||
|
||||
// objects types for ddl operations
|
||||
const int obj_database = obj_last_non_ddl + 1;
|
||||
const int obj_relations = obj_last_non_ddl + 2;
|
||||
const int obj_views = obj_last_non_ddl + 3;
|
||||
const int obj_procedures = obj_last_non_ddl + 4;
|
||||
const int obj_functions = obj_last_non_ddl + 5;
|
||||
const int obj_packages = obj_last_non_ddl + 6;
|
||||
const int obj_generators = obj_last_non_ddl + 7;
|
||||
const int obj_domains = obj_last_non_ddl + 8;
|
||||
const int obj_exceptions = obj_last_non_ddl + 9;
|
||||
const int obj_roles = obj_last_non_ddl + 10;
|
||||
const int obj_charsets = obj_last_non_ddl + 11;
|
||||
const int obj_collations = obj_last_non_ddl + 12;
|
||||
const int obj_filters = obj_last_non_ddl + 13;
|
||||
const ObjectType obj_database = 21;
|
||||
const ObjectType obj_relations = 22;
|
||||
const ObjectType obj_views = 23;
|
||||
const ObjectType obj_procedures = 24;
|
||||
const ObjectType obj_functions = 25;
|
||||
const ObjectType obj_packages = 26;
|
||||
const ObjectType obj_generators = 27;
|
||||
const ObjectType obj_domains = 28;
|
||||
const ObjectType obj_exceptions = 29;
|
||||
const ObjectType obj_roles = 30;
|
||||
const ObjectType obj_charsets = 31;
|
||||
const ObjectType obj_collations = 32;
|
||||
const ObjectType obj_filters = 33;
|
||||
|
||||
const int obj_type_MAX = obj_last_non_ddl + 14; // keep this last!
|
||||
// Add new codes here if they are used in RDB$DEPENDENCIES or RDB$USER_PRIVILEGES or stored in backup
|
||||
// Codes for DDL operations add in isDdlObject function as well (find it below).
|
||||
// etc. obj_tablespaces,
|
||||
|
||||
const ObjectType obj_type_MAX = 34;
|
||||
|
||||
// used in the parser only / no relation with obj_type_MAX (should be greater)
|
||||
const int obj_user_or_role = 100;
|
||||
const int obj_schema = 101;
|
||||
const int obj_parameter = 102;
|
||||
const ObjectType obj_user_or_role= 100;
|
||||
const ObjectType obj_parameter = 101;
|
||||
const ObjectType obj_column = 102;
|
||||
|
||||
inline const char* get_object_name(int object_type)
|
||||
const ObjectType obj_any = 255;
|
||||
|
||||
|
||||
inline bool isDdlObject(ObjectType object_type)
|
||||
{
|
||||
switch (object_type)
|
||||
{
|
||||
case obj_database:
|
||||
case obj_relations:
|
||||
case obj_views:
|
||||
case obj_procedures:
|
||||
case obj_functions:
|
||||
case obj_packages:
|
||||
case obj_generators:
|
||||
case obj_filters:
|
||||
case obj_domains:
|
||||
case obj_exceptions:
|
||||
case obj_roles:
|
||||
case obj_charsets:
|
||||
case obj_collations:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline const char* getSecurityClassName(ObjectType object_type)
|
||||
{
|
||||
switch (object_type)
|
||||
{
|
||||
@ -108,4 +140,44 @@ inline const char* get_object_name(int object_type)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline const char* getDdlObjectName(ObjectType object_type)
|
||||
{
|
||||
switch (object_type)
|
||||
{
|
||||
case obj_database:
|
||||
return "DATABASE";
|
||||
case obj_relations:
|
||||
return "TABLE";
|
||||
case obj_packages:
|
||||
return "PACKAGE";
|
||||
case obj_procedures:
|
||||
return "PROCEDURE";
|
||||
case obj_functions:
|
||||
return "FUNCTION";
|
||||
case obj_column:
|
||||
return "COLUMN";
|
||||
case obj_charsets:
|
||||
return "CHARACTER SET";
|
||||
case obj_collations:
|
||||
return "COLLATION";
|
||||
case obj_domains:
|
||||
return "DOMAIN";
|
||||
case obj_exceptions:
|
||||
return "EXCEPTION";
|
||||
case obj_generators:
|
||||
return "GENERATOR";
|
||||
case obj_views:
|
||||
return "VIEW";
|
||||
case obj_roles:
|
||||
return "ROLE";
|
||||
case obj_filters:
|
||||
return "FILTER";
|
||||
default:
|
||||
fb_assert(false);
|
||||
return "<unknown object type>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // JRD_OBJ_H
|
||||
|
@ -970,7 +970,7 @@ RecordSource* Optimizer::compile(BoolExprNodeStack* parentStack)
|
||||
|
||||
CMP_post_access(tdbb, csb, tail->csb_relation->rel_security_name,
|
||||
tail->csb_view ? tail->csb_view->rel_id : 0,
|
||||
SCL_update, SCL_object_table, tail->csb_relation->rel_name);
|
||||
SCL_update, obj_relations, tail->csb_relation->rel_name);
|
||||
}
|
||||
|
||||
rsb = FB_NEW_POOL(*tdbb->getDefaultPool()) LockedStream(csb, rsb);
|
||||
|
135
src/jrd/scl.epp
135
src/jrd/scl.epp
@ -75,10 +75,10 @@ static SecurityClass::flags_t compute_access(thread_db* tdbb, const SecurityClas
|
||||
static SecurityClass::flags_t get_sys_privileges(thread_db* tdbb);
|
||||
static SecurityClass::flags_t walk_acl(thread_db* tdbb, const Acl&, const MetaName&,
|
||||
SLONG, const MetaName&);
|
||||
static void raiseError(thread_db* tdbb, SecurityClass::flags_t mask, SLONG type, const MetaName& name,
|
||||
static void raiseError(thread_db* tdbb, SecurityClass::flags_t mask, ObjectType type, const MetaName& name,
|
||||
const MetaName& r_name, const MetaName &invoker);
|
||||
static bool check_object(thread_db* tdbb, bool found, const SecurityClass* s_class, SLONG obj_type,
|
||||
const MetaName& obj_name, SecurityClass::flags_t mask, SLONG type, const MetaName& name);
|
||||
const MetaName& obj_name, SecurityClass::flags_t mask, ObjectType type, const MetaName& name);
|
||||
|
||||
|
||||
namespace
|
||||
@ -105,79 +105,10 @@ namespace
|
||||
{ SCL_create, priv_create, "CREATE" },
|
||||
{ 0, 0, "" }
|
||||
};
|
||||
|
||||
|
||||
// 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";
|
||||
const char* const object_str_view = "VIEW";
|
||||
const char* const object_str_role = "ROLE";
|
||||
const char* const object_str_filter = "FILTER";
|
||||
|
||||
|
||||
struct SecObjectNamePriority
|
||||
{
|
||||
const char* name;
|
||||
SLONG num;
|
||||
};
|
||||
|
||||
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},
|
||||
{object_str_view, SCL_object_view},
|
||||
{object_str_role, SCL_object_role},
|
||||
{object_str_filter, SCL_object_filter},
|
||||
{"", 0}
|
||||
};
|
||||
|
||||
/* Unused, may be needed
|
||||
SLONG accTypeStrToNum(const char* name)
|
||||
{
|
||||
for (const SecObjectNamePriority* p = priorities; p->num != 0; ++p)
|
||||
{
|
||||
if (strcmp(p->name, name) == 0)
|
||||
return p->num;
|
||||
}
|
||||
fb_assert(false);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
const char* accTypeNumToStr(const SLONG num)
|
||||
{
|
||||
for (const SecObjectNamePriority* p = priorities; p->num != 0; ++p)
|
||||
{
|
||||
if (p->num == num)
|
||||
return p->name;
|
||||
}
|
||||
fb_assert(false);
|
||||
return "<unknown object type>";
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
static void raiseError(thread_db* tdbb, SecurityClass::flags_t mask, SLONG type, const MetaName& name,
|
||||
static void raiseError(thread_db* tdbb, SecurityClass::flags_t mask, ObjectType type, const MetaName& name,
|
||||
const MetaName& r_name, const MetaName& invoker)
|
||||
{
|
||||
const P_NAMES* names;
|
||||
@ -187,13 +118,13 @@ static void raiseError(thread_db* tdbb, SecurityClass::flags_t mask, SLONG type,
|
||||
break;
|
||||
}
|
||||
|
||||
const char* const typeAsStr = accTypeNumToStr(type);
|
||||
const char* const ddlObjectName = getDdlObjectName(type);
|
||||
const Firebird::string fullName = r_name.hasData() ?
|
||||
r_name.c_str() + Firebird::string(".") + name.c_str() : name.c_str();
|
||||
|
||||
Arg::StatusVector status;
|
||||
status << Arg::Gds(isc_no_priv) << Arg::Str(names->p_names_string) <<
|
||||
Arg::Str(typeAsStr) <<
|
||||
Arg::Str(ddlObjectName) <<
|
||||
Arg::Str(fullName);
|
||||
if (invoker.hasData())
|
||||
{
|
||||
@ -207,10 +138,10 @@ static void raiseError(thread_db* tdbb, SecurityClass::flags_t mask, SLONG type,
|
||||
|
||||
void SCL_check_access(thread_db* tdbb,
|
||||
const SecurityClass* s_class,
|
||||
SLONG obj_type,
|
||||
SLONG obj_id,
|
||||
const MetaName& obj_name,
|
||||
SecurityClass::flags_t mask,
|
||||
SLONG type,
|
||||
ObjectType type,
|
||||
bool recursive,
|
||||
const MetaName& name,
|
||||
const MetaName& r_name)
|
||||
@ -252,13 +183,13 @@ void SCL_check_access(thread_db* tdbb,
|
||||
return;
|
||||
|
||||
// Check global DDL permissions with ANY option which allow user to make changes non owned objects
|
||||
if ((type > obj_last_non_ddl) && (mask & SCL_get_object_mask(type)))
|
||||
if (isDdlObject(type) && (mask & SCL_get_object_mask(type)))
|
||||
return;
|
||||
|
||||
if (!s_class || (mask & s_class->scl_flags) )
|
||||
return;
|
||||
|
||||
if (obj_name.hasData() && (compute_access(tdbb, s_class, obj_type, obj_name) & mask) )
|
||||
if (obj_name.hasData() && (compute_access(tdbb, s_class, obj_id, obj_name) & mask) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -266,8 +197,8 @@ void SCL_check_access(thread_db* tdbb,
|
||||
// Allow recursive procedure/function call
|
||||
|
||||
if (recursive &&
|
||||
((type == SCL_object_procedure && obj_type == id_procedure) ||
|
||||
(type == SCL_object_function && obj_type == id_function)) &&
|
||||
((type == obj_procedures && obj_id == id_procedure) ||
|
||||
(type == obj_functions && obj_id == id_function)) &&
|
||||
obj_name == name)
|
||||
{
|
||||
return;
|
||||
@ -277,7 +208,7 @@ void SCL_check_access(thread_db* tdbb,
|
||||
}
|
||||
|
||||
|
||||
void SCL_check_create_access(thread_db* tdbb, int type)
|
||||
void SCL_check_create_access(thread_db* tdbb, ObjectType type)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -305,7 +236,7 @@ void SCL_check_create_access(thread_db* tdbb, int type)
|
||||
|
||||
if (!(obj_mask & SCL_create))
|
||||
{
|
||||
const char* name = accTypeNumToStr(type);
|
||||
const char* name = getDdlObjectName(type);
|
||||
ERR_post(Arg::Gds(isc_dyn_no_create_priv) << name);
|
||||
}
|
||||
}
|
||||
@ -338,7 +269,7 @@ void SCL_check_charset(thread_db* tdbb, const MetaName& name, SecurityClass::fla
|
||||
}
|
||||
END_FOR
|
||||
|
||||
SCL_check_access(tdbb, s_class, 0, name, mask, SCL_object_charset, false, name);
|
||||
SCL_check_access(tdbb, s_class, 0, name, mask, obj_charsets, false, name);
|
||||
}
|
||||
|
||||
|
||||
@ -369,7 +300,7 @@ void SCL_check_collation(thread_db* tdbb, const MetaName& name, SecurityClass::f
|
||||
}
|
||||
END_FOR
|
||||
|
||||
SCL_check_access(tdbb, s_class, 0, name, mask, SCL_object_collation, false, name);
|
||||
SCL_check_access(tdbb, s_class, 0, name, mask, obj_collations, false, name);
|
||||
}
|
||||
|
||||
|
||||
@ -406,7 +337,7 @@ void SCL_check_database(thread_db* tdbb, SecurityClass::flags_t mask)
|
||||
}
|
||||
|
||||
ERR_post(Arg::Gds(isc_no_priv) << Arg::Str(names->p_names_string) <<
|
||||
Arg::Str(object_str_database) <<
|
||||
Arg::Str(getDdlObjectName(obj_database)) <<
|
||||
Arg::Str(""));
|
||||
}
|
||||
|
||||
@ -438,7 +369,7 @@ void SCL_check_domain(thread_db* tdbb, const MetaName& name, SecurityClass::flag
|
||||
}
|
||||
END_FOR
|
||||
|
||||
SCL_check_access(tdbb, s_class, 0, name, mask, SCL_object_domain, false, name);
|
||||
SCL_check_access(tdbb, s_class, 0, name, mask, obj_domains, false, name);
|
||||
}
|
||||
|
||||
|
||||
@ -471,7 +402,7 @@ bool SCL_check_exception(thread_db* tdbb, const MetaName& name, SecurityClass::f
|
||||
}
|
||||
END_FOR
|
||||
|
||||
return check_object(tdbb, found, s_class, 0, name, mask, SCL_object_exception, name);
|
||||
return check_object(tdbb, found, s_class, 0, name, mask, obj_exceptions, name);
|
||||
}
|
||||
|
||||
|
||||
@ -504,7 +435,7 @@ bool SCL_check_generator(thread_db* tdbb, const MetaName& name, SecurityClass::f
|
||||
}
|
||||
END_FOR
|
||||
|
||||
return check_object(tdbb, found, s_class, 0, name, mask, SCL_object_generator, name);
|
||||
return check_object(tdbb, found, s_class, 0, name, mask, obj_generators, name);
|
||||
}
|
||||
|
||||
|
||||
@ -590,7 +521,7 @@ void SCL_check_index(thread_db* tdbb, const MetaName& index_name, UCHAR index_id
|
||||
{
|
||||
// Someone is going to reference system table in FK
|
||||
// Usually it's not good idea
|
||||
raiseError(tdbb, mask, SCL_object_table, reln_name, "", NULL);
|
||||
raiseError(tdbb, mask, obj_relations, reln_name, "", NULL);
|
||||
}
|
||||
|
||||
// Check if the relation exists. It may not have been created yet.
|
||||
@ -599,7 +530,7 @@ void SCL_check_index(thread_db* tdbb, const MetaName& index_name, UCHAR index_id
|
||||
if (reln_name.isEmpty())
|
||||
return;
|
||||
|
||||
SCL_check_access(tdbb, s_class, 0, NULL, mask, SCL_object_table, false, reln_name);
|
||||
SCL_check_access(tdbb, s_class, 0, NULL, mask, obj_relations, false, reln_name);
|
||||
|
||||
request.reset();
|
||||
|
||||
@ -620,7 +551,7 @@ void SCL_check_index(thread_db* tdbb, const MetaName& index_name, UCHAR index_id
|
||||
s_class = (!RF.RDB$SECURITY_CLASS.NULL) ?
|
||||
SCL_get_class(tdbb, RF.RDB$SECURITY_CLASS) : default_s_class;
|
||||
SCL_check_access(tdbb, s_class, 0, NULL, mask,
|
||||
SCL_object_column, false, RF.RDB$FIELD_NAME, reln_name);
|
||||
obj_column, false, RF.RDB$FIELD_NAME, reln_name);
|
||||
}
|
||||
END_FOR
|
||||
}
|
||||
@ -663,7 +594,7 @@ bool SCL_check_package(thread_db* tdbb, const dsc* dsc_name, SecurityClass::flag
|
||||
}
|
||||
END_FOR
|
||||
|
||||
return check_object(tdbb, found, s_class, id_package, name, mask, SCL_object_package, name);
|
||||
return check_object(tdbb, found, s_class, id_package, name, mask, obj_packages, name);
|
||||
}
|
||||
|
||||
|
||||
@ -705,7 +636,7 @@ bool SCL_check_procedure(thread_db* tdbb, const dsc* dsc_name, SecurityClass::fl
|
||||
}
|
||||
END_FOR
|
||||
|
||||
return check_object(tdbb, found, s_class, id_procedure, name, mask, SCL_object_procedure, name);
|
||||
return check_object(tdbb, found, s_class, id_procedure, name, mask, obj_procedures, name);
|
||||
}
|
||||
|
||||
|
||||
@ -747,7 +678,7 @@ bool SCL_check_function(thread_db* tdbb, const dsc* dsc_name, SecurityClass::fla
|
||||
}
|
||||
END_FOR
|
||||
|
||||
return check_object(tdbb, found, s_class, id_function, name, mask, SCL_object_function, name);
|
||||
return check_object(tdbb, found, s_class, id_function, name, mask, obj_functions, name);
|
||||
}
|
||||
|
||||
|
||||
@ -781,7 +712,7 @@ void SCL_check_filter(thread_db* tdbb, const MetaName &name, SecurityClass::flag
|
||||
}
|
||||
END_FOR
|
||||
|
||||
SCL_check_access(tdbb, s_class, id_filter, name, mask, SCL_object_filter, false, name);
|
||||
SCL_check_access(tdbb, s_class, id_filter, name, mask, obj_filters, false, name);
|
||||
}
|
||||
|
||||
|
||||
@ -819,7 +750,7 @@ void SCL_check_relation(thread_db* tdbb, const dsc* dsc_name, SecurityClass::fla
|
||||
{
|
||||
// Someone is going to modify system table layout
|
||||
// Usually it's not good idea
|
||||
raiseError(tdbb, mask, SCL_object_table, name, "", NULL);
|
||||
raiseError(tdbb, mask, obj_relations, name, "", NULL);
|
||||
}
|
||||
|
||||
if (!REL.RDB$SECURITY_CLASS.NULL)
|
||||
@ -827,7 +758,7 @@ void SCL_check_relation(thread_db* tdbb, const dsc* dsc_name, SecurityClass::fla
|
||||
}
|
||||
END_FOR
|
||||
|
||||
SCL_check_access(tdbb, s_class, 0, NULL, mask, SCL_object_table, false, name);
|
||||
SCL_check_access(tdbb, s_class, 0, NULL, mask, obj_relations, false, name);
|
||||
}
|
||||
|
||||
bool SCL_check_view(thread_db* tdbb, const dsc* dsc_name, SecurityClass::flags_t mask)
|
||||
@ -866,7 +797,7 @@ bool SCL_check_view(thread_db* tdbb, const dsc* dsc_name, SecurityClass::flags_t
|
||||
}
|
||||
END_FOR
|
||||
|
||||
return check_object(tdbb, found, s_class, 0, NULL, mask, SCL_object_view, name);
|
||||
return check_object(tdbb, found, s_class, 0, NULL, mask, obj_views, name);
|
||||
}
|
||||
|
||||
void SCL_check_role(thread_db* tdbb, const MetaName& name, SecurityClass::flags_t mask)
|
||||
@ -896,7 +827,7 @@ void SCL_check_role(thread_db* tdbb, const MetaName& name, SecurityClass::flags_
|
||||
}
|
||||
END_FOR
|
||||
|
||||
SCL_check_access(tdbb, s_class, 0, NULL, mask, SCL_object_role, false, name);
|
||||
SCL_check_access(tdbb, s_class, 0, NULL, mask, obj_roles, false, name);
|
||||
}
|
||||
|
||||
SecurityClass* SCL_get_class(thread_db* tdbb, const TEXT* par_string)
|
||||
@ -1292,7 +1223,7 @@ void SCL_release_all(SecurityClassList*& list)
|
||||
}
|
||||
|
||||
|
||||
SecurityClass::flags_t SCL_get_object_mask(const int object_type)
|
||||
SecurityClass::flags_t SCL_get_object_mask(ObjectType object_type)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -1307,7 +1238,7 @@ SecurityClass::flags_t SCL_get_object_mask(const int object_type)
|
||||
thread_db* tdbb = JRD_get_thread_data();
|
||||
Database* dbb = tdbb->getDatabase();
|
||||
|
||||
const TEXT* object_name = get_object_name(object_type);
|
||||
const TEXT* object_name = getSecurityClassName(object_type);
|
||||
if (!*object_name)
|
||||
return 0;
|
||||
|
||||
@ -1836,7 +1767,7 @@ static bool check_object(thread_db* tdbb,
|
||||
SLONG obj_type,
|
||||
const MetaName& obj_name,
|
||||
SecurityClass::flags_t mask,
|
||||
SLONG type,
|
||||
ObjectType type,
|
||||
const MetaName& name)
|
||||
{
|
||||
if (s_class)
|
||||
|
@ -389,24 +389,6 @@ private:
|
||||
void findGrantedRoles(thread_db* tdbb) const;
|
||||
};
|
||||
|
||||
// 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 = obj_database;
|
||||
const SLONG SCL_object_table = obj_relations;
|
||||
const SLONG SCL_object_package = obj_packages;
|
||||
const SLONG SCL_object_procedure = obj_procedures;
|
||||
const SLONG SCL_object_function = obj_functions;
|
||||
const SLONG SCL_object_collation = obj_collations;
|
||||
const SLONG SCL_object_exception = obj_exceptions;
|
||||
const SLONG SCL_object_generator = obj_generators;
|
||||
const SLONG SCL_object_charset = obj_charsets;
|
||||
const SLONG SCL_object_domain = obj_domains;
|
||||
const SLONG SCL_object_view = obj_views;
|
||||
const SLONG SCL_object_role = obj_roles;
|
||||
const SLONG SCL_object_filter = obj_filters;
|
||||
// Please keep it with code more than other objects
|
||||
// - relations and procedures should be sorted before columns.
|
||||
const SLONG SCL_object_column = obj_type_MAX + 1;
|
||||
|
||||
} //namespace Jrd
|
||||
|
||||
|
@ -35,9 +35,9 @@ struct dsc;
|
||||
|
||||
void SCL_check_access(Jrd::thread_db*, const Jrd::SecurityClass*,
|
||||
SLONG, const Jrd::MetaName&,
|
||||
Jrd::SecurityClass::flags_t, SLONG type, bool recursive, const Jrd::MetaName&,
|
||||
Jrd::SecurityClass::flags_t, ObjectType type, bool recursive, const Jrd::MetaName&,
|
||||
const Jrd::MetaName& = "");
|
||||
void SCL_check_create_access(Jrd::thread_db*, int type);
|
||||
void SCL_check_create_access(Jrd::thread_db*, ObjectType type);
|
||||
void SCL_check_charset(Jrd::thread_db* tdbb, const Jrd::MetaName&, Jrd::SecurityClass::flags_t);
|
||||
void SCL_check_collation(Jrd::thread_db* tdbb, const Jrd::MetaName&, Jrd::SecurityClass::flags_t);
|
||||
void SCL_check_database(Jrd::thread_db* tdbb, Jrd::SecurityClass::flags_t mask);
|
||||
@ -57,7 +57,7 @@ Jrd::SecurityClass::flags_t SCL_get_mask(Jrd::thread_db* tdbb, const TEXT*, cons
|
||||
void SCL_clear_classes(Jrd::thread_db*, const TEXT*);
|
||||
void SCL_release_all(Jrd::SecurityClassList*&);
|
||||
bool SCL_role_granted(Jrd::thread_db* tdbb, const Jrd::UserId& usr, const TEXT* sql_role);
|
||||
Jrd::SecurityClass::flags_t SCL_get_object_mask(const int object_type);
|
||||
Jrd::SecurityClass::flags_t SCL_get_object_mask(ObjectType object_type);
|
||||
ULONG SCL_get_number(const UCHAR*);
|
||||
USHORT SCL_convert_privilege(Jrd::thread_db* tdbb, Jrd::jrd_tra* transaction, const Firebird::string& priv);
|
||||
|
||||
|
@ -4076,12 +4076,12 @@ void jrd_tra::checkBlob(thread_db* tdbb, const bid* blob_id, jrd_fld* fld, bool
|
||||
|
||||
if (fld)
|
||||
{
|
||||
SCL_check_access(tdbb, s_class, 0, 0, SCL_select, SCL_object_column,
|
||||
SCL_check_access(tdbb, s_class, 0, 0, SCL_select, obj_column,
|
||||
false, fld->fld_name, blb_relation->rel_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
SCL_check_access(tdbb, s_class, 0, 0, SCL_select, SCL_object_table,
|
||||
SCL_check_access(tdbb, s_class, 0, 0, SCL_select, obj_relations,
|
||||
false, blb_relation->rel_name);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user