Package org.apache.derby.impl.sql.execute

Source Code of org.apache.derby.impl.sql.execute.TablePrivilegeInfo

/*

   Derby - Class org.apache.derby.impl.sql.execute.TablePrivilegeInfo

   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.

*/

package org.apache.derby.impl.sql.execute;

import org.apache.derby.iapi.services.io.FormatableBitSet;
import org.apache.derby.iapi.sql.Activation;
import org.apache.derby.iapi.error.StandardException;
import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
import org.apache.derby.iapi.store.access.TransactionController;
import org.apache.derby.iapi.sql.depend.DependencyManager;
import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;
import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
import org.apache.derby.iapi.sql.dictionary.TablePermsDescriptor;
import org.apache.derby.iapi.sql.dictionary.ColPermsDescriptor;
import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
import org.apache.derby.iapi.sql.dictionary.ViewDescriptor;
import org.apache.derby.iapi.sql.dictionary.DataDictionary;
import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;
import org.apache.derby.iapi.sql.dictionary.TupleDescriptor;
import org.apache.derby.iapi.reference.SQLState;

import java.util.List;
import java.util.Iterator;

public class TablePrivilegeInfo extends PrivilegeInfo
{
  // Action types
  public static final int SELECT_ACTION = 0;
  public static final int DELETE_ACTION = 1;
  public static final int INSERT_ACTION = 2;
  public static final int UPDATE_ACTION = 3;
  public static final int REFERENCES_ACTION = 4;
  public static final int TRIGGER_ACTION = 5;
  public static final int ACTION_COUNT = 6;

  private static final String YES_WITH_GRANT_OPTION = "Y";
  private static final String YES_WITHOUT_GRANT_OPTION = "y";
  private static final String NO = "N";

  private static final String[][] actionString =
  {{"s", "S"}, {"d", "D"}, {"i", "I"}, {"u", "U"}, {"r", "R"}, {"t", "T"}};

  private TableDescriptor td;
  private boolean[] actionAllowed;
  private FormatableBitSet[] columnBitSets;
  private List descriptorList;
 
  /**
   * @param actionAllowed actionAllowed[action] is true if action is in the privilege set.
   */
  public TablePrivilegeInfo( TableDescriptor td,
                 boolean[] actionAllowed,
                 FormatableBitSet[] columnBitSets,
                 List descriptorList)
  {
    this.actionAllowed = actionAllowed;
    this.columnBitSets = columnBitSets;
    this.td = td;
    this.descriptorList = descriptorList;
  }
 
  /**
   * Determines whether a user is the owner of an object
   * (table, function, or procedure). Note that the database
   * creator can access database objects without needing to be
   * their owner.
   *
   * @param user          authorizationId of current user
   * @param td                   table descriptor being checked against
   * @param sd          SchemaDescriptor
   * @param dd          DataDictionary
   * @param lcc                   LanguageConnectionContext
   * @param grant                 grant if true; revoke if false
   *
   * @exception StandardException if user does not own the object
   */
  protected void checkOwnership( String user,
                   TableDescriptor td,
                   SchemaDescriptor sd,
                   DataDictionary dd,
                   LanguageConnectionContext lcc,
                   boolean grant)
    throws StandardException
  {
    super.checkOwnership(user, td, sd, dd);
   
    // additional check specific to this subclass
    if (grant)
    {
      checkPrivileges(user, td, sd, dd, lcc);
    }
  }
 
  /**
   * Determines if the privilege is grantable by this grantor
   * for the given view.
   *
   * Note that the database owner can access database objects
   * without needing to be their owner.  This method should only
   * be called if it is a GRANT.
   *
   * @param user          authorizationId of current user
   * @param td                TableDescriptor to be checked against
   * @param sd          SchemaDescriptor
   * @param dd          DataDictionary
   * @param lcc                   LanguageConnectionContext
   *
   * @exception StandardException if user does not have permission to grant
   */
  private void checkPrivileges( String user,
                   TableDescriptor td,
                   SchemaDescriptor sd,
                   DataDictionary dd,
                   LanguageConnectionContext lcc)
    throws StandardException
  {
    if (user.equals(dd.getAuthorizationDatabaseOwner())) return;
   
    //  check view specific
    if (td.getTableType() == TableDescriptor.VIEW_TYPE)
    {
      if (descriptorList != null )
      {                
        TransactionController tc = lcc.getTransactionExecute();
        int siz = descriptorList.size();
        for (int i=0; i < siz; i++)
        {
          TupleDescriptor p;
          SchemaDescriptor s = null;

          p = (TupleDescriptor)descriptorList.get(i);
          if (p instanceof TableDescriptor)
          {
            TableDescriptor t = (TableDescriptor)p;
            s = t.getSchemaDescriptor();
            }
          else if (p instanceof ViewDescriptor)
          {
            ViewDescriptor v = (ViewDescriptor)p; 
            s = dd.getSchemaDescriptor(v.getCompSchemaId(), tc);
          }
            else if (p instanceof AliasDescriptor)
            {
              AliasDescriptor a = (AliasDescriptor)p;
            s = dd.getSchemaDescriptor( a.getSchemaUUID(), tc);
            }
               
          if (s != null && !user.equals(s.getAuthorizationId()) )
          {
            throw StandardException.newException(
                     SQLState.AUTH_NO_OBJECT_PERMISSION,
                     user,
                     "grant",
                     sd.getSchemaName(),
                   td.getName());     
          }
                  
            // FUTURE: if object is not own by grantor then check if
            //         the grantor have grant option.
        }
      }
    }
  }
 
  /**
   *  This is the guts of the Execution-time logic for GRANT/REVOKE of a table privilege
   *
   * @param activation
   * @param grant true if grant, false if revoke
   * @param grantees a list of authorization ids (strings)
   *
   * @exception StandardException    Thrown on failure
   */
  public void executeGrantRevoke( Activation activation,
                  boolean grant,
                  List grantees)
    throws StandardException
  {
    LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
    DataDictionary dd = lcc.getDataDictionary();
        String currentUser = lcc.getCurrentUserId(activation);
    TransactionController tc = lcc.getTransactionExecute();
    SchemaDescriptor sd = td.getSchemaDescriptor();
   
    // Check that the current user has permission to grant the privileges.
    checkOwnership( currentUser, td, sd, dd, lcc, grant);
   
    DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();

    TablePermsDescriptor tablePermsDesc =
      ddg.newTablePermsDescriptor( td,
                     getPermString( SELECT_ACTION, false),
                     getPermString( DELETE_ACTION, false),
                     getPermString( INSERT_ACTION, false),
                     getPermString( UPDATE_ACTION, false),
                     getPermString( REFERENCES_ACTION, false),
                     getPermString( TRIGGER_ACTION, false),
                     currentUser);
     
    ColPermsDescriptor[] colPermsDescs = new ColPermsDescriptor[ columnBitSets.length];
    for( int i = 0; i < columnBitSets.length; i++)
    {
      if( columnBitSets[i] != null ||
        // If it is a revoke and no column list is specified then revoke all column permissions.
        // A null column bitSet in a ColPermsDescriptor indicates that all the column permissions
        // should be removed.
        (!grant) && hasColumnPermissions(i) && actionAllowed[i]
        )
      {
        colPermsDescs[i] = ddg.newColPermsDescriptor( td,
                                getActionString(i, false),
                                columnBitSets[i],
                                currentUser);
      }
    }


    dd.startWriting(lcc);
    // Add or remove the privileges to/from the SYS.SYSTABLEPERMS and SYS.SYSCOLPERMS tables
    for( Iterator itr = grantees.iterator(); itr.hasNext();)
    {
      // Keep track to see if any privileges are revoked by a revoke
      // statement. If a privilege is not revoked, we need to raise a
      // warning. For table privileges, we do not check if privilege for
      // a specific action has been revoked or not. Also, we do not check
      // privileges for specific columns. If at least one privilege has
      // been revoked, we do not raise a warning. This has to be refined
      // further to check for specific actions/columns and raise warning
      // if any privilege has not been revoked.
      boolean privileges_revoked = false;
           
      String grantee = (String) itr.next();
      if( tablePermsDesc != null)
      {
        if (dd.addRemovePermissionsDescriptor( grant, tablePermsDesc, grantee, tc))
        {
          privileges_revoked = true;
          dd.getDependencyManager().invalidateFor
            (tablePermsDesc,
             DependencyManager.REVOKE_PRIVILEGE, lcc);

          // When revoking a privilege from a Table we need to
          // invalidate all GPSs refering to it. But GPSs aren't
          // Dependents of TablePermsDescr, but of the
          // TableDescriptor itself, so we must send
          // INTERNAL_RECOMPILE_REQUEST to the TableDescriptor's
          // Dependents.
          dd.getDependencyManager().invalidateFor
            (td, DependencyManager.INTERNAL_RECOMPILE_REQUEST, lcc);
        }
      }
      for( int i = 0; i < columnBitSets.length; i++)
      {
        if( colPermsDescs[i] != null)
        {
          if (dd.addRemovePermissionsDescriptor( grant, colPermsDescs[i], grantee, tc))
          {
            privileges_revoked = true;
            dd.getDependencyManager().invalidateFor(colPermsDescs[i], DependencyManager.REVOKE_PRIVILEGE, lcc);
            // When revoking a privilege from a Table we need to
            // invalidate all GPSs refering to it. But GPSs aren't
            // Dependents of colPermsDescs[i], but of the
            // TableDescriptor itself, so we must send
            // INTERNAL_RECOMPILE_REQUEST to the TableDescriptor's
            // Dependents.
            dd.getDependencyManager().invalidateFor
              (td,
               DependencyManager.INTERNAL_RECOMPILE_REQUEST,
               lcc);
          }
        }
      }
     
      addWarningIfPrivilegeNotRevoked(activation, grant, privileges_revoked, grantee);
    }
  } // end of executeConstantAction

  private String getPermString( int action, boolean forGrantOption)
  {
    if( actionAllowed[ action] && columnBitSets[action] == null)
      return forGrantOption ? YES_WITH_GRANT_OPTION : YES_WITHOUT_GRANT_OPTION;
    else
      return NO;
  } // end of getPermString

  private String getActionString( int action, boolean forGrantOption)
  {
    return actionString[action][forGrantOption ? 1 : 0];
  }

  private boolean hasColumnPermissions( int action)
  {
    return action == SELECT_ACTION || action == UPDATE_ACTION || action == REFERENCES_ACTION;
  }
}
TOP

Related Classes of org.apache.derby.impl.sql.execute.TablePrivilegeInfo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.