| //***************************************************************************** |
| // @@@ 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 |
| // PrivMgrCoreDesc |
| // PrivMgrDesc |
| // ========================================================================== |
| |
| #include "PrivMgrDesc.h" |
| #include "PrivMgrPrivileges.h" |
| #include <bitset> |
| #include <string> |
| #include <vector> |
| |
| // ***************************************************************************** |
| // PrivMgrCoreDesc methods |
| // ***************************************************************************** |
| bool PrivMgrCoreDesc::operator==(const PrivMgrCoreDesc& other) const |
| { |
| // Check for pathological case of X = X. |
| if ( this == &other ) |
| return true; |
| |
| return ( ( priv_ == other.priv_ ) && |
| ( wgo_ == other.wgo_ ) ); |
| } |
| |
| void PrivMgrCoreDesc::setPriv(const PrivType which, |
| const bool value) |
| { |
| switch(which) { |
| |
| case ALL_PRIVS: |
| |
| priv_.set(); |
| break; |
| |
| case ALL_DML: |
| |
| priv_.set(SELECT_PRIV, value); |
| priv_.set(INSERT_PRIV, value); |
| priv_.set(UPDATE_PRIV, value); |
| priv_.set(DELETE_PRIV, value); |
| priv_.set(REFERENCES_PRIV, value); |
| |
| // ANSI describes USAGE as a DML priv but it is only |
| // valid in Trafodion for sequence generators. For now, |
| // don't include in DML |
| //priv_.set(USAGE_PRIV, value); |
| //priv_.set(EXECUTE_PRIV, value); |
| |
| break; |
| |
| case ALL_DDL: |
| |
| priv_.set(CREATE_PRIV, value); |
| priv_.set(ALTER_PRIV, value); |
| priv_.set(DROP_PRIV, value); |
| break; |
| |
| default: |
| priv_.set(which, value); |
| break; |
| } |
| } |
| |
| void PrivMgrCoreDesc::setWgo(const PrivType which, |
| const bool value) |
| { |
| switch(which) { |
| |
| case ALL_PRIVS: |
| |
| wgo_.set(); |
| break; |
| |
| case ALL_DML: |
| |
| wgo_.set(SELECT_PRIV, value); |
| wgo_.set(INSERT_PRIV, value); |
| wgo_.set(UPDATE_PRIV, value); |
| wgo_.set(USAGE_PRIV, value); |
| wgo_.set(DELETE_PRIV, value); |
| wgo_.set(REFERENCES_PRIV, value); |
| wgo_.set(EXECUTE_PRIV, value); |
| |
| break; |
| |
| case ALL_DDL: |
| |
| wgo_.set(CREATE_PRIV, value); |
| wgo_.set(ALTER_PRIV, value); |
| wgo_.set(DROP_PRIV, value); |
| break; |
| |
| default: |
| wgo_.set(which, value); |
| break; |
| } |
| } |
| |
| // Set all privilege indicators for Grant to Table |
| // (Sel/Ins/Upd/Del/Ref only) (Sets these "priv" to True, |
| // with wgo indicators set as specified). |
| // If updatable=False, suppress Insert,Delete,Update. |
| // If insertable=False, suppress Insert. |
| void PrivMgrCoreDesc::setAllDMLGrantPrivileges(const bool wgo, |
| const bool updatable, |
| const bool insertable, |
| const bool deletable) |
| { |
| this->setPriv(SELECT_PRIV, true); |
| this->setWgo(SELECT_PRIV, wgo); |
| |
| if (updatable) |
| { |
| this->setPriv(UPDATE_PRIV, true); |
| this->setWgo(UPDATE_PRIV, wgo); |
| this->setPriv(REFERENCES_PRIV, true); |
| this->setWgo(REFERENCES_PRIV, wgo); |
| |
| if ( insertable) |
| { |
| this->setPriv(INSERT_PRIV, true); |
| this->setWgo(INSERT_PRIV, wgo); |
| } |
| if ( deletable ) |
| { |
| this->setPriv(DELETE_PRIV, true); |
| this->setWgo(DELETE_PRIV, wgo); |
| } |
| } |
| } |
| |
| void PrivMgrCoreDesc::setAllDDLGrantPrivileges(const bool wgo) |
| |
| { |
| this->setPriv(ALL_DDL, true); |
| this->setWgo (ALL_DDL, wgo); |
| |
| } |
| |
| /* |
| * The following setAllRevoke.. functions are used to set a mask in revoking privileges. |
| * |
| * When grantOptionFor is specified, we set the wgo bits because we want to use the mask |
| * in revoking the with grant option for those privileges. |
| * |
| * Otherwise, we set the priv bits because we want to use the mask to revoke those |
| * privileges. |
| * |
| */ |
| |
| void PrivMgrCoreDesc::setAllDMLRevokePrivileges(const bool grantOption) |
| { |
| if (grantOption) |
| { |
| //set all dml privs in wgo to true |
| //set all dml privs in priv to false |
| this->setPriv(ALL_DML, false); |
| this->setWgo(ALL_DML, true); |
| } |
| else |
| { |
| //set all dml privs in wgo to false |
| //set all dml privs in priv to true |
| this->setPriv(ALL_DML, true); |
| this->setWgo(ALL_DML, false); |
| } |
| } |
| |
| void PrivMgrCoreDesc::setAllDDLRevokePrivileges(const bool grantOption) |
| { |
| if (grantOption) |
| { |
| //set all ddl privs in wgo to true |
| //set all ddl privs in priv to false |
| this->setPriv(ALL_DDL, false); |
| this->setWgo(ALL_DDL, true); |
| } |
| else |
| { |
| //set all ddl privs in wgo to false |
| //set all ddl privs in priv to true |
| this->setPriv(ALL_DDL, true); |
| this->setWgo(ALL_DDL, false); |
| } |
| } |
| |
| // Set all privilege indicators for Revoke. |
| void PrivMgrCoreDesc::setAllRevokePrivileges(const bool grantOption) |
| { |
| if (grantOption) |
| { |
| priv_.reset(); // For "Revoke Grant Option for.." |
| wgo_.set(); // get priv=F, wgo=T. |
| } |
| else |
| { |
| priv_.set(); // For "Revoke ..." |
| wgo_.reset(); // get priv=T, wgo=F. |
| } |
| } |
| |
| // ---------------------------------------------------------------------------- |
| // method: setAllObjectGrantPrivilege |
| // |
| // This method sets all the relevant DML privileges for the specified |
| // object type. Optionally all corresponding WITH GRANT OPTIONS privileges |
| // are also set. |
| // |
| // Params: |
| // objectType - The type of object. Based on the object type (e.g. table, |
| // routine, sequence, etc.) all the relevant privs are set |
| // wgo - WITH GRANT OPTION. If true, the corresponding WGO bits are set. |
| // |
| // ---------------------------------------------------------------------------- |
| void PrivMgrCoreDesc::setAllObjectGrantPrivilege( |
| const ComObjectType objectType, |
| const bool wgo) |
| |
| { |
| |
| switch (objectType) |
| { |
| case COM_BASE_TABLE_OBJECT: |
| setAllTableGrantPrivileges(wgo); |
| break; |
| case COM_LIBRARY_OBJECT: |
| setAllLibraryGrantPrivileges(wgo); |
| break; |
| case COM_SEQUENCE_GENERATOR_OBJECT: |
| setAllSequenceGrantPrivileges(wgo); |
| break; |
| case COM_USER_DEFINED_ROUTINE_OBJECT: |
| case COM_STORED_PROCEDURE_OBJECT: |
| setAllUdrGrantPrivileges(wgo); |
| break; |
| case COM_VIEW_OBJECT: |
| // will reach here for native hive views |
| setAllTableGrantPrivileges(wgo); |
| break; |
| default: |
| ; //TODO: internal error? |
| } |
| |
| } |
| |
| |
| |
| // Set all privilege and wgo indicators to the specified value. |
| void PrivMgrCoreDesc::setAllPrivAndWgo(const bool val) |
| { |
| if (val) |
| { |
| priv_.set(); |
| wgo_.set(); |
| } |
| else |
| { |
| priv_.reset(); |
| wgo_.reset(); |
| } |
| } |
| |
| |
| // AndNot -- sets "this" to "this" AND NOT "other" |
| void PrivMgrCoreDesc::AndNot( const PrivMgrCoreDesc& other ) |
| { |
| PrivMgrCoreDesc temp(other); |
| temp.complementPrivs(); |
| this->intersectionOfPrivs(temp); |
| } |
| |
| // ------------------------------------------------------------------- |
| // grantPrivs -- modify the privilege settings of target PrivMgrCorePrivs |
| // by ORing values of this one. Change values of 'this' |
| // to carry only the privileges actually granted. |
| // Return a value to indicate how many privs actually granted. |
| // This function does three things: |
| // It modifies the privilege settings of the passed PrivMgrCorePrivs parameter, |
| // by applying the current object's settings as a grant against it; |
| // It modifies the current object's settings to indicate only those |
| // which were actually granted to the passed PrivMgrCorePrivs param; |
| // It returns a value indicating how many (all/some/none) of the settings |
| // which were to be granted actually had an effect. If no privs were |
| // to be granted, return a "neutral" value. |
| |
| // this object|passed param|passed param|this object |
| // on input: | on input: | on output: | on output: |
| // priv_ wgo_ | priv_ wgo_ | priv_ wgo_ | priv_ wgo_ |
| // --- --- | --- --- | --- --- | --- --- |
| // T T -> T T => T T F F |
| // T F T T F T |
| // F F T T T T |
| // T F -> T T => T T F F |
| // T F T F F F |
| // F F T F T F |
| // F F -> x y => x y F F |
| // F T (does not occur -- cannot grant wgo without granting priv) |
| |
| // The algorithm is: |
| // Output param = input param OR input this; |
| // Output this = input this AND NOT input param. |
| |
| // The return value is computed as follows: |
| // If no privs were specified in this on input, return Neutral. |
| // Otherwise : |
| // Return All if each T specified in input 'this' |
| // remains T in output 'this'; |
| // Return None if each T specified in input 'this' |
| // becomes F on output 'this'; |
| // Return Some for other combinations. |
| // ---------------------------------------------------------------------------- |
| PrivMgrCoreDesc::PrivResult PrivMgrCoreDesc::grantPrivs(PrivMgrCoreDesc& param) |
| { |
| if ( this->isNull() ) |
| return NEUTRAL; // Do nothing. No privs to be granted. |
| |
| std::bitset<NBR_OF_PRIVS> beforePriv (param.priv_); // save input values |
| std::bitset<NBR_OF_PRIVS> beforeWgo (param.wgo_); |
| std::bitset<NBR_OF_PRIVS> inPriv (priv_); |
| std::bitset<NBR_OF_PRIVS> inWgo (wgo_); |
| |
| param.priv_ |= priv_; // param(out) gets param(in) OR this(in). |
| param.wgo_ |= wgo_; |
| |
| priv_ &= ( beforePriv.flip() ); // this(out) gets this(in) |
| wgo_ &= ( beforeWgo.flip() ); // AND NOT param(in) |
| |
| PrivResult result(NEUTRAL); |
| |
| // Look at each privilege type |
| for ( size_t i = 0; i < NBR_OF_PRIVS; i++ ) |
| { |
| PrivType pType = PrivType(i); |
| PrivMgrCoreDesc::interpretChanges(inPriv.test(pType), |
| priv_.test(pType), |
| result); |
| PrivMgrCoreDesc::interpretChanges(inWgo.test(pType), |
| wgo_.test(pType), |
| result); |
| } |
| |
| return result; |
| } |
| |
| // ------------------------------------------------------------------- |
| // revoke -- modify the privilege settings of target PrivMgrCoreDesc |
| // by ANDing the NOT of values of this one. |
| // Change values of 'this' to carry only the privileges |
| // which were actually revoked. |
| // This function does three things: |
| // It modifies the privilege settings of the passed PrivMgrCoreDesc parameter, |
| // by applying the current object's settings as a revoke against it; |
| // It modifies the current object's settings to indicate only those |
| // which were actually revoked from the passed PrivMgrCoreDesc param; |
| // It returns a value indicating how many (all/some/none) of the settings |
| // which were to be revoked actually had an effect. |
| |
| // this object|passed param|passed param|this object |
| // on input: | on input: | on output: | on output: |
| // priv_ wgo_ | priv_ wgo_ | priv_ wgo_ | priv_ wgo_ |
| // --- --- | --- --- | --- --- | --- --- |
| // T T -> T T => F F T T |
| // T F F F T F |
| // F F F F F F |
| // F T -> T T => T F F T |
| // T F T F F F |
| // F F F F F F |
| // F F -> x y => x y F F |
| // T F (does not occur -- cannot revoke priv without revoking wgo) |
| // |
| // The algorithm is: |
| // Output param = input param AND NOT input this; |
| // Output this = input this AND input param. |
| // Return value is computed as described in grantPrivs. |
| // ---------------------------------------------------------------------------- |
| PrivMgrCoreDesc::PrivResult PrivMgrCoreDesc::revokePrivs(PrivMgrCoreDesc& param) |
| { |
| if ( this->isNull() ) |
| return NEUTRAL; // Do nothing. No privs to be revoked. |
| |
| std::bitset<NBR_OF_PRIVS> beforePriv = param.priv_; // save input values. |
| std::bitset<NBR_OF_PRIVS> beforeWgo = param.wgo_; |
| std::bitset<NBR_OF_PRIVS> inPriv (priv_); |
| std::bitset<NBR_OF_PRIVS> inWgo (wgo_); |
| |
| param.priv_ &= ( priv_.flip() ); // param(out) gets param(in) |
| //param.priv_ &= ( priv_ ); // param(out) gets param(in) |
| param.wgo_ &= ( wgo_.flip()); // AND NOT( this(in) ). |
| //param.wgo_ &= ( wgo_); // AND NOT( this(in) ). |
| param.wgo_ &= param.priv_; // Assure valid new setting. |
| |
| priv_ &= beforePriv; // this(out) gets this(in) |
| wgo_ &= beforeWgo; // AND param(in). |
| |
| PrivResult result(NEUTRAL); |
| // Look at each privilege type |
| for ( size_t i = 0; i < NBR_OF_PRIVS; i++ ) |
| { |
| PrivType pType = PrivType(i); |
| PrivMgrCoreDesc::interpretChanges(inPriv.test(pType), |
| priv_.test(pType), |
| result); |
| PrivMgrCoreDesc::interpretChanges(inWgo.test(pType), |
| wgo_.test(pType), |
| result); |
| } |
| |
| return result; |
| } |
| |
| // limitToGrantable --remove from this descriptor any privileges |
| // (both priv and WGO) which are not held WGO in other. |
| // Return True if any privileges were removed; else False. |
| bool PrivMgrCoreDesc::limitToGrantable( const PrivMgrCoreDesc& other ) |
| { |
| std::bitset<NBR_OF_PRIVS> beforePriv (this->priv_); // save the original |
| std::bitset<NBR_OF_PRIVS> beforeWgo (this->wgo_); |
| std::bitset<NBR_OF_PRIVS> allTrue; |
| allTrue.set(); |
| |
| priv_ &= other.wgo_; // priv gets priv AND other wgo |
| wgo_ &= other.wgo_; // wgo get wgo AND other wgo |
| beforePriv ^= priv_; // perform exclusive OR |
| beforeWgo ^= wgo_; // to see if anything was lost. |
| |
| // return false iff the exOR gave false in all positions. |
| return ! ( beforePriv.none() && |
| beforeWgo.none() ); |
| } |
| |
| // suppressDuplicatedPrivs --remove from this descriptor any priv/wgo |
| // settings which also appear in other. (this = this AND NOT other) |
| // Return True if any privileges were removed; else False. |
| bool PrivMgrCoreDesc::suppressDuplicatedPrivs( const PrivMgrCoreDesc& other ) |
| { |
| std::bitset<NBR_OF_PRIVS> beforePriv (this->priv_); // save the original |
| std::bitset<NBR_OF_PRIVS> beforeWgo (this->wgo_); |
| std::bitset<NBR_OF_PRIVS> otherPriv (other.priv_); // modifiable copies |
| std::bitset<NBR_OF_PRIVS> otherWgo (other.wgo_); |
| |
| priv_ &= ( otherPriv.flip() ); // priv gets priv AND NOT other priv |
| wgo_ &= ( otherWgo.flip() ); // wgo gets wgo AND NOT other wgo |
| |
| beforePriv ^= priv_; // perform exclusive OR |
| beforeWgo ^= wgo_; // to see if anything was lost. |
| |
| // return false iff the exOR gave false in all positions. |
| return ! ( beforePriv.none() && |
| beforeWgo.none() ); |
| } |
| |
| // Return true iff any flag set in "this" is not set in "other". |
| // (Evaluate whether "this" && !"other" is null.) |
| bool PrivMgrCoreDesc::anyNotSet( const PrivMgrCoreDesc& other ) const |
| { |
| std::bitset<NBR_OF_PRIVS> priv(this->priv_); // modifiable copies |
| std::bitset<NBR_OF_PRIVS> wgo(this->wgo_); |
| std::bitset<NBR_OF_PRIVS> otherPriv (other.priv_); |
| std::bitset<NBR_OF_PRIVS> otherWgo (other.wgo_); |
| |
| priv &= ( otherPriv.flip()); // priv gets priv AND NOT other priv |
| wgo &= ( otherWgo.flip() ); // wgo gets wgo AND NOT other wgo |
| |
| if ( priv.none() && |
| wgo.none() ) |
| return false; // All were set. |
| else |
| return true; // Something was not set. |
| } |
| |
| // If any priv/wgo flag is set in "this" and is not set in "other", |
| // unset the value in "this". |
| // Return true if any change was made. |
| bool PrivMgrCoreDesc::cascadeAnyNotSet( const PrivMgrCoreDesc& other ) |
| { |
| std::bitset<NBR_OF_PRIVS> priv(this->priv_); |
| std::bitset<NBR_OF_PRIVS> wgo(this->wgo_); |
| std::bitset<NBR_OF_PRIVS> otherPriv (other.priv_); |
| std::bitset<NBR_OF_PRIVS> otherWgo (other.wgo_); |
| bool anyCleared = false; |
| |
| priv &= otherPriv; // priv gets priv AND other priv |
| wgo &= otherWgo; // wgo gets wgo AND other wgo |
| |
| if ( ( this->priv_ == priv) && |
| ( this->wgo_ == wgo ) ) |
| anyCleared = false; // Nothing changed. |
| else |
| anyCleared = true; // Some privilege was reduced. |
| |
| this->priv_ = priv; // Set the new values into "this". |
| this->wgo_ = wgo; |
| |
| return anyCleared; |
| } |
| |
| // Private helper function to interpret changes to specified |
| // grant/revoke privileges. |
| void PrivMgrCoreDesc::interpretChanges( const bool before, // in |
| const bool after, // in |
| PrivResult& result ) // in/out |
| { |
| if ( before ) // In value T |
| { |
| if ( after ) // Out value T too |
| { |
| if ( ( result == NEUTRAL ) || ( result == ALL ) ) |
| result = ALL; |
| else |
| result = SOME; |
| } |
| else // In value T, Out value F |
| { |
| if ( ( result == NEUTRAL ) || ( result == NONE ) ) |
| result = NONE; |
| else |
| result = SOME; |
| } |
| } |
| // No change to result, if in value F. |
| } |
| |
| |
| // ***************************************************************************** |
| // PrivMgrDesc methods |
| // ***************************************************************************** |
| |
| // ---------------------------------------------------------------------------- |
| // method: limitToGrantable |
| // |
| // Remove from this descriptor any privileges |
| // (both priv and WGO) which are not held WGO in other. |
| // Return True if any privileges were removed; else False. |
| // ---------------------------------------------------------------------------- |
| bool PrivMgrDesc::limitToGrantable( const PrivMgrDesc& other ) |
| { |
| bool result = false; |
| if ( tableLevel_.limitToGrantable(other.tableLevel_) ) |
| result = true; |
| |
| // Consider table level privileges when checking column privs |
| PrivMgrCoreDesc temp = other.tableLevel_; |
| for (int i = 0; i < columnLevel_.entries(); i++) |
| { |
| // Find associated column in other Desc list |
| int index = other.getColumnPriv(columnLevel_[i].getColumnOrdinal()); |
| if (index >= 0) |
| { |
| temp.unionOfPrivs(other.columnLevel_[index]); |
| if (columnLevel_[i].limitToGrantable(temp)) |
| result = true; |
| } |
| else |
| { |
| if (columnLevel_[i].limitToGrantable(temp)) |
| result = true; |
| } |
| } |
| return result; |
| } |
| |