blob: bd3ce2e468250e381d44a2200a17dd6f86e3092f [file] [log] [blame]
//*****************************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
//*****************************************************************************
// ==========================================================================
// Contains non inline methods in the following classes
// ComSecurityKey
// Contains helper function: qiCheckForInvalidKeys
// ==========================================================================
#include "ComSecurityKey.h"
#include <bitset>
#include <string>
#include <vector>
#include "exp_function.h"
#include "ComDistribution.h"
NABoolean qiCheckForInvalidObject (const Int32 numInvalidationKeys,
const SQL_QIKEY* invalidationKeys,
const Int64 objectUID,
const ComSecurityKeySet objectKeys)
{
NABoolean found = FALSE;
ComQIActionType invalidationKeyType = COM_QI_INVALID_ACTIONTYPE;
// check each invalidation key against objects in NATableDB or NARoutineDB
// cache
for ( Int32 i = 0; i < numInvalidationKeys && !found; i++ )
{
invalidationKeyType = ComQIActionTypeLiteralToEnum( invalidationKeys[i].operation );
// if the object redef time changed and this is the object, remove entry
if (invalidationKeyType == COM_QI_OBJECT_REDEF &&
invalidationKeys[i].ddlObjectUID == objectUID)
found = TRUE;
else
{
// Scan the passed-in object keys to find any that match the
// invalidation key
Int32 numObjectKeys = objectKeys.entries();
for (Int32 j = 0; j < numObjectKeys && !found; j++ )
{
ComSecurityKey keyValue = objectKeys[j];
if ( ( invalidationKeys[i].revokeKey.subject ==
keyValue.getSubjectHashValue() ) &&
( invalidationKeys[i].revokeKey.object ==
keyValue.getObjectHashValue() ) &&
( invalidationKeyType ==
keyValue.getSecurityKeyType() ) )
found = TRUE;
}
}
}
return found;
}
// *****************************************************************************
// ComSecurityKey methods
// *****************************************************************************
// Constructor for privilege grant on a SQL object to an authID
ComSecurityKey::ComSecurityKey(const int32_t subjectUserID,
const int64_t objectUID,
const PrivType which,
const QIType typeOfObject)
:
subjectHash_(0),
objectHash_(0),
actionType_(COM_QI_INVALID_ACTIONTYPE)
{
// Set the type.
actionType_ = convertBitmapToQIActionType(which, typeOfObject);
if (actionType_ != COM_QI_INVALID_ACTIONTYPE)
{
// This is a valid key. Set the subject and object values.
// Authorization ID of the grantee
// Hash value of the authorization ID of the subject
subjectHash_ = generateHash(subjectUserID);
// Hash value of the UID of the object
objectHash_ = generateHash(objectUID);
}
}
ComSecurityKey::ComSecurityKey(
const int32_t subjectUserID,
const int64_t objectUserID,
const QIType typeOfSubject)
:
subjectHash_(0),
objectHash_(0),
actionType_(COM_QI_INVALID_ACTIONTYPE)
{
if (typeOfSubject == SUBJECT_IS_USER)
actionType_ = COM_QI_USER_GRANT_ROLE; // revoke role <object> from <user subject>
else
actionType_ = COM_QI_ROLE_GRANT_ROLE;
if (actionType_ != COM_QI_INVALID_ACTIONTYPE)
{
// This is a valid key. Set the subject and object values.
// Authorization ID of the grantee
// Hash value of the authorization ID of the subject
subjectHash_ = generateHash(subjectUserID);
// Hash value of the authorization ID of the object
objectHash_ = generateHash(objectUserID);
}
}
// Constructor for a special role grant to an authID.
ComSecurityKey::ComSecurityKey(
const int32_t subjectUserID,
const QIType typeOfObject )
:
subjectHash_(0),
objectHash_(0),
actionType_(COM_QI_INVALID_ACTIONTYPE)
{
// Set the values
if (typeOfObject == OBJECT_IS_SPECIAL_ROLE)
{
actionType_ = COM_QI_USER_GRANT_SPECIAL_ROLE;
subjectHash_ = generateHash(subjectUserID);
objectHash_ = SPECIAL_OBJECT_HASH;
}
}
ComSecurityKey::ComSecurityKey() :
subjectHash_(0),
objectHash_(0),
actionType_(COM_QI_INVALID_ACTIONTYPE)
{};
bool ComSecurityKey::operator == (const ComSecurityKey &other) const
{
if((subjectHash_ == other.subjectHash_)&&
(objectHash_ == other.objectHash_) &&
(actionType_ == other.actionType_))
return true;
return false;
}
ComQIActionType ComSecurityKey::convertBitmapToQIActionType (
const PrivType which,
const QIType inputType) const
{
// Convert from a PrivType value into a security key action type
// Note that this does not cover grant or revoke role
// Only converts values that are applicable to query invalidation. Returns an
// invalid value for all other privileges.
// Need to differentiate between schema, object, and column
ComQIActionType result = COM_QI_INVALID_ACTIONTYPE;
switch(which)
{
case SELECT_PRIV:
if (inputType == OBJECT_IS_OBJECT)
result = COM_QI_OBJECT_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;
break;
case DELETE_PRIV:
if (inputType == OBJECT_IS_OBJECT)
result = COM_QI_OBJECT_DELETE;
break;
case UPDATE_PRIV:
if (inputType == OBJECT_IS_OBJECT)
result = COM_QI_OBJECT_UPDATE;
//else
// result = COM_QI_COLUMN_UPDATE;
break;
case USAGE_PRIV:
if (inputType == OBJECT_IS_OBJECT)
result = COM_QI_OBJECT_USAGE;
break;
case REFERENCES_PRIV:
if (inputType == OBJECT_IS_OBJECT)
result = COM_QI_OBJECT_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;
break;
};
return (result);
}
// Basic method to generate hash values
uint32_t ComSecurityKey::generateHash(int64_t hashInput) const
{
uint32_t hashResult = ExHDPHash::hash8((char*)&hashInput, ExHDPHash::NO_FLAGS);
return hashResult;
}
// Generate hash value based on authorization ID
uint32_t ComSecurityKey::generateHash(int32_t hashID) const
{
int64_t hVal = (int64_t) hashID;
uint32_t hashResult = generateHash(hVal);
return hashResult;
}
void ComSecurityKey::getSecurityKeyTypeAsLit (std::string &actionString) const
{
switch(actionType_)
{
case COM_QI_USER_GRANT_ROLE:
actionString = COM_QI_USER_GRANT_ROLE_LIT;
break;
case COM_QI_ROLE_GRANT_ROLE:
actionString = COM_QI_ROLE_GRANT_ROLE_LIT;
break;
case COM_QI_OBJECT_SELECT:
actionString = COM_QI_OBJECT_SELECT_LIT;
break;
case COM_QI_OBJECT_INSERT:
actionString = COM_QI_OBJECT_INSERT_LIT;
break;
case COM_QI_OBJECT_DELETE:
actionString = COM_QI_OBJECT_DELETE_LIT;
break;
case COM_QI_OBJECT_UPDATE:
actionString = COM_QI_OBJECT_UPDATE_LIT;
break;
case COM_QI_OBJECT_USAGE:
actionString = COM_QI_OBJECT_USAGE_LIT;
break;
case COM_QI_OBJECT_REFERENCES:
actionString = COM_QI_OBJECT_REFERENCES_LIT;
break;
case COM_QI_SCHEMA_SELECT:
actionString = COM_QI_SCHEMA_SELECT_LIT;
break;
case COM_QI_SCHEMA_INSERT:
actionString = COM_QI_SCHEMA_INSERT_LIT;
break;
case COM_QI_SCHEMA_DELETE:
actionString = COM_QI_SCHEMA_DELETE_LIT;
break;
case COM_QI_SCHEMA_UPDATE:
actionString = COM_QI_SCHEMA_UPDATE_LIT;
break;
case COM_QI_OBJECT_EXECUTE:
actionString = COM_QI_OBJECT_EXECUTE_LIT;
break;
case COM_QI_SCHEMA_EXECUTE:
actionString = COM_QI_SCHEMA_EXECUTE_LIT;
break;
case COM_QI_USER_GRANT_SPECIAL_ROLE:
actionString = COM_QI_USER_GRANT_SPECIAL_ROLE;
break;
default:
actionString = COM_QI_INVALID_ACTIONTYPE_LIT;
}
}
void ComSecurityKey::print() const
{
std::string typeString;
switch(actionType_)
{
case COM_QI_USER_GRANT_ROLE:
typeString = "USER_GRANT_ROLE";
break;
case COM_QI_ROLE_GRANT_ROLE:
typeString = "ROLE_GRANT_ROLE";
break;
case COM_QI_SCHEMA_SELECT:
typeString = "SCHEMA_SELECT";
break;
case COM_QI_SCHEMA_INSERT:
typeString = "SCHEMA_INSERT";
break;
case COM_QI_SCHEMA_DELETE:
typeString = "SCHEMA_DELETE";
break;
case COM_QI_SCHEMA_UPDATE:
typeString = "SCHEMA_UPDATE";
break;
case COM_QI_OBJECT_SELECT:
typeString = "OBJECT_SELECT";
break;
case COM_QI_OBJECT_INSERT:
typeString = "OBJECT_INSERT";
break;
case COM_QI_OBJECT_DELETE:
typeString = "OBJECT_DELETE";
break;
case COM_QI_OBJECT_UPDATE:
typeString = "OBJECT_UPDATE";
break;
case COM_QI_OBJECT_USAGE:
typeString = "OBJECT_USAGE";
break;
case COM_QI_OBJECT_REFERENCES:
typeString = "OBJECT_REFERENCES";
break;
default:
typeString = "INVALID_ACTIONTYPE";
break;
};
cout << subjectHash_ << " : " << objectHash_ << " : " << typeString << endl;
}