Repository: incubator-trafodion Updated Branches: refs/heads/master cad7ab693 -> 39d3a0c44
http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/392031a3/core/sql/sqlcomp/PrivMgrPrivileges.cpp ---------------------------------------------------------------------- diff --git a/core/sql/sqlcomp/PrivMgrPrivileges.cpp b/core/sql/sqlcomp/PrivMgrPrivileges.cpp index f3462b9..335f736 100644 --- a/core/sql/sqlcomp/PrivMgrPrivileges.cpp +++ b/core/sql/sqlcomp/PrivMgrPrivileges.cpp @@ -237,25 +237,24 @@ public: // sets the privilege and grantable bitmaps to 0 void clearVisited() { - visited_.columnOrdinal = columnOrdinal_; - visited_.privsBitmap.reset(); - visited_.grantableBitmap.reset(); + visited_.setColumnOrdinal(columnOrdinal_); + visited_.getPrivDesc().setAllPrivAndWgo(false); } // sets the current entry to match the original privileges // before they are adjusted by a revoke command void setCurrentToOriginal() { - current_.columnOrdinal = columnOrdinal_; - current_.privsBitmap = privsBitmap_; - current_.grantableBitmap = grantableBitmap_; + current_.setColumnOrdinal(columnOrdinal_); + current_.setPrivBitmap(privsBitmap_); + current_.setGrantableBitmap(grantableBitmap_); } -// compares the current privileges with the regenerated grant tree to +// compares the current privileges with the visited grant tree to // see if there are any broken branches NABoolean anyNotVisited() - {return current_.privsBitmap != visited_.privsBitmap || - current_.grantableBitmap != visited_.grantableBitmap;} + {return current_.getPrivBitmap() != visited_.getPrivBitmap() || + current_.getGrantableBitmap() != visited_.getGrantableBitmap();} // ------------------------------------------------------------------- @@ -319,30 +318,6 @@ private: ColumnPrivsMDRow &rowOut); }; -class ColObjectGrants -{ -public: - ColObjectGrants(int64_t objectUID) : object_uid_(objectUID) {}; - ~ColObjectGrants(); - - const ColPrivEntry * getColPrivGrant(int32_t columnOrdinal) const - { - for (size_t i = 0; i < colPrivGrants_.size(); i++) - if (colPrivGrants_[i].columnOrdinal == columnOrdinal) - return &colPrivGrants_[i]; - return NULL; - } - - void clear() - { - colPrivGrants_.clear(); - } - -private: - int64_t object_uid_; - std::vector<ColPrivEntry> colPrivGrants_; -}; - // ***************************************************************************** // * PrivMgrPrivileges.cpp static function declarations * // ***************************************************************************** @@ -417,18 +392,16 @@ ColPrivEntry::ColPrivEntry ( const PrivMgrMDRow &row ) { PrivMgrMDRow theRow = row; ColumnPrivsMDRow &columnRow = static_cast<ColumnPrivsMDRow &> (theRow); - columnOrdinal = columnRow.columnOrdinal_; - privsBitmap = columnRow.privsBitmap_; - grantableBitmap = columnRow.grantableBitmap_; - isUpdate = false; + privDesc_.setColumnOrdinal(columnRow.columnOrdinal_); + privDesc_.setPrivBitmap(columnRow.privsBitmap_); + privDesc_.setWgoBitmap(columnRow.grantableBitmap_); + isUpdate_ = false; } ColPrivEntry::ColPrivEntry ( const ColPrivEntry &other) { - columnOrdinal = other.columnOrdinal; - privsBitmap = other.privsBitmap; - grantableBitmap = other.grantableBitmap; - isUpdate = other.isUpdate; + privDesc_ = other.privDesc_; + isUpdate_ = other.isUpdate_; } // ***************************************************************************** @@ -635,6 +608,40 @@ PrivStatus PrivMgrPrivileges::getColPrivsForUser( return STATUS_GOOD; } +// ***************************************************************************** +// Function: getColRowsForGranteeOrdinal +// +// Returns the list of column privileges granted for the object that have +// been granted to the granteeID for a particular column +// +// Parameters: +// +// <granteeID> is the authID granted the privileges. +// <columnOrdinal> is the column number to gather privileges +// <roleIDs> is the list of roles assigned the granteeID +// <rowList> the privileges granted to <granteeID> on <columnOrdinal>. +// +// ***************************************************************************** +void PrivMgrPrivileges::getColRowsForGranteeOrdinal( + const int32_t granteeID, + const int32_t columnOrdinal, + const std::vector<int32_t> &roleIDs, + std::vector<PrivMgrMDRow *> &rowList) +{ + for (size_t i = 0; i < columnRowList_.size(); ++i) + { + ColumnPrivsMDRow &row = static_cast<ColumnPrivsMDRow &> (*columnRowList_[i]); + ColPrivEntry colPrivGrant; + + if (row.granteeID_ == granteeID && row.columnOrdinal_ == columnOrdinal) + { + ColumnPrivsMDRow *pRow = new ColumnPrivsMDRow(); + *pRow = row; + rowList.push_back(pRow); + } + } +} + // ***************************************************************************** // * Method: getPrivRowsForObject @@ -1055,17 +1062,8 @@ PrivStatus PrivMgrPrivileges::grantColumnPrivileges( return privStatus; - // Determine if the grantor has WITH GRANT OPTION (WGO) for all the - // columns to be granted. If not, return an error. - ObjectPrivsMDTable objectPrivsTable(objectTableName_,pDiags_); - ColumnPrivsMDTable columnPrivsTable(columnTableName_,pDiags_); - // Grantor may have WGO from two sources, object-level grants on the object, - // and column-level grants. First check the object-level grants. If there - // are privileges still to grant, check for requisite column-level grants. - - std::vector<ColPrivEntry> grantedColPrivs; - + // and column-level grants. hasColumnWGO checks both if (!hasColumnWGO(colPrivsArrayIn,roleIDs,privStatus)) { if (privStatus == STATUS_NOTFOUND) @@ -1079,6 +1077,7 @@ PrivStatus PrivMgrPrivileges::grantColumnPrivileges( // the grants are already present. (may be adding WGO) // Get existing column grants from grantor to the specified grantee. + std::vector<ColPrivEntry> grantedColPrivs; getColRowsForGranteeGrantor(columnRowList_, granteeID,grantorID_, grantedColPrivs); @@ -1098,24 +1097,23 @@ PrivStatus PrivMgrPrivileges::grantColumnPrivileges( std::vector<ColPrivEntry> colPrivsToGrant; for (size_t i = 0; i < colPrivsArray.size(); i++) { - const ColPrivSpec &colPrivEntry = colPrivsArray[i]; + const ColPrivSpec &colPrivSpec = colPrivsArray[i]; - ColPrivEntry *existingEntry = findColumnEntry(colPrivsToGrant, - colPrivEntry.columnOrdinal); - if (existingEntry != NULL) - { - existingEntry->privsBitmap.set(colPrivEntry.privType); - if (isWGOSpecified) - existingEntry->grantableBitmap.set(colPrivEntry.privType); - } - else - { - ColPrivEntry colPrivToGrant; - - colPrivToGrant.columnOrdinal = colPrivEntry.columnOrdinal; - colPrivToGrant.privsBitmap.set(colPrivEntry.privType); - if (isWGOSpecified) - colPrivToGrant.grantableBitmap.set(colPrivEntry.privType); + ColPrivEntry *existingEntry = findColumnEntry(colPrivsToGrant, + colPrivSpec.columnOrdinal); + if (existingEntry != NULL) + { + existingEntry->setPriv(colPrivSpec.privType, true); + if (isWGOSpecified) + existingEntry->setGrantable(colPrivSpec.privType, true); + } + else + { + ColPrivEntry colPrivToGrant; + colPrivToGrant.setColumnOrdinal(colPrivSpec.columnOrdinal); + colPrivToGrant.setPriv(colPrivSpec.privType, true); + if (isWGOSpecified) + colPrivToGrant.setGrantable(colPrivSpec.privType, true); colPrivsToGrant.push_back(colPrivToGrant); } @@ -1135,76 +1133,65 @@ PrivStatus PrivMgrPrivileges::grantColumnPrivileges( whereBase += authIDToString(granteeID); whereBase += " AND column_number = "; - for (size_t i = 0; i < colPrivsToGrant.size(); i++) - { - ColPrivEntry &colPrivToGrant = colPrivsToGrant[i]; - bool updateOperation = false; - bool skipOperation = false; + ColumnPrivsMDTable columnPrivsTable(columnTableName_,pDiags_); - // Look for any existing granted privileges on the column for which - // privileges are to be granted. - for (size_t g = 0; g < grantedColPrivs.size(); g++) - { - const ColPrivEntry &grantedColPriv = grantedColPrivs[g]; - // See if there is an existing column privilege granted for this column. - // If not, check the next granted column privilege. If none are found - // for this column, it is an insert operation. - if (colPrivToGrant.columnOrdinal != grantedColPriv.columnOrdinal) - continue; - - // An existing row with the same column has been found, it is one of four cases: - // - // 1) Adding a privilege (e.g., authID had SELECT, now granting INSERT) [update operation] - // 2) AuthID had privilege, now adding WGO [update operation] - // 3) AuthID already has privilege and/or WGO specified [skip operation] - // 4) AuthID had privilege and WGO, now trying to take away WGO [error] - - // If the privilege bitmaps are not the same, adding a privilege. - // This is an update operation, break out of for loop. - if (colPrivToGrant.privsBitmap != grantedColPriv.privsBitmap) - { - updateOperation = true; // Case #1 - colPrivToGrant.privsBitmap |= grantedColPriv.privsBitmap; - colPrivToGrant.grantableBitmap |= grantedColPriv.grantableBitmap; - break; - } - - // Privilege bitmaps are the same, could be adding WGO. - if (colPrivToGrant.grantableBitmap.any()) - { - // If WGO was specified, and adding, this is an update. - // If user already has WGO, it is a NOP, so skip this entry. - if (colPrivToGrant.grantableBitmap == grantedColPriv.grantableBitmap) - { - skipOperation = true; //Case #3 - break; - } - // Adding WGO - updateOperation = true; //Case #2 - } - else // WGO not specified - { - // If user already has WGO, error. Cannot revoke WGO via GRANT. - if (grantedColPriv.grantableBitmap.any()) - { - *pDiags_ << DgSqlCode(-CAT_PRIVILEGE_NOT_GRANTED); //TODO: Add error for removing WGO in GRANT - return STATUS_ERROR; // Case #4 - } - // WGO not specified, current privs same as privs to grant, - // nothing to do. - skipOperation = true; //Case #3 - break; - } + for (size_t i = 0; i < colPrivsToGrant.size(); i++) + { + ColPrivEntry &colPrivToGrant = colPrivsToGrant[i]; + + colPrivToGrant.describe(traceMsg); + log (__FILE__, traceMsg, i); + + bool updateOperation = false; + bool skipOperation = false; + + ColPrivEntry *grantedColPriv = findColumnEntry(grantedColPrivs, colPrivToGrant.getColumnOrdinal()); + if (grantedColPriv) + { + // An existing row with the same column has been found, it is one of four cases: + // + // 1) AuthID had WGO, now trying to take away WGO [error] + // 2) Adding a privilege (e.g., authID had SELECT, now granting INSERT) [update operation] + // 3) AuthID had privilege, now adding WGO [update operation] + // 4) AuthID already has privilege and/or WGO specified [skip operation] - updateOperation = true; - colPrivToGrant.privsBitmap |= grantedColPriv.privsBitmap; - colPrivToGrant.grantableBitmap |= grantedColPriv.grantableBitmap; - // Found an existing row for this column ordinal, so break out of loop. - break; + // case 1: see if trying to take away WGO - anyNotSet returns true iff any + // WGO bit set in grantedColPriv is not set in colPrivToGrant - can this + // really occur? + if (colPrivToGrant.getPrivBitmap() == grantedColPriv->getPrivBitmap() && + grantedColPriv->getPrivDesc().anyNotSet(colPrivToGrant.getPrivDesc())) + { + PRIVMGR_INTERNAL_ERROR("trying to remove WGO during grant"); + return STATUS_ERROR; } + + // Case 2: If the privilege bitmaps are not the same, adding a privilege. + // This is an update operation + if (colPrivToGrant.getPrivBitmap() != grantedColPriv->getPrivBitmap()) + { + updateOperation = true; // Case #1 + colPrivToGrant.getPrivDesc().unionOfPrivs(grantedColPriv->getPrivDesc()); + } + + // Privilege bitmaps are the same + else + // Case 3: the privileges match, see if there are any additional WGO privs + // to set and mark updatable + // anyNotSet returns true iff any WGO bit set in colPrivToGrant is not set in + // grantedColPriv, this means more WGO bits need to be set. + if (colPrivToGrant.getPrivDesc().anyNotSet(grantedColPriv->getPrivDesc())) + { + updateOperation = true; + colPrivToGrant.getPrivDesc().unionOfPrivs(grantedColPriv->getPrivDesc()); + } + // Case 4: no changes to priv or WGO bits - no updates required - skip + else + skipOperation = true; + } - if (skipOperation) - continue; + // Done with this entry, go to the next one + if (skipOperation) + continue; // TBD: need to get the list of referencing views that need to have this // privilege progated. @@ -1232,9 +1219,9 @@ PrivStatus PrivMgrPrivileges::grantColumnPrivileges( row.granteeName_ = granteeName; row.grantorID_ = grantorID_; row.grantorName_ = grantorName; - row.privsBitmap_ = colPrivToGrant.privsBitmap; - row.grantableBitmap_ = colPrivToGrant.grantableBitmap; - row.columnOrdinal_ = colPrivToGrant.columnOrdinal; + row.privsBitmap_ = colPrivToGrant.getPrivBitmap(); + row.grantableBitmap_ = colPrivToGrant.getGrantableBitmap(); + row.columnOrdinal_ = colPrivToGrant.getColumnOrdinal(); if (updateOperation) privStatus = columnPrivsTable.updateColumnRow(row,whereBase); @@ -1334,6 +1321,10 @@ PrivStatus PrivMgrPrivileges::grantObjectPriv( if (generateObjectRowList() == STATUS_ERROR) return STATUS_ERROR; + // generate the list of privileges granted to columns and store in class + if (generateColumnRowList() == STATUS_ERROR) + return STATUS_ERROR; + // get roleIDs for the grantor std::vector<int_32> roleIDs; retcode = getRoleIDsForUserID(grantorID_,roleIDs); @@ -1483,6 +1474,7 @@ PrivStatus PrivMgrPrivileges::grantObjectPriv( } ObjectPrivsMDTable objectPrivsTable (objectTableName_, pDiags_); + ColumnPrivsMDTable columnPrivsTable(columnTableName_,pDiags_); char buf[1000]; if (foundRow) @@ -1493,6 +1485,7 @@ PrivStatus PrivMgrPrivileges::grantObjectPriv( objectUsage.grantorIsSystem = false; objectUsage.objectName = row.objectName_; objectUsage.objectType = row.objectType_; + objectUsage.columnReferences = NULL; PrivMgrDesc originalPrivs (row.granteeID_); originalPrivs.setTablePrivs(savedOriginalPrivs); @@ -1517,9 +1510,9 @@ PrivStatus PrivMgrPrivileges::grantObjectPriv( // update the OBJECT_PRIVILEGES row for each effected object for (size_t i = 0; i < listOfObjects.size(); i++) { - ObjectUsage *pObj = listOfObjects[i]; + ObjectUsage *pObjectUsage = listOfObjects[i]; - pObj->describe(traceMsg); + pObjectUsage->describe(traceMsg); log (__FILE__, traceMsg, i); // Determine the grantor: @@ -1538,10 +1531,10 @@ PrivStatus PrivMgrPrivileges::grantObjectPriv( // // The listOfObjects contains referencing views that meet the above // criteria. - int32_t theGrantor = (pObj->grantorIsSystem) ? SYSTEM_USER : grantorID_; - int32_t theGrantee = pObj->granteeID; - int64_t theUID = pObj->objectUID; - PrivMgrCoreDesc thePrivs = pObj->updatedPrivs.getTablePrivs(); + int32_t theGrantor = (pObjectUsage->grantorIsSystem) ? SYSTEM_USER : grantorID_; + int32_t theGrantee = pObjectUsage->granteeID; + int64_t theUID = pObjectUsage->objectUID; + PrivMgrCoreDesc thePrivs = pObjectUsage->updatedPrivs.getTablePrivs(); sprintf(buf, "where grantee_id = %d and grantor_id = %d and object_uid = %ld", theGrantee, theGrantor, theUID); @@ -1787,7 +1780,6 @@ PrivStatus PrivMgrPrivileges::insertPrivRowsForObject( } - // **************************************************************************** // method: dealWithConstraints // @@ -1831,32 +1823,36 @@ PrivStatus PrivMgrPrivileges::dealWithConstraints( if (retcode == STATUS_ERROR) return retcode; - // objectList contain ObjectReferences for all tables that reference the - // ObjectUsage (object losing privilege) through an RI constraint - PrivMgrDesc originalPrivs; - PrivMgrDesc currentPrivs; int32_t lastObjectOwnerID = 0; std::vector<int32_t> roleIDs; + // objectList contains the list of objects referencing the referenced table, + // see if the requested privilege change causes an RI constraint to be invalid for (size_t i = 0; i < objectList.size(); i++) { - ObjectReference *pObj = objectList[i]; + ObjectReference *pObjectRef = objectList[i]; + PrivMgrDesc originalPrivs; + PrivMgrDesc currentPrivs; - pObj->describe(traceMsg); + pObjectRef->describe(traceMsg); log (__FILE__, traceMsg, i); - - if (lastObjectOwnerID != pObj->objectOwner) + + // getRoleIDsForUserID does I/O to get information. The referencing + // list is returned by object owner to avoid rereading information for + // the same user + // At some time, we should cache user and role information + if (lastObjectOwnerID != pObjectRef->objectOwner) { roleIDs.clear(); - retcode = getRoleIDsForUserID(pObj->objectOwner,roleIDs); + retcode = getRoleIDsForUserID(pObjectRef->objectOwner,roleIDs); if (retcode == STATUS_ERROR) return retcode; } // get the summarized original and current privs for the referencing table - // current privs contains any adjustments - retcode = summarizeCurrentAndOriginalPrivs(pObj->objectUID, - pObj->objectOwner, + // current privs contains any adjustments due to the privilege change + retcode = summarizeCurrentAndOriginalPrivs(pObjectRef->objectUID, + pObjectRef->objectOwner, roleIDs, listOfAffectedObjects, originalPrivs, @@ -1864,25 +1860,66 @@ PrivStatus PrivMgrPrivileges::dealWithConstraints( if (retcode != STATUS_GOOD) return retcode; - // If the underlying table no long has REFERENCES privileges return - // a dependency error. - PrivMgrCoreDesc thePrivs = objectUsage.updatedPrivs.getTablePrivs(); + PrivMgrCoreDesc thePrivs = currentPrivs.getTablePrivs(); if (!thePrivs.getPriv(REFERENCES_PRIV)) { - std::string referencingTable; - if (admin.getConstraintName(objectUsage.objectUID, pObj->objectUID, referencingTable) == false) + log (__FILE__, "User does not have reference privilege on the object", -1); + + // no longer have REFERENCES privilege on the table, + // see if privileges are granted on all required columns + std::vector<ColumnReference *> summarizedColRefs; + summarizeColPrivs(*pObjectRef, roleIDs, listOfAffectedObjects, summarizedColRefs); + + // check summarized privileges to see if still have priv through other privs + std::vector<ColumnReference *> neededColRefs = *pObjectRef->columnReferences; + for (size_t i = 0; i < neededColRefs.size(); i++) { - referencingTable = "UNKNOWN, Referencing table ID is "; - referencingTable += UIDToString(pObj->objectUID); + + // neededColRefs contains the list of all columns referenced by this object + // summarizedColRefs are the current privileges with the privilege change + // incorporated. + // if user still has necessary privilege through column privileges, then + // revoke can proceed + ColumnReference *neededColRef = neededColRefs[i]; + for (size_t j = 0; j < summarizedColRefs.size(); j++) + { + ColumnReference *existingRef = summarizedColRefs[j]; + traceMsg = "Checking if have references for col: "; + traceMsg += to_string((long long int)existingRef->columnOrdinal); + log (__FILE__, traceMsg, -1); + if (existingRef->columnOrdinal == neededColRef->columnOrdinal) + { + PrivMgrCoreDesc colPrivs = existingRef->updatedPrivs; + traceMsg = "References setting: "; + traceMsg += (colPrivs.getPriv(REFERENCES_PRIV) ? "y" : "n"); + log (__FILE__, traceMsg, -1); + if (!colPrivs.getPriv(REFERENCES_PRIV)) + { + std::string referencingTable; + if (!admin.getConstraintName(objectUsage.objectUID, + pObjectRef->objectUID, + neededColRef->columnOrdinal, referencingTable)) + { + referencingTable = "UNKNOWN, Referencing table ID is "; + referencingTable += UIDToString(pObjectRef->objectUID ); + } + + *pDiags_ << DgSqlCode (-CAT_DEPENDENT_OBJECTS_EXIST) + << DgString0 (referencingTable.c_str()); + retcode = STATUS_ERROR; + } + break; + } + } } - *pDiags_ << DgSqlCode (-CAT_DEPENDENT_OBJECTS_EXIST) - << DgString0 (referencingTable.c_str()); - return STATUS_ERROR; + // remove list of summarized columns + while (!summarizedColRefs.empty()) + delete summarizedColRefs.back(), summarizedColRefs.pop_back(); } } - return STATUS_GOOD; + return retcode; } @@ -1960,9 +1997,9 @@ PrivStatus PrivMgrPrivileges::dealWithUdrs( { // There could be multiple udrs, just pick the first one in the list // for the error message. - ObjectReference *pObj = objectList[0]; + ObjectReference *pObjectRef = objectList[0]; *pDiags_ << DgSqlCode (-CAT_DEPENDENT_OBJECTS_EXIST) - << DgString0 (pObj->objectName.c_str()); + << DgString0 (pObjectRef->objectName.c_str()); return STATUS_ERROR; } } @@ -2127,15 +2164,15 @@ PrivStatus PrivMgrPrivileges::gatherViewPrivileges( for (size_t i = 0; i < objectList.size(); i++) { - ObjectReference *pObj = objectList[i]; + ObjectReference *pObjectRef = objectList[i]; - pObj->describe(traceMsg); + pObjectRef->describe(traceMsg); log (__FILE__, traceMsg, i); - if (lastObjectOwnerID != pObj->objectOwner) + if (lastObjectOwnerID != pObjectRef->objectOwner) { roleIDs.clear(); - retcode = getRoleIDsForUserID(pObj->objectOwner,roleIDs); + retcode = getRoleIDsForUserID(pObjectRef->objectOwner,roleIDs); if (retcode == STATUS_ERROR) return retcode; } @@ -2143,7 +2180,7 @@ PrivStatus PrivMgrPrivileges::gatherViewPrivileges( // referenced object that have been granted to the view owner // listOfAffectedObjects contain the privilege adjustments needed // to generate the current privs - retcode = summarizeCurrentAndOriginalPrivs(pObj->objectUID, + retcode = summarizeCurrentAndOriginalPrivs(pObjectRef->objectUID, viewUsage.viewOwner, roleIDs, listOfAffectedObjects, @@ -2285,15 +2322,20 @@ PrivStatus PrivMgrPrivileges::getAffectedObjects( pUsage->objectType = objectUsage.objectType; pUsage->originalPrivs = objectUsage.originalPrivs; pUsage->updatedPrivs = objectUsage.updatedPrivs; + pUsage->columnReferences = objectUsage.columnReferences; + listOfAffectedObjects.push_back(pUsage); + // Find list of affected constraints if (command != PrivCommand::GRANT_OBJECT) { + // TBD optimization: if no "references" privilege has been revoked, skip retcode = dealWithConstraints (objectUsage, listOfAffectedObjects); - if (retcode != STATUS_GOOD && retcode != STATUS_WARNING) + if (retcode == STATUS_ERROR) return retcode; + // TBD optimization: if no "execute" privilege has been revoked, skip retcode = dealWithUdrs (objectUsage, listOfAffectedObjects); if (retcode != STATUS_GOOD && retcode != STATUS_WARNING) return retcode; @@ -2505,6 +2547,10 @@ PrivStatus PrivMgrPrivileges::revokeColumnPrivileges( std::string privilege; std::vector<ColPrivEntry> grantedColPrivs; + // get the list of object privileges for the object + if (generateObjectRowList() == STATUS_ERROR) + return STATUS_ERROR; + // get the list of column privileges for the object if (generateColumnRowList() == STATUS_ERROR) return STATUS_ERROR; @@ -2533,13 +2579,14 @@ PrivStatus PrivMgrPrivileges::revokeColumnPrivileges( // Create a privsToRevoke array using the passed in revoke entries and the // list of currently granted column privileges. Combine multiple privileges // for the same column into one entry. + std::vector<ColPrivEntry> colPrivsToRevoke; for (size_t i = 0; i < colPrivsArray.size(); i++) { - const ColPrivSpec &colPrivSpecEntry = colPrivsArray[i]; - PrivType privType = colPrivSpecEntry.privType; - int32_t columnOrdinal = colPrivSpecEntry.columnOrdinal; + const ColPrivSpec &colPrivSpec = colPrivsArray[i]; + PrivType privType = colPrivSpec.privType; + int32_t columnOrdinal = colPrivSpec.columnOrdinal; // Find the priv details from metadata ColPrivEntry *metadataEntry = findColumnEntry(grantedColPrivs, @@ -2555,33 +2602,76 @@ PrivStatus PrivMgrPrivileges::revokeColumnPrivileges( columnOrdinal); if (existingEntry != NULL) { - existingEntry->privsBitmap.set(privType); + existingEntry->setPriv(privType, true); // if revoking a privilege and auth ID has WGO, then revoke // the WGO bit also - PrivColumnBitmap grantableBitmap = metadataEntry->grantableBitmap; - existingEntry->grantableBitmap.set(privType, grantableBitmap.test(privType)); + PrivColumnBitmap grantableBitmap = metadataEntry->getGrantableBitmap(); + existingEntry->setGrantable(privType, grantableBitmap.test(privType)); } else { ColPrivEntry colPrivToRevoke; - colPrivToRevoke.columnOrdinal = columnOrdinal; - colPrivToRevoke.privsBitmap.set(privType); - + colPrivToRevoke.setColumnOrdinal(columnOrdinal); + colPrivToRevoke.setPriv(privType,true); + // if revoking a privilege and auth ID has WGO, then revoke // the WGO bit also - colPrivToRevoke.grantableBitmap.set(privType, metadataEntry->grantableBitmap.test(privType)); + colPrivToRevoke.setGrantable(privType, metadataEntry->getGrantableBitmap().test(privType)); colPrivsToRevoke.push_back(colPrivToRevoke); } } + + // checks to see if can revoke if there are referenced items when + // revoke cascade is supported, this returns the list of referenced + // items that need to change. + ObjectUsage objectUsage; + objectUsage.objectUID = objectUID_; + objectUsage.granteeID = granteeID; + objectUsage.objectName = objectName_; + objectUsage.objectType = objectType; + + // Create list of ColumnReferences + objectUsage.columnReferences = new std::vector<ColumnReference *>; + for (size_t i = 0; i < colPrivsToRevoke.size(); i++) + { + ColPrivEntry &colPrivToRevoke = colPrivsToRevoke[i]; + ColPrivEntry *grantedColPriv = findColumnEntry(grantedColPrivs, colPrivToRevoke.getColumnOrdinal()); + if (grantedColPriv) + { + ColumnReference *adjustedCol = new ColumnReference; + adjustedCol->columnOrdinal = colPrivToRevoke.getColumnOrdinal(); + adjustedCol->originalPrivs = grantedColPriv->getPrivDesc(); + PrivMgrCoreDesc adjustedPrivs = grantedColPriv->getPrivDesc(); + adjustedPrivs.AndNot(colPrivToRevoke.getPrivDesc()); + adjustedCol->updatedPrivs = adjustedPrivs; + objectUsage.columnReferences->push_back(adjustedCol); + } + } + + // get privileges for the object, if they exist + ObjectPrivsMDRow row; + privStatus = getGrantedPrivs(granteeID, row); + if (privStatus == STATUS_GOOD) + { + PrivMgrCoreDesc coreDesc(row.privsBitmap_, row.grantableBitmap_); + objectUsage.originalPrivs.setTablePrivs(coreDesc); + objectUsage.updatedPrivs.setTablePrivs(coreDesc); + } - // Verify that the existing grant tree stays intact (i.e. no broken branches) - // if the requested privileges are revokew. - if (checkColumnRevokeRestrict (granteeID, colPrivsToRevoke, columnRowList_)) - return STATUS_ERROR; + std::vector<ObjectUsage *> listOfObjects; + privStatus = getAffectedObjects(objectUsage, + PrivCommand::REVOKE_OBJECT_RESTRICT, + listOfObjects); + if (privStatus == STATUS_ERROR) + { + deleteListOfAffectedObjects(listOfObjects); + return privStatus; + } + // At this point we have an array of privsToRevoke with column ordinal and // priv bitmap. // @@ -2599,6 +2689,11 @@ PrivStatus PrivMgrPrivileges::revokeColumnPrivileges( // F 1 Not equal Revoking some privs on this column plus // WGO for the revoked privs. Reset bits in // both bitmaps. Update operation. + + + if (checkColumnRevokeRestrict (granteeID, colPrivsToRevoke, columnRowList_)) + return STATUS_ERROR; + bool rowRevoked = false; PrivColumnBitmap revokedPrivs; @@ -2619,54 +2714,48 @@ PrivStatus PrivMgrPrivileges::revokeColumnPrivileges( // Look for any existing granted privileges on the column for which // privileges are to be granted. - for (size_t g = 0; g < grantedColPrivs.size(); g++) + ColPrivEntry *grantedColPriv = findColumnEntry(grantedColPrivs, colPrivToRevoke.getColumnOrdinal()); + if (grantedColPriv) { - const ColPrivEntry &grantedColPriv = grantedColPrivs[g]; - // See if there is an existing column privilege granted for this column. - // If not, check the next granted column privilege. If none are found - // for this column, it is an internal error. - if (colPrivToRevoke.columnOrdinal != grantedColPriv.columnOrdinal) - continue; - // Found row with grant for this column. - // Verify privilge(s) being revoked was/were granted. If not, internal error. - if ((colPrivToRevoke.privsBitmap & grantedColPriv.privsBitmap) == 0) + // Verify privilege(s) being revoked was/were granted. If not, internal error. + if ((colPrivToRevoke.getPrivBitmap() & grantedColPriv->getPrivBitmap()) == 0) { PRIVMGR_INTERNAL_ERROR("Privilege to revoke not found"); return STATUS_ERROR; } - if (isWGOSpecified) - { - // We want to clear the corresponding bits in the grantable bitmap. - // Flip the bits of the privs to revoke bitmap, then and the - // negation with the current grantable bitmap. Not revoking any - // privileges, so update with current priv bitmap. - PrivColumnBitmap revokeBitmap = ~colPrivToRevoke.privsBitmap; - colPrivToRevoke.privsBitmap = grantedColPriv.privsBitmap; - colPrivToRevoke.grantableBitmap = grantedColPriv.grantableBitmap & revokeBitmap; - updateRow = true; - } + // If all privileges are revoked, delete corresponding row + if (!isWGOSpecified && + (colPrivToRevoke.getPrivBitmap() == grantedColPriv->getPrivBitmap())) + deleteRow = true; else - { - if (colPrivToRevoke.privsBitmap == grantedColPriv.privsBitmap) - deleteRow = true; - else - { - PrivColumnBitmap revokeBitmap = ~colPrivToRevoke.privsBitmap; - colPrivToRevoke.privsBitmap = grantedColPriv.privsBitmap & revokeBitmap; - colPrivToRevoke.grantableBitmap = grantedColPriv.grantableBitmap & revokeBitmap; - updateRow = true; - } - revokedPrivs |= colPrivToRevoke.privsBitmap; - } - break; + updateRow = true; + + // generate the final bitmaps to store in metadata + // removing any privileges that already have been revoked + PrivMgrCoreDesc adjustedPrivs = grantedColPriv->getPrivDesc(); + adjustedPrivs.AndNot(colPrivToRevoke.getPrivDesc()); + + // If only removing WGO, then the privsBitmap does not change + // Not sure if this is needed ?? + if (isWGOSpecified) + adjustedPrivs.setPrivBitmap(grantedColPriv->getPrivBitmap()); + + // set adjusted privileges + colPrivToRevoke.setPrivBitmap(adjustedPrivs.getPrivBitmap()); + colPrivToRevoke.setGrantableBitmap(adjustedPrivs.getWgoBitmap()); + + // Using the list of privs to revoke, change so adjustedPrivs contains + // Some privileges may have been requested to revoke that aren't + // currently granted - flip adjusted bits to final list of privs + revokedPrivs |= adjustedPrivs.getPrivBitmap(); } if (deleteRow) { - std::string whereClause(whereBase + authIDToString(colPrivToRevoke.columnOrdinal)); + std::string whereClause(whereBase + authIDToString(colPrivToRevoke.getColumnOrdinal())); privStatus = columnPrivsTable.deleteWhere(whereClause); if (privStatus == STATUS_ERROR) @@ -2690,9 +2779,9 @@ PrivStatus PrivMgrPrivileges::revokeColumnPrivileges( row.granteeName_ = granteeName; row.grantorID_ = grantorID_; row.grantorName_ = grantorName; - row.privsBitmap_ = colPrivToRevoke.privsBitmap; - row.grantableBitmap_ = colPrivToRevoke.grantableBitmap; - row.columnOrdinal_ = colPrivToRevoke.columnOrdinal; + row.privsBitmap_ = colPrivToRevoke.getPrivBitmap(); + row.grantableBitmap_ = colPrivToRevoke.getGrantableBitmap(); + row.columnOrdinal_ = colPrivToRevoke.getColumnOrdinal(); privStatus = columnPrivsTable.updateColumnRow(row,whereBase); @@ -2725,15 +2814,15 @@ PrivStatus PrivMgrPrivileges::revokeColumnPrivileges( if (siIndex > 0) SQL_EXEC_SetSecInvalidKeys(siIndex,siKeyList); -// if (!rowRevoked) - // Warning - // ; + // if (!rowRevoked) + // Warning return STATUS_GOOD; } //************* End of PrivMgrPrivileges::revokeColumnPrivileges *************** + // ***************************************************************************** // * Method: revokeObjectPriv // * @@ -2822,6 +2911,10 @@ PrivStatus PrivMgrPrivileges::revokeObjectPriv (const ComObjectType objectType, if (generateObjectRowList() == STATUS_ERROR) return STATUS_ERROR; + // generate the list of privileges granted to columns and store in class + if (generateColumnRowList() == STATUS_ERROR) + return STATUS_ERROR; + // get privileges for the grantor and make sure the grantor can revoke // at least one of the requested privileges PrivMgrDesc privsOfTheGrantor(grantorID_); @@ -2936,8 +3029,8 @@ PrivStatus PrivMgrPrivileges::revokeObjectPriv (const ComObjectType objectType, // update the OBJECT_PRIVILEGES row for each effected object for (size_t i = 0; i < listOfObjects.size(); i++) { - ObjectUsage *pObj = listOfObjects[i]; - PrivMgrCoreDesc thePrivs = pObj->updatedPrivs.getTablePrivs(); + ObjectUsage *pObjectUsage = listOfObjects[i]; + PrivMgrCoreDesc thePrivs = pObjectUsage->updatedPrivs.getTablePrivs(); // Determine the grantor: // SQL ANSI general rules state @@ -2954,9 +3047,9 @@ PrivStatus PrivMgrPrivileges::revokeObjectPriv (const ComObjectType objectType, // // The listOfObjects contains referencing views that meet the above // criteria. - int32_t theGrantor = (pObj->grantorIsSystem) ? SYSTEM_USER : grantorID_; - int32_t theGrantee = pObj->granteeID; - int64_t theUID = pObj->objectUID; + int32_t theGrantor = (pObjectUsage->grantorIsSystem) ? SYSTEM_USER : grantorID_; + int32_t theGrantee = pObjectUsage->granteeID; + int64_t theUID = pObjectUsage->objectUID; sprintf(buf, "where grantee_id = %d and grantor_id = %d and object_uid = %ld", theGrantee, theGrantor, theUID); @@ -2964,7 +3057,7 @@ PrivStatus PrivMgrPrivileges::revokeObjectPriv (const ComObjectType objectType, if (thePrivs.isNull()) { - pObj->describe(traceMsg); + pObjectUsage->describe(traceMsg); traceMsg.insert (0, "deleted object usage "); // delete the row @@ -2974,13 +3067,6 @@ PrivStatus PrivMgrPrivileges::revokeObjectPriv (const ComObjectType objectType, deleteListOfAffectedObjects(listOfObjects); return retcode; } - // Delete any corresponding column-level privileges. - retcode = columnPrivsTable.deleteWhere(whereClause); - if (retcode == STATUS_ERROR) - { - deleteListOfAffectedObjects(listOfObjects); - return retcode; - } } else { @@ -2989,7 +3075,7 @@ PrivStatus PrivMgrPrivileges::revokeObjectPriv (const ComObjectType objectType, thePrivs.getWgoBitmap().to_ulong()); std::string setClause (buf); - pObj->describe(traceMsg); + pObjectUsage->describe(traceMsg); traceMsg.insert (0, "updated object usage "); // update the row retcode = objectPrivsTable.updateWhere(setClause, whereClause); @@ -2998,13 +3084,6 @@ PrivStatus PrivMgrPrivileges::revokeObjectPriv (const ComObjectType objectType, deleteListOfAffectedObjects(listOfObjects); return retcode; } - // Update any corresponding column-level privileges. - retcode = columnPrivsTable.updateWhere(setClause,whereClause); - if (retcode == STATUS_ERROR) - { - deleteListOfAffectedObjects(listOfObjects); - return retcode; - } } } @@ -3314,12 +3393,12 @@ bool PrivMgrPrivileges::checkColumnRevokeRestrict ( { ColPrivEntry updatedEntry = (ColPrivEntry)colPrivsToRevoke[j]; - if (updatedEntry.columnOrdinal == currentRow.columnOrdinal_) + if (updatedEntry.getColumnOrdinal() == currentRow.columnOrdinal_) { - PrivColumnBitmap newPrivsBitmap = updatedEntry.privsBitmap ^= currentRow.privsBitmap_; - PrivColumnBitmap newGrantableBitmap = updatedEntry.grantableBitmap ^= currentRow.grantableBitmap_; - currentRow.current_.privsBitmap = newPrivsBitmap; - currentRow.current_.grantableBitmap = newGrantableBitmap; + PrivColumnBitmap newPrivBitmap = updatedEntry.getPrivBitmap() ^= currentRow.privsBitmap_; + PrivColumnBitmap newGrantableBitmap = updatedEntry.getGrantableBitmap() ^= currentRow.grantableBitmap_; + currentRow.current_.setPrivBitmap(newPrivBitmap); + currentRow.current_.setGrantableBitmap(newGrantableBitmap); traceMsg = "Adjusted current_ to reflect revoked privileges"; traceMsg += ", grantor is "; traceMsg += to_string((long long int)currentRow.grantorID_); @@ -3348,8 +3427,8 @@ bool PrivMgrPrivileges::checkColumnRevokeRestrict ( std::set<int32_t> listOfColumnOrdinals; for ( size_t i = 0; i < colPrivsToRevoke.size(); i++) { - const ColPrivEntry colPrivToRevoke = colPrivsToRevoke[i]; - listOfColumnOrdinals.insert(colPrivToRevoke.columnOrdinal); + ColPrivEntry colPrivToRevoke = colPrivsToRevoke[i]; + listOfColumnOrdinals.insert(colPrivToRevoke.getColumnOrdinal()); } // Reconstruct tree @@ -3444,23 +3523,23 @@ void PrivMgrPrivileges::scanColumnBranch( const PrivType pType, // The listOfColumnOrdinals has this list ColPrivEntry current = currentRow.current_; std::set<int32_t>::iterator it; - it = std::find(listOfColumnOrdinals.begin(), listOfColumnOrdinals.end(), current.columnOrdinal); + it = std::find(listOfColumnOrdinals.begin(), listOfColumnOrdinals.end(), current.getColumnOrdinal()); if (it != listOfColumnOrdinals.end()) { - if ( current.privsBitmap.test(pType) ) + if ( current.getPrivBitmap().test(pType) ) { // This grantee has priv. Set corresponding visited flag. - currentRow.visited_.privsBitmap.set(pType, true); + currentRow.visited_.setPriv(pType, true); - if ( current.grantableBitmap.test(pType)) + if ( current.getGrantableBitmap().test(pType)) { // This grantee has wgo. - if ( currentRow.visited_.grantableBitmap.test(pType) ) + if ( currentRow.visited_.getGrantableBitmap().test(pType) ) { // Already processed this subtree. } else { - currentRow.visited_.grantableBitmap.set(pType, true); + currentRow.visited_.setGrantable(pType, true); // To check: since column level privileges do not have // an anchor, we choose the object owner as the root. @@ -3510,17 +3589,17 @@ void PrivMgrPrivileges::scanColumnPublic( // The listOfColumnOrdinals has this list ColPrivEntry current = currentRow.current_; std::set<int32_t>::iterator it; - it = std::find(listOfColumnOrdinals.begin(), listOfColumnOrdinals.end(), current.columnOrdinal); + it = std::find(listOfColumnOrdinals.begin(), listOfColumnOrdinals.end(), current.getColumnOrdinal()); if (it != listOfColumnOrdinals.end()) { - if ( current.privsBitmap.test(pType) ) + if ( current.getPrivBitmap().test(pType) ) { // This grantee has priv. Set corresponding visited flag. - currentRow.visited_.privsBitmap.set(pType, true); + currentRow.visited_.setPriv(pType, true); // This grantee has wgo. - if ( currentRow.visited_.grantableBitmap.test(pType) ) - currentRow.visited_.grantableBitmap.set(pType, true); + if ( currentRow.visited_.getGrantableBitmap().test(pType) ) + currentRow.visited_.setGrantable(pType, true); } } } // end scan privsList over all Grantees/Grantors @@ -4093,6 +4172,84 @@ PrivStatus PrivMgrPrivileges::getRowsForGrantee( return STATUS_GOOD; } +// **************************************************************************** +// method: summarizeColPrivs +// +// This method summarizes column privileges across all grantors. +// +// Params: +// objectReference - the affected object +// roleIDs - list of roles for the current object owner +// listOfAffectedObjects - list of affected objects +// summarizedColRefs - a list of ColumnReference pointers that contain the +// summarized privileges (the caller is responsible +// for deleting memory for this parameter +// **************************************************************************** +void PrivMgrPrivileges::summarizeColPrivs( + const ObjectReference &objReference, + const std::vector<int32_t> &roleIDs, + const std::vector<ObjectUsage *> &listOfAffectedObjects, + std::vector<ColumnReference *> &summarizedColRefs) +{ + std::string traceMsg; + objReference.describe(traceMsg); + traceMsg.insert (0, "summarizing column privileges "); + log (__FILE__, traceMsg, -1); + + // objReference.columnReferences is the list of columns for RI constraints + // referencing the referenced table + std::vector<ColumnReference *> *colRefs = objReference.columnReferences; + for (size_t i = 0; i < colRefs->size(); i++) + { + ColumnReference *colRef = (*colRefs)[i]; + colRef->describe(traceMsg); + log (__FILE__, traceMsg, i); + + // get COLUMN_PRIVILEGES rows where the grantee for the column has received + // privileges - the row list is in memory so this does not require I/O + std::vector<PrivMgrMDRow *> rowList; + getColRowsForGranteeOrdinal(objReference.objectOwner, + colRef->columnOrdinal, + roleIDs, + rowList); + + // go through the rowList to summarize the original and current privileges + // We do a union operation to capture privileges from all grantors + ColumnReference *summarized = new ColumnReference; + summarized->columnOrdinal = colRef->columnOrdinal; + for (int32_t i = 0; i < rowList.size();++i) + { + ColumnPrivsMDRow &row = static_cast<ColumnPrivsMDRow &> (*rowList[i]); + PrivMgrCoreDesc originalPrivs(row.privsBitmap_, row.grantableBitmap_); + + ColumnReference ref; + ref.columnOrdinal = row.columnOrdinal_; + ref.originalPrivs = originalPrivs; + ref.updatedPrivs = originalPrivs; + + // Update if privileges have been changed by request + for (size_t j = 0; j < listOfAffectedObjects.size(); j++) + { + ObjectUsage *currentObj = listOfAffectedObjects[j]; + if (currentObj->objectUID == row.objectUID_ && + grantorID_ == row.grantorID_ && + objReference.objectOwner == row.granteeID_ ) + { + ColumnReference *changedRef = currentObj->findColumn(row.columnOrdinal_); + if (changedRef) + ref.updatedPrivs = changedRef->updatedPrivs; + } + } + + summarized->originalPrivs.unionOfPrivs(ref.originalPrivs); + summarized->updatedPrivs.unionOfPrivs(ref.updatedPrivs); + } + + // Add column ref to the list + summarizedColRefs.push_back(summarized); + } +} + // ***************************************************************************** // * Method: summarizeCurrentAndOriginalPrivs // * @@ -4137,12 +4294,12 @@ PrivStatus PrivMgrPrivileges::summarizeCurrentAndOriginalPrivs( PrivMgrCoreDesc current = original; for (size_t j = 0; j < listOfChangedPrivs.size(); j++) { - ObjectUsage *pObj = listOfChangedPrivs[j]; - if (pObj->objectUID == row.objectUID_ && + ObjectUsage *pObjectUsage = listOfChangedPrivs[j]; + if (pObjectUsage->objectUID == row.objectUID_ && grantorID_ == row.grantorID_ && - pObj->granteeID == row.granteeID_ ) + pObjectUsage->granteeID == row.granteeID_ ) { - current = pObj->updatedPrivs.getTablePrivs(); + current = pObjectUsage->updatedPrivs.getTablePrivs(); } } summarizedOriginalPrivs.unionOfPrivs(original); @@ -4861,7 +5018,7 @@ static ColPrivEntry * findColumnEntry( { for (size_t i = 0; i < colPrivEntries.size(); i++) - if (colPrivEntries[i].columnOrdinal == columnOrdinal) + if (colPrivEntries[i].getColumnOrdinal() == columnOrdinal) return & colPrivEntries[i]; return NULL; @@ -4979,9 +5136,9 @@ static void getColRowsForGranteeGrantor( if (row.grantorID_ == grantorID && row.granteeID_ == granteeID) { - colPrivGrant.columnOrdinal = row.columnOrdinal_; - colPrivGrant.privsBitmap = row.privsBitmap_.to_ulong(); - colPrivGrant.grantableBitmap = row.grantableBitmap_.to_ulong(); + colPrivGrant.setColumnOrdinal(row.columnOrdinal_); + colPrivGrant.setPrivBitmap(row.privsBitmap_.to_ulong()); + colPrivGrant.setGrantableBitmap(row.grantableBitmap_.to_ulong()); grantedColPrivs.push_back(colPrivGrant); } @@ -5085,58 +5242,58 @@ std::vector<ColPrivSpec> &colPrivsArray = privStatus = STATUS_GOOD; -// Grantor may have column WGO from two sources, object-level grants on the -// object and column-level grants. First check the object-level grants. + // Grantor may have column WGO from two sources, object-level grants on the + // object and column-level grants. First check the object-level grants. -std::vector<PrivMgrMDRow *> objRowList; + std::vector<PrivMgrMDRow *> objRowList; - // Get object privileges that the grantor has been granted - that is, the - // grantor becomes the grantee. - privStatus = getRowsForGrantee(objectUID_,grantorID_,true,roleIDs,objRowList,NULL); - if (privStatus == STATUS_ERROR) - return privStatus; + // Get object privileges that the grantor has been granted - that is, the + // grantor becomes the grantee. + privStatus = getRowsForGrantee(objectUID_,grantorID_,true,roleIDs,objRowList,NULL); + if (privStatus == STATUS_ERROR) + return privStatus; -// For each privilege to grant, see if the grantor has been granted that -// privilege WITH GRANT OPTION (WGO). If so, note it in the colPrivsArray entry. -// If the grantor does not have WGO, note that we have to check column -// privileges for at least one grant. -bool checkColumnPrivs = false; + // For each privilege to grant, see if the grantor has been granted that + // privilege WITH GRANT OPTION (WGO). If so, note it in the colPrivsArray entry. + // If the grantor does not have WGO, note that we have to check column + // privileges for at least one grant. + bool checkColumnPrivs = false; for (size_t i = 0; i < colPrivsArray.size(); i++) { - ColPrivSpec &colPrivEntry = colPrivsArray[i]; - colPrivEntry.grantorHasWGO = false; + ColPrivSpec &colPrivSpec = colPrivsArray[i]; + colPrivSpec.grantorHasWGO = false; for (size_t j = 0; j < objRowList.size(); j++) { ObjectPrivsMDRow &objectRow = static_cast<ObjectPrivsMDRow &> (*objRowList[j]); - if (objectRow.grantableBitmap_.test(colPrivEntry.privType)) + if (objectRow.grantableBitmap_.test(colPrivSpec.privType)) { - colPrivEntry.grantorHasWGO = true; + colPrivSpec.grantorHasWGO = true; break; } } - if (!colPrivEntry.grantorHasWGO) + if (!colPrivSpec.grantorHasWGO) checkColumnPrivs = true; } -// If object-level privileges are sufficient to grant the column-level -// privileges, no need to read COLUMN_PRIVILEGES table. + // If object-level privileges are sufficient to grant the column-level + // privileges, no need to read COLUMN_PRIVILEGES table. if (!checkColumnPrivs) return true; -// The grantor did not have WGO at the object level for at least one -// of the privileges to be granted; see if they have the column privilege WGO. + // The grantor did not have WGO at the object level for at least one + // of the privileges to be granted; see if they have the column privilege WGO. -// Fetch any relevant WGO rows from COLUMN_PRIVILEGES. -std::vector<PrivMgrMDRow *> colRowList; + // Fetch any relevant WGO rows from COLUMN_PRIVILEGES. + std::vector<PrivMgrMDRow *> colRowList; - // Get object privileges that the grantor has been granted - that is, the - // grantor becomes the grantee. - privStatus = getRowsForGrantee(objectUID_,grantorID_,false,roleIDs,colRowList,NULL); - if (privStatus == STATUS_ERROR) - return privStatus; + // Get object privileges that the grantor has been granted - that is, the + // grantor becomes the grantee. + privStatus = getRowsForGrantee(objectUID_,grantorID_,false,roleIDs,colRowList,NULL); + if (privStatus == STATUS_ERROR) + return privStatus; for (size_t i = 0; i < colPrivsArray.size(); i++) { @@ -5145,21 +5302,21 @@ std::vector<PrivMgrMDRow *> colRowList; if (colPrivsArray[i].grantorHasWGO) continue; - ColPrivSpec &colPrivEntry = colPrivsArray[i]; + ColPrivSpec &colPrivSpec = colPrivsArray[i]; // See if the grantor has been granted WGO at column-level for priv. for (size_t j = 0; j < colRowList.size(); j++) { ColumnPrivsMDRow &columnRow = static_cast<ColumnPrivsMDRow &> (*colRowList[i]); - if (columnRow.grantableBitmap_.test(colPrivEntry.privType)) + if (columnRow.grantableBitmap_.test(colPrivSpec.privType)) { - colPrivEntry.grantorHasWGO = true; + colPrivSpec.grantorHasWGO = true; break; } } // If the grantor does not have an object-level or column-level WGO // for one of the privs to grant, return an error. - if (!colPrivEntry.grantorHasWGO) + if (!colPrivSpec.grantorHasWGO) { privStatus = STATUS_NOTFOUND; return false; @@ -5234,7 +5391,7 @@ static bool hasGrantedColumnPriv( for (size_t i = 0; i < colPrivsArray.size(); i++) { - const ColPrivSpec &colPrivEntry = colPrivsArray[i]; + const ColPrivSpec &colPrivSpec = colPrivsArray[i]; bool grantFound = false; for (size_t j = 0; j < colRowList.size(); j++) { @@ -5243,8 +5400,8 @@ static bool hasGrantedColumnPriv( // Only look at rows with the requested grantor and grantee if (columnRow.grantorID_ == grantorID && columnRow.granteeID_ == granteeID) { - if (columnRow.columnOrdinal_ == colPrivEntry.columnOrdinal && - columnRow.privsBitmap_.test(colPrivEntry.privType)) + if (columnRow.columnOrdinal_ == colPrivSpec.columnOrdinal && + columnRow.privsBitmap_.test(colPrivSpec.privType)) { grantFound = true; break; @@ -5254,7 +5411,7 @@ static bool hasGrantedColumnPriv( if (!grantFound) { - privilege = PrivMgrUserPrivs::convertPrivTypeToLiteral((PrivType)colPrivEntry.privType); + privilege = PrivMgrUserPrivs::convertPrivTypeToLiteral((PrivType)colPrivSpec.privType); privStatus = STATUS_NOTFOUND; return false; } @@ -5269,9 +5426,9 @@ static bool hasGrantedColumnPriv( { ColPrivEntry grantedColPriv; - grantedColPriv.columnOrdinal = columnRow.columnOrdinal_; - grantedColPriv.grantableBitmap = columnRow.grantableBitmap_; - grantedColPriv.privsBitmap = columnRow.privsBitmap_; + grantedColPriv.setColumnOrdinal(columnRow.columnOrdinal_); + grantedColPriv.setGrantableBitmap(columnRow.grantableBitmap_); + grantedColPriv.setPrivBitmap(columnRow.privsBitmap_); grantedColPrivs.push_back(grantedColPriv); } } @@ -6282,3 +6439,5 @@ char whereClause[1000]; + + http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/392031a3/core/sql/sqlcomp/PrivMgrPrivileges.h ---------------------------------------------------------------------- diff --git a/core/sql/sqlcomp/PrivMgrPrivileges.h b/core/sql/sqlcomp/PrivMgrPrivileges.h index 473e2cd..c62c0e4 100644 --- a/core/sql/sqlcomp/PrivMgrPrivileges.h +++ b/core/sql/sqlcomp/PrivMgrPrivileges.h @@ -64,14 +64,40 @@ public: class ColPrivEntry { public: - int32_t columnOrdinal; - PrivColumnBitmap privsBitmap; - PrivColumnBitmap grantableBitmap; - bool isUpdate; + PrivMgrCoreDesc privDesc_; + bool isUpdate_; + ColPrivEntry() - : columnOrdinal(0),isUpdate(false){}; + : isUpdate_(false){}; ColPrivEntry(const PrivMgrMDRow &row); ColPrivEntry(const ColPrivEntry &other); + + PrivMgrCoreDesc &getPrivDesc (void) { return privDesc_; } + + int32_t getColumnOrdinal (void) { return privDesc_.getColumnOrdinal(); } + PrivColumnBitmap getPrivBitmap (void) { return privDesc_.getPrivBitmap(); } + PrivColumnBitmap getGrantableBitmap (void) { return privDesc_.getWgoBitmap(); } + + void setColumnOrdinal (int32_t columnOrdinal) + { privDesc_.setColumnOrdinal(columnOrdinal); } + + void setPrivBitmap(PrivMgrBitmap privBitmap) + { privDesc_.setPrivBitmap(privBitmap); } + void setGrantableBitmap(PrivMgrBitmap grantableBitmap) + { privDesc_.setWgoBitmap(grantableBitmap);} + + void setPriv (PrivType privType, bool value) + { privDesc_.setPriv(privType, value); } + void setGrantable (PrivType privType, bool value) + { privDesc_.setWgo(privType, value); } + + void describe (std::string &details) const + { + details = "column usage - column number is "; + details += to_string((long long int) privDesc_.getColumnOrdinal()); + details += ", isUpdate is "; + details += (isUpdate_) ? "true " : "false "; + } }; // ***************************************************************************** @@ -326,6 +352,12 @@ private: const PrivCommand command, std::vector<ObjectUsage *> &listOfAffectedObjects); + void getColRowsForGranteeOrdinal( + const int32_t granteeID, + const int32_t columnOrdinal, + const std::vector<int32_t> &roleIDs, + std::vector<PrivMgrMDRow *> &rowList); + PrivStatus getGrantedPrivs( const int32_t granteeID, PrivMgrMDRow &row); @@ -376,6 +408,12 @@ private: const PrivType pType, // in const std::vector<PrivMgrMDRow *>& rowList ); // in + void summarizeColPrivs( + const ObjectReference &objRef, + const std::vector<int32_t> &roleIDs, + const std::vector<ObjectUsage *> &listOfAffectedObjects, + std::vector<ColumnReference *> &columnReferences); + PrivStatus summarizeCurrentAndOriginalPrivs( const int64_t objectUID, const int32_t granteeID,