Repository: trafodion Updated Branches: refs/heads/master aade2cffa -> 8c6eebffa
[TRAFODION-2600] Unable to create view ... but user has SELECT privilege Query invalidation is not resetting the role list when a user is granted a role. For DML operations, we always retry the request once, and between retries, the role list is reset. So DML works on a retry. However, DDL operations are not retried, so the role list is not reset and the create view fails. An analogous issue exists when the role is revoked from a user and the role list is not reset. In this case, the user can still create views even though they no longer have the privilege. Changes: - Grant role: sends a new query invalidation key - Revoke role: forces a query invalidation check even if the key is not present - Displays query invalidation keys when debug option DBUSER_DEBUG is set, e.g: set envvar DBUSER_DEBUG 1; Project: http://git-wip-us.apache.org/repos/asf/trafodion/repo Commit: http://git-wip-us.apache.org/repos/asf/trafodion/commit/f9820b26 Tree: http://git-wip-us.apache.org/repos/asf/trafodion/tree/f9820b26 Diff: http://git-wip-us.apache.org/repos/asf/trafodion/diff/f9820b26 Branch: refs/heads/master Commit: f9820b26144a45b7c7cbdedaeefc832f150f5d45 Parents: ad1c676 Author: Roberta Marton <roberta.mar...@apache.org> Authored: Mon Apr 16 22:26:07 2018 +0000 Committer: Roberta Marton <roberta.mar...@apache.org> Committed: Mon Apr 16 22:26:07 2018 +0000 ---------------------------------------------------------------------- core/sql/common/ComDistribution.cpp | 1 + core/sql/common/ComSecurityKey.cpp | 114 ++++++++++++++++++++++++++++++- core/sql/common/ComSecurityKey.h | 5 +- core/sql/common/ComSmallDefs.h | 3 +- core/sql/executor/ExExeUtilGet.cpp | 4 +- core/sql/regress/privs1/EXPECTED120 | 33 ++++++++- core/sql/regress/privs1/TEST120 | 5 +- core/sql/regress/privs2/EXPECTED144 | 26 ++++++- core/sql/regress/privs2/TEST144 | 1 + core/sql/runtimestats/sscpipc.cpp | 8 +++ core/sql/sqlcomp/PrivMgrRoles.cpp | 34 +++++++++ core/sql/sqlcomp/QCache.cpp | 17 +++++ 12 files changed, 235 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafodion/blob/f9820b26/core/sql/common/ComDistribution.cpp ---------------------------------------------------------------------- diff --git a/core/sql/common/ComDistribution.cpp b/core/sql/common/ComDistribution.cpp index 1fec747..14bb378 100644 --- a/core/sql/common/ComDistribution.cpp +++ b/core/sql/common/ComDistribution.cpp @@ -298,6 +298,7 @@ Int32 literalToEnum (const literalAndEnumStruct * conversionTable, const literalAndEnumStruct qiTypeConversionTable [] = { {COM_QI_INVALID_ACTIONTYPE, COM_QI_INVALID_ACTIONTYPE_LIT}, + {COM_QI_GRANT_ROLE, COM_QI_GRANT_ROLE_LIT}, {COM_QI_USER_GRANT_ROLE, COM_QI_USER_GRANT_ROLE_LIT}, {COM_QI_ROLE_GRANT_ROLE, COM_QI_ROLE_GRANT_ROLE_LIT}, {COM_QI_OBJECT_SELECT, COM_QI_OBJECT_SELECT_LIT}, http://git-wip-us.apache.org/repos/asf/trafodion/blob/f9820b26/core/sql/common/ComSecurityKey.cpp ---------------------------------------------------------------------- diff --git a/core/sql/common/ComSecurityKey.cpp b/core/sql/common/ComSecurityKey.cpp index 76b88e7..567d9ee 100644 --- a/core/sql/common/ComSecurityKey.cpp +++ b/core/sql/common/ComSecurityKey.cpp @@ -165,11 +165,26 @@ bool buildSecurityKeys( const int32_t userID, if (privs.isNull()) return true; + NABoolean doDebug = (getenv("DBUSER_DEBUG") ? TRUE : FALSE); + std::string msg ("Method: buildSecurityKeys: "); + if (doDebug) + { + printf("[DBUSER:%d] %s\n", (int) getpid(), msg.c_str()); + fflush(stdout); + } + // If public is the grantee, generate special security key // A user cannot be revoked from public if (ComUser::isPublicUserID(granteeID)) { ComSecurityKey key(granteeID, ComSecurityKey::OBJECT_IS_SPECIAL_ROLE); + if (doDebug) + { + NAString msg (key.print(granteeID, objectUID)); + printf("[DBUSER:%d] (public) %s\n", (int) getpid(), msg.data()); + fflush(stdout); + } + if (key.isValid()) secKeySet.insert(key); else @@ -181,6 +196,14 @@ bool buildSecurityKeys( const int32_t userID, if (PrivMgr::isRoleID(granteeID)) { ComSecurityKey key (userID, granteeID, ComSecurityKey::SUBJECT_IS_USER); + if (doDebug) + { + NAString msg = key.print(userID, granteeID); + printf("[DBUSER:%d] (role) %s\n", + (int) getpid(), msg.data()); + fflush(stdout); + } + if (key.isValid()) secKeySet.insert(key); else @@ -195,6 +218,14 @@ bool buildSecurityKeys( const int32_t userID, { ComSecurityKey key (granteeID, objectUID, PrivType(i), ComSecurityKey::OBJECT_IS_OBJECT); + if (doDebug) + { + NAString msg = key.print(granteeID, objectUID); + printf("[DBUSER:%d] (DML)%s\n", + (int) getpid(), msg.data()); + fflush(stdout); + } + if (key.isValid()) secKeySet.insert(key); else @@ -223,6 +254,9 @@ void qiInvalidationType (const Int32 numInvalidationKeys, bool &resetRoleList, bool &updateCaches) { + NABoolean doDebug = (getenv("DBUSER_DEBUG") ? TRUE : FALSE); + char buf[100]; + resetRoleList = false; updateCaches = false; ComQIActionType invalidationKeyType = COM_QI_INVALID_ACTIONTYPE; @@ -233,7 +267,16 @@ void qiInvalidationType (const Int32 numInvalidationKeys, // Perhaps a new constructor would be good (also done in RelRoot::checkPrivileges) uint32_t userHashValue = ComSecurityKey::generateHash(userID); - for ( Int32 i = 0; i < numInvalidationKeys && !resetRoleList && !updateCaches; i++ ) + if (doDebug) + { + sprintf(buf, ": num keys(%d)", numInvalidationKeys); + printf("[DBUSER:%d] Method: qiInvalidationType%s\n", + (int) getpid(), buf); + fflush(stdout); + sprintf(buf, "Not applicable"); + } + + for ( Int32 i = 0; i < numInvalidationKeys; i++ ) { invalidationKeyType = ComQIActionTypeLiteralToEnum( invalidationKeys[i].operation ); switch (invalidationKeyType) @@ -241,6 +284,12 @@ void qiInvalidationType (const Int32 numInvalidationKeys, // Object changed, need to update caches case COM_QI_OBJECT_REDEF: case COM_QI_STATS_UPDATED: + if (doDebug) + sprintf(buf, "object/stats, operation: %c%c, objectUID: %ld", + invalidationKeys[i].operation[0], + invalidationKeys[i].operation[1], + invalidationKeys[i].ddlObjectUID); + updateCaches = true; break; @@ -255,17 +304,37 @@ void qiInvalidationType (const Int32 numInvalidationKeys, case COM_QI_OBJECT_EXECUTE: // If the current user matches the revoke subject, update if (invalidationKeys[i].revokeKey.subject == userHashValue) + { + if (doDebug) + sprintf(buf, "user: %d, operation: %c%c, subject: %u, object: %u", userID, + invalidationKeys[i].operation[0], invalidationKeys[i].operation[1], + invalidationKeys[i].revokeKey.subject, invalidationKeys[i].revokeKey.object); + updateCaches = true; + } // If one of the users roles matches the revokes subject, update else if (qiSubjectMatchesRole(invalidationKeys[i].revokeKey.subject)) + { + if (doDebug) + sprintf(buf, "role: %d, operation: %c%c, subject: %u, object: %u", userID, + invalidationKeys[i].operation[0], invalidationKeys[i].operation[1], + invalidationKeys[i].revokeKey.subject, invalidationKeys[i].revokeKey.object); + updateCaches = true; + } break; // For public user (SPECIAL_ROLE), the subject is a special hash case COM_QI_USER_GRANT_SPECIAL_ROLE: if (invalidationKeys[i].revokeKey.subject == ComSecurityKey::SPECIAL_SUBJECT_HASH) + { + if (doDebug) + sprintf(buf, "user: %d, operation: %c%c, subject: %u, object: %u", userID, + invalidationKeys[i].operation[0], invalidationKeys[i].operation[1], + invalidationKeys[i].revokeKey.subject, invalidationKeys[i].revokeKey.object); updateCaches = true; + } break; // A revoke role from a user was performed. Need to reset role list @@ -274,17 +343,42 @@ void qiInvalidationType (const Int32 numInvalidationKeys, case COM_QI_USER_GRANT_ROLE: if (invalidationKeys[i].revokeKey.subject == userHashValue) { + if (doDebug) + sprintf(buf, "user: %d, operation: %c%c, subject: %u, object: %u", userID, + invalidationKeys[i].operation[0], invalidationKeys[i].operation[1], + invalidationKeys[i].revokeKey.subject, invalidationKeys[i].revokeKey.object); + resetRoleList = true; updateCaches = true; } break; + // If a role was granted, refresh the active role llist + case COM_QI_GRANT_ROLE: + if (doDebug) + sprintf(buf, "operation: %c%c, subject: %u, object: %u", + invalidationKeys[i].operation[0], invalidationKeys[i].operation[1], + invalidationKeys[i].revokeKey.subject, invalidationKeys[i].revokeKey.object); + + resetRoleList = true; + break; + // unknown key type, search and update cache (should not happen) default: + if (doDebug) + sprintf(buf, "user: %d, operation: %c%c, subject: %u, object: %u", userID, + invalidationKeys[i].operation[0], invalidationKeys[i].operation[1], + invalidationKeys[i].revokeKey.subject, invalidationKeys[i].revokeKey.object); resetRoleList = true; updateCaches = true; break; } + if (doDebug) + { + printf("[DBUSER:%d] %s\n", + (int) getpid(), buf); + fflush(stdout); + } } } @@ -328,6 +422,8 @@ ComSecurityKey::ComSecurityKey( { if (typeOfSubject == SUBJECT_IS_USER) actionType_ = COM_QI_USER_GRANT_ROLE; // revoke role <object> from <user subject> + else if (typeOfSubject == SUBJECT_IS_GRANT_ROLE) + actionType_ = COM_QI_GRANT_ROLE; else actionType_ = COM_QI_ROLE_GRANT_ROLE; @@ -455,6 +551,9 @@ void ComSecurityKey::getSecurityKeyTypeAsLit (std::string &actionString) const { switch(actionType_) { + case COM_QI_GRANT_ROLE: + actionString = COM_QI_GRANT_ROLE_LIT; + break; case COM_QI_USER_GRANT_ROLE: actionString = COM_QI_USER_GRANT_ROLE_LIT; break; @@ -505,11 +604,14 @@ void ComSecurityKey::getSecurityKeyTypeAsLit (std::string &actionString) const } } -void ComSecurityKey::print() const +NAString ComSecurityKey::print(Int32 subjectID, Int64 objectID) { std::string typeString; switch(actionType_) { + case COM_QI_GRANT_ROLE: + typeString = "GRANT_ROLE"; + break; case COM_QI_USER_GRANT_ROLE: typeString = "USER_GRANT_ROLE"; break; @@ -550,7 +652,13 @@ void ComSecurityKey::print() const typeString = "INVALID_ACTIONTYPE"; break; }; - cout << subjectHash_ << " : " << objectHash_ << " : " << typeString << endl; + char buf[200]; + sprintf (buf, " - subjectHash: %u (%d), objectHash: %u (%ld), type: %s", + subjectHash_, subjectID, + objectHash_, objectID, + typeString.data()); + NAString keyDetails = buf; + return keyDetails; } http://git-wip-us.apache.org/repos/asf/trafodion/blob/f9820b26/core/sql/common/ComSecurityKey.h ---------------------------------------------------------------------- diff --git a/core/sql/common/ComSecurityKey.h b/core/sql/common/ComSecurityKey.h index 1320549..8f90d16 100644 --- a/core/sql/common/ComSecurityKey.h +++ b/core/sql/common/ComSecurityKey.h @@ -80,7 +80,8 @@ public: OBJECT_IS_COLUMN, SUBJECT_IS_USER, SUBJECT_IS_ROLE, - OBJECT_IS_SPECIAL_ROLE + OBJECT_IS_SPECIAL_ROLE, + SUBJECT_IS_GRANT_ROLE }; // QISpecialHashValues are used for security keys for special roles @@ -136,7 +137,7 @@ public: static uint32_t generateHash(int32_t hashID); // For debugging purposes - void print() const ; + NAString print(Int32 subject, Int64 object); private: uint32_t subjectHash_ ; http://git-wip-us.apache.org/repos/asf/trafodion/blob/f9820b26/core/sql/common/ComSmallDefs.h ---------------------------------------------------------------------- diff --git a/core/sql/common/ComSmallDefs.h b/core/sql/common/ComSmallDefs.h index 29a0e0f..db99f28 100644 --- a/core/sql/common/ComSmallDefs.h +++ b/core/sql/common/ComSmallDefs.h @@ -1308,6 +1308,7 @@ enum ComQIActionType { COM_QI_INVALID_ACTIONTYPE = 0 , COM_QI_USER_GRANT_SPECIAL_ROLE , COM_QI_OBJECT_REDEF , COM_QI_STATS_UPDATED + , COM_QI_GRANT_ROLE } ; #define COM_QI_INVALID_ACTIONTYPE_LIT " " @@ -1330,7 +1331,7 @@ enum ComQIActionType { COM_QI_INVALID_ACTIONTYPE = 0 #define COM_QI_USER_GRANT_SPECIAL_ROLE_LIT "UZ" #define COM_QI_OBJECT_REDEF_LIT "OR" #define COM_QI_STATS_UPDATED_LIT "US" - +#define COM_QI_GRANT_ROLE_LIT "GG" http://git-wip-us.apache.org/repos/asf/trafodion/blob/f9820b26/core/sql/executor/ExExeUtilGet.cpp ---------------------------------------------------------------------- diff --git a/core/sql/executor/ExExeUtilGet.cpp b/core/sql/executor/ExExeUtilGet.cpp index f273219..3fdf07a 100644 --- a/core/sql/executor/ExExeUtilGet.cpp +++ b/core/sql/executor/ExExeUtilGet.cpp @@ -1735,9 +1735,9 @@ Int32 ExExeUtilGetMetadataInfoTcb::colPrivsFrag( OutputInfo * vi = (OutputInfo*)infoList_->getCurr(); if (vi && vi->get(0)) { - if (*(Lng32*)vi->get(0) > 0) + if (*(Int64*)vi->get(0) > 0) hasHive = true; - if(*(Lng32*)vi->get(1) > 0) + if(*(Int64*)vi->get(1) > 0) hasGrants = true; } http://git-wip-us.apache.org/repos/asf/trafodion/blob/f9820b26/core/sql/regress/privs1/EXPECTED120 ---------------------------------------------------------------------- diff --git a/core/sql/regress/privs1/EXPECTED120 b/core/sql/regress/privs1/EXPECTED120 index 113b2d8..4f0c699 100644 --- a/core/sql/regress/privs1/EXPECTED120 +++ b/core/sql/regress/privs1/EXPECTED120 @@ -736,8 +736,14 @@ TEAM_NUMBER NUM_PLAYERS End of MXCI Session +>> +>>-- queries s/b recompiled >>execute select_games; +*** WARNING[8597] Statement was automatically retried 1 time(s). Delay before each retry was 0 seconds. See next entry for the error that caused this retry. + +*** WARNING[8734] Statement must be recompiled to allow privileges to be re-evaluated. + GAME_NUMBER ----------- @@ -753,6 +759,10 @@ GAME_NUMBER --- 8 row(s) selected. >>execute select_teams; +*** WARNING[8597] Statement was automatically retried 1 time(s). Delay before each retry was 0 seconds. See next entry for the error that caused this retry. + +*** WARNING[8734] Statement must be recompiled to allow privileges to be re-evaluated. + TEAM_NUMBER TEAM_NAME ----------- -------------------- @@ -993,6 +1003,10 @@ GAME_NUMBER --- 8 row(s) selected. >>execute select_teams; +*** WARNING[8597] Statement was automatically retried 1 time(s). Delay before each retry was 0 seconds. See next entry for the error that caused this retry. + +*** WARNING[8734] Statement must be recompiled to allow privileges to be re-evaluated. + TEAM_NUMBER TEAM_NAME ----------- -------------------- @@ -1006,6 +1020,10 @@ TEAM_NUMBER TEAM_NAME --- 6 row(s) selected. >>execute select_standings; +*** WARNING[8597] Statement was automatically retried 1 time(s). Delay before each retry was 0 seconds. See next entry for the error that caused this retry. + +*** WARNING[8734] Statement must be recompiled to allow privileges to be re-evaluated. + TEAM_NUMBER (EXPR) ----------- -------------------- @@ -1016,11 +1034,12 @@ TEAM_NUMBER (EXPR) 5 80 --- 5 row(s) selected. ->> ->>-- still have privs, no query recompilation message because no invalidation ->>-- key for roles exist >>execute select_players; +*** WARNING[8597] Statement was automatically retried 1 time(s). Delay before each retry was 0 seconds. See next entry for the error that caused this retry. + +*** WARNING[8734] Statement must be recompiled to allow privileges to be re-evaluated. + (EXPR) -------------------- @@ -1171,6 +1190,10 @@ End of MXCI Session --- 0 row(s) selected. >>execute select_teams; +*** WARNING[8597] Statement was automatically retried 1 time(s). Delay before each retry was 0 seconds. See next entry for the error that caused this retry. + +*** WARNING[8734] Statement must be recompiled to allow privileges to be re-evaluated. + TEAM_NUMBER TEAM_NAME ----------- -------------------- @@ -1184,6 +1207,10 @@ TEAM_NUMBER TEAM_NAME --- 6 row(s) selected. >>execute select_players; +*** WARNING[8597] Statement was automatically retried 1 time(s). Delay before each retry was 0 seconds. See next entry for the error that caused this retry. + +*** WARNING[8734] Statement must be recompiled to allow privileges to be re-evaluated. + (EXPR) -------------------- http://git-wip-us.apache.org/repos/asf/trafodion/blob/f9820b26/core/sql/regress/privs1/TEST120 ---------------------------------------------------------------------- diff --git a/core/sql/regress/privs1/TEST120 b/core/sql/regress/privs1/TEST120 index 7dca9ea..16b7cd5 100755 --- a/core/sql/regress/privs1/TEST120 +++ b/core/sql/regress/privs1/TEST120 @@ -243,6 +243,8 @@ sh sqlci -i "TEST120(select_queries)" -u sql_user9; -- revoke t120role4 from sql_user6 sh sqlci -i "TEST120(revoke_t120role4)" -u sql_user3; + +-- queries s/b recompiled execute select_games; execute select_teams; @@ -266,9 +268,6 @@ sh sqlci -i "TEST120(revoke_t120role2)" -u sql_user3; execute select_games; execute select_teams; execute select_standings; - --- still have privs, no query recompilation message because no invalidation --- key for roles exist execute select_players; -- no longer has privilege (4481) and query attempted recompilation http://git-wip-us.apache.org/repos/asf/trafodion/blob/f9820b26/core/sql/regress/privs2/EXPECTED144 ---------------------------------------------------------------------- diff --git a/core/sql/regress/privs2/EXPECTED144 b/core/sql/regress/privs2/EXPECTED144 index af4f42f..752618c 100644 --- a/core/sql/regress/privs2/EXPECTED144 +++ b/core/sql/regress/privs2/EXPECTED144 @@ -911,7 +911,7 @@ _TRAFODION_T144 >> >>drop role t144role1; -*** ERROR[1348] Cannot drop role. Role is granted to one or more users. +*** ERROR[1348] Cannot drop role. Role is granted to one or more users. --- SQL operation failed with errors. >>revoke role t144role1 from sql_user4; @@ -919,7 +919,7 @@ _TRAFODION_T144 --- SQL operation complete. >>drop role t144role1; -*** ERROR[1228] Cannot drop role. Role T144ROLE1 has been granted privileges on TRAFODION.T144USER1.GEN_RANDOM. +*** ERROR[1228] Cannot drop role. Role T144ROLE1 has been granted privileges on TRAFODION.T144USER1.GEN_RANDOM. --- SQL operation failed with errors. >>revoke execute on function gen_random from t144role1; @@ -957,6 +957,28 @@ _TRAFODION_T144 >>revoke execute on procedure "_LIBMGR_".help from sql_user2; --- SQL operation complete. +>>obey TEST144(set_up); +>>set schema "_PRIVMGR_MD_"; + +--- SQL operation complete. +>>prepare get_privs from ++>select distinct ++> trim(substring (o.object_name,1,15)) as object_name, ++> grantor_id, grantee_id, ++> t144user1.t144_translatePrivsBitmap(privileges_bitmap) as granted_privs, ++> t144user1.t144_translatePrivsBitmap(grantable_bitmap) as grantable_privs ++>from object_privileges p, "_MD_".objects o ++>where p.object_uid in ++> (select object_uid ++> from "_MD_".objects ++> where schema_name like 'T144USER%' ++> and object_name not like 'SB_%') ++> and p.object_uid = o.object_uid ++>order by 1, 2, 3, 4 ++>; + +--- SQL command prepared. +>> >>execute get_privs; OBJECT_NAME GRANTOR_ID GRANTEE_ID GRANTED_PRIVS GRANTABLE_PRIVS http://git-wip-us.apache.org/repos/asf/trafodion/blob/f9820b26/core/sql/regress/privs2/TEST144 ---------------------------------------------------------------------- diff --git a/core/sql/regress/privs2/TEST144 b/core/sql/regress/privs2/TEST144 index df53a42..e49d6ef 100755 --- a/core/sql/regress/privs2/TEST144 +++ b/core/sql/regress/privs2/TEST144 @@ -212,6 +212,7 @@ revoke execute on function gen_phone from sql_user2; revoke execute on function gen_random from sql_user2; revoke execute on function gen_time from sql_user2; revoke execute on procedure "_LIBMGR_".help from sql_user2; +obey TEST144(set_up); execute get_privs; http://git-wip-us.apache.org/repos/asf/trafodion/blob/f9820b26/core/sql/runtimestats/sscpipc.cpp ---------------------------------------------------------------------- diff --git a/core/sql/runtimestats/sscpipc.cpp b/core/sql/runtimestats/sscpipc.cpp index 16d5d60..b382384 100755 --- a/core/sql/runtimestats/sscpipc.cpp +++ b/core/sql/runtimestats/sscpipc.cpp @@ -848,6 +848,14 @@ void SscpNewIncomingConnectionStream::processSecInvReq() } } } + + // If a role is granted or revoked from a user do checks next time query is executed + else if (siKeyType == COM_QI_USER_GRANT_ROLE) + { + keysAreInvalid = true; + masterStats->setValidPrivs(false); + } + else if (siKeyType != COM_QI_STATS_UPDATED) { // compare the new REVOKE invalidation key to each key in the http://git-wip-us.apache.org/repos/asf/trafodion/blob/f9820b26/core/sql/sqlcomp/PrivMgrRoles.cpp ---------------------------------------------------------------------- diff --git a/core/sql/sqlcomp/PrivMgrRoles.cpp b/core/sql/sqlcomp/PrivMgrRoles.cpp index 6d610d5..882ce93 100644 --- a/core/sql/sqlcomp/PrivMgrRoles.cpp +++ b/core/sql/sqlcomp/PrivMgrRoles.cpp @@ -853,10 +853,15 @@ PrivStatus PrivMgrRoles::grantRole( const int32_t grantDepth) { + NABoolean doDebug = (getenv("DBUSER_DEBUG") ? TRUE : FALSE); bool roleWasGranted = false; MyTable &myTable = static_cast<MyTable &>(myTable_); + int32_t numKeys = roleIDs.size() * granteeIDs.size(); + SQL_QIKEY siKeyList[numKeys]; + size_t siIndex = 0; + for (size_t r = 0; r < roleIDs.size(); r++) { int32_t roleID = roleIDs[r]; @@ -958,9 +963,30 @@ MyTable &myTable = static_cast<MyTable &>(myTable_); PRIVMGR_INTERNAL_ERROR("I/O error granting role"); return STATUS_ERROR; } + + // Add a special secKey to indicate a role grant. This forces the role + // list in cache to be regenerated + ComSecurityKey secKey(granteeIDs[g],roleIDs[r],ComSecurityKey::SUBJECT_IS_GRANT_ROLE); + + siKeyList[siIndex].revokeKey.subject = secKey.getSubjectHashValue(); + siKeyList[siIndex].revokeKey.object = secKey.getObjectHashValue(); + std::string actionString; + secKey.getSecurityKeyTypeAsLit(actionString); + strncpy(siKeyList[siIndex].operation, actionString.c_str(),2); + if (doDebug) + { + NAString msg (secKey.print(granteeIDs[g], roleIDs[r])); + printf("[DBUSER:%d] grant role %s\n", + (int) getpid(), msg.data()); + fflush(stdout); + } + siIndex++; }//grantees }//roles + // Call the CLI to send details to RMS + SQL_EXEC_SetSecInvalidKeys(siIndex,siKeyList); + //TODO: if we didn't have any errors, but no roles were granted, then all // grants are already performed. Should issue some message. // Related, need option to suppress already exists and does not exist errors. @@ -1671,6 +1697,7 @@ PrivStatus PrivMgrRoles::revokeRole( { //TODO: Currently only RESTRICT behavior is supported. + NABoolean doDebug = (getenv("DBUSER_DEBUG") ? TRUE : FALSE); if (dropBehavior == PrivDropBehavior::CASCADE) { @@ -1818,6 +1845,13 @@ PrivStatus PrivMgrRoles::revokeRole( std::string actionString; secKey.getSecurityKeyTypeAsLit(actionString); strncpy(siKeyList[siIndex].operation, actionString.c_str(),2); + if (doDebug) + { + NAString msg (secKey.print(granteeIDs[g2], roleIDs[r2])); + printf("[DBUSER:%d] revoke role %s\n", + (int) getpid(), msg.data()); + fflush(stdout); + } siIndex++; } } http://git-wip-us.apache.org/repos/asf/trafodion/blob/f9820b26/core/sql/sqlcomp/QCache.cpp ---------------------------------------------------------------------- diff --git a/core/sql/sqlcomp/QCache.cpp b/core/sql/sqlcomp/QCache.cpp index 81c9869..02d6bb6 100644 --- a/core/sql/sqlcomp/QCache.cpp +++ b/core/sql/sqlcomp/QCache.cpp @@ -2618,6 +2618,23 @@ void QCache::free_entries_with_QI_keys( Int32 pNumKeys, SQL_QIKEY * pSiKeyEntry } } } + + else if (siKeyType == COM_QI_USER_GRANT_ROLE) + { + for ( CollIndex ii = 0; ii < numPlanSecKeys && !found; ii ++ ) + { + // If user ID's (subjects match) + if ( ((pSiKeyEntry[jj]).revokeKey.subject == planSet[ii].getSubjectHashValue()) || + qiSubjectMatchesRole(planSet[ii].getSubjectHashValue()) ) + { + if ( ( pSiKeyEntry[jj]).revokeKey.object == + planSet[ii].getObjectHashValue() && + ( siKeyType == planSet[ii].getSecurityKeyType() ) ) + found = TRUE; + } + } + } + else if (siKeyType != COM_QI_STATS_UPDATED) { // this key passed in as a param is for REVOKE so look