use of org.apache.derby.iapi.services.context.ContextManager in project derby by apache.
the class StatementColumnPermission method check.
/**
* @see StatementPermission#check
*/
public void check(LanguageConnectionContext lcc, boolean forGrant, Activation activation) throws StandardException {
DataDictionary dd = lcc.getDataDictionary();
ExecPreparedStatement ps = activation.getPreparedStatement();
if (hasPermissionOnTable(lcc, activation, forGrant, ps)) {
return;
}
String currentUserId = lcc.getCurrentUserId(activation);
FormatableBitSet permittedColumns = null;
if (!forGrant) {
permittedColumns = addPermittedColumns(dd, false, /* non-grantable permissions */
Authorizer.PUBLIC_AUTHORIZATION_ID, permittedColumns);
permittedColumns = addPermittedColumns(dd, false, /* non-grantable permissions */
currentUserId, permittedColumns);
}
permittedColumns = addPermittedColumns(dd, true, /* grantable permissions */
Authorizer.PUBLIC_AUTHORIZATION_ID, permittedColumns);
permittedColumns = addPermittedColumns(dd, true, /* grantable permissions */
currentUserId, permittedColumns);
// select t1.c1 from t1, t2
if (privType == Authorizer.MIN_SELECT_PRIV && permittedColumns != null)
return;
FormatableBitSet unresolvedColumns = (FormatableBitSet) columns.clone();
for (int i = unresolvedColumns.anySetBit(); i >= 0; i = unresolvedColumns.anySetBit(i)) {
if (permittedColumns != null && permittedColumns.get(i)) {
// column i (zero-based here) accounted for:
unresolvedColumns.clear(i);
}
}
if (unresolvedColumns.anySetBit() < 0) {
// all ok
return;
}
// If columns are still unauthorized, look to role closure for
// resolution.
String role = lcc.getCurrentRoleId(activation);
RoleGrantDescriptor rd = null;
if (role != null) {
// Check that role is still granted to current user or
// to PUBLIC: A revoked role which is current for this
// session, is lazily set to none when it is attempted
// used.
String dbo = dd.getAuthorizationDatabaseOwner();
rd = dd.getRoleGrantDescriptor(role, currentUserId, dbo);
if (rd == null) {
rd = dd.getRoleGrantDescriptor(role, Authorizer.PUBLIC_AUTHORIZATION_ID, dbo);
}
if (rd == null) {
// we have lost the right to set this role, so we can't
// make use of any permission granted to it or its ancestors.
lcc.setCurrentRole(activation, null);
} else {
// The current role is OK, so we can make use of
// any permission granted to it.
//
// Look at the current role and, if necessary, the transitive
// closure of roles granted to current role to see if
// permission has been granted to any of the applicable roles.
RoleClosureIterator rci = dd.createRoleClosureIterator(activation.getTransactionController(), role, true);
String r;
while (unresolvedColumns.anySetBit() >= 0 && (r = rci.next()) != null) {
// The user does not have needed privilege directly
// granted to it, so let's see if he has that privilege
// available to him/her through his roles.
permittedColumns = tryRole(lcc, dd, forGrant, r);
// select t1.c1 from t1, t2
if (privType == Authorizer.MIN_SELECT_PRIV && permittedColumns != null) {
DependencyManager dm = dd.getDependencyManager();
RoleGrantDescriptor rgd = dd.getRoleDefinitionDescriptor(role);
ContextManager cm = lcc.getContextManager();
dm.addDependency(ps, rgd, cm);
dm.addDependency(activation, rgd, cm);
return;
}
// we will quit out of this while loop
for (int i = unresolvedColumns.anySetBit(); i >= 0; i = unresolvedColumns.anySetBit(i)) {
if (permittedColumns != null && permittedColumns.get(i)) {
unresolvedColumns.clear(i);
}
}
}
}
}
TableDescriptor td = getTableDescriptor(dd);
// privilege on the table or any column in the table
if (privType == Authorizer.MIN_SELECT_PRIV)
throw StandardException.newException(forGrant ? SQLState.AUTH_NO_TABLE_PERMISSION_FOR_GRANT : SQLState.AUTH_NO_TABLE_PERMISSION, currentUserId, getPrivName(), td.getSchemaName(), td.getName());
int remains = unresolvedColumns.anySetBit();
if (remains >= 0) {
// No permission on this column.
ColumnDescriptor cd = td.getColumnDescriptor(remains + 1);
if (cd == null) {
throw StandardException.newException(SQLState.AUTH_INTERNAL_BAD_UUID, "column");
} else {
throw StandardException.newException((forGrant ? SQLState.AUTH_NO_COLUMN_PERMISSION_FOR_GRANT : SQLState.AUTH_NO_COLUMN_PERMISSION), currentUserId, getPrivName(), cd.getColumnName(), td.getSchemaName(), td.getName());
}
} else {
// We found and successfully applied a role to resolve the
// (remaining) required permissions.
//
// Also add a dependency on the role (qua provider), so
// that if role is no longer available to the current
// user (e.g. grant is revoked, role is dropped,
// another role has been set), we are able to
// invalidate the ps or activation (the latter is used
// if the current role changes).
DependencyManager dm = dd.getDependencyManager();
RoleGrantDescriptor rgd = dd.getRoleDefinitionDescriptor(role);
ContextManager cm = lcc.getContextManager();
dm.addDependency(ps, rgd, cm);
dm.addDependency(activation, rgd, cm);
}
}
use of org.apache.derby.iapi.services.context.ContextManager in project derby by apache.
the class StatementPermission method genericCheck.
/**
* Generic logic called by check() for USAGE and EXECUTE privileges. Throws
* an exception if the correct permission cannot be found.
*/
public void genericCheck(LanguageConnectionContext lcc, boolean forGrant, Activation activation, String privilegeType) throws StandardException {
DataDictionary dd = lcc.getDataDictionary();
TransactionController tc = lcc.getTransactionExecute();
ExecPreparedStatement ps = activation.getPreparedStatement();
PermissionsDescriptor perm = getPermissionDescriptor(lcc.getCurrentUserId(activation), dd);
if (!isCorrectPermission(perm)) {
perm = getPermissionDescriptor(Authorizer.PUBLIC_AUTHORIZATION_ID, dd);
}
// if the user has the correct permission, we're done
if (isCorrectPermission(perm)) {
return;
}
boolean resolved = false;
// Since no permission exists for the current user or PUBLIC,
// check if a permission exists for the current role (if set).
String role = lcc.getCurrentRoleId(activation);
if (role != null) {
// Check that role is still granted to current user or
// to PUBLIC: A revoked role which is current for this
// session, is lazily set to none when it is attemped
// used.
String dbo = dd.getAuthorizationDatabaseOwner();
RoleGrantDescriptor rd = dd.getRoleGrantDescriptor(role, lcc.getCurrentUserId(activation), dbo);
if (rd == null) {
rd = dd.getRoleGrantDescriptor(role, Authorizer.PUBLIC_AUTHORIZATION_ID, dbo);
}
if (rd == null) {
// We have lost the right to set this role, so we can't
// make use of any permission granted to it or its
// ancestors.
lcc.setCurrentRole(activation, null);
} else {
// The current role is OK, so we can make use of
// any permission granted to it.
//
// Look at the current role and, if necessary, the
// transitive closure of roles granted to current role to
// see if permission has been granted to any of the
// applicable roles.
RoleClosureIterator rci = dd.createRoleClosureIterator(activation.getTransactionController(), role, true);
String r;
while (!resolved && (r = rci.next()) != null) {
perm = getPermissionDescriptor(r, dd);
if (isCorrectPermission(perm)) {
resolved = true;
}
}
}
if (resolved) {
// Also add a dependency on the role (qua provider), so that if
// role is no longer available to the current user (e.g. grant
// is revoked, role is dropped, another role has been set), we
// are able to invalidate the ps or activation (the latter is
// used if the current role changes).
DependencyManager dm = dd.getDependencyManager();
RoleGrantDescriptor rgd = dd.getRoleDefinitionDescriptor(role);
ContextManager cm = lcc.getContextManager();
dm.addDependency(ps, rgd, cm);
dm.addDependency(activation, rgd, cm);
}
}
if (!resolved) {
PrivilegedSQLObject pso = getPrivilegedObject(dd);
if (pso == null) {
throw StandardException.newException(SQLState.AUTH_INTERNAL_BAD_UUID, getObjectType());
}
SchemaDescriptor sd = pso.getSchemaDescriptor();
if (sd == null) {
throw StandardException.newException(SQLState.AUTH_INTERNAL_BAD_UUID, "SCHEMA");
}
throw StandardException.newException((forGrant ? SQLState.AUTH_NO_GENERIC_PERMISSION_FOR_GRANT : SQLState.AUTH_NO_GENERIC_PERMISSION), lcc.getCurrentUserId(activation), privilegeType, getObjectType(), sd.getSchemaName(), pso.getName());
}
}
use of org.apache.derby.iapi.services.context.ContextManager in project derby by apache.
the class SPSDescriptor method getPreparedStatement.
/**
* Get the preparedStatement for this statement.
* Expects the prepared statement to have already
* been added to SYS.SYSSTATEMENTS.
* <p>
* Side Effects: will update SYS.SYSSTATEMENTS with
* the new plan if it needs to be recompiled.
*
* @param recompIfInvalid if false, never recompile even
* if statement is invalid
*
* @return the preparedStatement
*
* @exception StandardException on error
*/
public final synchronized ExecPreparedStatement getPreparedStatement(boolean recompIfInvalid) throws StandardException {
/*
** Recompile if we are invalid, we don't have
** a prepared statement, or the statements activation
** has been cleared and cannot be reconstituted.
*/
if (recompIfInvalid && (!valid || (preparedStatement == null))) {
ContextManager cm = getContextService().getCurrentContextManager();
/*
** Find the language connection context. Get
** it each time in case a connection is dropped.
*/
LanguageConnectionContext lcc = (LanguageConnectionContext) cm.getContext(LanguageConnectionContext.CONTEXT_ID);
if (!lcc.getDataDictionary().isReadOnlyUpgrade()) {
final String savepoint = lcc.getUniqueSavepointName();
// First try compiling in a nested transaction so we can
// release the locks after the compilation, and not have them
// sit around in the parent transaction. But if we get lock
// time out in the nested transaction, then go ahead and do
// the compilation in the user transaction. When doing the
// compilation in the user transaction, the locks acquired for
// recompilation will be released at the end of the user
// transaction (commit or abort).
TransactionController nestedTC;
try {
nestedTC = lcc.getTransactionCompile().startNestedUserTransaction(false, true);
// DERBY-3693: The nested transaction may run into a lock
// conflict with its parent transaction, in which case we
// don't want to wait for a timeout. If a lock timeout is
// detected while we're executing the nested transaction,
// we ignore the error and retry in the user transaction.
// When retrying in the user transaction, we'll wait for
// locks if necessary.
nestedTC.setNoLockWait(true);
// Set a savepoint so that the work in the nested
// transaction can be rolled back on error without
// aborting the parent transaction.
nestedTC.setSavePoint(savepoint, null);
} catch (StandardException se) {
// If I cannot start a Nested User Transaction use the
// parent transaction to do all the work.
nestedTC = null;
}
try {
prepareAndRelease(lcc, null, nestedTC);
updateSYSSTATEMENTS(lcc, RECOMPILE, nestedTC);
} catch (StandardException se) {
if (nestedTC != null) {
// Roll back to savepoint to undo any work done by
// the nested transaction. We cannot abort the nested
// transaction in order to achieve the same, since
// that would also abort the parent transaction.
nestedTC.rollbackToSavePoint(savepoint, false, null);
}
if ((nestedTC != null) && (se.isLockTimeout() || se.isSelfDeadlock())) {
// Locks were set nowait, so a lock timeout here
// means that some lock request in the nested
// transaction immediately conflicted. A conflict
// with a parent lock would lead to a undetected
// deadlock so must give up trying in the nested
// transaction and retry with parent transaction.
nestedTC.commit();
nestedTC.destroy();
nestedTC = null;
// if we couldn't do this with a nested transaction,
// retry with parent-- we need to wait this time!
// Lock conflicts at this point are with other
// transactions, so must wait.
prepareAndRelease(lcc, null, null);
updateSYSSTATEMENTS(lcc, RECOMPILE, null);
} else {
throw se;
}
} finally {
// not abort the parent here.
if (nestedTC != null) {
nestedTC.commit();
nestedTC.destroy();
}
}
}
}
return preparedStatement;
}
use of org.apache.derby.iapi.services.context.ContextManager in project derby by apache.
the class EmbedConnection method restoreContextStack.
protected final void restoreContextStack() throws SQLException {
if (SanityManager.DEBUG)
Util.ASSERT(this, (active) || getTR().getCsf() != null, "No context service to do restore");
TransactionResourceImpl tr = getTR();
// are exiting the system in the nested case.
if (SanityManager.DEBUG) {
if (tr.getCsf() != null) {
ContextManager cm1 = tr.getCsf().getCurrentContextManager();
ContextManager cm2 = tr.getContextManager();
// If the system has been shut down, cm1 can be null.
// Otherwise, cm1 and cm2 should be identical.
Util.ASSERT(this, (cm1 == cm2 || cm1 == null), "Current Context Manager not the one was expected: " + cm1 + " " + cm2);
}
}
tr.restoreContextStack();
}
use of org.apache.derby.iapi.services.context.ContextManager in project derby by apache.
the class BasicDatabase method getJarFile.
/*
** Methods of JarReader
*/
public StorageFile getJarFile(String schemaName, String sqlName) throws StandardException {
SchemaDescriptor sd = dd.getSchemaDescriptor(schemaName, null, true);
FileInfoDescriptor fid = dd.getFileInfoDescriptor(sd, sqlName);
if (fid == null)
throw StandardException.newException(SQLState.LANG_FILE_DOES_NOT_EXIST, sqlName, schemaName);
long generationId = fid.getGenerationId();
ContextManager cm = getContextService().getCurrentContextManager();
FileResource fr = af.getTransaction(cm).getFileHandler();
String externalName = JarUtil.mkExternalName(fid.getUUID(), schemaName, sqlName, fr.getSeparatorChar());
return fr.getAsFile(externalName, generationId);
}
Aggregations