You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafodion.apache.org by rm...@apache.org on 2018/10/24 16:20:50 UTC

[1/3] trafodion git commit: TRAFODION - 3218 User still has privilege after user's role has been revoked ...

Repository: trafodion
Updated Branches:
  refs/heads/master 659f59a13 -> 8e38189d4


http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp b/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp
index a620624..cd785f6 100644
--- a/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp
+++ b/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp
@@ -12540,23 +12540,20 @@ ComTdbVirtTablePrivInfo * CmpSeabaseDDL::getSeabasePrivInfo(
 
   // Summarize privileges for object
   PrivStatus privStatus = STATUS_GOOD;
-  std::vector<PrivMgrDesc> privDescs;
+  ComTdbVirtTablePrivInfo *privInfo = new (heap_) ComTdbVirtTablePrivInfo();
+  privInfo->privmgr_desc_list = new (STMTHEAP) PrivMgrDescList(STMTHEAP);
+
+  // Summarize privileges for object
   PrivMgrCommands command(std::string(MDLoc.data()),
                           std::string(privMgrMDLoc.data()),
                           CmpCommon::diags());
-  if (command.getPrivileges(objUID, objType, privDescs) != STATUS_GOOD)
+  if (command.getPrivileges(objUID, objType,
+                            *privInfo->privmgr_desc_list) != STATUS_GOOD)
     {
       *CmpCommon::diags() << DgSqlCode(-CAT_UNABLE_TO_RETRIEVE_PRIVS);
       return NULL;
     }
 
-  ComTdbVirtTablePrivInfo *privInfo = new (STMTHEAP) ComTdbVirtTablePrivInfo();
-
-  // PrivMgrDesc operator= is a deep copy
-  privInfo->privmgr_desc_list = new (STMTHEAP) NAList<PrivMgrDesc>(STMTHEAP);
-  for (size_t i = 0; i < privDescs.size(); i++)
-    privInfo->privmgr_desc_list->insert(privDescs[i]);
-
   return privInfo;
 }
 

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/sqlcomp/PrivMgr.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgr.cpp b/core/sql/sqlcomp/PrivMgr.cpp
index 0a5f265..2429b9d 100644
--- a/core/sql/sqlcomp/PrivMgr.cpp
+++ b/core/sql/sqlcomp/PrivMgr.cpp
@@ -36,6 +36,7 @@
 #include "PrivMgrComponentOperations.h"
 #include "PrivMgrComponentPrivileges.h"
 #include "PrivMgrPrivileges.h"
+#include "PrivMgrRoles.h"
 
 // Trafodion includes
 #include "ComDistribution.h"
@@ -154,6 +155,42 @@ PrivMgr::~PrivMgr()
   resetFlags();
 }
 
+// *****************************************************************************
+// * Method: getGranteeIDsForRoleIDs                              
+// *                                                       
+// *    Returns the grantees assigned to the passed in roles
+// *    role list
+// *                                                       
+// *  Parameters:    
+// *                                                                       
+// *  <roleIDs>    list of roles to check
+// *  <granteeIDs> passed back the list (potentially empty) of users granted to 
+// *               the roleIDs
+// *                                                                     
+// * Returns: PrivStatus                                               
+// *                                                                  
+// * STATUS_GOOD: Role list returned
+// *           *: Unable to fetch granted roles, see diags.     
+// *                                                               
+// *****************************************************************************
+PrivStatus PrivMgr::getGranteeIDsForRoleIDs(
+  const std::vector<int32_t>  & roleIDs,
+  std::vector<int32_t> & granteeIDs,
+  bool includeSysGrantor)
+{
+  std::vector<int32_t> granteeIDsForRoleIDs;
+  PrivMgrRoles roles(" ",metadataLocation_,pDiags_);
+  if (roles.fetchGranteesForRoles(roleIDs, granteeIDsForRoleIDs, includeSysGrantor) == STATUS_ERROR)
+    return STATUS_ERROR;
+  for (size_t i = 0; i < granteeIDsForRoleIDs.size(); i++)
+  {
+     int32_t authID = granteeIDsForRoleIDs[i];
+     if (std::find(granteeIDs.begin(), granteeIDs.end(), authID) == granteeIDs.end())
+       granteeIDs.insert( std::upper_bound( granteeIDs.begin(), granteeIDs.end(), authID ), authID);
+  }
+  return STATUS_GOOD;
+}
+
 // ----------------------------------------------------------------------------
 // method:  authorizationEnabled
 //

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/sqlcomp/PrivMgr.h
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgr.h b/core/sql/sqlcomp/PrivMgr.h
index fd6b8bd..0cd52ce 100644
--- a/core/sql/sqlcomp/PrivMgr.h
+++ b/core/sql/sqlcomp/PrivMgr.h
@@ -168,6 +168,11 @@ class PrivMgr
     // -------------------------------------------------------------------
     // Accessors and destructors:
     // -------------------------------------------------------------------
+    PrivStatus getGranteeIDsForRoleIDs(
+      const std::vector<int32_t> & roleIDs,
+      std::vector<int32_t> & userIDs,
+      bool includeSysGrantor = true);
+
     inline std::string getMetadataLocation (void) {return metadataLocation_;}
     inline const std::string & getMetadataLocation (void) const {return metadataLocation_;}
     inline std::string getTrafMetadataLocation (void) {return trafMetadataLocation_;}

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/sqlcomp/PrivMgrCommands.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgrCommands.cpp b/core/sql/sqlcomp/PrivMgrCommands.cpp
index 499f544..b80b77c 100644
--- a/core/sql/sqlcomp/PrivMgrCommands.cpp
+++ b/core/sql/sqlcomp/PrivMgrCommands.cpp
@@ -41,6 +41,7 @@
 #include "PrivMgrRoles.h"
 #include "ComSecurityKey.h"
 #include "ComUser.h"
+#include "CmpSeabaseDDL.h"
 #include <cstdio>
 #include <algorithm>
 
@@ -396,9 +397,10 @@ PrivStatus PrivMgrCommands::getPrivileges(
   NATable *naTable,
   const int32_t userID,
   PrivMgrUserPrivs &userPrivs,
-  std::vector <ComSecurityKey *>* secKeySet)
+  ComSecurityKeySet *secKeySet)
 {
   PrivMgrDesc privsOfTheUser;
+  PrivStatus retcode = STATUS_GOOD;
 
   // authorization is not enabled, return bitmaps with all bits set
   // With all bits set, privilege checks will always succeed
@@ -409,35 +411,60 @@ PrivStatus PrivMgrCommands::getPrivileges(
     return STATUS_GOOD;
   }
 
-  // if a hive table and does not have an external table and is not
-  // registered in traf metadata, assume no privs
-  if ((naTable->isHiveTable()) && 
-      (NOT naTable->isRegistered()) &&
-      (!naTable->hasExternalTable()))
+  // if a native table that is not registered nor has an external table
+  // assume no privs.  No privileges, so no security keys are required
+  else if ((naTable->isHiveTable() ||
+            naTable->isHbaseCellTable() ||
+            naTable->isHbaseRowTable()) &&
+           (!naTable->isRegistered() && !naTable->hasExternalTable()))
   {
     PrivMgrDesc emptyDesc;
     userPrivs.initUserPrivs(emptyDesc);
   }
 
-  // if an hbase table and is not registered, assume no privs
- else if ((naTable->isHbaseCellTable() || naTable->isHbaseRowTable()) &&
-          (!naTable->hasExternalTable() && !naTable->isRegistered()))
-  {
-    PrivMgrDesc emptyDesc;
-    userPrivs.initUserPrivs(emptyDesc);
-  }
+  // Check for privileges defined in Trafodion metadata
   else
   {
-    PrivMgrPrivileges objectPrivs (metadataLocation_, pDiags_);
-    PrivStatus retcode = objectPrivs.getPrivsOnObjectForUser((int64_t)naTable->objectUid().get_value(),
-                                                             naTable->getObjectType(),
-                                                             userID,
-                                                             privsOfTheUser,
-                                                             secKeySet);
-    if (retcode != STATUS_GOOD)
-      return retcode;
+    int64_t objectUID = (int64_t)naTable->objectUid().get_value();
 
-    userPrivs.initUserPrivs(privsOfTheUser);
+    // If we are not storing privileges for the object in NATable, go read MD
+    if (naTable->getPrivDescs() == NULL)
+    {
+      PrivMgrPrivileges objectPrivs (metadataLocation_, pDiags_);
+      retcode = objectPrivs.getPrivsOnObjectForUser(objectUID,
+                                                    naTable->getObjectType(),
+                                                    userID,
+                                                    privsOfTheUser);
+      if (retcode != STATUS_GOOD)
+        return retcode;
+
+      userPrivs.initUserPrivs(privsOfTheUser);
+
+      if (secKeySet != NULL)
+      {
+        // The PrivMgrDescList destructor deletes memory
+        PrivMgrDescList descList(naTable->getHeap());
+        PrivMgrDesc *tableDesc = new (naTable->getHeap()) PrivMgrDesc(privsOfTheUser);
+        descList.insert(tableDesc);
+        if (!userPrivs.setPrivInfoAndKeys(descList, userID, objectUID, secKeySet))
+        {
+          SEABASEDDL_INTERNAL_ERROR("Could not create security keys");
+          return STATUS_ERROR;
+        }
+      }
+    }
+
+    // generate privileges from the stored desc list 
+    else
+    {
+      NAList<int32_t> roleIDs (naTable->getHeap());
+      if (ComUser::getCurrentUserRoles(roleIDs) != 0)
+        return STATUS_ERROR;
+
+      if (userPrivs.initUserPrivs(roleIDs, naTable->getPrivDescs(),
+                                  userID, objectUID, secKeySet) == STATUS_ERROR)
+        return retcode;
+    }
   }
 
   return STATUS_GOOD;
@@ -464,15 +491,26 @@ PrivStatus PrivMgrCommands::getPrivileges(
 PrivStatus PrivMgrCommands::getPrivileges(
   const int64_t objectUID,
   ComObjectType objectType,
-  std::vector <PrivMgrDesc > &privDescs)
+  PrivMgrDescList &privDescs)
 {
-  // If authorization is enabled, go get privilege bitmaps from metadata
+  PrivStatus retcode = STATUS_GOOD;
   if (authorizationEnabled())
   {
+    std::vector<PrivMgrDesc> privDescList;
+
     PrivMgrPrivileges privInfo (objectUID, metadataLocation_, pDiags_);
-    return privInfo.getPrivsOnObject(objectType, privDescs);
+    retcode = privInfo.getPrivsOnObject(objectType, privDescList);
+    if (retcode == STATUS_ERROR)
+      return STATUS_ERROR;
+
+    // copy privDescList to privDescs
+    for (size_t i = 0; i < privDescList.size(); i++)
+    {
+      PrivMgrDesc *desc = new (privDescs.getHeap()) PrivMgrDesc(privDescList[i]);
+      privDescs.insert(desc);
+    }
   }
-  return STATUS_GOOD;
+  return retcode;
 }
 
 
@@ -496,8 +534,7 @@ PrivStatus PrivMgrCommands::getPrivileges(
   const int64_t objectUID,
   ComObjectType objectType,
   const int32_t userID,
-  PrivMgrUserPrivs &userPrivs,
-  std::vector <ComSecurityKey *>* secKeySet)
+  PrivMgrUserPrivs &userPrivs)
 {
   PrivMgrDesc privsOfTheUser;
 
@@ -508,8 +545,7 @@ PrivStatus PrivMgrCommands::getPrivileges(
     PrivStatus retcode = objectPrivs.getPrivsOnObjectForUser(objectUID,
                                                              objectType,
                                                              userID,
-                                                             privsOfTheUser,
-                                                             secKeySet);
+                                                             privsOfTheUser);
     if (retcode != STATUS_GOOD)
       return retcode;
   }
@@ -524,34 +560,6 @@ PrivStatus PrivMgrCommands::getPrivileges(
   return STATUS_GOOD;
 }
 
-// ----------------------------------------------------------------------------
-// method: getRoles
-//
-// Returns roleIDs for the grantee.
-//                                                                       
-//  <granteeID> the authorization ID to obtain roles for
-//  <roleIDs> is the returned list of roles
-//                                                                  
-// Returns: PrivStatus                                               
-//                                                                  
-//   STATUS_GOOD: role list was built
-//             *: unexpected error occurred, see diags.     
-// ----------------------------------------------------------------------------
-PrivStatus PrivMgrCommands::getRoles(
-  const int32_t granteeID,
-  std::vector <int32_t > &roleIDs)
-{
-  // If authorization is not enabled, return
-  if (!authorizationEnabled())
-    return STATUS_GOOD;
-  
-  PrivMgrRoles roles(" ",metadataLocation_,pDiags_);
-  std::vector<std::string> roleNames;
-  std::vector<int32_t> roleDepths;
-
-  return  roles.fetchRolesForUser(granteeID,roleNames,roleIDs,roleDepths);
-}
-
 // *****************************************************************************
 // *                                                                           *
 // * Function: PrivMgrCommands::getPrivRowsForObject                           *

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/sqlcomp/PrivMgrCommands.h
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgrCommands.h b/core/sql/sqlcomp/PrivMgrCommands.h
index 312cbab..e5275b6 100644
--- a/core/sql/sqlcomp/PrivMgrCommands.h
+++ b/core/sql/sqlcomp/PrivMgrCommands.h
@@ -119,28 +119,23 @@ public:
       NATable *naTable,
       const int32_t granteeUID,
       PrivMgrUserPrivs &userPrivileges,
-      std::vector <ComSecurityKey *>* secKeySet = NULL);
+      NASet<ComSecurityKey> *secKeySet = NULL);
 
    PrivStatus getPrivileges(
       const int64_t objectUID,
       ComObjectType objectType,
-      std::vector<PrivMgrDesc> &userPrivileges);
-     
+      PrivMgrDescList &userPrivileges);
+
    PrivStatus getPrivileges(
       const int64_t objectUID,
       ComObjectType objectType,
       const int32_t granteeUID,
-      PrivMgrUserPrivs &userPrivileges,
-      std::vector <ComSecurityKey *>* secKeySet = NULL);
-     
+      PrivMgrUserPrivs &userPrivileges);
+
    PrivStatus getPrivRowsForObject(
       const int64_t objectUID,
       std::vector<ObjectPrivsRow> & objectPrivsRows);
       
-   PrivStatus getRoles(
-      const int32_t grantee,
-      std::vector<int32_t> &roleIDs);
-
    PrivStatus givePrivForObjects(
          const int32_t currentOwnerID,
          const int32_t newOwnerID,

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/sqlcomp/PrivMgrComponentPrivileges.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgrComponentPrivileges.cpp b/core/sql/sqlcomp/PrivMgrComponentPrivileges.cpp
index 257a123..9c85ffe 100644
--- a/core/sql/sqlcomp/PrivMgrComponentPrivileges.cpp
+++ b/core/sql/sqlcomp/PrivMgrComponentPrivileges.cpp
@@ -1299,11 +1299,13 @@ std::string whereClause(" WHERE COMPONENT_UID = 1 AND (OPERATION_CODE = '");
       std::vector<std::string> roleNames;
       std::vector<int32_t> roleIDs;
       std::vector<int32_t> grantDepths;
+      std::vector<int32_t> grantees;
       
       PrivMgrRoles roles(" ",metadataLocation_,pDiags_);
       
-      PrivStatus privStatus = roles.fetchRolesForUser(authID,roleNames,
-                                                      roleIDs,grantDepths);
+      PrivStatus privStatus = roles.fetchRolesForAuth(authID,roleNames,
+                                                      roleIDs,grantDepths,
+                                                      grantees);
       
       for (size_t r = 0; r < roleIDs.size(); r++)
       {
@@ -1379,11 +1381,13 @@ bool PrivMgrComponentPrivileges::hasWGO(
    std::vector<std::string> roleNames;
    std::vector<int32_t> roleIDs;
    std::vector<int32_t> grantDepths;
+   std::vector<int32_t> grantees;
 
    PrivMgrRoles roles(" ",metadataLocation_,pDiags_);
 
-   if (roles.fetchRolesForUser(authID,roleNames,
-                               roleIDs,grantDepths) == STATUS_ERROR)
+   if (roles.fetchRolesForAuth(authID,roleNames,
+                               roleIDs,grantDepths, 
+                               grantees) == STATUS_ERROR)
       return false;
 
    MyTable &myTable = static_cast<MyTable &>(myTable_);

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/sqlcomp/PrivMgrDesc.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgrDesc.cpp b/core/sql/sqlcomp/PrivMgrDesc.cpp
index 6a41978..3cfaf72 100644
--- a/core/sql/sqlcomp/PrivMgrDesc.cpp
+++ b/core/sql/sqlcomp/PrivMgrDesc.cpp
@@ -483,3 +483,4 @@ bool PrivMgrDesc::limitToGrantable( const PrivMgrDesc& other )
   return result;
 }
 
+

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/sqlcomp/PrivMgrDesc.h
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgrDesc.h b/core/sql/sqlcomp/PrivMgrDesc.h
index 0ff26af..d0e94d4 100644
--- a/core/sql/sqlcomp/PrivMgrDesc.h
+++ b/core/sql/sqlcomp/PrivMgrDesc.h
@@ -580,6 +580,36 @@ private:
 };
 
 
+/* *******************************************************************
+ * Class PrivMgrDescList -- A list of PrivMgrDesc pointers
+ * ****************************************************************** */
+
+class PrivMgrDescList : public LIST(PrivMgrDesc *)
+{
+  public:
+
+  // constructor
+  PrivMgrDescList(CollHeap *heap)
+   : LIST(PrivMgrDesc *)(heap),
+     heap_(heap)
+  {}
+
+  // virtual destructor
+  virtual ~PrivMgrDescList()
+  {
+    for (CollIndex i = 0; i < entries(); i++)
+      NADELETE(operator[](i), PrivMgrDesc, heap_);
+    clear();
+  }
+
+  CollHeap *getHeap() { return heap_; }
+
+  private:
+
+  CollHeap *heap_;
+
+}; // class PrivMgrDescList
+
 
 
 #endif // PRIVMGR_DESC_H

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/sqlcomp/PrivMgrPrivileges.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgrPrivileges.cpp b/core/sql/sqlcomp/PrivMgrPrivileges.cpp
index fe2c8d1..1e85905 100644
--- a/core/sql/sqlcomp/PrivMgrPrivileges.cpp
+++ b/core/sql/sqlcomp/PrivMgrPrivileges.cpp
@@ -462,59 +462,6 @@ PrivMgrPrivileges::~PrivMgrPrivileges()
 }
 
 // *****************************************************************************
-// * Method: buildSecurityKeys                                
-// *                                                       
-// *    Builds security keys for the current object and specified user.
-// *                                                       
-// *  Parameters:    
-// *                                                                       
-// *  <granteeID> is the unique identifier for the grantee
-// *  <privs> is the list of privileges the user has on the object
-// *  <secKeySet> is the set of security keys to be passed back.  Caller is 
-// *              responsible for freeing keys.
-// *                                                                  
-// * Returns: PrivStatus                                               
-// *                                                                  
-// * STATUS_GOOD: Security keys were built
-// *           *: Security keys were not built, see diags.     
-// *                                                               
-// *****************************************************************************
-PrivStatus PrivMgrPrivileges::buildSecurityKeys(
-  const int32_t granteeID,
-  const PrivMgrCoreDesc &privs,
-  std::vector <ComSecurityKey *> & secKeySet)
-{
-  if (privs.isNull())
-    return STATUS_GOOD;
-
-  // Only need to generate keys for DML privileges
-  for ( size_t i = FIRST_DML_PRIV; i <= LAST_DML_PRIV; i++ )
-  {
-    if ( privs.getPriv(PrivType(i)))
-    {
-      ComSecurityKey *key = NULL;
-      if (ComUser::isPublicUserID(granteeID))
-        key = new ComSecurityKey(granteeID, 
-                                 ComSecurityKey::OBJECT_IS_SPECIAL_ROLE);
-      else
-        key = new ComSecurityKey(granteeID, 
-                                 objectUID_,
-                                 PrivType(i),
-                                 ComSecurityKey::OBJECT_IS_OBJECT);
-      if (key->isValid())
-         secKeySet.push_back(key);
-      else
-      {
-        PRIVMGR_INTERNAL_ERROR("ComSecurityKey is null");
-        return STATUS_ERROR;
-      }
-    }
-  }
-   
-  return STATUS_GOOD;
-}
-
-// *****************************************************************************
 // * Method: getPrivsOnObject                                
 // *                                                       
 // * Creates a set of priv descriptors for all user grantees on an object
@@ -571,7 +518,7 @@ PrivStatus PrivMgrPrivileges::getPrivsOnObject (
     // getUserPrivs returns object and column privileges summarized across all
     // grantors.  Just get direct grants to the user (role list is empty) 
     if (getUserPrivs(objectType, userID, emptyRoleIDs, privsOfTheUser,
-                     hasManagePrivileges, NULL ) != STATUS_GOOD)
+                     hasManagePrivileges) != STATUS_GOOD)
       return STATUS_ERROR;
     
     if (!privsOfTheUser.isNull())
@@ -590,7 +537,7 @@ PrivStatus PrivMgrPrivileges::getPrivsOnObject (
     // getUserPrivs returns object and column privileges summarized across
     // all grantors. 
     if (getUserPrivs(objectType, grantee, emptyRoleIDs, privsOfTheUser,
-                     hasManagePrivileges, NULL ) != STATUS_GOOD)
+                     hasManagePrivileges) != STATUS_GOOD)
       return STATUS_ERROR;
     
     if (!privsOfTheUser.isNull())
@@ -1760,7 +1707,7 @@ PrivStatus PrivMgrPrivileges::initGrantRevoke(
   // get column and object privileges across all grantors 
   bool hasManagePrivileges;
   retcode = getUserPrivs(objectType, grantorID_, roleIDs, privsOfTheGrantor,
-                         hasManagePrivileges, NULL );
+                         hasManagePrivileges);
   if (retcode != STATUS_GOOD)
     return retcode;
 
@@ -3185,11 +3132,8 @@ PrivStatus PrivMgrPrivileges::revokeColumnPriv(
          revokedPrivs |= adjustedPrivs.getPrivBitmap(); 
       }
       else
-      {
-         // The row should exist in "grantedColPrivs" 
-         PRIVMGR_INTERNAL_ERROR("Column privilege not found to revoke");
-         return STATUS_ERROR;
-      }   
+         // if column not exist, just continue (ComDiags contains a warning)
+         continue;
 
       
       if (deleteRow)
@@ -3646,8 +3590,9 @@ void PrivMgrPrivileges::scanObjectBranch( const PrivType pType, // in
                       std::vector<int32_t> roleIDs;
                       std::vector<int32_t> userIDs;
                       roleIDs.push_back(thisGrantee);
-                      if (getUserIDsForRoleIDs(roleIDs,userIDs) == STATUS_ERROR)
+                      if (getGranteeIDsForRoleIDs(roleIDs,userIDs) == STATUS_ERROR)
                         return;
+
                       for (size_t j = 0; j < userIDs.size(); j++)
                       {
                          granteeAsGrantor = userIDs[j];
@@ -3913,7 +3858,7 @@ void PrivMgrPrivileges::scanColumnBranch( const PrivType pType,
                   std::vector<int32_t> roleIDs;
                   std::vector<int32_t> userIDs;
                   roleIDs.push_back(thisGrantee);
-                  if (getUserIDsForRoleIDs(roleIDs,userIDs) == STATUS_ERROR)
+                  if (getGranteeIDsForRoleIDs(roleIDs,userIDs) == STATUS_ERROR)
                     return;
                   for (size_t j = 0; j < userIDs.size(); j++)
                   {
@@ -4004,53 +3949,68 @@ PrivStatus PrivMgrPrivileges::sendSecurityKeysToRMS(
   const int32_t granteeID, 
   const PrivMgrDesc &revokedPrivs)
 {
+  NAList<int32_t> roleGrantees (STMTHEAP);
+
+  // If the privilege is revoked from a role, then need to generate QI keys for 
+  // the users associated with the role.
+  if (PrivMgr::isRoleID(granteeID))
+  {
+    // Get users granted to role (granteeID)
+    std::vector<int32_t> roleID;
+    roleID.push_back(granteeID);
+    std::vector<int32_t> granteeIDs;
+    if (getGranteeIDsForRoleIDs(roleID, granteeIDs, false) == STATUS_ERROR)
+      return STATUS_ERROR;
+
+    for (size_t g = 0; g < granteeIDs.size(); g++)
+      roleGrantees.insert(granteeIDs[g]);
+  }
+  else
+    roleGrantees.insert(grantorID_);
+
   // Go through the list of table privileges and generate SQL_QIKEYs
-  std::vector<ComSecurityKey *> keyList;
+  ComSecurityKeySet keyList(NULL);
   const PrivMgrCoreDesc &privs = revokedPrivs.getTablePrivs();
-  PrivStatus privStatus = buildSecurityKeys(granteeID,
-                                            revokedPrivs.getTablePrivs(),
-                                            keyList);
-  if (privStatus != STATUS_GOOD)
+  if (!buildSecurityKeys(roleGrantees,
+                         granteeID,
+                         objectUID_,
+                         false, /* isColumn */
+                         revokedPrivs.getTablePrivs(),
+                         keyList))
   {
-    for(size_t k = 0; k < keyList.size(); k++)
-     delete keyList[k]; 
-    keyList.clear();
-    return privStatus;
+    PRIVMGR_INTERNAL_ERROR("ComSecurityKey is null");
+    return STATUS_ERROR;
   }
 
+
   for (int i = 0; i < revokedPrivs.getColumnPrivs().entries(); i++)
   {
     const NAList<PrivMgrCoreDesc> &columnPrivs = revokedPrivs.getColumnPrivs();
-    privStatus = buildSecurityKeys(granteeID,
-                                   columnPrivs[i],
-                                   keyList);
-    if (privStatus != STATUS_GOOD)
+    if (!buildSecurityKeys(roleGrantees,
+                           granteeID,
+                           objectUID_,
+                           true, /* isColumn */
+                           columnPrivs[i],
+                           keyList))
     {
-      for(size_t k = 0; k < keyList.size(); k++)
-       delete keyList[k]; 
-      keyList.clear();
-      return privStatus;
+      PRIVMGR_INTERNAL_ERROR("ComSecurityKey is null");
+      return STATUS_ERROR;
     }
   }
-  
+
   // Create an array of SQL_QIKEYs
-  int32_t numKeys = keyList.size();
+  int32_t numKeys = keyList.entries();
   SQL_QIKEY siKeyList[numKeys];
-  for (size_t j = 0; j < keyList.size(); j++)
+  for (size_t j = 0; j < numKeys; j++)
   {
-    ComSecurityKey *pKey = keyList[j];
-    siKeyList[j].revokeKey.subject = pKey->getSubjectHashValue();
-    siKeyList[j].revokeKey.object = pKey->getObjectHashValue();
+    ComSecurityKey key = keyList[j];
+    siKeyList[j].revokeKey.subject = key.getSubjectHashValue();
+    siKeyList[j].revokeKey.object = key.getObjectHashValue();
     std::string actionString;
-    pKey->getSecurityKeyTypeAsLit(actionString);
+    key.getSecurityKeyTypeAsLit(actionString);
     strncpy(siKeyList[j].operation, actionString.c_str(), 2);
   }
   
-  // delete the security list
-  for(size_t k = 0; k < keyList.size(); k++)
-   delete keyList[k]; 
-  keyList.clear();
-
   // Call the CLI to send details to RMS
   SQL_EXEC_SetSecInvalidKeys(numKeys, siKeyList);
 
@@ -4209,8 +4169,7 @@ PrivStatus PrivMgrPrivileges::getPrivsOnObjectForUser(
   const int64_t objectUID,
   ComObjectType objectType,
   const int32_t userID,
-  PrivMgrDesc &privsOfTheUser,
-  std::vector <ComSecurityKey *>* secKeySet)
+  PrivMgrDesc &privsOfTheUser)
 {
   PrivStatus retcode = STATUS_GOOD;
   
@@ -4239,7 +4198,7 @@ PrivStatus PrivMgrPrivileges::getPrivsOnObjectForUser(
   bool hasManagePrivileges = false;
   
   retcode = getUserPrivs(objectType, userID, roleIDs, privsOfTheUser, 
-                         hasManagePrivileges, secKeySet);
+                         hasManagePrivileges);
 
   return retcode;
 }
@@ -4272,48 +4231,14 @@ PrivStatus retcode = STATUS_GOOD;
 PrivMgrRoles roles(" ",metadataLocation_,pDiags_);
 std::vector<std::string> roleNames;
 std::vector<int32_t> roleDepths;
+std::vector<int32_t> grantees;
   
-   retcode =  roles.fetchRolesForUser(userID,roleNames,roleIDs,roleDepths);
+   retcode =  roles.fetchRolesForAuth(userID,roleNames,roleIDs,roleDepths,grantees);
    return retcode;
 }
 //*************** End of PrivMgrPrivileges::getRoleIDsForUserID ****************
 
 // *****************************************************************************
-// * Method: getUserIDsForRoleIDs                              
-// *                                                       
-// *    Returns the userIDs granted to the role passed in role list
-// *                                                       
-// *  Parameters:    
-// *                                                                       
-// *  <roleIDs> list of roles to check
-// *  <userIDs> passed back the list (potentially empty) of users granted to 
-// *            the roleIDs
-// *                                                                     
-// * Returns: PrivStatus                                               
-// *                                                                  
-// * STATUS_GOOD: Role list returned
-// *           *: Unable to fetch granted roles, see diags.     
-// *                                                               
-// *****************************************************************************
-PrivStatus PrivMgrPrivileges::getUserIDsForRoleIDs(
-  const std::vector<int32_t>  & roleIDs,
-  std::vector<int32_t> & userIDs)
-{
-  std::vector<int32_t> userIDsForRoleIDs;
-  PrivMgrRoles roles(" ",metadataLocation_,pDiags_);
-  if (roles.fetchUsersForRoles(roleIDs, userIDsForRoleIDs) == STATUS_ERROR)
-    return STATUS_ERROR;
-
-  for (size_t i = 0; i < userIDsForRoleIDs.size(); i++)
-  {
-     int32_t authID = userIDsForRoleIDs[i];
-     if (std::find(userIDs.begin(), userIDs.end(), authID) == userIDs.end())
-       userIDs.insert( std::upper_bound( userIDs.begin(), userIDs.end(), authID ), authID);
-  }
-  return STATUS_GOOD;
-}
-
-// *****************************************************************************
 // * Method: getUserPrivs                                
 // *                                                       
 // *    Accumulates privileges for a user summarized over all grantors
@@ -4326,7 +4251,6 @@ PrivStatus PrivMgrPrivileges::getUserIDsForRoleIDs(
 // *  <roleIDs> specifies a list of roles granted to the grantee
 // *  <summarizedPrivs> contains the summarized privileges
 // *  <hasManagePrivileges> returns whether the grantee has MANAGE_PRIVILEGES authority
-// *  <secKeySet> if not NULL, returns a set of keys for user
 // *                                                                     
 // * Returns: PrivStatus                                               
 // *                                                                  
@@ -4339,8 +4263,7 @@ PrivStatus PrivMgrPrivileges::getUserPrivs(
   const int32_t granteeID,
   const std::vector<int32_t> & roleIDs,
   PrivMgrDesc &summarizedPrivs,
-  bool & hasManagePrivileges,
-  std::vector<ComSecurityKey *>* secKeySet 
+  bool & hasManagePrivileges
   )
 {
    PrivStatus retcode = STATUS_GOOD;
@@ -4351,8 +4274,7 @@ PrivStatus PrivMgrPrivileges::getUserPrivs(
                                       granteeID,
                                       roleIDs,
                                       temp,
-                                      hasManagePrivileges,
-                                      secKeySet
+                                      hasManagePrivileges
                                       );
    if (retcode != STATUS_GOOD)
     return retcode;
@@ -4390,8 +4312,7 @@ PrivStatus PrivMgrPrivileges::getPrivsFromAllGrantors(
    const int32_t granteeID,
    const std::vector<int32_t> & roleIDs,
    PrivMgrDesc &summarizedPrivs,
-   bool & hasManagePrivPriv,
-   std::vector <ComSecurityKey *>* secKeySet 
+   bool & hasManagePrivPriv
    )
 {
   PrivStatus retcode = STATUS_GOOD;
@@ -4429,7 +4350,7 @@ PrivStatus PrivMgrPrivileges::getPrivsFromAllGrantors(
   // Accumulate object level privileges
   else
   {
-    retcode = getRowsForGrantee(objectUID, granteeID, true, roleIDs, rowList, secKeySet);
+    retcode = getRowsForGrantee(objectUID, granteeID, true, roleIDs, rowList);
     if (retcode == STATUS_ERROR)
       return retcode; 
 
@@ -4443,15 +4364,6 @@ PrivStatus PrivMgrPrivileges::getPrivsFromAllGrantors(
         hasPublicGrantee = true;
 
       PrivMgrCoreDesc temp (row.privsBitmap_, row.grantableBitmap_);
-      if (secKeySet)
-      {
-        retcode = buildSecurityKeys(granteeID,
-                                    temp,
-                                    *secKeySet);
-        if (retcode == STATUS_ERROR)
-          return retcode;
-      }
-
       coreTablePrivs.unionOfPrivs(temp);
     }
   
@@ -4468,7 +4380,7 @@ PrivStatus PrivMgrPrivileges::getPrivsFromAllGrantors(
 
   // Add accumulated column level privileges
   rowList.clear();
-  retcode = getRowsForGrantee(objectUID, granteeID, false, roleIDs, rowList, secKeySet);
+  retcode = getRowsForGrantee(objectUID, granteeID, false, roleIDs, rowList);
   if (retcode == STATUS_ERROR)
     return retcode;
 
@@ -4483,15 +4395,6 @@ PrivStatus PrivMgrPrivileges::getPrivsFromAllGrantors(
 
     // See if the ordinal has already been specified
     PrivMgrCoreDesc temp (row.privsBitmap_, row.grantableBitmap_, row.columnOrdinal_);
-    if (secKeySet)
-    {
-      retcode = buildSecurityKeys(granteeID,
-                                  temp,
-                                  *secKeySet);
-      if (retcode == STATUS_ERROR)
-        return retcode;
-    }
-
     PrivMgrCoreDesc *coreColumnPriv = findColumnEntry(coreColumnPrivs, row.columnOrdinal_);
     if (coreColumnPriv)
       coreColumnPriv->unionOfPrivs(temp);
@@ -4576,8 +4479,7 @@ PrivStatus PrivMgrPrivileges::getRowsForGrantee(
   const int32_t granteeID,
   const bool isObjectTable,
   const std::vector<int_32> &roleIDs,
-  std::vector<PrivMgrMDRow *> &rowList,
-  std::vector <ComSecurityKey *>* secKeySet) 
+  std::vector<PrivMgrMDRow *> &rowList)
 {
   PrivStatus retcode = STATUS_GOOD;
 
@@ -4747,7 +4649,7 @@ PrivStatus PrivMgrPrivileges::summarizeCurrentAndOriginalPrivs(
 
   // get OBJECT_PRIVILEGES rows where the grantee has received privileges
   std::vector<PrivMgrMDRow *> rowList;
-  retcode = getRowsForGrantee(objectUID, granteeID, true, roleIDs, rowList, NULL);
+  retcode = getRowsForGrantee(objectUID, granteeID, true, roleIDs, rowList);
 
   // rowList contains the original privileges, 
   // listOfChangedPrivs contains any updates to privileges

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/sqlcomp/PrivMgrPrivileges.h
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgrPrivileges.h b/core/sql/sqlcomp/PrivMgrPrivileges.h
index e0597a2..5b687a6 100644
--- a/core/sql/sqlcomp/PrivMgrPrivileges.h
+++ b/core/sql/sqlcomp/PrivMgrPrivileges.h
@@ -110,11 +110,6 @@ public:
   // -------------------------------------------------------------------
   // Public functions:
   // -------------------------------------------------------------------
-   PrivStatus buildSecurityKeys(
-      const int32_t granteeID, 
-      const PrivMgrCoreDesc &privs,
-      std::vector <ComSecurityKey *> & secKeySet);
-      
    PrivStatus getGrantorDetailsForObject(
       const bool isGrantedBySpecified,
       const std::string grantedByName,
@@ -135,8 +130,7 @@ public:
       const int64_t objectUID,
       ComObjectType objectType,
       const int32_t userID,
-      PrivMgrDesc &privsForTheUser,
-      std::vector <ComSecurityKey *>* secKeySet);
+      PrivMgrDesc &privsForTheUser);
 
    PrivStatus getPrivRowsForObject(
       const int64_t objectUID,
@@ -243,8 +237,7 @@ protected:
      const int32_t grantee,
      const std::vector<int32_t> & roleIDs,
      PrivMgrDesc &privs,
-     bool & hasManagePrivileges,
-     std::vector <ComSecurityKey *>* secKeySet = NULL
+     bool & hasManagePrivileges
      );
           
    PrivStatus getUserPrivs(
@@ -252,8 +245,7 @@ protected:
      const int32_t grantee,
      const std::vector<int32_t> & roleIDs,
      PrivMgrDesc &privs,
-     bool & hasManagePrivileges,
-     std::vector <ComSecurityKey *>* secKeySet = NULL
+     bool & hasManagePrivileges
      );
      
 private: 
@@ -359,17 +351,12 @@ private:
     const int32_t granteeID,
     const bool isObjectTable,
     const std::vector<int32_t> & roleIDs,
-    std::vector<PrivMgrMDRow *> &rowList,
-    std::vector <ComSecurityKey *>* secKeySet); 
+    std::vector<PrivMgrMDRow *> &rowList);
     
   void getTreeOfGrantors(
     const int32_t granteeID,
     std::set<int32_t> &listOfGrantors);
 
-  PrivStatus getUserIDsForRoleIDs(
-    const std::vector<int32_t> & roleIDs,
-    std::vector<int32_t> & userIDs);
-
   PrivStatus givePriv(
      const int32_t currentOwnerID,
      const int32_t newOwnerID,

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/sqlcomp/PrivMgrRoles.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgrRoles.cpp b/core/sql/sqlcomp/PrivMgrRoles.cpp
index 882ce93..64644d4 100644
--- a/core/sql/sqlcomp/PrivMgrRoles.cpp
+++ b/core/sql/sqlcomp/PrivMgrRoles.cpp
@@ -580,7 +580,7 @@ bool PrivMgrRoles::dependentObjectsExist(
 
 // *****************************************************************************
 // *                                                                           *
-// * Function: PrivMgrRoles::fetchRolesForUser                                 *
+// * Function: PrivMgrRoles::fetchRolesForAuth                                 *
 // *                                                                           *
 // *    Returns all unique roles granted to an authorization ID.  If a role is *
 // * granted more than once, it is only returned one time.  If one or more of  *
@@ -615,24 +615,22 @@ bool PrivMgrRoles::dependentObjectsExist(
 // *              error.  The error is put into the diags area.                *
 // *                                                                           *
 // *****************************************************************************
-PrivStatus PrivMgrRoles::fetchRolesForUser(
+PrivStatus PrivMgrRoles::fetchRolesForAuth(
    const int32_t authID,
    std::vector<std::string> & roleNames,
    std::vector<int32_t> & roleIDs,
-   std::vector<int32_t> & grantDepths)
-
+   std::vector<int32_t> & grantDepths,
+   std::vector<int32_t> & grantees)
 {
-
-std::string whereClause(" WHERE GRANTEE_ID = ");
-
+   std::string whereClause(" WHERE GRANTEE_ID = ");
    whereClause += authIDToString(authID);
-   
-std::vector<MyRow> rows;
-MyTable &myTable = static_cast<MyTable &>(myTable_);
 
-std::string orderByClause(" ORDER BY ROLE_ID");
+   std::vector<MyRow> rows;
+   MyTable &myTable = static_cast<MyTable &>(myTable_);
 
-PrivStatus privStatus = myTable.selectAllWhere(whereClause,orderByClause,rows);
+   std::string orderByClause(" ORDER BY ROLE_ID");
+
+   PrivStatus privStatus = myTable.selectAllWhere(whereClause,orderByClause,rows);
    
    if (privStatus != STATUS_GOOD && privStatus != STATUS_WARNING)
       return privStatus;
@@ -641,28 +639,24 @@ PrivStatus privStatus = myTable.selectAllWhere(whereClause,orderByClause,rows);
    {
       MyRow &row = rows[r];
       
-      if (hasValue(roleIDs,row.roleID_))
+      if (hasValue(roleIDs,row.roleID_) &&
+          hasValue(grantees, row.granteeID_))
       {
          if (grantDepths.back() == 0)
             grantDepths.back() = row.grantDepth_;
          continue;
       }
-      roleNames.push_back(row.granteeName_);
+      roleNames.push_back(row.roleName_);
       roleIDs.push_back(row.roleID_);
+      grantees.push_back(row.granteeID_);
       grantDepths.push_back(row.grantDepth_);
    }
 
    return STATUS_GOOD;
-
 }
-//****************** End of PrivMgrRoles::fetchRolesForUser ********************
+//****************** End of PrivMgrRoles::fetchRolesForAuth ********************
+
 
-// *****************************************************************************
-// *                                                                           *
-// * Function: PrivMgrRoles::fetchUsersForRole                                 *
-// *                                                                           *
-// *    Returns all grantees of a role.                                        *
-// *                                                                           *
 // *****************************************************************************
 // *                                                                           *
 // *  Parameters:                                                              *
@@ -688,45 +682,42 @@ PrivStatus privStatus = myTable.selectAllWhere(whereClause,orderByClause,rows);
 // *              A CLI error is put into the diags area.                      *
 // *                                                                           *
 // *****************************************************************************
-PrivStatus PrivMgrRoles::fetchUsersForRole(
+
+PrivStatus PrivMgrRoles::fetchGranteesForRole(
    const int32_t roleID,
    std::vector<std::string> & granteeNames,
    std::vector<int32_t> & grantorIDs,
    std::vector<int32_t> & grantDepths)
-
 {
+  std::string whereClause(" WHERE ROLE_ID = ");
+   whereClause += authIDToString(roleID);
 
-std::string whereClause(" WHERE ROLE_ID = ");
+  std::vector<MyRow> rows;
+  MyTable &myTable = static_cast<MyTable &>(myTable_);
 
-   whereClause += authIDToString(roleID);
-   
-std::vector<MyRow> rows;
-MyTable &myTable = static_cast<MyTable &>(myTable_);
+  std::string orderByClause(" ORDER BY GRANTEE_NAME");
 
-std::string orderByClause(" ORDER BY GRANTEE_NAME");
+  PrivStatus privStatus = myTable.selectAllWhere(whereClause,orderByClause,rows);
 
-PrivStatus privStatus = myTable.selectAllWhere(whereClause,orderByClause,rows);
-   
    if (privStatus != STATUS_GOOD && privStatus != STATUS_WARNING)
       return privStatus;
-   
+
    for (size_t r = 0; r < rows.size(); r++)
    {
       MyRow &row = rows[r];
-      
+
       granteeNames.push_back(row.granteeName_);
       grantorIDs.push_back(row.grantorID_);
       grantDepths.push_back(row.grantDepth_);
    }
 
    return STATUS_GOOD;
-
 }
-//****************** End of PrivMgrRoles::fetchUsersForRole ********************
+//**************** End of PrivMgrRoles::fetchGranteesForRole *******************
 
 // *****************************************************************************
 // *                                                                           *
-// * Function: PrivMgrRoles::fetchUsersForRoles                                *
+// * Function: PrivMgrRoles::fetchGranteesForRoles                             *
 // *                                                                           *
 // *    Returns all users granted the list of roles                            *
 // *                                                                           *
@@ -737,30 +728,34 @@ PrivStatus privStatus = myTable.selectAllWhere(whereClause,orderByClause,rows);
 // *  <roleIDs>                       const std::vector<int32_t> &    In       *
 // *    is a list of roles.                                                    *
 // *                                                                           *
-// *  <userIDs>                       std::vector<std::int32_t> &     Out      *
-// *    passes back a list of user grantees for the roles.                     *
+// *  <granteeIDs>                    std::vector<std::int32_t> &     Out      *
+// *    passes back a list of user and group grantees for the roles.           *
 // *                                                                           *
 // *****************************************************************************
 // *                                                                           *
 // * Returns: PrivStatus                                                       *
 // *                                                                           *
-// *   STATUS_GOOD: Zero or more userIDs were returned                         *
+// *   STATUS_GOOD: Zero or more granteeIDs were returned                      *
 // *             *: Grants for roles were not returned due to SQL error.       *
 // *                A CLI error is put into the diags area.                    *
 // *                                                                           *
 // *****************************************************************************
-PrivStatus PrivMgrRoles::fetchUsersForRoles(
-   const std::vector<int32_t> & userIDs,
-   std::vector<std::int32_t> & granteeIDs)
+PrivStatus PrivMgrRoles::fetchGranteesForRoles(
+   const std::vector<int32_t> & roleIDs,
+   std::vector<std::int32_t> & granteeIDs,
+   bool includeSysGrantor)
 {
    std::string whereClause(" WHERE ROLE_ID IN( ");
-   for (size_t i = 0; i < userIDs.size(); i++)
+   for (size_t i = 0; i < roleIDs.size(); i++)
    {
       if (i > 0)
         whereClause += ", ";
-      whereClause += authIDToString(userIDs[i]);
+      whereClause += authIDToString(roleIDs[i]);
    }
    whereClause += ")";
+
+   if (!includeSysGrantor)
+     whereClause += " AND GRANTOR_ID <> -2 ";
    std::string orderByClause(" ORDER BY GRANTEE_ID");
 
    std::vector<MyRow> rows;
@@ -775,14 +770,13 @@ PrivStatus PrivMgrRoles::fetchUsersForRoles(
       MyRow &row = rows[r];
 
       if (CmpSeabaseDDLauth::isUserID(row.granteeID_))
-         granteeIDs.push_back(row.granteeID_);
+         if (row.grantorID_ != SYSTEM_USER)
+           granteeIDs.push_back(row.granteeID_);
    }
 
    return STATUS_GOOD;
 }
-//****************** End of PrivMgrRoles::fetchUsersForRole ********************
-
-
+//**************** End of PrivMgrRoles::fetchGranteesForRoles ******************
 
 // *****************************************************************************
 // *                                                                           *

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/sqlcomp/PrivMgrRoles.h
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgrRoles.h b/core/sql/sqlcomp/PrivMgrRoles.h
index 83a9120..354fb22 100644
--- a/core/sql/sqlcomp/PrivMgrRoles.h
+++ b/core/sql/sqlcomp/PrivMgrRoles.h
@@ -54,22 +54,24 @@ public:
 // Public functions:
 // -------------------------------------------------------------------
    
-   PrivStatus fetchRolesForUser(
+   PrivStatus fetchRolesForAuth(
       const int32_t authID,
       std::vector<std::string> & roleNames,
       std::vector<int32_t> & roleIDs,
-      std::vector<int32_t> & grantDepths);
-   
-   PrivStatus fetchUsersForRole(
+      std::vector<int32_t> & grantDepths,
+      std::vector<int32_t> & grantees);
+
+   PrivStatus fetchGranteesForRole(
       const int32_t roleID,
       std::vector<std::string> & granteeNames,
       std::vector<int32_t> & grantorIDs,
       std::vector<int32_t> & grantDepths);
-   
-   PrivStatus fetchUsersForRoles(
+
+   PrivStatus fetchGranteesForRoles(
       const std::vector<int32_t> & roleIDs,
-      std::vector<int32_t> & userIDs);
-   
+      std::vector<int32_t> & granteeIDs,
+      bool includeSysGrantor = true);
+
    PrivStatus grantRole(
       const std::vector<int32_t> & roleIDs,
       const std::vector<std::string> & roleNames,

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/sqlcomp/PrivMgrUserPrivs.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgrUserPrivs.cpp b/core/sql/sqlcomp/PrivMgrUserPrivs.cpp
index fcdf247..af07694 100644
--- a/core/sql/sqlcomp/PrivMgrUserPrivs.cpp
+++ b/core/sql/sqlcomp/PrivMgrUserPrivs.cpp
@@ -77,82 +77,101 @@ PrivMgrObjectInfo::PrivMgrObjectInfo(
 // ****************************************************************************
 // Class: PrivMgrUserPrivs
 // ****************************************************************************
+
+// ----------------------------------------------------------------------------
+// method: initUserPrivs
+//
+// Creates a PrivMgrUserPrivs object from a PrivMgrDescs list
+// ----------------------------------------------------------------------------
 bool PrivMgrUserPrivs::initUserPrivs(
-  const std::vector<int32_t> & roleIDs,
-  const TrafDesc *priv_desc,
+  const NAList<Int32> & roleIDs,
+  PrivMgrDescList *privDescs,
   const int32_t userID,
   const int64_t objectUID,
-  ComSecurityKeySet & secKeySet)
+  ComSecurityKeySet * secKeySet)
 {
   hasPublicPriv_ = false;
 
-  // generate PrivMgrUserPrivs from the priv_desc structure
-  TrafDesc *priv_grantees_desc = priv_desc->privDesc()->privGrantees;
-  NAList<PrivMgrDesc> descList(NULL);
-
-  // Find relevant descs for the user
-  while (priv_grantees_desc)
+  // create a subset of PrivDesc containing privs applicable for the userID
+  PrivMgrDescList userDescList(privDescs->getHeap());
+  for ( CollIndex i = 0; i < privDescs->entries(); i++)
   {
-    Int32 grantee = priv_grantees_desc->privGranteeDesc()->grantee;
+    const PrivMgrDesc *privs = privDescs->operator[](i);
+    Int32 grantee = privs->getGrantee();
     bool addDesc = false;
-    if (grantee == userID)
+    if (ComUser::isPublicUserID(grantee))
+    {
+      hasPublicPriv_ = true;
+      addDesc = true;
+    }
+    else if (grantee == userID)
       addDesc = true;
 
-    if (PrivMgr::isRoleID(grantee))
+    else if (PrivMgr::isRoleID(grantee))
     {
-      if ((std::find(roleIDs.begin(), roleIDs.end(), grantee)) != roleIDs.end())
+      Int32 entry;
+      if (roleIDs.find(grantee, entry))
         addDesc = true;
     }
 
-    if (ComUser::isPublicUserID(grantee))
+    if (addDesc)
     {
-      addDesc = true;
-      hasPublicPriv_ = true;
+      PrivMgrDesc *myPrivs = new (userDescList.getHeap()) PrivMgrDesc (*privs);
+      userDescList.insert(myPrivs);
     }
+  }
 
-    // Create a list of PrivMgrDesc contain privileges for user, user's roles,
-    // and public
-    if (addDesc)
-    {
-      TrafDesc *objectPrivs = priv_grantees_desc->privGranteeDesc()->objectBitmap;
-
-      PrivMgrCoreDesc objectDesc(objectPrivs->privBitmapDesc()->privBitmap,
-                                 objectPrivs->privBitmapDesc()->privWGOBitmap);
-      
-      TrafDesc *priv_grantee_desc = priv_grantees_desc->privGranteeDesc();
-      TrafDesc *columnPrivs = priv_grantee_desc->privGranteeDesc()->columnBitmaps;
-      NAList<PrivMgrCoreDesc> columnDescs(NULL);
-      while (columnPrivs)
-      {
-        PrivMgrCoreDesc columnDesc(columnPrivs->privBitmapDesc()->privBitmap,
-                                   columnPrivs->privBitmapDesc()->privWGOBitmap,
-                                   columnPrivs->privBitmapDesc()->columnOrdinal);
-        columnDescs.insert(columnDesc);
-        columnPrivs = columnPrivs->next;
-      }
+  if (userDescList.entries() > 0)
+    return setPrivInfoAndKeys(userDescList, userID, objectUID, secKeySet);
+  return true;
+}
 
-      PrivMgrDesc privs(priv_grantees_desc->privGranteeDesc()->grantee);
-      privs.setTablePrivs(objectDesc);
-      privs.setColumnPrivs(columnDescs);
-      privs.setHasPublicPriv(hasPublicPriv_);
+// ----------------------------------------------------------------------------
+// method: initUserPrivs
+//
+// Creates a PrivMgrUserPrivs object from a PrivMgrDesc object
+// ----------------------------------------------------------------------------
+void PrivMgrUserPrivs::initUserPrivs(PrivMgrDesc &privsOfTheUser)
+{
+  objectBitmap_ = privsOfTheUser.getTablePrivs().getPrivBitmap();
+  grantableBitmap_ = privsOfTheUser.getTablePrivs().getWgoBitmap();
 
-      descList.insert(privs);
-    }
-    priv_grantees_desc = priv_grantees_desc->next;
+  for (int32_t i = 0; i < privsOfTheUser.getColumnPrivs().entries(); i++)
+  {
+    const int32_t columnOrdinal = privsOfTheUser.getColumnPrivs()[i].getColumnOrdinal();
+    colPrivsList_[columnOrdinal] = privsOfTheUser.getColumnPrivs()[i].getPrivBitmap();
+    colGrantableList_[columnOrdinal] = privsOfTheUser.getColumnPrivs()[i].getWgoBitmap();
   }
+  hasPublicPriv_ = privsOfTheUser.getHasPublicPriv();
+}
+
+// ----------------------------------------------------------------------------
+// method: setPrivInfoAndKeys
+//
+// Creates a security keys for a list of PrivMgrDescs
+// ----------------------------------------------------------------------------
+bool PrivMgrUserPrivs::setPrivInfoAndKeys(
+  PrivMgrDescList &descList,
+  const int32_t userID,
+  const int64_t objectUID,
+  NASet<ComSecurityKey> *secKeySet)
+{
+  // Get the list of roleIDs and grantees from cache
+  NAList<int32_t> roleIDs (descList.getHeap());
+  NAList<int32_t> grantees (descList.getHeap());
+  if (ComUser::getCurrentUserRoles(roleIDs, grantees) != 0)
+    return false;
 
-  // Union privileges from all grantees together to create a single set of
-  // bitmaps.  Create security invalidation keys
   for (int i = 0; i < descList.entries(); i++)
   {
-    PrivMgrDesc privs = descList[i];
+    PrivMgrDesc *privs = descList[i];
 
     // Set up object level privileges
-    objectBitmap_ |= privs.getTablePrivs().getPrivBitmap();
-    grantableBitmap_ |= privs.getTablePrivs().getWgoBitmap();
+    objectBitmap_ |= privs->getTablePrivs().getPrivBitmap();
+    grantableBitmap_ |= privs->getTablePrivs().getWgoBitmap();
 
     // Set up column level privileges
-    NAList<PrivMgrCoreDesc> columnPrivs = privs.getColumnPrivs();
+    NAList<PrivMgrCoreDesc> columnPrivs = privs->getColumnPrivs();
     std::map<size_t,PrivColumnBitmap>::iterator it;
     for (int j = 0; j < columnPrivs.entries(); j++)
     {
@@ -172,37 +191,60 @@ bool PrivMgrUserPrivs::initUserPrivs(
     }
 
     // set up security invalidation keys
-    if (!buildSecurityKeys(userID, privs.getGrantee(), objectUID, privs.getTablePrivs(), secKeySet))
+    Int32 grantee = privs->getGrantee();
+    NAList<Int32> roleGrantees(descList.getHeap());
+
+    // If the grantee is a role, then get all users that
+    // have been granted the role.  Create a security key for each.
+    if (PrivMgr::isRoleID(grantee))
+    {
+      for (Int32 j = 0; j < grantees.entries(); j++)
+      {
+         if (grantee == roleIDs[j])
+           roleGrantees.insert(grantees[j]);
+      }
+    }
+
+    // add object security keys
+    if (!buildSecurityKeys(roleGrantees, grantee, objectUID, false, privs->getTablePrivs(), *secKeySet))
       return false;
 
-    for (int k = 0; k < colPrivsList_.size(); k++)
+    // add column security keys
+    NAList<PrivMgrCoreDesc> colPrivs = privs->getColumnPrivs();
+    for (int k = 0; k < colPrivs.entries(); k++)
     {
-      PrivMgrCoreDesc colDesc(colPrivsList_[k], colGrantableList_[k]);
-      if (!buildSecurityKeys(userID, privs.getGrantee(), objectUID, colDesc, secKeySet))
+      PrivMgrCoreDesc colDesc = colPrivs[0];
+      //PrivMgrCoreDesc colDesc(colPrivs[k], colGrantableList_[k]);
+      if (!buildSecurityKeys(roleGrantees, grantee, objectUID, true, colDesc, *secKeySet))
         return false;
     }
   }
 
-  // TBD - add schema privilege bitmaps
   return true;
 }
 
-// ----------------------------------------------------------------------------
-// method: initUserPrivs
+
+// -----------------------------------------------------------------------------
+// Method:: print
 //
-// Creates a PrivMgrUserPrivs object from a PrivMgrDesc object
-// ----------------------------------------------------------------------------
-void PrivMgrUserPrivs::initUserPrivs(PrivMgrDesc &privsOfTheUser)
+// Prints out the bitmaps for the current user
+// -----------------------------------------------------------------------------
+std::string PrivMgrUserPrivs::print()
 {
-  objectBitmap_ = privsOfTheUser.getTablePrivs().getPrivBitmap();
-  grantableBitmap_ = privsOfTheUser.getTablePrivs().getWgoBitmap();
+  std::string privList("Obj: ");
+  privList += objectBitmap_.to_string<char,std::string::traits_type,std::string::allocator_type>();
 
-  for (int32_t i = 0; i < privsOfTheUser.getColumnPrivs().entries(); i++)
+  privList += ", Col: ";
+  Int32 bufSize = 100;
+  char buf[bufSize];
+  for (size_t i = 0; i < colPrivsList_.size(); i++)
   {
-    const int32_t columnOrdinal = privsOfTheUser.getColumnPrivs()[i].getColumnOrdinal();
-    colPrivsList_[columnOrdinal] = privsOfTheUser.getColumnPrivs()[i].getPrivBitmap();
-    colGrantableList_[columnOrdinal] = privsOfTheUser.getColumnPrivs()[i].getWgoBitmap();
+    std::string bits = colPrivsList_[i].to_string<char,std::string::traits_type,std::string::allocator_type>();
+    // Ignore potential buffer overruns
+    snprintf(buf, bufSize, "%d %s ", (int)i, bits.c_str());
+    privList += buf;
   }
-  hasPublicPriv_ = privsOfTheUser.getHasPublicPriv();
+
+  return privList;
 }
 

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/sqlcomp/PrivMgrUserPrivs.h
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgrUserPrivs.h b/core/sql/sqlcomp/PrivMgrUserPrivs.h
index a5264c5..473e59e 100644
--- a/core/sql/sqlcomp/PrivMgrUserPrivs.h
+++ b/core/sql/sqlcomp/PrivMgrUserPrivs.h
@@ -28,6 +28,7 @@
 #include <vector>
 #include <bitset>
 #include "PrivMgrDefs.h"
+#include "PrivMgrDesc.h"
 
 class ComSecurityKey;
 class ComDiagsArea;
@@ -333,6 +334,11 @@ class PrivMgrUserPrivs
     return false;
   }
 
+  bool setPrivInfoAndKeys ( PrivMgrDescList &privDescs,
+                            const int32_t userID,
+                            const int64_t objectUID,
+                            NASet<ComSecurityKey> *secKeySet);
+
   PrivColList & getColPrivList() {return colPrivsList_;}
   void setColPrivList(PrivColList colPrivsList)
      {colPrivsList_ = colPrivsList;}
@@ -379,11 +385,14 @@ class PrivMgrUserPrivs
   bool getHasPublicPriv() { return hasPublicPriv_; }
   void setHasPublicPriv(bool hasPublicPriv) {hasPublicPriv_ = hasPublicPriv;}
   void initUserPrivs (PrivMgrDesc &privsOfTheGrantor);
-  bool initUserPrivs ( const std::vector<int32_t> &roleIDs,
-                       const TrafDesc *priv_desc,
+
+  bool initUserPrivs ( const NAList<Int32> &roleIDs,
+                       PrivMgrDescList *privDescs,
                        const int32_t userID,
                        const int64_t objectUID,
-                       NASet<ComSecurityKey> & secKeySet);
+                       NASet<ComSecurityKey> *secKeySet = NULL);
+
+  std::string print();
 
  private:
    PrivObjectBitmap objectBitmap_;


[2/3] trafodion git commit: TRAFODION - 3218 User still has privilege after user's role has been revoked ...

Posted by rm...@apache.org.
TRAFODION - 3218 User still has privilege after user's role has been revoked ...

Partial support for column level privileges with QI support for:

  column select
  column insert
  column references
  column update

Also, as part of this, updated privilege code in a couple of areas:

Changed object caching code in NATable and NARoutine to store all privileges
assigned to the object when the object is cached (privDescs_).  During the load
operation, the code creates bitmaps (privInfo_) for the current user.  Privilege
checks are performed against the user bitmaps (privInfo_).  This is in
anticipation for some performance updates when connecting to Trafodion (mxosrvr)
with different users.

Change getRoleList to include the roleID and the granteeID that granted the
privilege. The grantee can be a user or a role.

When a privilege is revoked from a role, send QI keys for every user that has
been granted to role.


Project: http://git-wip-us.apache.org/repos/asf/trafodion/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafodion/commit/adf2b8f2
Tree: http://git-wip-us.apache.org/repos/asf/trafodion/tree/adf2b8f2
Diff: http://git-wip-us.apache.org/repos/asf/trafodion/diff/adf2b8f2

Branch: refs/heads/master
Commit: adf2b8f23d87bd3bdcccf64523b730a4c9b57843
Parents: c52b07c
Author: Roberta Marton <ro...@apache.org>
Authored: Wed Oct 3 17:54:39 2018 +0000
Committer: Roberta Marton <ro...@apache.org>
Committed: Wed Oct 3 17:54:39 2018 +0000

----------------------------------------------------------------------
 core/sql/cli/Cli.cpp                            |   7 +-
 core/sql/cli/Cli.h                              |   7 +-
 core/sql/cli/CliExtern.cpp                      |  10 +-
 core/sql/cli/Context.cpp                        |  63 ++++--
 core/sql/cli/Context.h                          |   8 +-
 core/sql/cli/SQLCLIdev.h                        |   5 +-
 core/sql/comexe/ComTdb.h                        |   2 +-
 core/sql/common/ComDistribution.cpp             |   4 +
 core/sql/common/ComSecurityKey.cpp              | 125 +++++++----
 core/sql/common/ComSecurityKey.h                |  16 +-
 core/sql/common/ComSmallDefs.h                  |   9 +
 core/sql/common/ComUser.cpp                     |  62 ++++-
 core/sql/common/ComUser.h                       |   5 +-
 core/sql/executor/ExExeUtilGet.cpp              |   7 +-
 core/sql/generator/Generator.cpp                |  15 +-
 core/sql/optimizer/BindRelExpr.cpp              | 144 ++++++++----
 core/sql/optimizer/NARoutine.cpp                |  96 ++++----
 core/sql/optimizer/NARoutine.h                  |  11 +-
 core/sql/optimizer/NATable.cpp                  | 104 ++++++---
 core/sql/optimizer/NATable.h                    |  21 +-
 core/sql/optimizer/RelMisc.h                    |   3 +-
 core/sql/regress/privs1/EXPECTED120             |  15 +-
 core/sql/regress/privs1/TEST120                 |   2 +-
 core/sql/regress/privs2/EXPECTED129             | 218 +++++++++++++-----
 core/sql/regress/privs2/TEST129                 |  32 ++-
 core/sql/sqlcomp/CmpSeabaseDDLauth.cpp          |  40 +++-
 core/sql/sqlcomp/CmpSeabaseDDLauth.h            |   3 +-
 core/sql/sqlcomp/CmpSeabaseDDLtable.cpp         |  15 +-
 core/sql/sqlcomp/PrivMgr.cpp                    |  37 +++
 core/sql/sqlcomp/PrivMgr.h                      |   5 +
 core/sql/sqlcomp/PrivMgrCommands.cpp            | 124 +++++-----
 core/sql/sqlcomp/PrivMgrCommands.h              |  15 +-
 core/sql/sqlcomp/PrivMgrComponentPrivileges.cpp |  12 +-
 core/sql/sqlcomp/PrivMgrDesc.cpp                |   1 +
 core/sql/sqlcomp/PrivMgrDesc.h                  |  30 +++
 core/sql/sqlcomp/PrivMgrPrivileges.cpp          | 224 ++++++-------------
 core/sql/sqlcomp/PrivMgrPrivileges.h            |  21 +-
 core/sql/sqlcomp/PrivMgrRoles.cpp               |  92 ++++----
 core/sql/sqlcomp/PrivMgrRoles.h                 |  18 +-
 core/sql/sqlcomp/PrivMgrUserPrivs.cpp           | 174 ++++++++------
 core/sql/sqlcomp/PrivMgrUserPrivs.h             |  15 +-
 41 files changed, 1128 insertions(+), 689 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/cli/Cli.cpp
----------------------------------------------------------------------
diff --git a/core/sql/cli/Cli.cpp b/core/sql/cli/Cli.cpp
index 3d5f033..9318fa5 100644
--- a/core/sql/cli/Cli.cpp
+++ b/core/sql/cli/Cli.cpp
@@ -6240,8 +6240,9 @@ Int32 SQLCLI_GetAuthState (
 
 Lng32 SQLCLI_GetRoleList(
    CliGlobals * cliGlobals,
-   Int32 &numRoles,
-   Int32 *&roleIDs)
+   Int32 &numEntries,
+   Int32 *& roleIDs,
+   Int32 *& granteeIDs)
 
 {
    Lng32 retcode = 0;
@@ -6254,7 +6255,7 @@ Lng32 SQLCLI_GetRoleList(
    ContextCli &currContext = *(cliGlobals->currContext());
    ComDiagsArea &diags = currContext.diags();
 
-   retcode = currContext.getRoleList(numRoles,roleIDs);
+   retcode = currContext.getRoleList(numEntries,roleIDs,granteeIDs);
 
    return CliEpilogue(cliGlobals, NULL, retcode);
 

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/cli/Cli.h
----------------------------------------------------------------------
diff --git a/core/sql/cli/Cli.h b/core/sql/cli/Cli.h
index a8a6b9a..c5aa690 100644
--- a/core/sql/cli/Cli.h
+++ b/core/sql/cli/Cli.h
@@ -536,9 +536,10 @@ Int32 SQLCLI_GetAuthState (
 
 Lng32 SQLCLI_GetRoleList(
    CliGlobals *cliGlobals,
-   Int32 &numRoles,
-   Int32 *&roleIDs);
-                         
+   Int32 &numEntries,
+   Int32 *& roleIDs,
+   Int32 *& granteeIDs);
+
 Lng32 SQLCLI_ResetRoleList (
     /*IN*/            CliGlobals *cliGlobals);
 

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/cli/CliExtern.cpp
----------------------------------------------------------------------
diff --git a/core/sql/cli/CliExtern.cpp b/core/sql/cli/CliExtern.cpp
index 69e4717..7091d14 100644
--- a/core/sql/cli/CliExtern.cpp
+++ b/core/sql/cli/CliExtern.cpp
@@ -4346,8 +4346,9 @@ Lng32 SQL_EXEC_SetSessionAttr_Internal(
 
 
 Lng32 SQL_EXEC_GetRoleList(
-   Int32 &numRoles,
-   Int32 *&roleIDs)
+   Int32 &numEntries,
+   Int32 *& roleIDs,
+   Int32 *& granteeIDs)
 
 {
 
@@ -4363,8 +4364,9 @@ Lng32 SQL_EXEC_GetRoleList(
       threadContext->incrNumOfCliCalls();
       retcode =
       SQLCLI_GetRoleList(GetCliGlobals(),
-                         numRoles,
-                         roleIDs);
+                         numEntries,
+                         roleIDs,
+                         granteeIDs);
    }
    catch(...)
    {

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/cli/Context.cpp
----------------------------------------------------------------------
diff --git a/core/sql/cli/Context.cpp b/core/sql/cli/Context.cpp
index 46310d9..fc66151 100644
--- a/core/sql/cli/Context.cpp
+++ b/core/sql/cli/Context.cpp
@@ -173,6 +173,7 @@ ContextCli::ContextCli(CliGlobals *cliGlobals)
     arkcmpInitFailed_(&exHeap_),
     trustedRoutines_(&exHeap_),
     roleIDs_(NULL),
+    granteeIDs_(NULL),
     numRoles_(0),
     unusedBMOsMemoryQuota_(0)
 {
@@ -3974,7 +3975,9 @@ RETCODE ContextCli::authQuery(
    char localNameBuf[32];
    char isValidFromUsersTable[3];
 
-   if (queryType == USERS_QUERY_BY_USER_ID)
+   if (queryType == USERS_QUERY_BY_USER_ID ||
+       queryType == ROLE_QUERY_BY_ROLE_ID ||
+       queryType == ROLES_QUERY_BY_AUTH_ID) 
    {
       sprintf(localNameBuf, "%d", (int) authID);
       nameForDiags = localNameBuf;
@@ -4040,7 +4043,24 @@ RETCODE ContextCli::authQuery(
       case ROLES_QUERY_BY_AUTH_ID:
       {
          authInfoPtr = &authInfo;
-         authStatus = authInfo.getRoleIDs(authID, roleIDs);
+         std::vector<int32_t> roleIDs;
+         std::vector<int32_t> granteeIDs;
+         authStatus = authInfo.getRoleIDs(authID, roleIDs, granteeIDs);
+         ex_assert((roleIDs.size() == granteeIDs.size()), "mismatch between roleIDs and granteeIDs");
+         numRoles_ = roleIDs.size() + 1; // extra for public role
+         roleIDs_ = new (&exHeap_) Int32[numRoles_];
+         granteeIDs_ = new (&exHeap_) Int32[numRoles_];
+
+         for (size_t i = 0; i < roleIDs.size(); i++)
+         {
+           roleIDs_[i] = roleIDs[i];
+           granteeIDs_[i] = granteeIDs[i];
+         }
+
+         // Add the public user to the last entry
+         Int32 lastEntry = numRoles_ - 1;
+         roleIDs_[lastEntry] = PUBLIC_USER;
+         granteeIDs_[lastEntry] = databaseUserID_;
       }   
       break;
 
@@ -4199,19 +4219,35 @@ RETCODE ContextCli::setDatabaseUserByName(const char *userName)
 // *
 // * Function: ContextCli::getRoleList
 // *
-// * Return the role IDs granted to the current user 
+// * Return the role IDs and their grantees for the current user.  
 // *   If the list of roles is already stored, just return this list.
 // *   If the list of roles does not exist extract the roles granted to the
 // *     current user from the Metadata and store in roleIDs_.
 // *
 // ****************************************************************************
 RETCODE ContextCli::getRoleList(
-  Int32 &numRoles,
-  Int32 *&roleIDs)
+  Int32 &numEntries,
+  Int32 *& roleIDs,
+  Int32 *& granteeIDs)
 {
   // If role list has not been created, go read metadata
   if (roleIDs_ == NULL)
   {
+    // If authorization is not enabled, just setup the PUBLIC role
+    CmpContext *cmpCntxt = CmpCommon::context();
+    ex_assert(cmpCntxt, "No compiler context exists");
+    if (!cmpCntxt->isAuthorizationEnabled())
+    {
+      numRoles_ = 1;
+      roleIDs_ = new (&exHeap_) Int32[numRoles_];
+      roleIDs_[0] = PUBLIC_USER;
+      granteeIDs = new (&exHeap_) Int32[numRoles_];
+      granteeIDs[0] = databaseUserID_;
+      numEntries = numRoles_;
+      roleIDs = roleIDs_;
+      return SUCCESS;
+    }
+
     // Get roles for userID
     char usersNameFromUsersTable[MAX_USERNAME_LEN +1];
     Int32 userIDFromUsersTable;
@@ -4225,19 +4261,11 @@ RETCODE ContextCli::getRoleList(
                                 myRoles);  // OUT
     if (result != SUCCESS)
       return result;
-
-    // Include the public user
-    myRoles.push_back(PUBLIC_USER);
-
-    // Add role info to ContextCli
-    numRoles_ = myRoles.size();
-    roleIDs_ = new (&exHeap_) Int32[numRoles_];
-    for (size_t i = 0; i < numRoles_; i++)
-      roleIDs_[i] = myRoles[i];
   }
 
-  numRoles = numRoles_;
+  numEntries = numRoles_;
   roleIDs = roleIDs_;
+  granteeIDs = granteeIDs_;
 
   return SUCCESS;
 }
@@ -4256,6 +4284,11 @@ RETCODE ContextCli::resetRoleList()
   if (roleIDs_)
     NADELETEBASIC(roleIDs_, &exHeap_);
   roleIDs_ = NULL;
+
+  if (granteeIDs_)
+    NADELETEBASIC(granteeIDs_, &exHeap_);
+  granteeIDs_ = NULL;
+
   numRoles_ = 0;
 
   return SUCCESS;

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/cli/Context.h
----------------------------------------------------------------------
diff --git a/core/sql/cli/Context.h b/core/sql/cli/Context.h
index c000714..23846d6 100644
--- a/core/sql/cli/Context.h
+++ b/core/sql/cli/Context.h
@@ -150,8 +150,9 @@ public:
 
 
   // functions to get and set roles for the current user
-  RETCODE getRoleList(Int32  &numRoles,
-                      Int32  *&roleIDs);
+  RETCODE getRoleList(Int32  &numEntries,
+                      Int32 *& roleIDs,
+                      Int32 *& granteeIDs);
 
   RETCODE resetRoleList();
 
@@ -258,8 +259,9 @@ private:
   char *databaseUserName_;
 
   // List of active roles for the databaseUser
-  Int32  *roleIDs_;
   Int32   numRoles_;
+  Int32  *roleIDs_;
+  Int32  *granteeIDs_;
 
   NABoolean userNameChanged_;
 

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/cli/SQLCLIdev.h
----------------------------------------------------------------------
diff --git a/core/sql/cli/SQLCLIdev.h b/core/sql/cli/SQLCLIdev.h
index 3dddf9e..59646be 100644
--- a/core/sql/cli/SQLCLIdev.h
+++ b/core/sql/cli/SQLCLIdev.h
@@ -310,8 +310,9 @@ Lng32 SQL_EXEC_SetErrorCodeInRTS(
 	        /*IN*/ Lng32     sqlErrorCode);  
 
 Lng32 SQL_EXEC_GetRoleList(
-   Int32 &numRoles,
-   Int32 *&roleIDs);
+   Int32 &numEntries,
+   Int32 *& roleIDs,
+   Int32 *& granteeIDs);
 
 Lng32 SQL_EXEC_ResetRoleList_Internal ();
 

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/comexe/ComTdb.h
----------------------------------------------------------------------
diff --git a/core/sql/comexe/ComTdb.h b/core/sql/comexe/ComTdb.h
index e00728f..59db8a7 100644
--- a/core/sql/comexe/ComTdb.h
+++ b/core/sql/comexe/ComTdb.h
@@ -1111,7 +1111,7 @@ class ComTdbVirtTablePrivInfo : public ComTdbVirtTableBase
 
   virtual Int32 size() { return sizeof(ComTdbVirtTablePrivInfo);}
 
-  NAList<PrivMgrDesc>     *privmgr_desc_list;     
+  PrivMgrDescList         *privmgr_desc_list;     
 };
 
 class ComTdbVirtTableLibraryInfo : public ComTdbVirtTableBase

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/common/ComDistribution.cpp
----------------------------------------------------------------------
diff --git a/core/sql/common/ComDistribution.cpp b/core/sql/common/ComDistribution.cpp
index 14bb378..a741536 100644
--- a/core/sql/common/ComDistribution.cpp
+++ b/core/sql/common/ComDistribution.cpp
@@ -301,6 +301,10 @@ const literalAndEnumStruct qiTypeConversionTable [] =
   {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_COLUMN_SELECT, COM_QI_COLUMN_SELECT_LIT},
+  {COM_QI_COLUMN_INSERT, COM_QI_COLUMN_INSERT_LIT},
+  {COM_QI_COLUMN_UPDATE, COM_QI_COLUMN_UPDATE_LIT},
+  {COM_QI_COLUMN_REFERENCES, COM_QI_COLUMN_REFERENCES_LIT},
   {COM_QI_OBJECT_SELECT, COM_QI_OBJECT_SELECT_LIT},
   {COM_QI_OBJECT_INSERT, COM_QI_OBJECT_INSERT_LIT},
   {COM_QI_OBJECT_DELETE, COM_QI_OBJECT_DELETE_LIT},

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/common/ComSecurityKey.cpp
----------------------------------------------------------------------
diff --git a/core/sql/common/ComSecurityKey.cpp b/core/sql/common/ComSecurityKey.cpp
index 567d9ee..a2b4706 100644
--- a/core/sql/common/ComSecurityKey.cpp
+++ b/core/sql/common/ComSecurityKey.cpp
@@ -46,7 +46,9 @@
 NABoolean qiSubjectMatchesRole(uint32_t subjectKey)
 {
   NAList <Int32> roleIDs(NULL);
-  ComUser::getCurrentUserRoles(roleIDs);
+  if (ComUser::getCurrentUserRoles(roleIDs) != 0)
+    return TRUE;  // force recompilation if can't get current roles
+
   for (int i = 0; i < roleIDs.entries(); i++)
   {
     if (subjectKey = ComSecurityKey::generateHash(roleIDs[i]))
@@ -84,6 +86,7 @@ NABoolean qiCheckForInvalidObject (const Int32 numInvalidationKeys,
     {
       // Indicates that the DDL of the object has changed. 
       case COM_QI_OBJECT_REDEF:
+
       // Indicates that the histogram statistics of the object has changed.
       case COM_QI_STATS_UPDATED:
       {
@@ -95,6 +98,10 @@ NABoolean qiCheckForInvalidObject (const Int32 numInvalidationKeys,
       // Scan the passed-in object keys to find any that match the subject, 
       // object, and key type. That is, the subject has the privilege
       // (invalidation key type) on the object or a column of the object.
+      case COM_QI_COLUMN_SELECT:
+      case COM_QI_COLUMN_INSERT:
+      case COM_QI_COLUMN_UPDATE:
+      case COM_QI_COLUMN_REFERENCES:
       case COM_QI_OBJECT_SELECT:
       case COM_QI_OBJECT_INSERT:
       case COM_QI_OBJECT_DELETE:
@@ -117,6 +124,7 @@ NABoolean qiCheckForInvalidObject (const Int32 numInvalidationKeys,
           }
         }
         break;
+
       case COM_QI_USER_GRANT_SPECIAL_ROLE:
       case COM_QI_USER_GRANT_ROLE:
       {
@@ -146,19 +154,36 @@ NABoolean qiCheckForInvalidObject (const Int32 numInvalidationKeys,
 // Function that builds query invalidation keys for privileges. A separate
 // invalidation key is added for each granted DML privilege. 
 //
+// Parameters:
+//    roleGrantees - needed to create invalidation keys to represent:
+//                   all authorization ID that have been granted the role
+//    granteeID - the authID which has been granted one or more privileges
+//                could be a userID, a role the userID is granted or PUBLIC
+//    objectUID - the object (object) granted privilege
+//    privs - the list of DML privileges
+//    secKeySet - the list of invalidation keys generated
+//
+// secKeySet is a set so it automatically silently ignores duplicate entries
+//
 // Types of keys available for privs:
-//   OBJECT_IS_SCHEMA - not supported until we support schema level privs
+//   OBJECT_IS_SCHEMA - not supported
 //   OBJECT_IS_OBJECT - supported for granting privs to user
-//   OBJECT_IS_COLUMN - not supported at this time
+//     grant <priv-list> on <object> to <granteeID>
+//   OBJECT_IS_COLUMN - partially supported
+//     grant <priv-list> (col-list) on <object> to <granteeID>
 //   OBJECT_IS_SPECIAL_ROLE - key for PUBLIC authorization ID
+//     grant <priv-list> [(col-list)] on <object> to PUBLIC
 //   SUBJECT_IS_USER - support for granting roles to user
-//   SUBJECT_IS_ROLE - not supported until we grant roles to roles
+//     grant role <granteeID> to <grantRoleAuthID>
+//   SUBJECT_IS_ROLE - support for granting roles to role
+//     grant <priv-list> on <object> to <role>
 //
 // returns false is unable to build keys
 // ****************************************************************************
-bool buildSecurityKeys( const int32_t userID,
+bool buildSecurityKeys( const NAList<int32_t> &roleGrantees,
                         const int32_t granteeID,
                         const int64_t objectUID,
+                        const bool isColumn,
                         const PrivMgrCoreDesc &privs,
                         ComSecurityKeySet &secKeySet )
 {
@@ -166,7 +191,7 @@ bool buildSecurityKeys( const int32_t userID,
     return true;
 
   NABoolean doDebug = (getenv("DBUSER_DEBUG") ? TRUE : FALSE);
-  std::string  msg ("Method: buildSecurityKeys: ");
+  std::string  msg ("Method: buildSecurityKeys ");
   if (doDebug)
   {
     printf("[DBUSER:%d] %s\n", (int) getpid(), msg.c_str());
@@ -191,33 +216,41 @@ bool buildSecurityKeys( const int32_t userID,
       return false;
   }
 
-  // If the grantee is a role, generate a special security key
-  // If the role is revoked from the user, this key takes affect
+  // If the grantee is a role, generate special security keys, one for
+  // the user and one for each of the user's roles. 
+  // If the role is revoked from the user these key takes affect
   if (PrivMgr::isRoleID(granteeID))
   {
-    ComSecurityKey key (userID, granteeID, ComSecurityKey::SUBJECT_IS_USER);
-    if (doDebug)
+    char buf [200];
+    for (CollIndex r = 0; r < roleGrantees.entries(); r++)
     {
-      NAString msg = key.print(userID, granteeID);
-      printf("[DBUSER:%d]   (role) %s\n",
-             (int) getpid(), msg.data());
-      fflush(stdout);
-    }
+      ComSecurityKey::QIType qiType = ComSecurityKey::SUBJECT_IS_USER;
+      ComSecurityKey key (roleGrantees[r], granteeID, qiType);
+      if (doDebug)
+      {
+        NAString msg = key.print(roleGrantees[r], granteeID);
+        printf("[DBUSER:%d]   (role) %s\n",
+               (int) getpid(), msg.data());
+        fflush(stdout);
+      }
 
-    if (key.isValid())
-     secKeySet.insert(key);
-    else
-      return false;
+      if (key.isValid())
+        secKeySet.insert(key);
+      else
+        return false;
+    }
   }
 
-  // Generate object invalidation keys
-  // Only need to generate keys for DML privileges
+  // Generate keys one per granted DML privilege
   for ( size_t i = FIRST_DML_PRIV; i <= LAST_DML_PRIV; i++ )
   {
     if ( privs.getPriv(PrivType(i)))
     {
-      ComSecurityKey key (granteeID, objectUID, PrivType(i), 
-                          ComSecurityKey::OBJECT_IS_OBJECT);
+      ComSecurityKey::QIType qiType = (isColumn) ?
+           ComSecurityKey::OBJECT_IS_COLUMN :
+           ComSecurityKey::OBJECT_IS_OBJECT;
+
+      ComSecurityKey key (granteeID, objectUID, PrivType(i), qiType);
       if (doDebug)
       {
         NAString msg = key.print(granteeID, objectUID);
@@ -270,7 +303,7 @@ void qiInvalidationType (const Int32 numInvalidationKeys,
   if (doDebug)
   {
     sprintf(buf, ": num keys(%d)", numInvalidationKeys);
-    printf("[DBUSER:%d] Method: qiInvalidationType%s\n",
+    printf("[DBUSER:%d] Method: qiInvalidationType (what should be invalidated) %s\n",
            (int) getpid(), buf);
     fflush(stdout);
     sprintf(buf, "Not applicable");
@@ -491,14 +524,14 @@ ComQIActionType ComSecurityKey::convertBitmapToQIActionType (
     case SELECT_PRIV:
       if (inputType == OBJECT_IS_OBJECT)
         result = COM_QI_OBJECT_SELECT;
-      //else 
-      //  result = COM_QI_COLUMN_SELECT;
+      else 
+        result = COM_QI_COLUMN_SELECT;
       break;
     case INSERT_PRIV:
       if (inputType == OBJECT_IS_OBJECT)
         result = COM_QI_OBJECT_INSERT;
-      //else 
-      //  result = COM_QI_COLUMN_INSERT;
+      else 
+        result = COM_QI_COLUMN_INSERT;
       break;
     case DELETE_PRIV:
       if (inputType == OBJECT_IS_OBJECT)
@@ -507,8 +540,8 @@ ComQIActionType ComSecurityKey::convertBitmapToQIActionType (
     case UPDATE_PRIV:
       if (inputType == OBJECT_IS_OBJECT)
         result = COM_QI_OBJECT_UPDATE;
-      //else 
-      //  result = COM_QI_COLUMN_UPDATE;
+      else 
+        result = COM_QI_COLUMN_UPDATE;
       break;
     case USAGE_PRIV:
       if (inputType == OBJECT_IS_OBJECT)
@@ -517,12 +550,12 @@ ComQIActionType ComSecurityKey::convertBitmapToQIActionType (
     case REFERENCES_PRIV:
       if (inputType == OBJECT_IS_OBJECT)
         result = COM_QI_OBJECT_REFERENCES;
+      else
+        result = COM_QI_COLUMN_REFERENCES;
       break;
     case EXECUTE_PRIV:  
       if (inputType == OBJECT_IS_OBJECT)
         result = COM_QI_OBJECT_EXECUTE;
-      else if (inputType == OBJECT_IS_SCHEMA)
-        result = COM_QI_SCHEMA_EXECUTE;
       break;
     default:
       result = COM_QI_INVALID_ACTIONTYPE;
@@ -560,6 +593,18 @@ void ComSecurityKey::getSecurityKeyTypeAsLit (std::string &actionString) const
     case COM_QI_ROLE_GRANT_ROLE:
       actionString = COM_QI_ROLE_GRANT_ROLE_LIT;
       break;
+    case COM_QI_COLUMN_SELECT:
+      actionString = COM_QI_COLUMN_SELECT_LIT;
+      break;
+    case COM_QI_COLUMN_INSERT:
+      actionString = COM_QI_COLUMN_INSERT_LIT;
+      break;
+    case COM_QI_COLUMN_UPDATE:
+      actionString = COM_QI_COLUMN_UPDATE_LIT;
+      break;
+    case COM_QI_COLUMN_REFERENCES:
+      actionString = COM_QI_COLUMN_REFERENCES_LIT;
+      break;
     case COM_QI_OBJECT_SELECT:
       actionString = COM_QI_OBJECT_SELECT_LIT;
       break;
@@ -618,17 +663,17 @@ NAString ComSecurityKey::print(Int32 subjectID, Int64 objectID)
     case COM_QI_ROLE_GRANT_ROLE:
       typeString = "ROLE_GRANT_ROLE";
       break;
-    case COM_QI_SCHEMA_SELECT:
-      typeString = "SCHEMA_SELECT";
+    case COM_QI_COLUMN_SELECT:
+      typeString = "COLUMN_SELECT";
       break;
-    case COM_QI_SCHEMA_INSERT:
-      typeString = "SCHEMA_INSERT";
+    case COM_QI_COLUMN_INSERT:
+      typeString = "COLUMN_INSERT";
       break;
-    case COM_QI_SCHEMA_DELETE:
-      typeString = "SCHEMA_DELETE";
+    case COM_QI_COLUMN_UPDATE:
+      typeString = "COLUMN_UPDATE";
       break;
-    case COM_QI_SCHEMA_UPDATE:
-      typeString = "SCHEMA_UPDATE";
+    case COM_QI_COLUMN_REFERENCES:
+      typeString = "COLUMN_REFERENCES";
       break;
     case COM_QI_OBJECT_SELECT:
       typeString = "OBJECT_SELECT";

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/common/ComSecurityKey.h
----------------------------------------------------------------------
diff --git a/core/sql/common/ComSecurityKey.h b/core/sql/common/ComSecurityKey.h
index 8f90d16..3a06779 100644
--- a/core/sql/common/ComSecurityKey.h
+++ b/core/sql/common/ComSecurityKey.h
@@ -37,9 +37,10 @@ class ComSecurityKey;
 
 typedef NASet<ComSecurityKey>  ComSecurityKeySet;
 
-bool buildSecurityKeys( const int32_t userID,
-                        const int32_t granteeID,
+bool buildSecurityKeys( const NAList <Int32> &roleGrantees,
+                        const int32_t roleID,
                         const int64_t objectUID,
+                        const bool isColumn,
                         const PrivMgrCoreDesc &privs,
                         ComSecurityKeySet &secKeySet);
 
@@ -101,13 +102,22 @@ public:
   ComSecurityKey(
    const int32_t subjectUserID, 
    const int64_t objectUserID, 
-   const QIType typeOfSubject = SUBJECT_IS_USER);
+   const QIType typeOfSubject);
 
   // Constructor for a special role grant to an authID.
   ComSecurityKey(
     const int32_t subjectUserID, 
     const QIType typeOfObject);
 
+  // Constructor for generating revoke role from subject
+  ComSecurityKey(
+    const uint32_t subjectHashValue,
+    const uint32_t objectHashValue)
+  : subjectHash_(subjectHashValue),
+    objectHash_ (objectHashValue),
+    actionType_(COM_QI_USER_GRANT_ROLE)
+  {};
+
   ComSecurityKey();  // do not use
   bool operator == (const ComSecurityKey &other) const;
    

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/common/ComSmallDefs.h
----------------------------------------------------------------------
diff --git a/core/sql/common/ComSmallDefs.h b/core/sql/common/ComSmallDefs.h
index db99f28..c18662d 100644
--- a/core/sql/common/ComSmallDefs.h
+++ b/core/sql/common/ComSmallDefs.h
@@ -1309,6 +1309,10 @@ enum ComQIActionType { COM_QI_INVALID_ACTIONTYPE = 0
                      , COM_QI_OBJECT_REDEF
                      , COM_QI_STATS_UPDATED
                      , COM_QI_GRANT_ROLE
+                     , COM_QI_COLUMN_SELECT
+                     , COM_QI_COLUMN_INSERT
+                     , COM_QI_COLUMN_UPDATE
+                     , COM_QI_COLUMN_REFERENCES
                      } ;
 
 #define COM_QI_INVALID_ACTIONTYPE_LIT  "  "
@@ -1332,6 +1336,11 @@ enum ComQIActionType { COM_QI_INVALID_ACTIONTYPE = 0
 #define COM_QI_OBJECT_REDEF_LIT        "OR"
 #define COM_QI_STATS_UPDATED_LIT       "US"
 #define COM_QI_GRANT_ROLE_LIT          "GG"
+#define COM_QI_COLUMN_SELECT_LIT       "CS"
+#define COM_QI_COLUMN_INSERT_LIT       "CI"
+#define COM_QI_COLUMN_UPDATE_LIT       "CU"
+#define COM_QI_COLUMN_REFERENCES_LIT   "CF"
+
 
 
 

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/common/ComUser.cpp
----------------------------------------------------------------------
diff --git a/core/sql/common/ComUser.cpp b/core/sql/common/ComUser.cpp
index 2b6831f..516d411 100644
--- a/core/sql/common/ComUser.cpp
+++ b/core/sql/common/ComUser.cpp
@@ -362,7 +362,8 @@ bool ComUser::currentUserHasRole(Int32 roleID)
 {
   Int32 numRoles = 0;
   Int32 *roleIDs = 0;
-  if (SQL_EXEC_GetRoleList(numRoles, roleIDs) < 0)
+  Int32 *granteeIDs = NULL;
+  if (SQL_EXEC_GetRoleList(numRoles, roleIDs, granteeIDs) < 0)
     return false;
 
   for (Int32 i = 0; i < numRoles; i++)
@@ -374,15 +375,64 @@ bool ComUser::currentUserHasRole(Int32 roleID)
   return false;
 }
 
-void ComUser::getCurrentUserRoles(NAList <Int32> &roleList)
+// ----------------------------------------------------------------------------
+// method: getCurrentUserRoles
+//
+// Gets the active roles for the current user as a list of Int32's
+// There should be at least one role in this list (PUBLIC)
+//
+// Returns:
+//   -1 -- unexpected error getting roles
+//    0 -- successful
+// ----------------------------------------------------------------------------
+Int16 ComUser::getCurrentUserRoles(NAList <Int32> &roleIDs)
 {
   Int32 numRoles = 0;
-  Int32 *roleIDs = 0;
-  Int32 retcode = SQL_EXEC_GetRoleList(numRoles, roleIDs);
-  assert(retcode == 0);
+  Int32 *cachedRoleIDs = NULL;
+  Int32 *cachedGranteeIDs = NULL;
+  RETCODE retcode =
+    GetCliGlobals()->currContext()->getRoleList(numRoles, cachedRoleIDs, cachedGranteeIDs);
+
+  if (retcode != SUCCESS)
+    return -1;
+
+  for (Int32 i = 0; i < numRoles; i++)
+  {
+    // in case there are duplicates
+    if (!roleIDs.contains(cachedRoleIDs[i]))
+      roleIDs.insert (cachedRoleIDs[i]);
+  }
+  return 0;
+}
+
+// ----------------------------------------------------------------------------
+// method: getCurrentUserRoles
+//
+// Gets the active roles and grantees for the current user as a list of Int32's
+// There should be at least one role in this list (PUBLIC)
+//
+// Returns:
+//   -1 -- unexpected error getting roles
+//    0 -- successful
+// ----------------------------------------------------------------------------
+Int16 ComUser::getCurrentUserRoles(NAList<Int32> &roleIDs, NAList<Int32> &granteeIDs)
+{
+  Int32 numRoles = 0;
+  Int32 *cachedRoleIDs = NULL;
+  Int32 *cachedGranteeIDs = NULL;
+  RETCODE retcode =
+    GetCliGlobals()->currContext()->getRoleList(numRoles, cachedRoleIDs, cachedGranteeIDs);
+
+  if (retcode != SUCCESS)
+    return -1;
 
   for (Int32 i = 0; i < numRoles; i++)
-    roleList.insert (roleIDs[i]);
+  {
+    roleIDs.insert (cachedRoleIDs[i]);
+    granteeIDs.insert (cachedGranteeIDs[i]);
+  }
+
+  return 0;
 }
 
 

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/common/ComUser.h
----------------------------------------------------------------------
diff --git a/core/sql/common/ComUser.h b/core/sql/common/ComUser.h
index eb5db65..8a24de9 100644
--- a/core/sql/common/ComUser.h
+++ b/core/sql/common/ComUser.h
@@ -91,7 +91,10 @@ class ComUser
                                          Int32 & authID);
 
      static bool currentUserHasRole(Int32 roleID);
-     static void getCurrentUserRoles(NAList <Int32> &roleList);
+     static Int16 getCurrentUserRoles(NAList <Int32> &roleIDs);
+     static Int16 getCurrentUserRoles(NAList <Int32> &roleIDs,
+                                     NAList <Int32> &granteeIDs);
+
 
      static Int32 getRoleList (char *roleList,
                                Int32 &actualLen,

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/executor/ExExeUtilGet.cpp
----------------------------------------------------------------------
diff --git a/core/sql/executor/ExExeUtilGet.cpp b/core/sql/executor/ExExeUtilGet.cpp
index 590b068..86e6a7b 100644
--- a/core/sql/executor/ExExeUtilGet.cpp
+++ b/core/sql/executor/ExExeUtilGet.cpp
@@ -1665,10 +1665,10 @@ NABoolean ExExeUtilGetMetadataInfoTcb::checkUserPrivs(
   if (ComUser::isRootUserID())
     return FALSE;
 
-  // any user granted the DB__ROOTROLE sees everything
   Int32 numRoles;
   Int32 *roleList;
-  if (currContext->getRoleList(numRoles, roleList) == SUCCESS)
+  Int32 *granteeList;
+  if (currContext->getRoleList(numRoles, roleList, granteeList) == SUCCESS)
   {
     char authIDAsChar[sizeof(Int32)+10];
     NAString auths;
@@ -2001,7 +2001,8 @@ short ExExeUtilGetMetadataInfoTcb::work()
                // add list of roles stored in context
                Int32 numRoles;
                Int32 *roleList;
-               if (currContext->getRoleList(numRoles, roleList) != SUCCESS)
+               Int32 *granteeList;
+               if (currContext->getRoleList(numRoles, roleList, granteeList) != SUCCESS)
                  numRoles = 0;
                for (Int32 i = 0; i < numRoles; i++)
                {

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/generator/Generator.cpp
----------------------------------------------------------------------
diff --git a/core/sql/generator/Generator.cpp b/core/sql/generator/Generator.cpp
index 4cbb8bf..df98a66 100644
--- a/core/sql/generator/Generator.cpp
+++ b/core/sql/generator/Generator.cpp
@@ -1723,8 +1723,8 @@ TrafDesc * Generator::createPrivDescs( const ComTdbVirtTablePrivInfo * privInfo,
 {
   // When authorization is enabled, each object must have at least one grantee
   // - the system grant to the object owner
-  NAList<PrivMgrDesc> *privGrantees = privInfo[0].privmgr_desc_list;
-  DCMPASSERT (privGrantees.size() > 0);
+  PrivMgrDescList *privGrantees = privInfo[0].privmgr_desc_list;
+  DCMPASSERT (privGrantees->entries() > 0);
  
   TrafDesc * priv_desc = TrafAllocateDDLdesc(DESC_PRIV_TYPE, space);
   TrafDesc * first_grantee_desc = NULL;
@@ -1734,17 +1734,18 @@ TrafDesc * Generator::createPrivDescs( const ComTdbVirtTablePrivInfo * privInfo,
   // attach to the privileges descriptor (priv_desc)
   for (int i = 0; i < privGrantees->entries(); i++)
     {
-      PrivMgrDesc &granteeDesc = (*privGrantees)[i];
+      PrivMgrDesc *granteeDesc = (*privGrantees)[i];
       TrafDesc * curr_grantee_desc = TrafAllocateDDLdesc(DESC_PRIV_GRANTEE_TYPE, space);
       if (! first_grantee_desc)
         first_grantee_desc = curr_grantee_desc;
 
-      curr_grantee_desc->privGranteeDesc()->grantee = granteeDesc.getGrantee();
+      curr_grantee_desc->privGranteeDesc()->grantee = granteeDesc->getGrantee();
 
       // generate a TrafPrivBitmap for the object level privs and
       // attach it to the privilege grantee descriptor (curr_grantee_desc)
       TrafDesc * bitmap_desc = TrafAllocateDDLdesc(DESC_PRIV_BITMAP_TYPE, space);
-      PrivMgrCoreDesc objDesc = granteeDesc.getTablePrivs();
+      PrivMgrCoreDesc objDesc = granteeDesc->getTablePrivs();
+
       bitmap_desc->privBitmapDesc()->columnOrdinal = -1;
       bitmap_desc->privBitmapDesc()->privBitmap = objDesc.getPrivBitmap().to_ulong();
       bitmap_desc->privBitmapDesc()->privWGOBitmap = objDesc.getWgoBitmap().to_ulong();
@@ -1752,14 +1753,14 @@ TrafDesc * Generator::createPrivDescs( const ComTdbVirtTablePrivInfo * privInfo,
 
       // generate a list of TrafPrivBitmapDesc, one for each column and
       // attach it to the TrafPrivGranteeDesc
-      size_t numCols = granteeDesc.getColumnPrivs().entries();
+      size_t numCols = granteeDesc->getColumnPrivs().entries();
       if (numCols > 0)
         {
           TrafDesc * first_col_desc = NULL;
           TrafDesc * prev_col_desc = NULL;
           for (int j = 0; j < numCols; j++)
             {
-              const PrivMgrCoreDesc colBitmap = granteeDesc.getColumnPrivs()[j];
+              const PrivMgrCoreDesc colBitmap = granteeDesc->getColumnPrivs()[j];
               TrafDesc * curr_col_desc = TrafAllocateDDLdesc(DESC_PRIV_BITMAP_TYPE, space);
               if (! first_col_desc)
                 first_col_desc = curr_col_desc;

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/optimizer/BindRelExpr.cpp
----------------------------------------------------------------------
diff --git a/core/sql/optimizer/BindRelExpr.cpp b/core/sql/optimizer/BindRelExpr.cpp
index 716a9c6..43afef6 100644
--- a/core/sql/optimizer/BindRelExpr.cpp
+++ b/core/sql/optimizer/BindRelExpr.cpp
@@ -7005,6 +7005,7 @@ NABoolean RelRoot::checkPrivileges(BindWA* bindWA)
     optStoi = (bindWA->getStoiList())[i];
     stoi = optStoi->getStoi();
     NATable* tab = optStoi->getTable();
+    ComSecurityKeySet secKeySet = tab->getSecKeySet();
 
     // System metadata tables do not, by default, have privileges stored in the
     // NATable structure.  Go ahead and retrieve them now. 
@@ -7012,6 +7013,7 @@ NABoolean RelRoot::checkPrivileges(BindWA* bindWA)
     PrivMgrUserPrivs privInfo;
     if (!pPrivInfo)
     {
+      secKeySet.clear();
       CmpSeabaseDDL cmpSBD(STMTHEAP);
       if (cmpSBD.switchCompiler(CmpContextInfo::CMPCONTEXT_TYPE_META))
       {
@@ -7019,7 +7021,7 @@ NABoolean RelRoot::checkPrivileges(BindWA* bindWA)
           *CmpCommon::diags() << DgSqlCode( -4400 );
         return FALSE;
       }
-      retcode = privInterface.getPrivileges( tab, thisUserID, privInfo);
+      retcode = privInterface.getPrivileges( tab, thisUserID, privInfo, &secKeySet);
       cmpSBD.switchBackCompiler();
 
       if (retcode != STATUS_GOOD)
@@ -7034,7 +7036,7 @@ NABoolean RelRoot::checkPrivileges(BindWA* bindWA)
 
     // Check each primary DML privilege to see if the query requires it. If 
     // so, verify that the user has the privilege
-    bool insertQIKeys = (QI_enabled && tab->getSecKeySet().entries() > 0);
+    bool insertQIKeys = (QI_enabled && secKeySet.entries() > 0);
     for (int_32 i = FIRST_DML_PRIV; i <= LAST_PRIMARY_DML_PRIV; i++)
     {
       if (stoi->getPrivAccess((PrivType)i))
@@ -7043,7 +7045,7 @@ NABoolean RelRoot::checkPrivileges(BindWA* bindWA)
           RemoveNATableEntryFromCache = TRUE;
         else
           if (insertQIKeys)    
-            findKeyAndInsertInOutputList(tab->getSecKeySet(),userHashValue,(PrivType)(i));
+            findKeyAndInsertInOutputList(secKeySet,userHashValue,(PrivType)(i), bindWA);
       }
     }
 
@@ -7085,7 +7087,7 @@ NABoolean RelRoot::checkPrivileges(BindWA* bindWA)
         {
           // do this only if QI is enabled and object has security keys defined
           if ( insertQIKeys )
-            findKeyAndInsertInOutputList(rtn->getSecKeySet(), userHashValue, EXECUTE_PRIV);
+            findKeyAndInsertInOutputList(rtn->getSecKeySet(), userHashValue, EXECUTE_PRIV, bindWA);
         }
 
         // plan requires privilege but user has none, report an error
@@ -7121,6 +7123,7 @@ NABoolean RelRoot::checkPrivileges(BindWA* bindWA)
     NATable* tab = bindWA->getSchemaDB()->getNATableDB()->
                                    get(coProcAggr->getCorrName(), bindWA, NULL);
 
+    ComSecurityKeySet secKeySet = tab->getSecKeySet();
     Int32 numSecKeys = 0;
 
     // Privilege info for the user/table combination is stored in the NATable
@@ -7132,6 +7135,7 @@ NABoolean RelRoot::checkPrivileges(BindWA* bindWA)
     // NATable structure.  Go ahead and retrieve them now. 
     if (!pPrivInfo)
     {
+      secKeySet.clear();
       CmpSeabaseDDL cmpSBD(STMTHEAP);
       if (cmpSBD.switchCompiler(CmpContextInfo::CMPCONTEXT_TYPE_META))
       {
@@ -7139,7 +7143,7 @@ NABoolean RelRoot::checkPrivileges(BindWA* bindWA)
           *CmpCommon::diags() << DgSqlCode( -4400 );
         return FALSE;
       }
-      retcode = privInterface.getPrivileges( tab, thisUserID, privInfo);
+      retcode = privInterface.getPrivileges( tab, thisUserID, privInfo, &secKeySet);
       cmpSBD.switchBackCompiler();
 
       if (retcode != STATUS_GOOD)
@@ -7155,13 +7159,13 @@ NABoolean RelRoot::checkPrivileges(BindWA* bindWA)
     // Verify that the user has select priv
     // Select priv is needed for EXPLAIN requests, so no special check is done
     NABoolean insertQIKeys = FALSE; 
-    if (QI_enabled && (tab->getSecKeySet().entries()) > 0)
+    if (QI_enabled && (secKeySet.entries()) > 0)
       insertQIKeys = TRUE;
     if (pPrivInfo->hasPriv(SELECT_PRIV))
     {
       // do this only if QI is enabled and object has security keys defined
       if ( insertQIKeys )
-        findKeyAndInsertInOutputList(tab->getSecKeySet(), userHashValue, SELECT_PRIV );
+        findKeyAndInsertInOutputList(secKeySet, userHashValue, SELECT_PRIV, bindWA );
     }
 
     // plan requires privilege but user has none, report an error
@@ -7183,12 +7187,14 @@ NABoolean RelRoot::checkPrivileges(BindWA* bindWA)
     SequenceValue *seqVal = (bindWA->getSeqValList())[i];
     NATable* tab = const_cast<NATable*>(seqVal->getNATable());
     CMPASSERT(tab);
+    ComSecurityKeySet secKeySet = tab->getSecKeySet();
 
     // get privilege information from the NATable structure
     PrivMgrUserPrivs *pPrivInfo = tab->getPrivInfo();
     PrivMgrUserPrivs privInfo;
     if (!pPrivInfo)
     {
+      secKeySet.clear();
       CmpSeabaseDDL cmpSBD(STMTHEAP);
       if (cmpSBD.switchCompiler(CmpContextInfo::CMPCONTEXT_TYPE_META))
       {
@@ -7196,7 +7202,7 @@ NABoolean RelRoot::checkPrivileges(BindWA* bindWA)
           *CmpCommon::diags() << DgSqlCode( -4400 );
         return FALSE;
       }
-      retcode = privInterface.getPrivileges(tab, thisUserID, privInfo);
+      retcode = privInterface.getPrivileges(tab, thisUserID, privInfo, &secKeySet);
       cmpSBD.switchBackCompiler();
       if (retcode != STATUS_GOOD)
       {
@@ -7210,13 +7216,13 @@ NABoolean RelRoot::checkPrivileges(BindWA* bindWA)
 
     // Verify that the user has usage priv
     NABoolean insertQIKeys = FALSE; 
-    if (QI_enabled && (tab->getSecKeySet().entries()) > 0)
+    if (QI_enabled && (secKeySet.entries()) > 0)
       insertQIKeys = TRUE;
     if (pPrivInfo->hasPriv(USAGE_PRIV))
     {
       // do this only if QI is enabled and object has security keys defined
       if ( insertQIKeys )
-        findKeyAndInsertInOutputList(tab->getSecKeySet(), userHashValue, USAGE_PRIV );
+        findKeyAndInsertInOutputList(secKeySet, userHashValue, USAGE_PRIV, bindWA );
     }
 
     // plan requires privilege but user has none, report an error
@@ -7248,44 +7254,68 @@ NABoolean RelRoot::checkPrivileges(BindWA* bindWA)
 //   COM_QI_USER_GRANT_SPECIAL_ROLE: privileges granted to PUBLIC
 //
 // Keys are added as follows:
-//   if a privilege has been granted via a role, add a RoleUserKey
-//      if this role is revoked from the user, then invalidation is forced
-//   if a privilege has been granted to public, add a UserObjectPublicKey
-//      if a privilege is revoked from public, then invalidation is forced
-//   if a privilege has been granted directly to an object, add UserObjectKey
-//      if the privilege is revoked from the user, then invalidation is forced
-//   If a privilege has not been granted to an object, but is has been granted
-//      to a role, add a RoleObjectKey
+//   if a privilege has been granted to public, 
+//     add UserObjectPublicKey
+//       invalidation is enforced when priv is revoked from public
+//   if a privilege has been granted on a column of an object to a user:
+//     add UserColumnKey
+//       invalidation is enforced when and column priv is revoked from the user
+//   if a privilege has been granted on a column of an object to a role:
+//      add to ColumnRoleKeys
+//        invalidation is enforced when any priv is revoked from one of these roles
+//        or when one of these roles is revoked from the user.   
+//   if a privilege has been granted directly on an object to a user: 
+//     add UserObjectKey 
+//       invalidation is enforced when priv is revoked from the user
+//   if a privilege has been granted directly on an object to a role:
+//     add an entry to ObjectRoleKeys 
+//       invalidation is enforced when priv is revoked from one of these roles,
+//       or when one of these roles is revoked from user
 //
-//   So if the same privilege has been granted directly to the user and via
-//   a role granted to the user, we only add a UserObjectKey
 // ****************************************************************************
 void RelRoot::findKeyAndInsertInOutputList( ComSecurityKeySet KeysForTab
                                           , const uint32_t userHashValue
                                           , const PrivType which
+                                          , BindWA* bindWA
                                           )
 {
    // If no keys associated with object, just return
    if (KeysForTab.entries() == 0)
      return;
 
+   ComSecurityKey * UserColumnKey = NULL;
+   ComSecurityKey * RoleColumnKey = NULL;
    ComSecurityKey * UserObjectKey = NULL;
    ComSecurityKey * RoleObjectKey = NULL;
    ComSecurityKey * UserObjectPublicKey = NULL;
-   ComSecurityKey * RoleUserKey = NULL;
    
    // These may be implemented at a later time
    ComSecurityKey * UserSchemaKey = NULL; //privs granted at schema level to user
-   ComSecurityKey * RoleSchemaKey = NULL; //privs granted at schema level to role
 
    // Get action type for UserObjectKey based on the privilege (which)
    // so if (which) is SELECT, then the objectActionType is COM_QI_OBJECT_SELECT
    ComSecurityKey  dummyKey;
+   ComQIActionType columnActionType = 
+                   dummyKey.convertBitmapToQIActionType ( which, ComSecurityKey::OBJECT_IS_COLUMN );
    ComQIActionType objectActionType =
                    dummyKey.convertBitmapToQIActionType ( which, ComSecurityKey::OBJECT_IS_OBJECT );
 
    ComSecurityKey * thisKey = NULL;
 
+   // With column level privileges, the user may get privileges from various
+   // roles.  Today, we add all roles that may hold the requested privilege.
+   // If we ever fully support invalidation keys at the column level, then only 
+   // roles that are required to run the query should be added. 
+   // For example, 
+   //  user gets select on table1: col1, col2 from role1
+   //  user gets select on table1: col3, col4 from role2
+   //  If the query performs a select for col1, then only changes to role1 are relevant
+   //  Today, we include both role1 and role2 
+   //  Therefore, if role2 is revoked from the user, invalidation is unnecessarily enforced
+   ComSecurityKeySet ColumnRoleKeys(bindWA->wHeap());
+   ComSecurityKeySet ObjectRoleKeys(bindWA->wHeap());
+   ComSecurityKeySet SchemaRoleKeys(bindWA->wHeap());
+
    // NOTE: hashValueOfPublic will be the same for all keys, so we generate it only once.
    uint32_t hashValueOfPublic = ComSecurityKey::SPECIAL_OBJECT_HASH;
 
@@ -7294,33 +7324,38 @@ void RelRoot::findKeyAndInsertInOutputList( ComSecurityKeySet KeysForTab
    {
       thisKey = &(KeysForTab[ii]);
   
-      // See if the key is object related
-      if ( thisKey->getSecurityKeyType() == objectActionType )
+      // See if the key is column related
+      if ( thisKey->getSecurityKeyType() == columnActionType )
       {
          if ( thisKey->getSubjectHashValue() == userHashValue )
          {
             // Found a security key for the objectActionType
-            if ( ! UserObjectKey ) 
-               UserObjectKey = thisKey;
+            if ( ! UserColumnKey )
+               UserColumnKey = thisKey;
          }
          // Found a security key for a role associated with the user
-         else
+         else if (qiSubjectMatchesRole(thisKey->getSubjectHashValue()))
          {
-            if ( ! RoleObjectKey )
-               RoleObjectKey = thisKey;
+            ColumnRoleKeys.insert(*thisKey);
          }
       }
-     
-      // See if the security key is role related
-      else if (thisKey->getSecurityKeyType() == COM_QI_USER_GRANT_ROLE) 
+
+      // See if the key is object related
+      else if ( thisKey->getSecurityKeyType() == objectActionType )
       {
          if ( thisKey->getSubjectHashValue() == userHashValue )
          {
-            if (! RoleUserKey ) 
-               RoleUserKey = thisKey;
+            // Found a security key for the objectActionType
+            if ( ! UserObjectKey ) 
+               UserObjectKey = thisKey;
+         }
+         // Found a security key for a role associated with the user
+         else if (qiSubjectMatchesRole(thisKey->getSubjectHashValue()))
+         {
+            ObjectRoleKeys.insert(*thisKey);
          }
       }
-
+     
       else if (thisKey->getSecurityKeyType() == COM_QI_USER_GRANT_SPECIAL_ROLE)
       {
          if (thisKey->getObjectHashValue() == hashValueOfPublic )
@@ -7333,16 +7368,39 @@ void RelRoot::findKeyAndInsertInOutputList( ComSecurityKeySet KeysForTab
       else {;} // Not right action type, just continue traversing.
    }
 
-   // Determine best key, UserObjectKeys are better than RoleObjectKeys
-   ComSecurityKey * BestKey = (UserObjectKey) ? UserObjectKey : RoleObjectKey;
+   // Determine best key (fewest invalidations required)
 
-   if ( BestKey != NULL)
-      securityKeySet_.insert(*BestKey);
+   // For now, always add column invalidation keys.  Once full integration of
+   // column privileges is implemented, then this code changes
+   if (UserColumnKey)
+     securityKeySet_.insert(*UserColumnKey);
+   else if (ColumnRoleKeys.entries() > 0)
+   {
+      for (int j = 0; j < ColumnRoleKeys.entries(); j++)
+      {
+        securityKeySet_.insert(ColumnRoleKeys[j]);
+
+        // add a key in case the role is revoked from the user
+        ComSecurityKey roleKey(userHashValue, ColumnRoleKeys[j].getSubjectHashValue());
+        securityKeySet_.insert(roleKey);
+      }
+   }
 
-   // Add RoleUserKey if priv comes from role - handles revoke role from user
-   if (BestKey == RoleObjectKey)
-      if ( RoleUserKey )
-         securityKeySet_.insert(*RoleUserKey );
+   //   UserObjectKeys are better than ObjectRoleKeys
+   if (UserObjectKey)
+      securityKeySet_.insert(*UserObjectKey);
+
+   else if (ObjectRoleKeys.entries() > 0)
+   {
+      for (int j = 0; j < ObjectRoleKeys.entries(); j++)
+      {
+        securityKeySet_.insert(ObjectRoleKeys[j]);
+
+        // add a key in case the role is revoked from the user
+        ComSecurityKey roleKey(userHashValue, ObjectRoleKeys[j].getSubjectHashValue());
+        securityKeySet_.insert(roleKey);
+      }
+   }
 
    // Add public if it exists - handles revoke public from user
    if ( UserObjectPublicKey != NULL )

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/optimizer/NARoutine.cpp
----------------------------------------------------------------------
diff --git a/core/sql/optimizer/NARoutine.cpp b/core/sql/optimizer/NARoutine.cpp
index 905e374..49df34f 100644
--- a/core/sql/optimizer/NARoutine.cpp
+++ b/core/sql/optimizer/NARoutine.cpp
@@ -96,7 +96,7 @@ NARoutine::NARoutine (CollHeap *heap)
     , hasOutParams_           (FALSE)
     , redefTime_              (0)
     , lastUsedTime_           (0)
-    , routineSecKeySet_       (heap)
+    , secKeySet_              (heap)
     , passThruDataNumEntries_ (0)
     , passThruData_           (NULL)
     , passThruDataSize_       (NULL)
@@ -117,6 +117,7 @@ NARoutine::NARoutine (CollHeap *heap)
     , objectOwner_            (0)
     , schemaOwner_            (0)
     , privInfo_               (NULL)
+    , privDescs_               (NULL)
     , heap_                   (heap)
 {
 }
@@ -154,7 +155,7 @@ NARoutine::NARoutine (  const QualifiedName &name
     , hasOutParams_           (FALSE)
     , redefTime_              (0)
     , lastUsedTime_           (0)
-    , routineSecKeySet_       (heap)
+    , secKeySet_              (heap)
     , passThruDataNumEntries_ (0)
     , passThruData_           (NULL)
     , passThruDataSize_       (NULL)
@@ -175,6 +176,7 @@ NARoutine::NARoutine (  const QualifiedName &name
     , objectOwner_            (0)
     , schemaOwner_            (0)
     , privInfo_               (NULL)
+    , privDescs_               (NULL)
     , heap_(heap)
 {
   CollIndex colCount = 0;
@@ -285,7 +287,7 @@ NARoutine::NARoutine (const NARoutine &old, CollHeap *h)
     , hasOutParams_           (old.hasOutParams_)
     , redefTime_              (old.redefTime_)
     , lastUsedTime_           (old.lastUsedTime_)
-    , routineSecKeySet_       (h)
+    , secKeySet_              (h)
     , isUniversal_            (old.isUniversal_)
     , executionMode_          (old.getExecutionMode())
     , objectUID_              (old.objectUID_)
@@ -307,6 +309,7 @@ NARoutine::NARoutine (const NARoutine &old, CollHeap *h)
     , objectOwner_            (0)
     , schemaOwner_            (0) 
     , privInfo_               (NULL)
+    , privDescs_               (NULL)
     , heap_                   (h)
 {
   extRoutineName_ = new (h) ExtendedQualName(*old.extRoutineName_, h);
@@ -335,7 +338,7 @@ NARoutine::NARoutine (const NARoutine &old, CollHeap *h)
     }
   }
 
-  routineSecKeySet_ = old.routineSecKeySet_;
+  secKeySet_ = old.secKeySet_;
 
   heapSize_ = (h ? h->getTotalSize() : 0);
 }
@@ -368,7 +371,7 @@ NARoutine::NARoutine(const QualifiedName   &name,
     , hasOutParams_           (FALSE)
     , redefTime_              (0)  //TODO
     , lastUsedTime_           (0)
-    , routineSecKeySet_       (heap)
+    , secKeySet_              (heap)
     , passThruDataNumEntries_ (0)
     , passThruData_           (NULL)
     , passThruDataSize_       (0)
@@ -388,6 +391,7 @@ NARoutine::NARoutine(const QualifiedName   &name,
     , objectOwner_            (routine_desc->routineDesc()->owner)
     , schemaOwner_            (routine_desc->routineDesc()->schemaOwner)
     , privInfo_               (NULL)
+    , privDescs_               (NULL)
     , heap_(heap)
 {
   char parallelism[5];
@@ -602,7 +606,7 @@ NARoutine::NARoutine(const QualifiedName   &name,
     }
     
      
-  getPrivileges(routine_desc->routineDesc()->priv_desc);
+  getPrivileges(routine_desc->routineDesc()->priv_desc, bindWA);
 
   heapSize_ = (heap ? heap->getTotalSize() : 0);
 }
@@ -645,7 +649,7 @@ void NARoutine::setSasFormatWidth(NAString &width)
 // If authorization is enabled, set privs based on the passed in priv_desc
 // and set up query invalidation (security) keys for the routine.
 // ----------------------------------------------------------------------------
-void NARoutine::getPrivileges(TrafDesc *priv_desc)
+void NARoutine::getPrivileges(TrafDesc *priv_desc, BindWA *bindWA)
 {
   if ( !CmpCommon::context()->isAuthorizationEnabled() || ComUser::isRootUserID())
   {
@@ -677,52 +681,58 @@ void NARoutine::getPrivileges(TrafDesc *priv_desc)
                                 COM_STORED_PROCEDURE_OBJECT :
                                 COM_USER_DEFINED_ROUTINE_OBJECT);
 
-    std::vector <ComSecurityKey *>* secKeyVec = new(heap_) std::vector<ComSecurityKey *>;
-    if (privInterface.getPrivileges(objectUID_, objectType,
-                                    ComUser::getCurrentUser(), 
-                                   *privInfo_, secKeyVec) != STATUS_GOOD)
-    {
-      NADELETE(privInfo_, PrivMgrUserPrivs, heap_);
-      privInfo_ = NULL;
-    }
-
+    // get all privileges granted to routine object
+    privDescs_ = new (heap_) PrivMgrDescList(heap_); //initialize empty list
+    PrivStatus privStatus = privInterface.getPrivileges(objectUID_, objectType, *privDescs_);
     cmpSBD.switchBackCompiler();
 
-    if (privInfo_)
-    {
-      for (std::vector<ComSecurityKey*>::iterator iter = secKeyVec->begin();
-           iter != secKeyVec->end();
-           iter++)
-      {
-        // Insertion of the dereferenced pointer results in NASet making
-        // a copy of the object, and then we delete the original.
-        routineSecKeySet_.insert(**iter);
-          delete *iter;
-      }
-    }
+    if (privStatus == STATUS_ERROR)
+      return;
   }
   else
   {
-    // get roles granted to current user 
-    // SQL_EXEC_GetRoleList returns the list of roles from the CliContext
-    std::vector<int32_t> myRoles;
-    Int32 numRoles = 0;
-    Int32 *roleIDs = NULL;
-    if (SQL_EXEC_GetRoleList(numRoles, roleIDs) < 0)
+    // convert priv_desc (TrafPrivDesc) in privDescs_ member
+    privDescs_ = new (heap_) PrivMgrDescList(heap_); //initialize empty list
+    TrafDesc *priv_grantees_desc = priv_desc->privDesc()->privGrantees;
+    while (priv_grantees_desc)
     {
-      *CmpCommon::diags() << DgSqlCode(-1034);
-      return;
-    }
+      PrivMgrDesc *privs = new (heap_) PrivMgrDesc(priv_grantees_desc->privGranteeDesc()->grantee);
+      TrafDesc *objectPrivs = priv_grantees_desc->privGranteeDesc()->objectBitmap;
+
+      PrivMgrCoreDesc objectDesc(objectPrivs->privBitmapDesc()->privBitmap,
+                                 objectPrivs->privBitmapDesc()->privWGOBitmap);
 
-    // At this time we should have at least one entry in roleIDs (PUBLIC_USER)
-    CMPASSERT (roleIDs && numRoles > 0);
+      TrafDesc *priv_grantee_desc = priv_grantees_desc->privGranteeDesc();
+      TrafDesc *columnPrivs = priv_grantee_desc->privGranteeDesc()->columnBitmaps;
+      NAList<PrivMgrCoreDesc> columnDescs(NULL);
+      while (columnPrivs)
+      {
+        PrivMgrCoreDesc columnDesc(columnPrivs->privBitmapDesc()->privBitmap,
+                                   columnPrivs->privBitmapDesc()->privWGOBitmap,
+                                   columnPrivs->privBitmapDesc()->columnOrdinal);
+        columnDescs.insert(columnDesc);
+        columnPrivs = columnPrivs->next;
+      }
 
-    for (Int32 i = 0; i < numRoles; i++)
-      myRoles.push_back(roleIDs[i]);
+      privs->setTablePrivs(objectDesc);
+      privs->setColumnPrivs(columnDescs);
+      privs->setHasPublicPriv(ComUser::isPublicUserID(privs->getGrantee()));
 
-    privInfo_ = new (heap_) PrivMgrUserPrivs;
-    privInfo_->initUserPrivs(myRoles, priv_desc, ComUser::getCurrentUser(),objectUID_, routineSecKeySet_);
+      privDescs_->insert(privs);
+      priv_grantees_desc = priv_grantees_desc->next;
+    }
   }
+
+  // get roles granted to current user 
+  NAList <Int32> roleIDs(heap_);
+  NAList <Int32> grantees(heap_);
+  if (ComUser::getCurrentUserRoles(roleIDs, grantees) != 0)
+    return;
+
+  // set up privileges for current user
+  privInfo_ = new (heap_) PrivMgrUserPrivs;
+  privInfo_->initUserPrivs(roleIDs, privDescs_, ComUser::getCurrentUser(),
+                           objectUID_, &secKeySet_);
 }
 
 ULng32 NARoutineDBKey::hash() const

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/optimizer/NARoutine.h
----------------------------------------------------------------------
diff --git a/core/sql/optimizer/NARoutine.h b/core/sql/optimizer/NARoutine.h
index 65aa473..0ffc83b 100644
--- a/core/sql/optimizer/NARoutine.h
+++ b/core/sql/optimizer/NARoutine.h
@@ -145,7 +145,7 @@ public:
   inline const ComString        &getSignature()            const { return signature_; }
   inline const ComObjectName    &getLibrarySqlName()       const { return librarySqlName_; }
   inline const QualifiedName    &getSqlName()              const { return name_; }  
-  inline       ComSecurityKeySet getSecKeySet()                  { return routineSecKeySet_ ; }
+  inline       ComSecurityKeySet getSecKeySet()                  { return secKeySet_ ; }
   inline const Int64             getRoutineID()            const { return objectUID_; }
   inline const Int32              getStateAreaSize()        const { return stateAreaSize_; }
   inline const NAString         &getDllName()              const { return dllName_; }
@@ -174,6 +174,7 @@ public:
   inline Int32                        getActionPosition() const { return actionPosition_; }
 
   inline PrivMgrUserPrivs *              getPrivInfo()    const { return privInfo_; }
+  inline PrivMgrDescList  *              getPrivDescs()   const { return privDescs_; }
   inline Int32                           getObjectOwner() const { return objectOwner_; }
   inline Int32                           getSchemaOwner() const { return schemaOwner_; }
 
@@ -205,7 +206,9 @@ public:
   inline NABoolean hasResultSets()        const { return (maxResults_ > 0); }
 
 
-  void getPrivileges(TrafDesc * priv_desc);
+  void setPrivInfo(PrivMgrUserPrivs *privInfo) { privInfo_ = privInfo; }
+  void setPrivDescs(PrivMgrDescList *privDescs) { privDescs_ = privDescs; }
+  void getPrivileges(TrafDesc * priv_desc, BindWA * bindWA);
 
   // -------------------------------------------------------------------
   // Standard operators
@@ -258,7 +261,6 @@ private:
   NABoolean            isExtraCall_;
   NABoolean            hasOutParams_;
 
-  ComSecurityKeySet    routineSecKeySet_ ;
 
   Int64                objectUID_;
   NABoolean            isUniversal_;
@@ -283,7 +285,10 @@ private:
   COM_VERSION          schemaVersionOfRoutine_;
   Int32                objectOwner_;
   Int32                schemaOwner_;
+
+  PrivMgrDescList     *privDescs_;
   PrivMgrUserPrivs    *privInfo_;
+  ComSecurityKeySet    secKeySet_ ;
 
 };
 

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/optimizer/NATable.cpp
----------------------------------------------------------------------
diff --git a/core/sql/optimizer/NATable.cpp b/core/sql/optimizer/NATable.cpp
index 2d13bc2..0f282f6 100644
--- a/core/sql/optimizer/NATable.cpp
+++ b/core/sql/optimizer/NATable.cpp
@@ -4981,6 +4981,7 @@ NABoolean NATable::fetchObjectUIDForNativeTable(const CorrName& corrName,
      hiveTableId_(-1),
      tableDesc_(inTableDesc),
      privInfo_(NULL),
+     privDescs_(NULL),
      secKeySet_(heap),
      newColumns_(heap),
      snapshotName_(NULL),
@@ -5713,6 +5714,7 @@ NATable::NATable(BindWA *bindWA,
        tableDesc_(NULL),
        secKeySet_(heap),
        privInfo_(NULL),
+       privDescs_(NULL),
        newColumns_(heap),
        snapshotName_(NULL),
        allColFams_(heap)
@@ -6792,10 +6794,12 @@ void NATable::getPrivileges(TrafDesc * priv_desc)
     return;
   }
 
+  Int32 currentUser (ComUser::getCurrentUser());
+
   // Generally, if the current user is the object owner, then the automatically
   // have all privs.  However, if this is a shared schema then views can be
   // owned by the current user but not have all privs
-  if (ComUser::getCurrentUser() == owner_ && objectType_ != COM_VIEW_OBJECT)
+  if (currentUser == owner_ && objectType_ != COM_VIEW_OBJECT)
   {
     privInfo_ = new(heap_) PrivMgrUserPrivs;
     privInfo_->setOwnerDefaultPrivs();
@@ -6805,46 +6809,94 @@ void NATable::getPrivileges(TrafDesc * priv_desc)
   ComSecurityKeySet secKeyVec(heap_);
   if (priv_desc == NULL)
   {
-    if (isHiveTable() || isHbaseCellTable() ||
-        isHbaseRowTable() || isHbaseMapTable())
+    if (!isSeabaseTable())
       readPrivileges();
     else
+    {
       privInfo_ = NULL;
-    return;
+      return;
+    }
   }
   else
   {
     // get roles granted to current user 
-    // SQL_EXEC_GetRoleList returns the list of roles from the CliContext
-    std::vector<int32_t> myRoles;
-    Int32 numRoles = 0;
-    Int32 *roleIDs = NULL;
-    if (SQL_EXEC_GetRoleList(numRoles, roleIDs) < 0)
-    {
-      *CmpCommon::diags() << DgSqlCode(-1034);
+    NAList <Int32> roleIDs(heap_);
+    if (ComUser::getCurrentUserRoles(roleIDs) != 0)
       return;
-    }
+
+    Int32 numRoles = roleIDs.entries();
 
     // At this time we should have at least one entry in roleIDs (PUBLIC_USER)
-    CMPASSERT (roleIDs && numRoles > 0);
+    CMPASSERT (numRoles > 0);
+
+    // (PrivMgrUserPrivs)  privInfo_ are privs for the current user
+    // (PrivMgrDescList)   privDescs_ are all privs for the object
+    // (TrafPrivDesc)      priv_desc are all object privs in TrafDesc form
+    //                     created by CmpSeabaseDDL::getSeabasePrivInfo
+    //                     before the NATable entry is constructed
+    // (ComSecurityKeySet) secKeySet_ are the qi keys for the current user
+
+    // Convert priv_desc into a list of PrivMgrDesc (privDescs_)
+    privDescs_ = new (heap_) PrivMgrDescList(heap_); //initialize empty list
+    TrafDesc *priv_grantees_desc = priv_desc->privDesc()->privGrantees;
+    while (priv_grantees_desc)
+    {
+      PrivMgrDesc *privs = new (heap_) PrivMgrDesc(priv_grantees_desc->privGranteeDesc()->grantee);
+      TrafDesc *objectPrivs = priv_grantees_desc->privGranteeDesc()->objectBitmap;
+      PrivMgrCoreDesc objectDesc(objectPrivs->privBitmapDesc()->privBitmap,
+                                 objectPrivs->privBitmapDesc()->privWGOBitmap);
+
+      TrafDesc *priv_grantee_desc = priv_grantees_desc->privGranteeDesc();
+      TrafDesc *columnPrivs = priv_grantee_desc->privGranteeDesc()->columnBitmaps;
+      NAList<PrivMgrCoreDesc> columnDescs(heap_);
+      while (columnPrivs)
+      {
+        PrivMgrCoreDesc columnDesc(columnPrivs->privBitmapDesc()->privBitmap,
+                                   columnPrivs->privBitmapDesc()->privWGOBitmap,
+                                   columnPrivs->privBitmapDesc()->columnOrdinal);
+        columnDescs.insert(columnDesc);
+        columnPrivs = columnPrivs->next;
+      }
 
-    for (Int32 i = 0; i < numRoles; i++)
-      myRoles.push_back(roleIDs[i]);
+      privs->setTablePrivs(objectDesc);
+      privs->setColumnPrivs(columnDescs);
 
-    // Build privInfo_ based on the priv_desc
-    privInfo_ = new(heap_) PrivMgrUserPrivs;
-    privInfo_->initUserPrivs(myRoles, priv_desc, 
-                             ComUser::getCurrentUser(), 
-                             objectUID_.get_value(), secKeySet_);
-  }
+      privs->setHasPublicPriv(ComUser::isPublicUserID(privs->getGrantee()));
+
+      privDescs_->insert(privs);
+      priv_grantees_desc = priv_grantees_desc->next;
+    }
 
+    // Generate privInfo_ and secKeySet_ for current user from privDescs_
+    privInfo_ = new(heap_) PrivMgrUserPrivs;
+    privInfo_->initUserPrivs(roleIDs,
+                             privDescs_,
+                             currentUser,
+                             objectUID_.get_value(),
+                             &secKeySet_);
 
-  if (privInfo_ == NULL)
+    if (privInfo_ == NULL)
     {
-      *CmpCommon::diags() << DgSqlCode(-1034);
+      if (!CmpCommon::diags()->containsError(-1034))
+        *CmpCommon::diags() << DgSqlCode(-1034);
       return;
     }
+  }
 
+  // log privileges enabled for table
+  Int32 len = 500;
+  char msg[len];
+  std::string privDetails = privInfo_->print();
+  snprintf(msg, len, "NATable::getPrivileges (list of all privileges on object), user: %s obj %s, %s",
+          ComUser::getCurrentUsername(),
+          qualifiedName_.getExtendedQualifiedNameAsString().data(),
+          privDetails.c_str());
+  QRLogger::log(CAT_SQL_EXE, LL_DEBUG, "%s", msg);
+  if (getenv("DBUSER_DEBUG"))
+  {
+    printf("[DBUSER:%d] %s\n", (int) getpid(), msg);
+    fflush(stdout);
+  }
 }
 
 // Call privilege manager to get privileges and security keys
@@ -6879,8 +6931,10 @@ void NATable::readPrivileges ()
   std::vector <ComSecurityKey *> secKeyVec;
 
   if (testError || (STATUS_GOOD !=
-                    privInterface.getPrivileges((NATable *)this,
-                                                ComUser::getCurrentUser(), *privInfo_, &secKeyVec)))
+    privInterface.getPrivileges((NATable *)this,
+                                 ComUser::getCurrentUser(),
+                                 *privInfo_, &secKeySet_)))
+
     {
       if (testError)
 #ifndef NDEBUG

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/optimizer/NATable.h
----------------------------------------------------------------------
diff --git a/core/sql/optimizer/NATable.h b/core/sql/optimizer/NATable.h
index 746142f..f28230c 100644
--- a/core/sql/optimizer/NATable.h
+++ b/core/sql/optimizer/NATable.h
@@ -679,8 +679,6 @@ public:
   NABoolean isToBeRemovedFromCacheBNC() const   /* BNC = Before Next Compilation attempt */
   {  return( (flags_ & REMOVE_FROM_CACHE_BNC) != 0 ); }
 
-  ComSecurityKeySet getSecKeySet() { return secKeySet_ ; }
-
   void setDroppableTable( NABoolean value )
   {  value ? flags_ |= DROPPABLE : flags_ &= ~DROPPABLE; }
 
@@ -917,7 +915,12 @@ public:
   NAMemory* getHeap() const { return heap_; }
   NATableHeapType getHeapType() { return heapType_; }
 
-  PrivMgrUserPrivs* getPrivInfo() const { return privInfo_; }
+  // Privilege related operations
+  PrivMgrDescList  *getPrivDescs() { return privDescs_; }
+  PrivMgrUserPrivs *getPrivInfo() const { return privInfo_; }
+  void setPrivInfo(PrivMgrUserPrivs *privInfo){ privInfo_ = privInfo; }
+  ComSecurityKeySet getSecKeySet() { return secKeySet_ ; }
+  void setSecKeySet(ComSecurityKeySet secKeySet) { secKeySet_ = secKeySet; }
 
   // Get the part of the row size that is computable with info we have available
   // without accessing HBase. The result is passed to estimateHBaseRowCount(),
@@ -1208,8 +1211,6 @@ private:
 
   char *snapshotName_;
 
-  ComSecurityKeySet secKeySet_ ;
-
   TrafDesc *partnsDesc_;
 
   TrafDesc *tableDesc_;
@@ -1242,8 +1243,14 @@ private:
   Int32 hiveDefaultStringLen_;  // in bytes
   Int32 hiveTableId_;
   
-  // Object containing info on all privileges the current user has for this table.
-  PrivMgrUserPrivs* privInfo_;
+  // Privilege information for the object
+  //   privDescs_ is the list of all grants on the object
+  //   privInfo_ are the privs for the current user
+  //   secKeySet_ are the security keys for the current user
+  PrivMgrDescList  *privDescs_;
+  PrivMgrUserPrivs *privInfo_;
+  ComSecurityKeySet secKeySet_ ;
+
   // While creating the index keys, the NAColumn from colArray_
   // is not used in all cases. Sometimes, a new NAColumn is 
   // constructured from the NAColumn. The variable below

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/optimizer/RelMisc.h
----------------------------------------------------------------------
diff --git a/core/sql/optimizer/RelMisc.h b/core/sql/optimizer/RelMisc.h
index 9275cac..6b03b21 100644
--- a/core/sql/optimizer/RelMisc.h
+++ b/core/sql/optimizer/RelMisc.h
@@ -364,7 +364,8 @@ public:
   NABoolean checkPrivileges(BindWA* bindWA);
   void findKeyAndInsertInOutputList( ComSecurityKeySet KeysForTab
                                    , const uint32_t userHashValue
-                                   , const PrivType which );
+                                   , const PrivType which
+                                   , BindWA* bindWA );
 
   //++ MVs
   NABoolean hasMvBindContext() const;

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/regress/privs1/EXPECTED120
----------------------------------------------------------------------
diff --git a/core/sql/regress/privs1/EXPECTED120 b/core/sql/regress/privs1/EXPECTED120
index 13d19fe..45713b9 100644
--- a/core/sql/regress/privs1/EXPECTED120
+++ b/core/sql/regress/privs1/EXPECTED120
@@ -583,11 +583,13 @@ End of MXCI Session
 >>--   AR - role involved, check query plans that rely on roles during revoke
 >>log;
 Query_Invalidation_Keys explain output for select_games, select_teams, insert_teams, update_teams, select_players, select_standings: 
-Query_Invalidation_Keys{,,OS}{,,UR}
+Query_Invalidation_Keys{,,CS}{,,
+UR}{,,CS}{,
+,UR}
 Query_Invalidation_Keys{,,OS}
 Query_Invalidation_Keys{,,OI}{,,UR}
 Query_Invalidation_Keys{,,OS}{,,
-OU}{,,UR}
+CU}{,,UR}
 Query_Invalidation_Keys{,,OS}
 Query_Invalidation_Keys{,,OS}{,,
 OG}{,,UR}
@@ -799,9 +801,13 @@ SQL_USER3
 
 End of MXCI Session
 
->>-- still have privilege
+>>-- still have privilege but recompile because of revoke on t120_role2
 >>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           
 -----------  --------------------
 
@@ -1274,7 +1280,8 @@ End of MXCI Session
 --- SQL command prepared.
 >>log;
 Query_Invalidation_Keys explain output for select_stats: 
-Query_Invalidation_Keys{,,OS}{,,UZ}
+Query_Invalidation_Keys{,,CS}{,,
+UR}{,,UZ}
 >>shecho"Query_Invalidation_Keysexplainoutputforselect_stats:">>LOG;
 >>
 >>execute select_stats;

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/regress/privs1/TEST120
----------------------------------------------------------------------
diff --git a/core/sql/regress/privs1/TEST120 b/core/sql/regress/privs1/TEST120
index 384dee0..632202c 100755
--- a/core/sql/regress/privs1/TEST120
+++ b/core/sql/regress/privs1/TEST120
@@ -251,7 +251,7 @@ execute select_teams;
 
 -- revoke insert, delete privilege from t120role2
 sh sqlci -i "TEST120(revoke_t120role2p)" -u sql_user3;
--- still have privilege
+-- still have privilege but recompile because of revoke on t120_role2
 execute select_teams;
 -- no longer has privilege (4481) and query attempted recompilation
 execute insert_teams;

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/regress/privs2/EXPECTED129
----------------------------------------------------------------------
diff --git a/core/sql/regress/privs2/EXPECTED129 b/core/sql/regress/privs2/EXPECTED129
index c844a4a..d6ef9e6 100644
--- a/core/sql/regress/privs2/EXPECTED129
+++ b/core/sql/regress/privs2/EXPECTED129
@@ -222,6 +222,25 @@ CREATE TABLE TRAFODION.US4.T4
 End of MXCI Session
 
 >>-- As user1, should fail
+>>get privileges for user sql_user1;
+
+Privileges for User SQL_USER1
+=============================
+
+------E    TRAFODION."_LIBMGR_".EVENT_LOG_READER
+------E    TRAFODION."_LIBMGR_".JDBC
+---U---    TRAFODION.US4.T1
+S------    TRAFODION.US4.T1 <Column> COL3
+S------    TRAFODION.US4.T129_A
+S------    TRAFODION.US4.T129_STARTER
+SI-----    TRAFODION.US4.T2
+S------    TRAFODION.US4.V1
+-I-U---    TRAFODION.US4.V1 <Column> VC1
+
+=======================
+ 9 row(s) returned
+
+--- SQL operation complete.
 >>select * from us4.t1 ;
 
 *** ERROR[4481] The user does not have SELECT privilege on table or view TRAFODION.US4.T1(columns: COL1, COL2).
@@ -284,36 +303,43 @@ VC1          VC2          VC3
 
 --- 1 row(s) inserted.
 >>
->>delete all from table(querycache()) ;
-
-*** ERROR[15001] A syntax error occurred at or before: 
-delete all from table(querycache()) ;
-                                 ^ (34 characters from start of SQL statement)
-
-*** ERROR[8822] The statement was not prepared.
-
->>delete all from table(natablecache());
+>>delete all from table(querycache('user', 'local')) ;
 
 --- 0 row(s) deleted.
->>select * from table(querycacheentries());
-
-*** ERROR[15001] A syntax error occurred at or before: 
-select * from table(querycacheentries());
-                                      ^ (39 characters from start of SQL statement)
-
-*** ERROR[8822] The statement was not prepared.
+>>select count(*) from table(querycacheentries('user', 'local'));
 
->>select * from table(natablecache()) ;
+(EXPR)              
+--------------------
 
-*** ERROR[15001] A syntax error occurred at or before: 
-select * from table(natablecache()) ;
-                                 ^ (34 characters from start of SQL statement)
+                   0
 
-*** ERROR[8822] The statement was not prepared.
+--- 1 row(s) selected.
+>>delete all from table (natablecache());
 
+--- 0 row(s) deleted.
+>>--select context, num_entries from table(natablecache('all','local')) ;
 >>
 >>log;
 >>-- As user1, should fail
+>>get privileges for user sql_user1;
+
+Privileges for User SQL_USER1
+=============================
+
+------E    TRAFODION."_LIBMGR_".EVENT_LOG_READER
+------E    TRAFODION."_LIBMGR_".JDBC
+---U---    TRAFODION.US4.T1
+S------    TRAFODION.US4.T1 <Column> COL3
+S------    TRAFODION.US4.T129_A
+S------    TRAFODION.US4.T129_STARTER
+SI-----    TRAFODION.US4.T2
+S------    TRAFODION.US4.V1
+-I-U---    TRAFODION.US4.V1 <Column> VC1
+
+=======================
+ 9 row(s) returned
+
+--- SQL operation complete.
 >>select * from us4.t1 ;
 
 *** ERROR[4481] The user does not have SELECT privilege on table or view TRAFODION.US4.T1(columns: COL1, COL2).
@@ -381,36 +407,41 @@ VC1          VC2          VC3
 
 --- 0 row(s) inserted.
 >>
->>delete all from table(querycache()) ;
-
-*** ERROR[15001] A syntax error occurred at or before: 
-delete all from table(querycache()) ;
-                                 ^ (34 characters from start of SQL statement)
-
-*** ERROR[8822] The statement was not prepared.
-
->>delete all from table(natablecache());
+>>delete all from table(querycache('user', 'local')) ;
 
 --- 0 row(s) deleted.
->>select * from table(querycacheentries());
+>>select count(*) from table(querycacheentries('user', 'local'));
 
-*** ERROR[15001] A syntax error occurred at or before: 
-select * from table(querycacheentries());
-                                      ^ (39 characters from start of SQL statement)
-
-*** ERROR[8822] The statement was not prepared.
-
->>select * from table(natablecache()) ;
+(EXPR)              
+--------------------
 
-*** ERROR[15001] A syntax error occurred at or before: 
-select * from table(natablecache()) ;
-                                 ^ (34 characters from start of SQL statement)
+                   0
 
-*** ERROR[8822] The statement was not prepared.
+--- 1 row(s) selected.
+>>delete all from table (natablecache());
 
+--- 0 row(s) deleted.
+>>--select context, num_entries from table(natablecache('all','local')) ;
 >>
 >>log;
 >>-- As user2, should fail
+>>get privileges for user sql_user2;
+
+Privileges for User SQL_USER2
+=============================
+
+------E    TRAFODION."_LIBMGR_".EVENT_LOG_READER
+------E    TRAFODION."_LIBMGR_".JDBC
+S------    TRAFODION.US4.T1
+---U---    TRAFODION.US4.T1 <Column> COL2
+---U---    TRAFODION.US4.T1 <Column> COL3
+SI-----    TRAFODION.US4.T2 <Column> A
+SI-----    TRAFODION.US4.T2 <Column> B
+
+=======================
+ 7 row(s) returned
+
+--- SQL operation complete.
 >>delete from us4.t1 ;
 
 *** ERROR[4481] The user does not have DELETE privilege on table or view TRAFODION.US4.T1.
@@ -460,6 +491,24 @@ COL1         COL2         COL3
 --- 1 row(s) inserted.
 >>log;
 >>-- as user3
+>>get privileges for user sql_user3;
+
+Privileges for User SQL_USER3
+=============================
+
+------E    TRAFODION."_LIBMGR_".EVENT_LOG_READER
+------E    TRAFODION."_LIBMGR_".JDBC
+S--U---    TRAFODION.US4.T1 <Column> COL1
+SI-----    TRAFODION.US4.T2 <Column> A
+S------    TRAFODION.US4.T3 <Column> B
+S------    TRAFODION.US4.T3 <Column> D
+S------    TRAFODION.US4.T4 <Column> F
+S------    TRAFODION.US4.T4 <Column> G
+
+=======================
+ 8 row(s) returned
+
+--- SQL operation complete.
 >>insert into us4.t2(a,b) values (2,2) ;
 
 *** ERROR[4481] The user does not have SELECT privilege on table or view TRAFODION.US4.T2(columns: B).
@@ -600,6 +649,24 @@ X
 >>-- Testing create view based on column-level SELECT
 >>-- as user3
 >>
+>>get privileges for user sql_user3;
+
+Privileges for User SQL_USER3
+=============================
+
+------E    TRAFODION."_LIBMGR_".EVENT_LOG_READER
+------E    TRAFODION."_LIBMGR_".JDBC
+S--U---    TRAFODION.US4.T1 <Column> COL1
+SI-----    TRAFODION.US4.T2 <Column> A
+S------    TRAFODION.US4.T3 <Column> B
+S------    TRAFODION.US4.T3 <Column> D
+S------    TRAFODION.US4.T4 <Column> F
+S------    TRAFODION.US4.T4 <Column> G
+
+=======================
+ 8 row(s) returned
+
+--- SQL operation complete.
 >>set schema cat.us4;
 
 --- SQL operation complete.
@@ -782,6 +849,28 @@ X
 >>set schema us4;
 
 --- SQL operation complete.
+>>get privileges for user sql_user4;
+
+Privileges for User SQL_USER4
+=============================
+
+------E    TRAFODION."_LIBMGR_".EVENT_LOG_READER
+------E    TRAFODION."_LIBMGR_".JDBC
+SIDU-R-    TRAFODION.US4.SB_HISTOGRAMS
+SIDU-R-    TRAFODION.US4.SB_HISTOGRAM_INTERVALS
+SIDU-R-    TRAFODION.US4.SB_PERSISTENT_SAMPLES
+SIDU-R-    TRAFODION.US4.T1
+SIDU-R-    TRAFODION.US4.T129_A
+SIDU-R-    TRAFODION.US4.T129_STARTER
+SIDU-R-    TRAFODION.US4.T2
+SIDU-R-    TRAFODION.US4.T3
+SIDU-R-    TRAFODION.US4.T4
+SIDU-R-    TRAFODION.US4.V1
+
+=======================
+ 12 row(s) returned
+
+--- SQL operation complete.
 >>
 >>grant select (b,d) on t3 to sql_user3 with grant option;
 
@@ -868,6 +957,25 @@ CREATE TABLE TRAFODION.US4.T3
 End of MXCI Session
 
 >>-- as user1
+>>get privileges for user sql_user1;
+
+Privileges for User SQL_USER1
+=============================
+
+------E    TRAFODION."_LIBMGR_".EVENT_LOG_READER
+------E    TRAFODION."_LIBMGR_".JDBC
+---U---    TRAFODION.US4.T1
+S------    TRAFODION.US4.T1 <Column> COL3
+S------    TRAFODION.US4.T129_A
+S------    TRAFODION.US4.T129_STARTER
+SI-----    TRAFODION.US4.T2
+S------    TRAFODION.US4.V1
+-I-U---    TRAFODION.US4.V1 <Column> VC1
+
+=======================
+ 9 row(s) returned
+
+--- SQL operation complete.
 >>
 >>cqd query_cache '0' ;
 
@@ -910,15 +1018,16 @@ End of MXCI Session
 
 --- SQL operation complete.
 >>
->>select case when current_cache_size > 0 then 1 else 0 end from table(natablecache());
+>>select case when current_cache_size > 0 then 1 else 0 end from table(natablecache('all', 'local'));
 
-*** ERROR[15001] A syntax error occurred at or before: 
-select case when current_cache_size > 0 then 1 else 0 end from table(natablecac
-he());
-   ^ (83 characters from start of SQL statement)
+(EXPR)
+------
 
-*** ERROR[8822] The statement was not prepared.
+     0
+     1
+     1
 
+--- 3 row(s) selected.
 >>
 >>--should error but place t129_a in natable cache
 >>prepare s1 from select * from us4.t129_a where c1 > 10;
@@ -928,15 +1037,16 @@ he());
 *** ERROR[8822] The statement was not prepared.
 
 >>
->>select case when current_cache_size > 0 then 1 else 0 end from table(natablecache());
+>>select case when current_cache_size > 0 then 1 else 0 end from table(natablecache('all', 'local'));
 
-*** ERROR[15001] A syntax error occurred at or before: 
-select case when current_cache_size > 0 then 1 else 0 end from table(natablecac
-he());
-   ^ (83 characters from start of SQL statement)
+(EXPR)
+------
 
-*** ERROR[8822] The statement was not prepared.
+     1
+     1
+     1
 
+--- 3 row(s) selected.
 >>
 >>sh  sh runmxci.ksh -i "TEST129(grant1)" -u sql_user4;
 >>grant select on us4.t129_a to sql_user1 ;

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/regress/privs2/TEST129
----------------------------------------------------------------------
diff --git a/core/sql/regress/privs2/TEST129 b/core/sql/regress/privs2/TEST129
index 1cea5c2..9cbe511 100755
--- a/core/sql/regress/privs2/TEST129
+++ b/core/sql/regress/privs2/TEST129
@@ -32,7 +32,6 @@ sh sqlci -i "TEST129(step3)" -u sql_user3;
 sh sqlci -i "TEST129(step4)" -u sql_user3;
 sh sqlci -i "TEST129(step5)" -u sql_user4;
 sh sqlci -i "TEST129(step6)" -u sql_user4;
-sh sqlci -i "TEST129(step7)" -u sql_user4;
 sh sqlci -i "TEST129(invalidate)" -u sql_user1;
 
 obey TEST129(clean_up);
@@ -44,7 +43,6 @@ drop schema us4 cascade;
 
 ?section setup
 cqd SHOWDDL_DISPLAY_PRIVILEGE_GRANTS 'ON';
-cqd CAT_TEST_BOOL 'ON';
 log LOG129 clear;
 log LOG129;
 create schema us4;
@@ -123,9 +121,9 @@ insert into t3 values (1,2,3,4), (5,6,7,8);
 insert into t4 values (11,22,33,44), (55,66,77,88);
 
 ?section step1
-cqd CAT_TEST_BOOL 'ON';
 log LOG129;
 -- As user1, should fail
+get privileges for user sql_user1;
 select * from us4.t1 ;
 delete from us4.t1;
 insert into us4.t1 values (1,1,1);
@@ -140,17 +138,17 @@ insert into us4.t2 values (5,5,5);
 update us4.v1 set vc1 = vc1 ;
 insert into us4.v1(vc1) values (10) ;
 
-delete all from table(querycache()) ;
-delete all from table(natablecache());
-select * from table(querycacheentries());
-select * from table(natablecache()) ;
+delete all from table(querycache('user', 'local')) ;
+select count(*) from table(querycacheentries('user', 'local'));
+delete all from table (natablecache());
+--select context, num_entries from table(natablecache('all','local')) ;
 
 log;
 
 ?section step2
-cqd CAT_TEST_BOOL 'ON';
 log LOG129;
 -- As user2, should fail
+get privileges for user sql_user2;
 delete from us4.t1 ;
 insert into us4.t1 values (1,1,1);
 select * from us4.v1 ;
@@ -164,9 +162,9 @@ insert into us4.t2(a,b) values (1,1);
 log;
 
 ?section step3
-cqd CAT_TEST_BOOL 'ON';
 log LOG129;
 -- as user3
+get privileges for user sql_user3;
 insert into us4.t2(a,b) values (2,2) ;
 update us4.t1 set col2 = col1;
 
@@ -202,11 +200,11 @@ select * from us4.t1 ;
 log;
 
 ?section step4
-cqd CAT_TEST_BOOL 'ON';
 log LOG129;
 -- Testing create view based on column-level SELECT
 -- as user3
 
+get privileges for user sql_user3; 
 set schema cat.us4;
 
 -- View on single table (positive):
@@ -253,12 +251,12 @@ create view v34bh as select b,h from t3,t4;
 log;
 
 ?section step5
-cqd CAT_TEST_BOOL 'ON';
 log LOG129;
 -- Testing revoke for column-level SELECT
 -- as user4
 
 set schema us4;
+get privileges for user sql_user4;
 
 grant select (b,d) on t3 to sql_user3 with grant option;
 grant select (f,g) on t4 to sql_user3;
@@ -278,8 +276,8 @@ revoke grant option for select (b) on t3 from sql_user3 cascade;
 showddl t3;
 
 ?section step6
-cqd CAT_TEST_BOOL 'ON';
 set schema us4;
+get privileges for user sql_user4;
 
 -- Testing other variations of column level
 
@@ -306,9 +304,9 @@ revoke select (a) on t1 from sql_user5 cascade;
 showddl t1;
 
 ?section invalidate
-cqd CAT_TEST_BOOL 'ON';
 log LOG129;
 -- as user1
+get privileges for user sql_user1;
 
 cqd query_cache '0' ;
 cqd metadata_cache_size '0' ;
@@ -325,12 +323,12 @@ prepare s1 from select * from us4.t129_a ;
 
 cqd metadata_cache_size reset ;
 
-select case when current_cache_size > 0 then 1 else 0 end from table(natablecache());
+select case when current_cache_size > 0 then 1 else 0 end from table(natablecache('all', 'local'));
 
 --should error but place t129_a in natable cache
 prepare s1 from select * from us4.t129_a where c1 > 10;
 
-select case when current_cache_size > 0 then 1 else 0 end from table(natablecache());
+select case when current_cache_size > 0 then 1 else 0 end from table(natablecache('all', 'local'));
 
 sh  sh runmxci.ksh -i "TEST129(grant1)" -u sql_user4; 
 
@@ -421,22 +419,18 @@ log ;
 exit ;
 
 ?section revoke1
-cqd CAT_TEST_BOOL 'ON';
 log LOG129;
 revoke select on us4.t129_a from sql_user1 ;
 
 ?section grant1
-cqd CAT_TEST_BOOL 'ON';
 log LOG129;
 grant select on us4.t129_a to sql_user1 ;
 
 ?section grant2
-cqd CAT_TEST_BOOL 'ON';
 log LOG129;
 grant select on us4.t129_a to sql_user2 ;
 
 ?section grant3
-cqd CAT_TEST_BOOL 'ON';
 log LOG129;
 grant select on us4.t129_a to sql_user3 ;
 

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/sqlcomp/CmpSeabaseDDLauth.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/CmpSeabaseDDLauth.cpp b/core/sql/sqlcomp/CmpSeabaseDDLauth.cpp
index 3c9939d..d4a2038 100644
--- a/core/sql/sqlcomp/CmpSeabaseDDLauth.cpp
+++ b/core/sql/sqlcomp/CmpSeabaseDDLauth.cpp
@@ -246,9 +246,24 @@ CmpSeabaseDDLauth::AuthStatus CmpSeabaseDDLauth::getAuthDetails(Int32 authID)
   }
 }
 
+// ----------------------------------------------------------------------------
+// public method:  getRoleIDs
+//
+// Return the list of roles that granted to the passed in authID
+//
+// Input:
+//    authID - the database authorization ID to search for
+//
+//  Output:
+//    A returned parameter:
+//       STATUS_GOOD: list of roles returned
+//       STATUS_NOTFOUND: no roles were granted
+//       STATUS_ERROR: error was returned, diags area populated
+// ----------------------------------------------------------------------------
 CmpSeabaseDDLauth::AuthStatus CmpSeabaseDDLauth::getRoleIDs(
   const Int32 authID,
-  std::vector<int32_t> &roleIDs)
+  std::vector<int32_t> &roleIDs,
+  std::vector<int32_t> &grantees)
 {
   NAString privMgrMDLoc;
   CONCAT_CATSCH(privMgrMDLoc,systemCatalog_.data(),SEABASE_PRIVMGR_SCHEMA);
@@ -257,11 +272,13 @@ CmpSeabaseDDLauth::AuthStatus CmpSeabaseDDLauth::getRoleIDs(
                     std::string(privMgrMDLoc.data()),
                     CmpCommon::diags());
   std::vector<std::string> roleNames;
-  std::vector<int32_t> roleDepths;
+  std::vector<int32_t> grantDepths;
 
-  if (role.fetchRolesForUser(authID,roleNames,roleIDs,roleDepths) == PrivStatus::STATUS_ERROR)
+  if (role.fetchRolesForAuth(authID,roleNames,roleIDs,grantDepths,grantees) == PrivStatus::STATUS_ERROR)
     return STATUS_ERROR;
-  return STATUS_GOOD; 
+
+  assert (roleIDs.size() == grantees.size());
+  return STATUS_GOOD;
 }
 
 // ----------------------------------------------------------------------------
@@ -1820,16 +1837,15 @@ bool CmpSeabaseDDLrole::describe(
       std::vector<std::string> granteeNames;
       std::vector<int32_t> grantDepths;
       std::vector<int32_t> grantorIDs;
-      
-      PrivStatus privStatus = PrivStatus::STATUS_GOOD;
-      
-      privStatus = roles.fetchUsersForRole(getAuthID(),granteeNames,
-                                           grantorIDs,grantDepths);
-      
-      // If no users were granted this role, nothing to do.                                     
+
+
+      PrivStatus privStatus = roles.fetchGranteesForRole(getAuthID() ,granteeNames,
+                                                         grantorIDs,grantDepths);
+
+      // If nobody was granted this role, nothing to do.                                     
       if (privStatus == PrivStatus::STATUS_NOTFOUND || granteeNames.size() == 0)
          return true;
-         
+
       if (privStatus == PrivStatus::STATUS_ERROR)                                   
          SEABASEDDL_INTERNAL_ERROR("Could not fetch users granted role.");
          

http://git-wip-us.apache.org/repos/asf/trafodion/blob/adf2b8f2/core/sql/sqlcomp/CmpSeabaseDDLauth.h
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/CmpSeabaseDDLauth.h b/core/sql/sqlcomp/CmpSeabaseDDLauth.h
index fbfe354..d451fb7 100644
--- a/core/sql/sqlcomp/CmpSeabaseDDLauth.h
+++ b/core/sql/sqlcomp/CmpSeabaseDDLauth.h
@@ -78,7 +78,8 @@ class CmpSeabaseDDLauth
      virtual bool describe       (const NAString &authName, 
                                     NAString &authText);
      AuthStatus   getRoleIDs     (const Int32 authID,
-                                    std::vector<int32_t> &roleIDs);
+                                    std::vector<int32_t> &roleIDs,
+                                    std::vector<int32_t> &granteeIDs);
      NAString     getObjectName  (const std::vector <int64_t> objectUIDs);
 
      // accessors


[3/3] trafodion git commit: Merge [TRAFODION-3218] pr 1723 user still has privilege after user's role revoked

Posted by rm...@apache.org.
Merge [TRAFODION-3218] pr 1723 user still has privilege after user's role revoked


Project: http://git-wip-us.apache.org/repos/asf/trafodion/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafodion/commit/8e38189d
Tree: http://git-wip-us.apache.org/repos/asf/trafodion/tree/8e38189d
Diff: http://git-wip-us.apache.org/repos/asf/trafodion/diff/8e38189d

Branch: refs/heads/master
Commit: 8e38189d43d6abe57f6a2c992ebaeaf79ce92408
Parents: 659f59a adf2b8f
Author: Roberta Marton <ro...@apache.org>
Authored: Wed Oct 24 16:19:42 2018 +0000
Committer: Roberta Marton <ro...@apache.org>
Committed: Wed Oct 24 16:19:42 2018 +0000

----------------------------------------------------------------------
 core/sql/cli/Cli.cpp                            |   7 +-
 core/sql/cli/Cli.h                              |   7 +-
 core/sql/cli/CliExtern.cpp                      |  10 +-
 core/sql/cli/Context.cpp                        |  63 ++++--
 core/sql/cli/Context.h                          |   8 +-
 core/sql/cli/SQLCLIdev.h                        |   5 +-
 core/sql/comexe/ComTdb.h                        |   2 +-
 core/sql/common/ComDistribution.cpp             |   4 +
 core/sql/common/ComSecurityKey.cpp              | 125 +++++++----
 core/sql/common/ComSecurityKey.h                |  16 +-
 core/sql/common/ComSmallDefs.h                  |   9 +
 core/sql/common/ComUser.cpp                     |  62 ++++-
 core/sql/common/ComUser.h                       |   5 +-
 core/sql/executor/ExExeUtilGet.cpp              |   7 +-
 core/sql/generator/Generator.cpp                |  15 +-
 core/sql/optimizer/BindRelExpr.cpp              | 144 ++++++++----
 core/sql/optimizer/NARoutine.cpp                |  96 ++++----
 core/sql/optimizer/NARoutine.h                  |  11 +-
 core/sql/optimizer/NATable.cpp                  | 104 ++++++---
 core/sql/optimizer/NATable.h                    |  21 +-
 core/sql/optimizer/RelMisc.h                    |   3 +-
 core/sql/regress/privs1/EXPECTED120             |  15 +-
 core/sql/regress/privs1/TEST120                 |   2 +-
 core/sql/regress/privs2/EXPECTED129             | 218 +++++++++++++-----
 core/sql/regress/privs2/TEST129                 |  32 ++-
 core/sql/sqlcomp/CmpSeabaseDDLauth.cpp          |  40 +++-
 core/sql/sqlcomp/CmpSeabaseDDLauth.h            |   3 +-
 core/sql/sqlcomp/CmpSeabaseDDLtable.cpp         |  15 +-
 core/sql/sqlcomp/PrivMgr.cpp                    |  37 +++
 core/sql/sqlcomp/PrivMgr.h                      |   5 +
 core/sql/sqlcomp/PrivMgrCommands.cpp            | 124 +++++-----
 core/sql/sqlcomp/PrivMgrCommands.h              |  15 +-
 core/sql/sqlcomp/PrivMgrComponentPrivileges.cpp |  12 +-
 core/sql/sqlcomp/PrivMgrDesc.cpp                |   1 +
 core/sql/sqlcomp/PrivMgrDesc.h                  |  30 +++
 core/sql/sqlcomp/PrivMgrPrivileges.cpp          | 224 ++++++-------------
 core/sql/sqlcomp/PrivMgrPrivileges.h            |  21 +-
 core/sql/sqlcomp/PrivMgrRoles.cpp               |  92 ++++----
 core/sql/sqlcomp/PrivMgrRoles.h                 |  18 +-
 core/sql/sqlcomp/PrivMgrUserPrivs.cpp           | 174 ++++++++------
 core/sql/sqlcomp/PrivMgrUserPrivs.h             |  15 +-
 41 files changed, 1128 insertions(+), 689 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafodion/blob/8e38189d/core/sql/cli/Cli.cpp
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/trafodion/blob/8e38189d/core/sql/optimizer/RelMisc.h
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/trafodion/blob/8e38189d/core/sql/sqlcomp/PrivMgr.cpp
----------------------------------------------------------------------