8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 21:23:04 +01:00

Fixed regression: performance penalty when check access rights of user with super privileges granted (such as SYSDBA, DBO, etc)

This commit is contained in:
hvlad 2017-01-30 01:17:09 +02:00
parent 1deb7fb8b5
commit c8956bd1ae
2 changed files with 40 additions and 13 deletions

View File

@ -73,6 +73,7 @@ static bool check_user_group(thread_db* tdbb, const UCHAR*, USHORT);
static bool check_string(const UCHAR*, const Firebird::MetaName&);
static SecurityClass::flags_t compute_access(thread_db* tdbb, const SecurityClass*,
const MetaName &userName, SLONG, const Firebird::MetaName&);
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 Firebird::MetaName&);
static void raiseError(SecurityClass::flags_t mask, SLONG type, const Firebird::MetaName& name,
@ -230,6 +231,10 @@ void SCL_check_access(thread_db* tdbb,
Arg::Str(s_class->scl_name));
}
// Make fast check first
if (mask & get_sys_privileges(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)))
return;
@ -1414,6 +1419,35 @@ static void get_string(const UCHAR* acl, Firebird::MetaName& string)
string.assign(ptr, length);
}
static SecurityClass::flags_t get_sys_privileges(thread_db* tdbb)
{
/**************************************
*
* g e t _ s y s _ p r i v i l e g e s
*
**************************************
*
* Functional description
* Returns access flags for current user's system-wide privileges
*
**************************************/
const Jrd::Attachment* attachment = tdbb->getAttachment();
if (!attachment)
return 0;
SecurityClass::flags_t flags = 0;
if (attachment->locksmith(tdbb, ACCESS_ANY_OBJECT_IN_DATABASE))
flags |= SCL_ACCESS_ANY;
else if (attachment->locksmith(tdbb, SELECT_ANY_OBJECT_IN_DATABASE))
flags |= SCL_SELECT_ANY;
if (attachment->locksmith(tdbb, MODIFY_ANY_OBJECT_IN_DATABASE))
flags |= SCL_MODIFY_ANY;
return flags;
}
static SecurityClass::flags_t compute_access(thread_db* tdbb,
const SecurityClass* s_class,
const MetaName& userName,
@ -1439,19 +1473,7 @@ static SecurityClass::flags_t compute_access(thread_db* tdbb,
jrd_tra* sysTransaction = attachment->getSysTransaction();
SecurityClass::flags_t privileges = 0;
SecurityClass::flags_t sysPriv = SCL_exists;
const SecurityClass::flags_t selectAnyObject = SCL_select | SCL_references;
const SecurityClass::flags_t accessAnyObject = SCL_insert | SCL_update | SCL_delete |
SCL_execute | SCL_usage | selectAnyObject;
const SecurityClass::flags_t anyDdl = SCL_create | SCL_alter | SCL_control | SCL_drop;
if (attachment->locksmith(tdbb, ACCESS_ANY_OBJECT_IN_DATABASE))
sysPriv |= accessAnyObject;
else if (attachment->locksmith(tdbb, SELECT_ANY_OBJECT_IN_DATABASE))
sysPriv |= selectAnyObject;
if (attachment->locksmith(tdbb, MODIFY_ANY_OBJECT_IN_DATABASE))
sysPriv |= anyDdl;
SecurityClass::flags_t sysPriv = SCL_exists | get_sys_privileges(tdbb);
AutoCacheRequest request(tdbb, irq_l_security, IRQ_REQUESTS);

View File

@ -83,6 +83,11 @@ const SecurityClass::flags_t SCL_execute = 1024; // EXECUTE access
const SecurityClass::flags_t SCL_usage = 2048; // USAGE access
const SecurityClass::flags_t SCL_create = 4096;
const SecurityClass::flags_t SCL_SELECT_ANY = SCL_select | SCL_references;
const SecurityClass::flags_t SCL_ACCESS_ANY = SCL_insert | SCL_update | SCL_delete |
SCL_execute | SCL_usage | SCL_SELECT_ANY;
const SecurityClass::flags_t SCL_MODIFY_ANY = SCL_create | SCL_alter | SCL_control | SCL_drop;
/*
scl pathcalls