You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by th...@apache.org on 2014/01/17 22:22:32 UTC

svn commit: r1559253 - in /hive/trunk/ql/src: java/org/apache/hadoop/hive/ql/ java/org/apache/hadoop/hive/ql/exec/ java/org/apache/hadoop/hive/ql/metadata/ java/org/apache/hadoop/hive/ql/parse/ java/org/apache/hadoop/hive/ql/session/ test/org/apache/ha...

Author: thejas
Date: Fri Jan 17 21:22:31 2014
New Revision: 1559253

URL: http://svn.apache.org/r1559253
Log:
HIVE-5928 : Add a hive authorization plugin api that does not assume privileges needed (Thejas Nair reviewed by Brock Noland)

Modified:
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/Driver.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/ErrorMsg.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/Utilities.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/metadata/Hive.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/metadata/HiveUtils.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/session/SessionState.java
    hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/TestUtilities.java

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/Driver.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/Driver.java?rev=1559253&r1=1559252&r2=1559253&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/Driver.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/Driver.java Fri Jan 17 21:22:31 2014
@@ -55,6 +55,7 @@ import org.apache.hadoop.hive.ql.exec.Ta
 import org.apache.hadoop.hive.ql.exec.Utilities;
 import org.apache.hadoop.hive.ql.history.HiveHistory.Keys;
 import org.apache.hadoop.hive.ql.hooks.Entity;
+import org.apache.hadoop.hive.ql.hooks.Entity.Type;
 import org.apache.hadoop.hive.ql.hooks.ExecuteWithHookContext;
 import org.apache.hadoop.hive.ql.hooks.Hook;
 import org.apache.hadoop.hive.ql.hooks.HookContext;
@@ -101,6 +102,9 @@ import org.apache.hadoop.hive.ql.plan.Op
 import org.apache.hadoop.hive.ql.plan.TableDesc;
 import org.apache.hadoop.hive.ql.processors.CommandProcessor;
 import org.apache.hadoop.hive.ql.processors.CommandProcessorResponse;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveOperationType;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject.HivePrivilegeObjectType;
 import org.apache.hadoop.hive.ql.session.SessionState;
 import org.apache.hadoop.hive.ql.session.SessionState.LogHelper;
 import org.apache.hadoop.hive.serde2.ByteStream;
@@ -523,6 +527,11 @@ public class Driver implements CommandPr
     SessionState ss = SessionState.get();
     HiveOperation op = ss.getHiveOperation();
     Hive db = sem.getDb();
+    if(ss.isAuthorizationModeV2()){
+      doAuthorizationV2(ss, op, inputs, outputs);
+      return;
+    }
+
     if (op != null) {
       if (op.equals(HiveOperation.CREATEDATABASE)) {
         ss.getAuthorizer().authorize(
@@ -543,6 +552,7 @@ public class Driver implements CommandPr
         }
       }
       if (outputs != null && outputs.size() > 0) {
+        //do authorization for each output
         for (WriteEntity write : outputs) {
           if (write.getType() == Entity.Type.DATABASE) {
             ss.getAuthorizer().authorize(write.getDatabase(),
@@ -570,10 +580,10 @@ public class Driver implements CommandPr
     }
 
     if (inputs != null && inputs.size() > 0) {
-
       Map<Table, List<String>> tab2Cols = new HashMap<Table, List<String>>();
       Map<Partition, List<String>> part2Cols = new HashMap<Partition, List<String>>();
 
+      //determine if partition level privileges should be checked for input tables
       Map<String, Boolean> tableUsePartLevelAuth = new HashMap<String, Boolean>();
       for (ReadEntity read : inputs) {
         if (read.getType() == Entity.Type.DATABASE) {
@@ -596,6 +606,8 @@ public class Driver implements CommandPr
         }
       }
 
+      //for a select or create-as-select query, populate the partition to column (par2Cols) or
+      // table to columns mapping (tab2Cols)
       if (op.equals(HiveOperation.CREATETABLE_AS_SELECT)
           || op.equals(HiveOperation.QUERY)) {
         SemanticAnalyzer querySem = (SemanticAnalyzer) sem;
@@ -691,6 +703,49 @@ public class Driver implements CommandPr
     }
   }
 
+  private void doAuthorizationV2(SessionState ss, HiveOperation op, HashSet<ReadEntity> inputs,
+      HashSet<WriteEntity> outputs) {
+    HiveOperationType hiveOpType = getHiveOperationType(op);
+    List<HivePrivilegeObject> inputsHObjs = getHivePrivObjects(inputs);
+    List<HivePrivilegeObject> outputHObjs = getHivePrivObjects(outputs);
+    ss.getAuthorizerV2().checkPrivileges(hiveOpType, inputsHObjs, outputHObjs);
+    return;
+  }
+
+  private List<HivePrivilegeObject> getHivePrivObjects(HashSet<? extends Entity> inputs) {
+    List<HivePrivilegeObject> hivePrivobjs = new ArrayList<HivePrivilegeObject>();
+    for(Entity input : inputs){
+      HivePrivilegeObjectType privObjType = getHivePrivilegeObjectType(input.getType());
+      //support for authorization on partitions or uri needs to be added
+      HivePrivilegeObject hPrivObject = new HivePrivilegeObject(privObjType,
+          input.getDatabase().getName(),
+          input.getTable().getTableName());
+      hivePrivobjs.add(hPrivObject);
+    }
+    return hivePrivobjs;
+  }
+
+  private HivePrivilegeObjectType getHivePrivilegeObjectType(Type type) {
+    switch(type){
+    case DATABASE:
+      return HivePrivilegeObjectType.DATABASE;
+    case TABLE:
+      return HivePrivilegeObjectType.TABLE;
+    case LOCAL_DIR:
+    case DFS_DIR:
+      return HivePrivilegeObjectType.URI;
+    case PARTITION:
+    case DUMMYPARTITION: //need to determine if a different type is needed for dummy partitions
+      return HivePrivilegeObjectType.PARTITION;
+    default:
+      return null;
+    }
+  }
+
+  private HiveOperationType getHiveOperationType(HiveOperation op) {
+    return HiveOperationType.valueOf(op.name());
+  }
+
   /**
    * @return The current query plan associated with this Driver, if any.
    */

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/ErrorMsg.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/ErrorMsg.java?rev=1559253&r1=1559252&r2=1559253&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/ErrorMsg.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/ErrorMsg.java Fri Jan 17 21:22:31 2014
@@ -45,7 +45,7 @@ public enum ErrorMsg {
   // 30000 to 39999: Runtime errors which Hive thinks may be transient and retrying may succeed.
   // 40000 to 49999: Errors where Hive is unable to advise about retries.
   // In addition to the error code, ErrorMsg also has a SQLState field.
-  // SQLStates are taken from Section 12.5 of ISO-9075.
+  // SQLStates are taken from Section 22.1 of ISO-9075.
   // See http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt
   // Most will just rollup to the generic syntax error state of 42000, but
   // specific errors can override the that state.
@@ -53,6 +53,7 @@ public enum ErrorMsg {
   // http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-error-sqlstates.html
   GENERIC_ERROR(40000, "Exception while processing"),
 
+  //========================== 10000 range starts here ========================//
   INVALID_TABLE(10001, "Table not found", "42S02"),
   INVALID_COLUMN(10002, "Invalid column reference"),
   INVALID_INDEX(10003, "Invalid index"),
@@ -370,7 +371,11 @@ public enum ErrorMsg {
   INVALID_DIR(10252, "{0} is not a directory", true),
   NO_VALID_LOCATIONS(10253, "Could not find any valid location to place the jars. " +
   "Please update hive.jar.directory or hive.user.install.directory with a valid location", false),
+  UNNSUPPORTED_AUTHORIZATION_PRINCIPAL_TYPE_GROUP(10254,
+      "Principal type GROUP is not supported in this authorization setting", "28000"),
+  INVALID_TABLE_NAME(10255, "Invalid table name {0}", true),
 
+  //========================== 20000 range starts here ========================//
   SCRIPT_INIT_ERROR(20000, "Unable to initialize custom script."),
   SCRIPT_IO_ERROR(20001, "An error occurred while reading or writing to your custom script. "
       + "It may have crashed with an error."),
@@ -382,6 +387,7 @@ public enum ErrorMsg {
       "tried to create too many dynamic partitions. The maximum number of dynamic partitions " +
       "is controlled by hive.exec.max.dynamic.partitions and hive.exec.max.dynamic.partitions.pernode. "),
 
+  //========================== 30000 range starts here ========================//
   STATSPUBLISHER_NOT_OBTAINED(30000, "StatsPublisher cannot be obtained. " +
     "There was a error to retrieve the StatsPublisher, and retrying " +
     "might help. If you dont want the query to fail because accurate statistics " +

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java?rev=1559253&r1=1559252&r2=1559253&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java Fri Jan 17 21:22:31 2014
@@ -156,6 +156,12 @@ import org.apache.hadoop.hive.ql.plan.Un
 import org.apache.hadoop.hive.ql.plan.UnlockTableDesc;
 import org.apache.hadoop.hive.ql.plan.api.StageType;
 import org.apache.hadoop.hive.ql.security.authorization.Privilege;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizer;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrincipal;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrincipal.HivePrincipalType;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilege;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject.HivePrivilegeObjectType;
 import org.apache.hadoop.hive.ql.session.SessionState;
 import org.apache.hadoop.hive.serde.serdeConstants;
 import org.apache.hadoop.hive.serde2.Deserializer;
@@ -398,7 +404,8 @@ public class DDLTask extends Task<DDLWor
       GrantDesc grantDesc = work.getGrantDesc();
       if (grantDesc != null) {
         return grantOrRevokePrivileges(grantDesc.getPrincipals(), grantDesc
-            .getPrivileges(), grantDesc.getPrivilegeSubjectDesc(), grantDesc.getGrantor(), grantDesc.getGrantorType(), grantDesc.isGrantOption(), true);
+            .getPrivileges(), grantDesc.getPrivilegeSubjectDesc(), grantDesc.getGrantor(),
+            grantDesc.getGrantorType(), grantDesc.isGrantOption(), true);
       }
 
       RevokeDesc revokeDesc = work.getRevokeDesc();
@@ -488,6 +495,11 @@ public class DDLTask extends Task<DDLWor
       boolean grantRole = grantOrRevokeRoleDDL.getGrant();
       List<PrincipalDesc> principals = grantOrRevokeRoleDDL.getPrincipalDesc();
       List<String> roles = grantOrRevokeRoleDDL.getRoles();
+
+      if(SessionState.get().isAuthorizationModeV2()){
+        return grantOrRevokeRoleV2(grantOrRevokeRoleDDL);
+      }
+
       for (PrincipalDesc principal : principals) {
         String userName = principal.getName();
         for (String roleName : roles) {
@@ -506,6 +518,28 @@ public class DDLTask extends Task<DDLWor
     return 0;
   }
 
+  private int grantOrRevokeRoleV2(GrantRevokeRoleDDL grantOrRevokeRoleDDL) throws HiveException {
+    HiveAuthorizer authorizer = SessionState.get().getAuthorizerV2();
+    //convert to the types needed for plugin api
+    HivePrincipal grantorPrinc = null;
+    if(grantOrRevokeRoleDDL.getGrantor() != null){
+      grantorPrinc = new HivePrincipal(grantOrRevokeRoleDDL.getGrantor(),
+          getHivePrincipalType(grantOrRevokeRoleDDL.getGrantorType()));
+    }
+    List<HivePrincipal> hivePrincipals = getHivePrincipals(grantOrRevokeRoleDDL.getPrincipalDesc());
+    List<String> roles = grantOrRevokeRoleDDL.getRoles();
+
+    if(grantOrRevokeRoleDDL.getGrant()){
+      authorizer.grantRole(hivePrincipals, roles,
+          grantOrRevokeRoleDDL.isGrantOption(), grantorPrinc);
+    }
+    else{
+      authorizer.revokeRole(hivePrincipals, roles,
+          grantOrRevokeRoleDDL.isGrantOption(), grantorPrinc);
+    }
+    return 0;
+  }
+
   private int showGrants(ShowGrantDesc showGrantDesc) throws HiveException {
     StringBuilder builder = new StringBuilder();
     try {
@@ -513,6 +547,7 @@ public class DDLTask extends Task<DDLWor
       PrivilegeObjectDesc hiveObjectDesc = showGrantDesc.getHiveObj();
       String principalName = principalDesc.getName();
       if (hiveObjectDesc == null) {
+        //show all privileges for this user
         List<HiveObjectPrivilege> users = db.showPrivilegeGrant(
             HiveObjectType.GLOBAL, principalName, principalDesc.getType(),
             null, null, null, null);
@@ -618,7 +653,14 @@ public class DDLTask extends Task<DDLWor
 
   private int grantOrRevokePrivileges(List<PrincipalDesc> principals,
       List<PrivilegeDesc> privileges, PrivilegeObjectDesc privSubjectDesc,
-      String grantor, PrincipalType grantorType, boolean grantOption, boolean isGrant) {
+      String grantor, PrincipalType grantorType, boolean grantOption, boolean isGrant)
+          throws HiveException {
+
+    if(SessionState.get().isAuthorizationModeV2()){
+      return grantOrRevokePrivilegesV2(principals, privileges, privSubjectDesc, grantor,
+          grantorType, grantOption, isGrant);
+    }
+
     if (privileges == null || privileges.size() == 0) {
       console.printError("No privilege found.");
       return 1;
@@ -637,15 +679,12 @@ public class DDLTask extends Task<DDLWor
         }
         String obj = privSubjectDesc.getObject();
 
+        //get the db, table objects
         if (privSubjectDesc.getTable()) {
-          String[] dbTab = obj.split("\\.");
-          if (dbTab.length == 2) {
-            dbName = dbTab[0];
-            tableName = dbTab[1];
-          } else {
-            dbName = SessionState.get().getCurrentDatabase();
-            tableName = obj;
-          }
+          String[] dbTable = Utilities.getDbTableName(obj);
+          dbName = dbTable[0];
+          tableName = dbTable[1];
+
           dbObj = db.getDatabase(dbName);
           if (dbObj == null) {
             throwNotFound("Database", dbName);
@@ -756,13 +795,83 @@ public class DDLTask extends Task<DDLWor
     return 0;
   }
 
+  private int grantOrRevokePrivilegesV2(List<PrincipalDesc> principals,
+      List<PrivilegeDesc> privileges, PrivilegeObjectDesc privSubjectDesc, String grantor,
+      PrincipalType grantorType, boolean grantOption, boolean isGrant) throws HiveException {
+    HiveAuthorizer authorizer = SessionState.get().getAuthorizerV2();
+
+    //Convert to object types used by the authorization plugin interface
+    List<HivePrincipal> hivePrincipals = getHivePrincipals(principals);
+    List<HivePrivilege> hivePrivileges = getHivePrivileges(privileges);
+    HivePrivilegeObject hivePrivObject = getHivePrivilegeObject(privSubjectDesc);
+    HivePrincipal grantorPrincipal = new HivePrincipal(grantor, getHivePrincipalType(grantorType));
+
+    if(isGrant){
+      authorizer.grantPrivileges(hivePrincipals, hivePrivileges, hivePrivObject,
+          grantorPrincipal, grantOption);
+    }else {
+      authorizer.revokePrivileges(hivePrincipals, hivePrivileges,
+          hivePrivObject, grantorPrincipal, grantOption);
+    }
+    //no exception thrown, so looks good
+    return 0;
+  }
+
+  private HivePrivilegeObject getHivePrivilegeObject(PrivilegeObjectDesc privSubjectDesc)
+      throws HiveException {
+    String [] dbTable = Utilities.getDbTableName(privSubjectDesc.getObject());
+    return new HivePrivilegeObject(getPrivObjectType(privSubjectDesc), dbTable[0], dbTable[1]);
+  }
+
+  private HivePrivilegeObjectType getPrivObjectType(PrivilegeObjectDesc privSubjectDesc) {
+    //TODO: This needs to change to support view once view grant/revoke is supported as
+    // part of HIVE-6181
+    return privSubjectDesc.getTable() ? HivePrivilegeObjectType.TABLE : HivePrivilegeObjectType.DATABASE;
+  }
+
+  private List<HivePrivilege> getHivePrivileges(List<PrivilegeDesc> privileges) {
+    List<HivePrivilege> hivePrivileges = new ArrayList<HivePrivilege>();
+    for(PrivilegeDesc privilege : privileges){
+      hivePrivileges.add(
+          new HivePrivilege(privilege.getPrivilege().toString(), privilege.getColumns()));
+    }
+    return hivePrivileges;
+  }
+
+  private List<HivePrincipal> getHivePrincipals(List<PrincipalDesc> principals) throws HiveException {
+    ArrayList<HivePrincipal> hivePrincipals = new ArrayList<HivePrincipal>();
+    for(PrincipalDesc principal : principals){
+      hivePrincipals.add(
+          new HivePrincipal(principal.getName(), getHivePrincipalType(principal.getType())));
+    }
+    return hivePrincipals;
+  }
+
+  private HivePrincipalType getHivePrincipalType(PrincipalType type) throws HiveException {
+    switch(type){
+    case USER:
+      return HivePrincipalType.USER;
+    case ROLE:
+      return HivePrincipalType.ROLE;
+    case GROUP:
+      throw new HiveException(ErrorMsg.UNNSUPPORTED_AUTHORIZATION_PRINCIPAL_TYPE_GROUP);
+    default:
+      //should not happen as we take care of all existing types
+      throw new HiveException("Unsupported authorization type specified");
+    }
+  }
+
   private void throwNotFound(String objType, String objName) throws HiveException {
     throw new HiveException(objType + " " + objName + " not found");
   }
 
-  private int roleDDL(RoleDDLDesc roleDDLDesc) {
-    RoleDDLDesc.RoleOperation operation = roleDDLDesc.getOperation();
+  private int roleDDL(RoleDDLDesc roleDDLDesc) throws HiveException, IOException {
+    if(SessionState.get().isAuthorizationModeV2()){
+      return roleDDLV2(roleDDLDesc);
+    }
+
     DataOutputStream outStream = null;
+    RoleDDLDesc.RoleOperation operation = roleDDLDesc.getOperation();
     try {
       if (operation.equals(RoleDDLDesc.RoleOperation.CREATE_ROLE)) {
         db.createRole(roleDDLDesc.getName(), roleDDLDesc.getRoleOwnerName());
@@ -812,6 +921,48 @@ public class DDLTask extends Task<DDLWor
     return 0;
   }
 
+  private int roleDDLV2(RoleDDLDesc roleDDLDesc) throws HiveException, IOException {
+    HiveAuthorizer authorizer = SessionState.get().getAuthorizerV2();
+    RoleDDLDesc.RoleOperation operation = roleDDLDesc.getOperation();
+    //call the appropriate hive authorizer function
+    switch(operation){
+    case CREATE_ROLE:
+      authorizer.createRole(roleDDLDesc.getName(), null);
+      break;
+    case DROP_ROLE:
+      authorizer.dropRole(roleDDLDesc.getName());
+      break;
+    case SHOW_ROLE_GRANT:
+      List<String> roles = authorizer.getRoles(new HivePrincipal(roleDDLDesc.getName(),
+          getHivePrincipalType(roleDDLDesc.getPrincipalType())));
+      writeListToFile(roles, roleDDLDesc.getResFile());
+      break;
+    case SHOW_ROLES:
+      List<String> allRoles = authorizer.getAllRoles();
+      writeListToFile(allRoles, roleDDLDesc.getResFile());
+      break;
+    default:
+      throw new HiveException("Unkown role operation "
+          + operation.getOperationName());
+    }
+    return 0;
+  }
+
+  /**
+   * Write list of string entries into given file
+   * @param entries
+   * @param resFile
+   * @throws IOException
+   */
+  private void writeListToFile(List<String> entries, String resFile) throws IOException {
+    StringBuilder sb = new StringBuilder(entries.size()*2);
+    for(String entry : entries){
+      sb.append(entry);
+      sb.append(terminator);
+    }
+    writeToFile(sb.toString(), resFile);
+  }
+
   private int alterDatabase(AlterDatabaseDesc alterDbDesc) throws HiveException {
 
     String dbName = alterDbDesc.getDatabaseName();

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/Utilities.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/Utilities.java?rev=1559253&r1=1559252&r2=1559253&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/Utilities.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/Utilities.java Fri Jan 17 21:22:31 2014
@@ -2008,6 +2008,25 @@ public final class Utilities {
     return names;
   }
 
+  /**
+   * Extract db and table name from dbtable string, where db and table are separated by "."
+   * If there is no db name part, set the current sessions default db
+   * @param dbtable
+   * @return String array with two elements, first is db name, second is table name
+   * @throws HiveException
+   */
+  public static String[] getDbTableName(String dbtable) throws HiveException{
+    String[] names =  dbtable.split("\\.");
+    switch (names.length) {
+    case 2:
+      return names;
+    case 1:
+      return new String [] {SessionState.get().getCurrentDatabase(), dbtable};
+    default:
+      throw new HiveException(ErrorMsg.INVALID_TABLE_NAME, dbtable);
+    }
+  }
+
   public static void validateColumnNames(List<String> colNames, List<String> checkCols)
       throws SemanticException {
     Iterator<String> checkColsIter = checkCols.iterator();

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/metadata/Hive.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/metadata/Hive.java?rev=1559253&r1=1559252&r2=1559253&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/metadata/Hive.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/metadata/Hive.java Fri Jan 17 21:22:31 2014
@@ -2514,20 +2514,8 @@ private void constructOneLBLocationMap(F
     }
 
   public Table newTable(String tableName) throws HiveException {
-    String[] names = getQualifiedNames(tableName);
-    switch (names.length) {
-    case 2:
-      return new Table(names[0], names[1]);
-    case 1:
-      return new Table(SessionState.get().getCurrentDatabase(), names[0]);
-    default:
-      try{
-        throw new HiveException("Invalid table name: " + tableName);
-      }catch(Exception e) {
-        e.printStackTrace();
-      }
-      throw new HiveException("Invalid table name: " + tableName);
-    }
+    String[] names = Utilities.getDbTableName(tableName);
+    return new Table(names[0], names[1]);
   }
 
   public String getDelegationToken(String owner, String renewer)

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/metadata/HiveUtils.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/metadata/HiveUtils.java?rev=1559253&r1=1559252&r2=1559253&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/metadata/HiveUtils.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/metadata/HiveUtils.java Fri Jan 17 21:22:31 2014
@@ -29,6 +29,9 @@ import org.apache.hadoop.hive.ql.securit
 import org.apache.hadoop.hive.ql.security.HiveAuthenticationProvider;
 import org.apache.hadoop.hive.ql.security.authorization.DefaultHiveAuthorizationProvider;
 import org.apache.hadoop.hive.ql.security.authorization.HiveAuthorizationProvider;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.DefaultHiveAuthorizerFactory;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizer;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizerFactory;
 import org.apache.hadoop.io.Text;
 import org.apache.hadoop.util.ReflectionUtils;
 
@@ -334,6 +337,23 @@ public final class HiveUtils {
   public static HiveAuthorizationProvider getAuthorizeProviderManager(
       Configuration conf, HiveConf.ConfVars authorizationProviderConfKey,
       HiveAuthenticationProvider authenticator) throws HiveException {
+    return getAuthorizeProviderManager(conf, authorizationProviderConfKey, authenticator, false);
+  }
+
+  /**
+   * Create a new instance of HiveAuthorizationProvider
+   * @param conf
+   * @param authorizationProviderConfKey
+   * @param authenticator
+   * @param nullIfOtherClass - return null if configuration
+   *  does not point to a HiveAuthorizationProvider subclass
+   * @return new instance of HiveAuthorizationProvider
+   * @throws HiveException
+   */
+  @SuppressWarnings("unchecked")
+  public static HiveAuthorizationProvider getAuthorizeProviderManager(
+      Configuration conf, HiveConf.ConfVars authorizationProviderConfKey,
+      HiveAuthenticationProvider authenticator, boolean nullIfOtherClass) throws HiveException {
 
     String clsStr = HiveConf.getVar(conf, authorizationProviderConfKey);
 
@@ -343,8 +363,11 @@ public final class HiveUtils {
       if (clsStr == null || clsStr.trim().equals("")) {
         cls = DefaultHiveAuthorizationProvider.class;
       } else {
-        cls = (Class<? extends HiveAuthorizationProvider>) Class.forName(
-            clsStr, true, JavaUtils.getClassLoader());
+        Class<?> configClass = Class.forName(clsStr, true, JavaUtils.getClassLoader());
+        if(nullIfOtherClass && !HiveAuthorizationProvider.class.isAssignableFrom(configClass) ){
+          return null;
+        }
+        cls = (Class<? extends HiveAuthorizationProvider>)configClass;
       }
       if (cls != null) {
         ret = ReflectionUtils.newInstance(cls, conf);
@@ -356,6 +379,31 @@ public final class HiveUtils {
     return ret;
   }
 
+
+  /**
+   * Return HiveAuthorizerFactory used by new authorization plugin interface.
+   * @param conf
+   * @param authorizationProviderConfKey
+   * @return
+   * @throws HiveException if HiveAuthorizerFactory specified in configuration could not
+   */
+  public static HiveAuthorizerFactory getAuthorizerFactory(
+      Configuration conf, HiveConf.ConfVars authorizationProviderConfKey)
+          throws HiveException {
+
+    Class<? extends HiveAuthorizerFactory> cls = conf.getClass(authorizationProviderConfKey.varname,
+        DefaultHiveAuthorizerFactory.class, HiveAuthorizerFactory.class);
+
+    if(cls == null){
+      //should not happen as default value is set
+      throw new HiveException("Configuration value " + authorizationProviderConfKey.varname
+          + " is not set to valid HiveAuthorizerFactory subclass" );
+    }
+
+    HiveAuthorizerFactory authFactory = ReflectionUtils.newInstance(cls, conf);
+    return authFactory;
+  }
+
   @SuppressWarnings("unchecked")
   public static HiveAuthenticationProvider getAuthenticator(
       Configuration conf, HiveConf.ConfVars authenticatorConfKey

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java?rev=1559253&r1=1559252&r2=1559253&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java Fri Jan 17 21:22:31 2014
@@ -181,7 +181,9 @@ import org.apache.hadoop.hive.serde2.typ
 import org.apache.hadoop.mapred.InputFormat;
 
 /**
- * Implementation of the semantic analyzer.
+ * Implementation of the semantic analyzer. It generates the query plan.
+ * There are other specific semantic analyzers for some hive operations such as
+ * DDLSemanticAnalyzer for ddl operations.
  */
 
 public class SemanticAnalyzer extends BaseSemanticAnalyzer {

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/session/SessionState.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/session/SessionState.java?rev=1559253&r1=1559252&r2=1559253&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/session/SessionState.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/session/SessionState.java Fri Jan 17 21:22:31 2014
@@ -54,7 +54,11 @@ import org.apache.hadoop.hive.ql.metadat
 import org.apache.hadoop.hive.ql.metadata.HiveUtils;
 import org.apache.hadoop.hive.ql.plan.HiveOperation;
 import org.apache.hadoop.hive.ql.security.HiveAuthenticationProvider;
+import org.apache.hadoop.hive.ql.security.authorization.AuthorizationPreEventListener;
 import org.apache.hadoop.hive.ql.security.authorization.HiveAuthorizationProvider;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizer;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizerFactory;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveMetastoreClientFactoryImpl;
 import org.apache.hadoop.hive.ql.util.DosToUnix;
 import org.apache.hadoop.hive.shims.ShimLoader;
 import org.apache.hadoop.util.ReflectionUtils;
@@ -120,6 +124,10 @@ public class SessionState {
 
   private HiveAuthorizationProvider authorizer;
 
+  private HiveAuthorizer authorizerV2;
+
+  public enum AuthorizationMode{V1, V2};
+
   private HiveAuthenticationProvider authenticator;
 
   private CreateTableAutomaticGrant createTableGrants;
@@ -299,15 +307,33 @@ public class SessionState {
       // that would cause ClassNoFoundException otherwise
       throw new RuntimeException(e);
     }
+    setupAuth(startSs);
+    return startSs;
+  }
 
+  /**
+   * Setup authentication and authorization plugins for this session.
+   * @param startSs
+   */
+  private static void setupAuth(SessionState startSs) {
     try {
       startSs.authenticator = HiveUtils.getAuthenticator(
           startSs.getConf(),HiveConf.ConfVars.HIVE_AUTHENTICATOR_MANAGER);
       startSs.authorizer = HiveUtils.getAuthorizeProviderManager(
           startSs.getConf(), HiveConf.ConfVars.HIVE_AUTHORIZATION_MANAGER,
-          startSs.authenticator);
-      startSs.createTableGrants = CreateTableAutomaticGrant.create(startSs
-          .getConf());
+          startSs.authenticator, true);
+
+      if(startSs.authorizer == null){
+        //if it was null, the new authorization plugin must be specified in config
+        HiveAuthorizerFactory authorizerFactory =
+            HiveUtils.getAuthorizerFactory(startSs.getConf(), HiveConf.ConfVars.HIVE_AUTHENTICATOR_MANAGER);
+        startSs.authorizerV2 = authorizerFactory.createHiveAuthorizer(new HiveMetastoreClientFactoryImpl(),
+            startSs.getConf(), startSs.authenticator.getUserName());
+      }
+      else{
+        startSs.createTableGrants = CreateTableAutomaticGrant.create(startSs
+            .getConf());
+      }
     } catch (HiveException e) {
       throw new RuntimeException(e);
     }
@@ -325,8 +351,7 @@ public class SessionState {
     } else {
        LOG.info("No Tez session required at this point. hive.execution.engine=mr.");
     }
-
-    return startSs;
+    return;
   }
 
   /**
@@ -759,6 +784,10 @@ public class SessionState {
     this.authorizer = authorizer;
   }
 
+  public HiveAuthorizer getAuthorizerV2() {
+    return authorizerV2;
+  }
+
   public HiveAuthenticationProvider getAuthenticator() {
     return authenticator;
   }
@@ -852,6 +881,20 @@ public class SessionState {
     }
   }
 
+  public AuthorizationMode getAuthorizationMode(){
+    if(authorizer != null){
+      return AuthorizationMode.V1;
+    }else if(authorizerV2 != null){
+      return AuthorizationMode.V2;
+    }
+    //should not happen - this should not get called before this.start() is called
+    throw new AssertionError("Authorization plugins not initialized!");
+  }
+
+  public boolean isAuthorizationModeV2(){
+    return getAuthorizationMode() == AuthorizationMode.V2;
+  }
+
   /**
    * @param resetPerfLogger
    * @return  Tries to return an instance of the class whose name is configured in

Modified: hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/TestUtilities.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/TestUtilities.java?rev=1559253&r1=1559252&r2=1559253&view=diff
==============================================================================
--- hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/TestUtilities.java (original)
+++ hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/TestUtilities.java Fri Jan 17 21:22:31 2014
@@ -26,10 +26,13 @@ import java.util.List;
 
 import junit.framework.TestCase;
 
+import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat;
+import org.apache.hadoop.hive.ql.metadata.HiveException;
 import org.apache.hadoop.hive.ql.plan.ExprNodeConstantDesc;
 import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;
 import org.apache.hadoop.hive.ql.plan.ExprNodeGenericFuncDesc;
+import org.apache.hadoop.hive.ql.session.SessionState;
 import org.apache.hadoop.hive.ql.udf.generic.GenericUDFFromUtcTimestamp;
 import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
 import org.apache.hadoop.mapred.JobConf;
@@ -74,4 +77,33 @@ public class TestUtilities extends TestC
     assertEquals(desc.getExprString(), Utilities.deserializeExpression(
       Utilities.serializeExpression(desc)).getExprString());
   }
+
+  public void testgetDbTableName() throws HiveException{
+    String tablename;
+    String [] dbtab;
+    SessionState.start(new HiveConf(this.getClass()));
+    String curDefaultdb = SessionState.get().getCurrentDatabase();
+
+    //test table without db portion
+    tablename = "tab1";
+    dbtab = Utilities.getDbTableName(tablename);
+    assertEquals("db name", curDefaultdb, dbtab[0]);
+    assertEquals("table name", tablename, dbtab[1]);
+
+    //test table with db portion
+    tablename = "dab1.tab1";
+    dbtab = Utilities.getDbTableName(tablename);
+    assertEquals("db name", "dab1", dbtab[0]);
+    assertEquals("table name", "tab1", dbtab[1]);
+
+    //test invalid table name
+    tablename = "dab1.tab1.x1";
+    try {
+      dbtab = Utilities.getDbTableName(tablename);
+      fail("exception was expected for invalid table name");
+    } catch(HiveException ex){
+      assertEquals("Invalid table name " + tablename, ex.getMessage());
+    }
+  }
+
 }