use of org.apache.derby.iapi.sql.dictionary.PermissionsDescriptor in project derby by apache.
the class DataDictionaryImpl method dropTablePermDescriptor.
/**
* Delete the appropriate rows from systableperms when
* dropping a table
*
* @param tc The TransactionController
* @param keyRow Start/stop position.
*
* @exception StandardException Thrown on failure
*/
private void dropTablePermDescriptor(TransactionController tc, ExecIndexRow keyRow) throws StandardException {
ExecRow curRow;
PermissionsDescriptor perm;
TabInfoImpl ti = getNonCoreTI(SYSTABLEPERMS_CATALOG_NUM);
SYSTABLEPERMSRowFactory rf = (SYSTABLEPERMSRowFactory) ti.getCatalogRowFactory();
while ((curRow = ti.getRow(tc, keyRow, rf.TABLEID_INDEX_NUM)) != null) {
perm = (PermissionsDescriptor) rf.buildDescriptor(curRow, (TupleDescriptor) null, this);
removePermEntryInCache(perm);
// Build key on UUID and drop the entry as we want to drop only this row
ExecIndexRow uuidKey;
uuidKey = rf.buildIndexKeyRow(rf.TABLEPERMSID_INDEX_NUM, perm);
ti.deleteRow(tc, uuidKey, rf.TABLEPERMSID_INDEX_NUM);
}
}
use of org.apache.derby.iapi.sql.dictionary.PermissionsDescriptor in project derby by apache.
the class DataDictionaryImpl method visitPermsByGrantee.
/**
* Scan <code>indexNo</code> index on a permission table
* <code>catalog</code>, looking for match(es) for the grantee column
* (given by granteeColnoInIndex for the catalog in question).
*
* The action argument can be either <code>EXISTS</code> or
* <code>DROP</code> (to check for existence, or to drop that row).
*
* There is no index on grantee column only on on any of the
* permissions tables, so we use the index which contain grantee
* and scan that, setting up a scan qualifier to match the
* grantee, then fetch the base row.
*
* If this proves too slow, we should add an index on grantee
* only.
*
* @param authId grantee to match against
* @param tc transaction controller
* @param catalog the underlying permission table to visit
* @param indexNo the number of the index by which to access the catalog
* @param granteeColnoInIndex the column number to match
* <code>authId</code> against
* @param action drop matching rows (<code>DROP</code>), or return
* <code>true</code> if there is a matching row
* (<code>EXISTS</code>)
*
* @return action=EXISTS: return {@code true} if there is a matching row
* else return {@code false}.
* @exception StandardException
*/
private boolean visitPermsByGrantee(String authId, TransactionController tc, int catalog, int indexNo, int granteeColnoInIndex, int action) throws StandardException {
TabInfoImpl ti = getNonCoreTI(catalog);
PermissionsCatalogRowFactory rf = (PermissionsCatalogRowFactory) ti.getCatalogRowFactory();
ConglomerateController heapCC = tc.openConglomerate(ti.getHeapConglomerate(), false, 0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
DataValueDescriptor authIdOrderable = new SQLVarchar(authId);
ScanQualifier[][] scanQualifier = exFactory.getScanQualifier(1);
scanQualifier[0][0].setQualifier(granteeColnoInIndex - 1, /* to zero-based */
authIdOrderable, Orderable.ORDER_OP_EQUALS, false, false, false);
ScanController sc = tc.openScan(ti.getIndexConglomerate(indexNo), // don't hold open across commit
false, // for update
0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ, // all fields as objects
(FormatableBitSet) null, // start position -
(DataValueDescriptor[]) null, // startSearchOperation - none
0, //
scanQualifier, // stop position -through last row
(DataValueDescriptor[]) null, // stopSearchOperation - none
0);
try {
ExecRow outRow = rf.makeEmptyRow();
ExecIndexRow indexRow = getIndexRowFromHeapRow(ti.getIndexRowGenerator(indexNo), heapCC.newRowLocationTemplate(), outRow);
while (sc.fetchNext(indexRow.getRowArray())) {
RowLocation baseRowLocation = (RowLocation) indexRow.getColumn(indexRow.nColumns());
boolean base_row_exists = heapCC.fetch(baseRowLocation, outRow.getRowArray(), (FormatableBitSet) null);
if (SanityManager.DEBUG) {
// it can not be possible for heap row to
// disappear while holding scan cursor on index at
// ISOLATION_REPEATABLE_READ.
SanityManager.ASSERT(base_row_exists, "base row doesn't exist");
}
if (action == DataDictionaryImpl.EXISTS) {
return true;
} else if (action == DataDictionaryImpl.DROP) {
PermissionsDescriptor perm = (PermissionsDescriptor) rf.buildDescriptor(outRow, (TupleDescriptor) null, this);
removePermEntryInCache(perm);
ti.deleteRow(tc, indexRow, indexNo);
}
}
} finally {
if (sc != null) {
sc.close();
}
if (heapCC != null) {
heapCC.close();
}
}
return false;
}
use of org.apache.derby.iapi.sql.dictionary.PermissionsDescriptor in project derby by apache.
the class DataDictionaryImpl method dropAllRoutinePermDescriptors.
/**
* Drops all routine permission descriptors for the given routine.
*
* @param routineID The UUID of the routine from which to drop
* all the permission descriptors
* @param tc TransactionController for the transaction
*
* @exception StandardException Thrown on error
*/
public void dropAllRoutinePermDescriptors(UUID routineID, TransactionController tc) throws StandardException {
TabInfoImpl ti = getNonCoreTI(SYSROUTINEPERMS_CATALOG_NUM);
SYSROUTINEPERMSRowFactory rf = (SYSROUTINEPERMSRowFactory) ti.getCatalogRowFactory();
DataValueDescriptor routineIdOrderable;
ExecRow curRow;
PermissionsDescriptor perm;
// In Derby authorization mode, permission catalogs may not be present
if (!usesSqlAuthorization)
return;
/* Use tableIDOrderable in both start and stop position for scan. */
routineIdOrderable = getIDValueAsCHAR(routineID);
/* Set up the start/stop position for the scan */
ExecIndexRow keyRow = exFactory.getIndexableRow(1);
keyRow.setColumn(1, routineIdOrderable);
while ((curRow = ti.getRow(tc, keyRow, rf.ALIASID_INDEX_NUM)) != null) {
perm = (PermissionsDescriptor) rf.buildDescriptor(curRow, (TupleDescriptor) null, this);
removePermEntryInCache(perm);
// Build new key based on UUID and drop the entry as we want to drop
// only this row
ExecIndexRow uuidKey;
uuidKey = rf.buildIndexKeyRow(rf.ROUTINEPERMSID_INDEX_NUM, perm);
ti.deleteRow(tc, uuidKey, rf.ROUTINEPERMSID_INDEX_NUM);
}
}
use of org.apache.derby.iapi.sql.dictionary.PermissionsDescriptor in project derby by apache.
the class DDLConstantAction method findRoleUsage.
/**
* We have determined that the statement permission described by statPerm
* is not granted to the current user nor to PUBLIC, so it must be granted
* to the current role or one of the roles inherited by the current
* role. Find the relevant permission descriptor and return it.
*
* @return the permission descriptor that yielded the privilege
*/
private static PermissionsDescriptor findRoleUsage(Activation activation, StatementPermission statPerm) throws StandardException {
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
String role = lcc.getCurrentRoleId(activation);
PermissionsDescriptor permDesc = null;
if (SanityManager.DEBUG) {
SanityManager.ASSERT(role != null, "Unexpected: current role is not set");
}
// If not found in current role, get transitive
// closure of roles granted to current role and
// iterate over it to see if permission has
// been granted to any of the roles the current
// role inherits.
RoleClosureIterator rci = dd.createRoleClosureIterator(activation.getTransactionController(), role, true);
String graphGrant;
while (permDesc == null && (graphGrant = rci.next()) != null) {
permDesc = statPerm.getPermissionDescriptor(graphGrant, dd);
}
if (SanityManager.DEBUG) {
SanityManager.ASSERT(permDesc != null, "Unexpected: Permission needs to be found via role");
}
return permDesc;
}
use of org.apache.derby.iapi.sql.dictionary.PermissionsDescriptor in project derby by apache.
the class DDLConstantAction method storeConstraintDependenciesOnPrivileges.
/**
* This method saves dependencies of constraints on privileges in the
* dependency system. It gets called by CreateConstraintConstantAction.
* Views and triggers and constraints run with definer's privileges. If
* one of the required privileges is revoked from the definer, the
* dependent view/trigger/constraint on that privilege will be dropped
* automatically. In order to implement this behavior, we need to save
* view/trigger/constraint dependencies on required privileges in the
* dependency system. Following method accomplishes that part of the
* equation for constraints only. The dependency collection for
* constraints is not same as for views and triggers and hence
* constraints are handled by this special method.
*
* Views and triggers can depend on many different kind of privileges
* where as constraints only depend on REFERENCES privilege on a table
* (FOREIGN KEY constraints) or EXECUTE privileges on one or more
* functions (CHECK constraints).
*
* Another difference is only one view or trigger can be defined by a
* sql statement and hence all the dependencies collected for the sql
* statement apply to the view or trigger in question. As for constraints,
* one sql statement can defined multiple constraints and hence the
* all the privileges required by the statement are not necessarily
* required by all the constraints defined by that sql statement. We need
* to identify right privileges for right constraints for a given sql
* statement. Because of these differences between constraints and views
* (and triggers), there are 2 different methods in this class to save
* their privileges in the dependency system.
*
* For each required privilege, we now register a dependency on a role if
* that role was required to find an applicable privilege.
*
* @param activation The execution environment for this constant action.
* @param dependent Make this object depend on required privileges
* @param refTableUUID Make sure we are looking for REFERENCES privilege
* for right table
* @param providers set of providers for this constraint
* @exception StandardException Thrown on failure
*/
protected void storeConstraintDependenciesOnPrivileges(Activation activation, Dependent dependent, UUID refTableUUID, ProviderInfo[] providers) throws StandardException {
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
DependencyManager dm = dd.getDependencyManager();
String currentUser = lcc.getCurrentUserId(activation);
SettableBoolean roleDepAdded = new SettableBoolean();
// access any objects without any restrictions
if (!currentUser.equals(dd.getAuthorizationDatabaseOwner())) {
PermissionsDescriptor permDesc;
// Now, it is time to add into dependency system the FOREIGN
// constraint's dependency on REFERENCES privilege, or, if it is a
// CHECK constraint, any EXECUTE or USAGE privileges. If the REFERENCES is
// revoked from the constraint owner, the constraint will get
// dropped automatically.
List<StatementPermission> requiredPermissionsList = activation.getPreparedStatement().getRequiredPermissionsList();
if (requiredPermissionsList != null && !requiredPermissionsList.isEmpty()) {
for (StatementPermission statPerm : requiredPermissionsList) {
// are not required for a foreign key constraint.
if (statPerm instanceof StatementTablePermission) {
// It is a table/column level privilege
StatementTablePermission statementTablePermission = (StatementTablePermission) statPerm;
// required privileges list
if (statementTablePermission.getPrivType() != Authorizer.REFERENCES_PRIV)
continue;
// privilege in the required privileges list
if (!statementTablePermission.getTableUUID().equals(refTableUUID))
continue;
} else if (statPerm instanceof StatementSchemaPermission || statPerm instanceof StatementRolePermission || statPerm instanceof StatementGenericPermission) {
continue;
} else {
if (SanityManager.DEBUG) {
SanityManager.ASSERT(statPerm instanceof StatementRoutinePermission, "only StatementRoutinePermission expected");
}
// skip if this permission concerns a function not
// referenced by this constraint
StatementRoutinePermission rp = (StatementRoutinePermission) statPerm;
if (!inProviderSet(providers, rp.getRoutineUUID())) {
continue;
}
}
// We know that we are working with a REFERENCES, EXECUTE, or USAGE
// privilege. Find all the PermissionDescriptors for this
// privilege and make constraint depend on it through
// dependency manager. The REFERENCES privilege could be
// defined at the table level or it could be defined at
// individual column levels. In addition, individual column
// REFERENCES privilege could be available at the user
// level, PUBLIC or role level. EXECUTE and USAGE privileges could be
// available at the user level, PUBLIC or role level.
permDesc = statPerm.getPermissionDescriptor(currentUser, dd);
if (permDesc == null) {
// No privilege exists for given user. The privilege
// has to exist at at PUBLIC level....
permDesc = statPerm.getPermissionDescriptor(Authorizer.PUBLIC_AUTHORIZATION_ID, dd);
// .... or at the role level. Additionally, for column
// level privileges, even if *some* were available at
// the PUBLIC level others may be still be missing,
// hence the call in the test below to
// allColumnsCoveredByUserOrPUBLIC.
boolean roleUsed = false;
if (permDesc == null || ((permDesc instanceof ColPermsDescriptor) && !((StatementColumnPermission) statPerm).allColumnsCoveredByUserOrPUBLIC(currentUser, dd))) {
roleUsed = true;
permDesc = findRoleUsage(activation, statPerm);
}
// for the owner.
if (!permDesc.checkOwner(currentUser)) {
dm.addDependency(dependent, permDesc, lcc.getContextManager());
if (roleUsed) {
// We had to rely on role, so track that
// dependency, too.
trackRoleDependency(activation, dependent, roleDepAdded);
}
}
} else // object's privilege dependency in the dependency system
if (!permDesc.checkOwner(currentUser)) {
dm.addDependency(dependent, permDesc, lcc.getContextManager());
if (permDesc instanceof ColPermsDescriptor) {
// The if statement above means we found a
// REFERENCES privilege at column level for the
// given authorizer. If this privilege doesn't
// cover all the column , then there has to exisit
// REFERENCES for the remaining columns at PUBLIC
// level or at role level. Get that permission
// descriptor and save it in dependency system
StatementColumnPermission statementColumnPermission = (StatementColumnPermission) statPerm;
permDesc = statementColumnPermission.getPUBLIClevelColPermsDescriptor(currentUser, dd);
// into the dependency system
if (permDesc != null && permDesc.getObjectID() != null) {
// User did not have all required column
// permissions and at least one column is
// covered by PUBLIC.
dm.addDependency(dependent, permDesc, lcc.getContextManager());
}
// upon.
if (!statementColumnPermission.allColumnsCoveredByUserOrPUBLIC(currentUser, dd)) {
// Role has been relied upon, so register a
// dependency.
trackRoleDependency(activation, dependent, roleDepAdded);
}
}
}
if (!(statPerm instanceof StatementRoutinePermission)) {
// for this sql statement.
break;
} else {
// For EXECUTE privilege there may be several functions
// referenced in the constraint, so continue looking.
}
}
}
}
}
Aggregations