Search in sources :

Example 46 with DataDictionary

use of org.apache.derby.iapi.sql.dictionary.DataDictionary 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;
}
Also used : LanguageConnectionContext(org.apache.derby.iapi.sql.conn.LanguageConnectionContext) PermissionsDescriptor(org.apache.derby.iapi.sql.dictionary.PermissionsDescriptor) RoleClosureIterator(org.apache.derby.iapi.sql.dictionary.RoleClosureIterator) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary)

Example 47 with DataDictionary

use of org.apache.derby.iapi.sql.dictionary.DataDictionary 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.
                }
            }
        }
    }
}
Also used : PermissionsDescriptor(org.apache.derby.iapi.sql.dictionary.PermissionsDescriptor) DependencyManager(org.apache.derby.iapi.sql.depend.DependencyManager) StatementSchemaPermission(org.apache.derby.iapi.sql.dictionary.StatementSchemaPermission) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary) StatementRoutinePermission(org.apache.derby.iapi.sql.dictionary.StatementRoutinePermission) StatementGenericPermission(org.apache.derby.iapi.sql.dictionary.StatementGenericPermission) StatementColumnPermission(org.apache.derby.iapi.sql.dictionary.StatementColumnPermission) StatementPermission(org.apache.derby.iapi.sql.dictionary.StatementPermission) ColPermsDescriptor(org.apache.derby.iapi.sql.dictionary.ColPermsDescriptor) LanguageConnectionContext(org.apache.derby.iapi.sql.conn.LanguageConnectionContext) StatementTablePermission(org.apache.derby.iapi.sql.dictionary.StatementTablePermission) StatementRolePermission(org.apache.derby.iapi.sql.dictionary.StatementRolePermission)

Example 48 with DataDictionary

use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.

the class DDLConstantAction method trackRoleDependency.

/**
 * The statement permission needed for dependent has been found to rely on
 * the current role. If not already done, register the dependency so that
 * if the current role (or any of the roles it inherits) is revoked (or
 * dropped), we can invalidate dependent.
 *
 * @param activation the current activation
 * @param dependent the view, constraint or trigger that is dependent on the
 *        current role for some privilege.
 * @param roleDepAdded keeps track of whether a dependency on the
 *        current role has already been registered.
 */
private static void trackRoleDependency(Activation activation, Dependent dependent, SettableBoolean roleDepAdded) throws StandardException {
    // fails for triggers at least).
    if (!roleDepAdded.get()) {
        LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
        DataDictionary dd = lcc.getDataDictionary();
        DependencyManager dm = dd.getDependencyManager();
        String role = lcc.getCurrentRoleId(activation);
        RoleGrantDescriptor rgd = dd.getRoleDefinitionDescriptor(role);
        dm.addDependency(dependent, rgd, lcc.getContextManager());
        roleDepAdded.set(true);
    }
}
Also used : LanguageConnectionContext(org.apache.derby.iapi.sql.conn.LanguageConnectionContext) DependencyManager(org.apache.derby.iapi.sql.depend.DependencyManager) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary) RoleGrantDescriptor(org.apache.derby.iapi.sql.dictionary.RoleGrantDescriptor)

Example 49 with DataDictionary

use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.

the class DDLSingleTableConstantAction method executeConglomReplacement.

/**
 * Execute the received ConstantAction, which will create a
 * new physical conglomerate (or find an existing physical
 * conglomerate that is "sharable") to replace some dropped
 * physical conglomerate.  Then find any conglomerate descriptors
 * which still reference the dropped physical conglomerate and
 * update them all to have a conglomerate number that points
 * to the conglomerate created by the ConstantAction.
 *
 * This method is called as part of DROP processing to handle
 * cases where a physical conglomerate that was shared by
 * multiple descriptors is dropped--in which case a new physical
 * conglomerate must be created to support the remaining
 * descriptors.
 *
 * @param replaceConglom Constant action which, when executed,
 *  will either create a new conglomerate or find an existing
 *  one that satisfies the ConstantAction's requirements.
 * @param activation Activation used when creating the conglom
 */
void executeConglomReplacement(ConstantAction replaceConglom, Activation activation) throws StandardException {
    CreateIndexConstantAction replaceConglomAction = (CreateIndexConstantAction) replaceConglom;
    LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
    DataDictionary dd = lcc.getDataDictionary();
    // Create the new (replacment) backing conglomerate...
    replaceConglomAction.executeConstantAction(activation);
    /* Find all conglomerate descriptors that referenced the
		 * old backing conglomerate and update them to have the
		 * conglomerate number for the new backing conglomerate.
		 */
    ConglomerateDescriptor[] congDescs = dd.getConglomerateDescriptors(replaceConglomAction.getReplacedConglomNumber());
    if (SanityManager.DEBUG) {
        /* There should be at least one descriptor requiring
			 * an updated conglomerate number--namely, the one
			 * corresponding to "srcCD" for which the constant
			 * action was created (see getConglomReplacementAction()
			 * above). There may be others, as well.
			 */
        if (congDescs.length < 1) {
            SanityManager.THROWASSERT("Should have found at least one conglomerate " + "descriptor that needs an updated conglomerate " + "number (due to a dropped index), but only " + "found " + congDescs.length);
        }
    }
    dd.updateConglomerateDescriptor(congDescs, replaceConglomAction.getCreatedConglomNumber(), lcc.getTransactionExecute());
    return;
}
Also used : LanguageConnectionContext(org.apache.derby.iapi.sql.conn.LanguageConnectionContext) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary) ConglomerateDescriptor(org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)

Example 50 with DataDictionary

use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.

the class GrantRoleConstantAction method executeConstantAction.

// INTERFACE METHODS
/**
 *  This is the guts of the Execution-time logic for GRANT role.
 *
 *  @see ConstantAction#executeConstantAction
 *
 * @exception StandardException     Thrown on failure
 */
public void executeConstantAction(Activation activation) throws StandardException {
    LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
    DataDictionary dd = lcc.getDataDictionary();
    TransactionController tc = lcc.getTransactionExecute();
    DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
    final String grantor = lcc.getCurrentUserId(activation);
    dd.startWriting(lcc);
    for (Iterator rIter = roleNames.iterator(); rIter.hasNext(); ) {
        String role = (String) rIter.next();
        if (role.equals(Authorizer.PUBLIC_AUTHORIZATION_ID)) {
            throw StandardException.newException(SQLState.AUTH_PUBLIC_ILLEGAL_AUTHORIZATION_ID);
        }
        for (Iterator gIter = grantees.iterator(); gIter.hasNext(); ) {
            String grantee = (String) gIter.next();
            // check that role exists
            RoleGrantDescriptor rdDef = dd.getRoleDefinitionDescriptor(role);
            if (rdDef == null) {
                throw StandardException.newException(SQLState.ROLE_INVALID_SPECIFICATION, role);
            }
            // :
            if (grantor.equals(lcc.getDataDictionary().getAuthorizationDatabaseOwner())) {
                // All ok, we are database owner
                if (SanityManager.DEBUG) {
                    SanityManager.ASSERT(rdDef.getGrantee().equals(grantor), "expected database owner in role grant descriptor");
                    SanityManager.ASSERT(rdDef.isWithAdminOption(), "expected role definition to have ADMIN OPTION");
                }
            } else {
                throw StandardException.newException(SQLState.AUTH_ROLE_DBO_ONLY, "GRANT role");
            }
            // Has it already been granted?
            RoleGrantDescriptor rgd = dd.getRoleGrantDescriptor(role, grantee, grantor);
            if (rgd != null && withAdminOption && !rgd.isWithAdminOption()) {
                // NOTE: Never called yet, withAdminOption not yet
                // implemented.
                // Remove old descriptor and add a new one with admin
                // option: cf. SQL 2003, section 12.5, general rule 3
                rgd.drop(lcc);
                rgd.setWithAdminOption(true);
                dd.addDescriptor(rgd, // parent
                null, DataDictionary.SYSROLES_CATALOG_NUM, // no duplicatesAllowed
                false, tc);
            } else if (rgd == null) {
                // Check if the grantee is a role (if not, it is a user)
                RoleGrantDescriptor granteeDef = dd.getRoleDefinitionDescriptor(grantee);
                if (granteeDef != null) {
                    checkCircularity(role, grantee, grantor, tc, dd);
                }
                rgd = ddg.newRoleGrantDescriptor(dd.getUUIDFactory().createUUID(), role, grantee, // dbo for now
                grantor, withAdminOption, // not definition
                false);
                dd.addDescriptor(rgd, // parent
                null, DataDictionary.SYSROLES_CATALOG_NUM, // no duplicatesAllowed
                false, tc);
            }
        // else exists already, no need to add
        }
    }
}
Also used : DataDescriptorGenerator(org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator) LanguageConnectionContext(org.apache.derby.iapi.sql.conn.LanguageConnectionContext) Iterator(java.util.Iterator) RoleClosureIterator(org.apache.derby.iapi.sql.dictionary.RoleClosureIterator) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary) TransactionController(org.apache.derby.iapi.store.access.TransactionController) RoleGrantDescriptor(org.apache.derby.iapi.sql.dictionary.RoleGrantDescriptor)

Aggregations

DataDictionary (org.apache.derby.iapi.sql.dictionary.DataDictionary)102 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)57 TransactionController (org.apache.derby.iapi.store.access.TransactionController)40 SchemaDescriptor (org.apache.derby.iapi.sql.dictionary.SchemaDescriptor)33 TableDescriptor (org.apache.derby.iapi.sql.dictionary.TableDescriptor)23 DependencyManager (org.apache.derby.iapi.sql.depend.DependencyManager)22 ConglomerateDescriptor (org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)17 StandardException (org.apache.derby.shared.common.error.StandardException)16 UUID (org.apache.derby.catalog.UUID)15 ConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor)15 DataDescriptorGenerator (org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator)13 CompilerContext (org.apache.derby.iapi.sql.compile.CompilerContext)10 AliasDescriptor (org.apache.derby.iapi.sql.dictionary.AliasDescriptor)9 RoleGrantDescriptor (org.apache.derby.iapi.sql.dictionary.RoleGrantDescriptor)8 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)7 ConstraintDescriptorList (org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList)7 ReferencedKeyConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor)7 ColumnDescriptor (org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)6 ConglomerateController (org.apache.derby.iapi.store.access.ConglomerateController)6 Iterator (java.util.Iterator)5