mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 06:43:04 +01:00
Backport of fixed CORE-5861: GRANT OPTION is not checked for new object.
Also now GRANT OPTION can be checked for roles too.
This commit is contained in:
parent
d41875903e
commit
1dfb1d2095
@ -11394,8 +11394,11 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
||||
break;
|
||||
}
|
||||
|
||||
case obj_procedure:
|
||||
case obj_udf:
|
||||
case obj_exception:
|
||||
case obj_generator:
|
||||
case obj_package_header:
|
||||
{
|
||||
checkGrantorCanGrantObject(tdbb, transaction,
|
||||
tdbb->getAttachment()->att_user->usr_user_name.c_str(), priv, objName, objType);
|
||||
@ -11519,6 +11522,8 @@ void GrantRevokeNode::checkGrantorCanGrantRelation(thread_db* tdbb, jrd_tra* tra
|
||||
const char* grantor, const char* privilege, const MetaName& relationName,
|
||||
const MetaName& fieldName, bool topLevel)
|
||||
{
|
||||
const Attachment* attachment = tdbb->getAttachment();
|
||||
|
||||
// Verify that the input relation exists.
|
||||
|
||||
AutoCacheRequest request(tdbb, drq_gcg4, DYN_REQUESTS);
|
||||
@ -11569,7 +11574,7 @@ void GrantRevokeNode::checkGrantorCanGrantRelation(thread_db* tdbb, jrd_tra* tra
|
||||
|
||||
// If the current user is locksmith - allow all grants to occur
|
||||
|
||||
if (tdbb->getAttachment()->locksmith())
|
||||
if (attachment->locksmith())
|
||||
return;
|
||||
|
||||
// If this is a non-sql table, then the owner will probably not have any
|
||||
@ -11604,34 +11609,36 @@ void GrantRevokeNode::checkGrantorCanGrantRelation(thread_db* tdbb, jrd_tra* tra
|
||||
|
||||
request.reset(tdbb, drq_gcg1, DYN_REQUESTS);
|
||||
|
||||
const char* roleName = attachment->att_user->usr_sql_role_name.c_str();
|
||||
|
||||
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
PRV IN RDB$USER_PRIVILEGES WITH
|
||||
PRV.RDB$USER = UPPERCASE(grantor) AND
|
||||
PRV.RDB$USER_TYPE = obj_user AND
|
||||
PRV IN RDB$USER_PRIVILEGES
|
||||
WITH ((PRV.RDB$USER = UPPERCASE(grantor) AND PRV.RDB$USER_TYPE = obj_user) OR
|
||||
(PRV.RDB$USER = UPPERCASE(roleName) AND (PRV.RDB$USER_TYPE = obj_sql_role))) AND
|
||||
PRV.RDB$RELATION_NAME = relationName.c_str() AND
|
||||
PRV.RDB$OBJECT_TYPE = obj_relation AND
|
||||
PRV.RDB$PRIVILEGE = privilege
|
||||
{
|
||||
const bool hasGrantOption = !PRV.RDB$GRANT_OPTION.NULL && PRV.RDB$GRANT_OPTION;
|
||||
if (PRV.RDB$FIELD_NAME.NULL)
|
||||
{
|
||||
if (PRV.RDB$GRANT_OPTION.NULL || !PRV.RDB$GRANT_OPTION)
|
||||
goRel = 0;
|
||||
else if (goRel)
|
||||
if (goRel == -1)
|
||||
goRel = hasGrantOption ? 1 : 0;
|
||||
else if ((goRel == 0) && hasGrantOption)
|
||||
goRel = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PRV.RDB$GRANT_OPTION.NULL || !PRV.RDB$GRANT_OPTION)
|
||||
if (fieldName.hasData() && fieldName == PRV.RDB$FIELD_NAME)
|
||||
{
|
||||
if (fieldName.hasData() && fieldName == PRV.RDB$FIELD_NAME)
|
||||
goFld = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fieldName.hasData() && fieldName == PRV.RDB$FIELD_NAME)
|
||||
if (goFld == -1)
|
||||
goFld = hasGrantOption ? 1 : 0;
|
||||
else if ((goFld == 0) && hasGrantOption)
|
||||
goFld = 1;
|
||||
}
|
||||
}
|
||||
if ( (goRel > 0) && (goFld > 0 || !fieldName.hasData()) )
|
||||
break; // We've found a privilege with grant option and can break the loop
|
||||
}
|
||||
END_FOR
|
||||
|
||||
@ -11641,7 +11648,7 @@ void GrantRevokeNode::checkGrantorCanGrantRelation(thread_db* tdbb, jrd_tra* tra
|
||||
{
|
||||
// no grant option for privilege .. on column .. of [base] table/view ..
|
||||
status_exception::raise(Arg::PrivateDyn(topLevel ? 167 : 168) <<
|
||||
privilege << fieldName.c_str() << relationName.c_str());
|
||||
privilegeName(*privilege) << fieldName.c_str() << relationName.c_str());
|
||||
}
|
||||
|
||||
if (goFld == -1)
|
||||
@ -11650,14 +11657,14 @@ void GrantRevokeNode::checkGrantorCanGrantRelation(thread_db* tdbb, jrd_tra* tra
|
||||
{
|
||||
// no grant option for privilege .. on [base] table/view .. (for column ..)
|
||||
status_exception::raise(Arg::PrivateDyn(topLevel ? 169 : 170) <<
|
||||
privilege << relationName.c_str() << fieldName.c_str());
|
||||
privilegeName(*privilege) << relationName.c_str() << fieldName.c_str());
|
||||
}
|
||||
|
||||
if (goRel == -1)
|
||||
{
|
||||
// no .. privilege with grant option on [base] table/view .. (for column ..)
|
||||
status_exception::raise(Arg::PrivateDyn(topLevel ? 171 : 172) <<
|
||||
privilege << relationName.c_str() << fieldName.c_str());
|
||||
privilegeName(*privilege) << relationName.c_str() << fieldName.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -11666,13 +11673,13 @@ void GrantRevokeNode::checkGrantorCanGrantRelation(thread_db* tdbb, jrd_tra* tra
|
||||
if (goRel == 0)
|
||||
{
|
||||
// no grant option for privilege .. on table/view ..
|
||||
status_exception::raise(Arg::PrivateDyn(173) << privilege << relationName.c_str());
|
||||
status_exception::raise(Arg::PrivateDyn(173) << privilegeName(*privilege) << relationName.c_str());
|
||||
}
|
||||
|
||||
if (goRel == -1)
|
||||
{
|
||||
// no .. privilege with grant option on table/view ..
|
||||
status_exception::raise(Arg::PrivateDyn(174) << privilege << relationName.c_str());
|
||||
status_exception::raise(Arg::PrivateDyn(174) << privilegeName(*privilege) << relationName.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -11763,29 +11770,35 @@ void GrantRevokeNode::checkGrantorCanGrantRole(thread_db* tdbb, jrd_tra* transac
|
||||
void GrantRevokeNode::checkGrantorCanGrantDdl(thread_db* tdbb, jrd_tra* transaction,
|
||||
const MetaName& grantor, const char* privilege, const MetaName& objName)
|
||||
{
|
||||
if (tdbb->getAttachment()->locksmith())
|
||||
Attachment* attachment = tdbb->getAttachment();
|
||||
if (attachment->locksmith())
|
||||
return;
|
||||
|
||||
AutoCacheRequest request(tdbb, drq_l_grant_option, DYN_REQUESTS);
|
||||
bool grantable = false;
|
||||
|
||||
const char* roleName = attachment->att_user->usr_sql_role_name.c_str();
|
||||
|
||||
FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
PRV IN RDB$USER_PRIVILEGES
|
||||
WITH PRV.RDB$USER = UPPERCASE(grantor.c_str()) AND
|
||||
PRV.RDB$USER_TYPE = obj_user AND
|
||||
WITH ((PRV.RDB$USER = UPPERCASE(grantor.c_str()) AND PRV.RDB$USER_TYPE = obj_user) OR
|
||||
(PRV.RDB$USER = UPPERCASE(roleName) AND (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$PRIVILEGE EQ privilege
|
||||
{
|
||||
if (PRV.RDB$GRANT_OPTION == 1)
|
||||
{
|
||||
grantable = true;
|
||||
break; // We've found a privilege with grant option and can break the loop
|
||||
}
|
||||
}
|
||||
END_FOR
|
||||
|
||||
if (!grantable)
|
||||
{
|
||||
// no @1 privilege with grant option on DDL @2
|
||||
status_exception::raise(Arg::PrivateDyn(299) << privilege << objName.c_str());
|
||||
status_exception::raise(Arg::PrivateDyn(299) << privilegeName(*privilege) << objName.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -11794,28 +11807,35 @@ void GrantRevokeNode::checkGrantorCanGrantDdl(thread_db* tdbb, jrd_tra* transact
|
||||
void GrantRevokeNode::checkGrantorCanGrantObject(thread_db* tdbb, jrd_tra* transaction, const char* grantor,
|
||||
const char* privilege, const Firebird::MetaName& objName, SSHORT objType)
|
||||
{
|
||||
if (tdbb->getAttachment()->locksmith())
|
||||
Attachment* attachment = tdbb->getAttachment();
|
||||
if (attachment->locksmith())
|
||||
return;
|
||||
|
||||
AutoCacheRequest request(tdbb, drq_l_grant_object, DYN_REQUESTS);
|
||||
bool grantable = false;
|
||||
|
||||
const char* roleName = attachment->att_user->usr_sql_role_name.c_str();
|
||||
|
||||
FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
PRV IN RDB$USER_PRIVILEGES
|
||||
WITH (PRV.RDB$USER = UPPERCASE(grantor) AND PRV.RDB$USER_TYPE = obj_user) AND
|
||||
WITH ((PRV.RDB$USER = UPPERCASE(grantor) AND PRV.RDB$USER_TYPE = obj_user) OR
|
||||
(PRV.RDB$USER = UPPERCASE(roleName) AND (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 = objType AND
|
||||
PRV.RDB$PRIVILEGE EQ privilege
|
||||
{
|
||||
if (PRV.RDB$GRANT_OPTION == 1)
|
||||
{
|
||||
grantable = true;
|
||||
break; // We've found a privilege with grant option and can break the loop
|
||||
}
|
||||
}
|
||||
END_FOR
|
||||
|
||||
if (!grantable)
|
||||
{
|
||||
// no @1 privilege with grant option on object @2
|
||||
status_exception::raise(Arg::PrivateDyn(300) << privilege << objName.c_str());
|
||||
status_exception::raise(Arg::PrivateDyn(300) << privilegeName(*privilege) << objName.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2166,19 +2166,19 @@ private:
|
||||
{
|
||||
switch (UPPER7(symbol))
|
||||
{
|
||||
case 'A': return "All";
|
||||
case 'I': return "Insert";
|
||||
case 'U': return "Update";
|
||||
case 'D': return "Delete";
|
||||
case 'S': return "Select";
|
||||
case 'X': return "Execute";
|
||||
case 'G': return "Usage";
|
||||
case 'M': return "Role";
|
||||
case 'R': return "Reference";
|
||||
case 'A': return "ALL";
|
||||
case 'I': return "INSERT";
|
||||
case 'U': return "UPDATE";
|
||||
case 'D': return "DELETE";
|
||||
case 'S': return "SELECT";
|
||||
case 'X': return "EXECUTE";
|
||||
case 'G': return "USAGE";
|
||||
case 'M': return "ROLE";
|
||||
case 'R': return "REFERENCE";
|
||||
// ddl
|
||||
case 'C': return "Create";
|
||||
case 'L': return "Alter";
|
||||
case 'O': return "Drop";
|
||||
case 'C': return "CREATE";
|
||||
case 'L': return "ALTER";
|
||||
case 'O': return "DROP";
|
||||
}
|
||||
|
||||
return "<Unknown>";
|
||||
|
Loading…
Reference in New Issue
Block a user