Author: thejas
Date: Fri Feb 14 00:26:11 2014
New Revision: 1568175

URL: http://svn.apache.org/r1568175
Log:
HIVE-5989 : Hive metastore authorization check is not threadsafe (Sushanth 
Sowmyan via Thejas Nair)

Modified:
    
hive/trunk/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java
    
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/HadoopDefaultMetastoreAuthenticator.java
    
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/AuthorizationPreEventListener.java

Modified: 
hive/trunk/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java
URL: 
http://svn.apache.org/viewvc/hive/trunk/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java?rev=1568175&r1=1568174&r2=1568175&view=diff
==============================================================================
--- 
hive/trunk/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java
 (original)
+++ 
hive/trunk/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java
 Fri Feb 14 00:26:11 2014
@@ -409,7 +409,7 @@ public class HiveMetaStore extends Thrif
       }
     }
 
-    private Configuration getConf() {
+    public Configuration getConf() {
       Configuration conf = threadLocalConf.get();
       if (conf == null) {
         conf = new Configuration(hiveConf);

Modified: 
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/HadoopDefaultMetastoreAuthenticator.java
URL: 
http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/HadoopDefaultMetastoreAuthenticator.java?rev=1568175&r1=1568174&r2=1568175&view=diff
==============================================================================
--- 
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/HadoopDefaultMetastoreAuthenticator.java
 (original)
+++ 
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/HadoopDefaultMetastoreAuthenticator.java
 Fri Feb 14 00:26:11 2014
@@ -25,7 +25,7 @@ public class HadoopDefaultMetastoreAuthe
 
   @Override
   public void setMetaStoreHandler(HMSHandler handler) {
-    setConf(handler.getHiveConf());
+    setConf(handler.getConf());
   }
 
 }

Modified: 
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/AuthorizationPreEventListener.java
URL: 
http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/AuthorizationPreEventListener.java?rev=1568175&r1=1568174&r2=1568175&view=diff
==============================================================================
--- 
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/AuthorizationPreEventListener.java
 (original)
+++ 
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/AuthorizationPreEventListener.java
 Fri Feb 14 00:26:11 2014
@@ -59,25 +59,68 @@ public class AuthorizationPreEventListen
   public static final Log LOG = LogFactory.getLog(
       AuthorizationPreEventListener.class);
 
-  private static HiveConf conf;
-  private static HiveMetastoreAuthorizationProvider authorizer;
-  private static HiveMetastoreAuthenticationProvider authenticator;
+  private final ThreadLocal<Configuration> tConfig = new 
ThreadLocal<Configuration>() {
+    @Override
+    protected Configuration initialValue() {
+      return new HiveConf(AuthorizationPreEventListener.class);
+    }
+  };
+
+  private final ThreadLocal<HiveMetastoreAuthenticationProvider> tAuthenticator
+      = new ThreadLocal<HiveMetastoreAuthenticationProvider>() {
+    @Override
+    protected HiveMetastoreAuthenticationProvider initialValue() {
+      try {
+        return  (HiveMetastoreAuthenticationProvider) 
HiveUtils.getAuthenticator(
+            tConfig.get(), 
HiveConf.ConfVars.HIVE_METASTORE_AUTHENTICATOR_MANAGER);
+      } catch (HiveException he) {
+        throw new IllegalStateException("Authentication provider instantiation 
failure",he);
+      }
+    }
+  };
+
+  private final ThreadLocal<HiveMetastoreAuthorizationProvider> tAuthorizer
+      = new ThreadLocal<HiveMetastoreAuthorizationProvider>() {
+    @Override
+    protected HiveMetastoreAuthorizationProvider initialValue() {
+      try {
+        return  (HiveMetastoreAuthorizationProvider) 
HiveUtils.getAuthorizeProviderManager(
+            tConfig.get(), 
HiveConf.ConfVars.HIVE_METASTORE_AUTHORIZATION_MANAGER, tAuthenticator.get());
+      } catch (HiveException he) {
+        throw new IllegalStateException("Authorization provider instantiation 
failure",he);
+      }
+    }
+  };
+
+  private final ThreadLocal<Boolean> tConfigSetOnAuths = new 
ThreadLocal<Boolean>() {
+    @Override
+    protected Boolean initialValue() {
+      return false;
+    }
+  };
 
   public AuthorizationPreEventListener(Configuration config) throws 
HiveException {
     super(config);
-
-    authenticator = (HiveMetastoreAuthenticationProvider) 
HiveUtils.getAuthenticator(
-        config, HiveConf.ConfVars.HIVE_METASTORE_AUTHENTICATOR_MANAGER);
-    authorizer = (HiveMetastoreAuthorizationProvider) 
HiveUtils.getAuthorizeProviderManager(
-        config, HiveConf.ConfVars.HIVE_METASTORE_AUTHORIZATION_MANAGER, 
authenticator);
   }
 
   @Override
   public void onEvent(PreEventContext context) throws MetaException, 
NoSuchObjectException,
       InvalidOperationException {
 
-    authenticator.setMetaStoreHandler(context.getHandler());
-    authorizer.setMetaStoreHandler(context.getHandler());
+    if (!tConfigSetOnAuths.get()){
+      // The reason we do this guard is because when we do not have a good way 
of initializing
+      // the config to the handler's thread local config until this call, so 
we do it then.
+      // Once done, though, we need not repeat this linking, we simply call 
setMetaStoreHandler
+      // and let the AuthorizationProvider and AuthenticationProvider do what 
they want.
+      tConfig.set(context.getHandler().getConf());
+      // Warning note : HMSHandler.getHiveConf() is not thread-unique, 
.getConf() is.
+      tAuthenticator.get().setConf(tConfig.get());
+      tAuthorizer.get().setConf(tConfig.get());
+      tConfigSetOnAuths.set(true); // set so we don't repeat this 
initialization
+    }
+
+    tAuthenticator.get().setMetaStoreHandler(context.getHandler());
+    tAuthorizer.get().setMetaStoreHandler(context.getHandler());
 
     switch (context.getEventType()) {
     case CREATE_TABLE:
@@ -116,7 +159,7 @@ public class AuthorizationPreEventListen
   private void authorizeCreateDatabase(PreCreateDatabaseEvent context)
       throws InvalidOperationException, MetaException {
     try {
-      authorizer.authorize(new Database(context.getDatabase()),
+      tAuthorizer.get().authorize(new Database(context.getDatabase()),
           HiveOperation.CREATEDATABASE.getInputRequiredPrivileges(),
           HiveOperation.CREATEDATABASE.getOutputRequiredPrivileges());
     } catch (AuthorizationException e) {
@@ -129,7 +172,7 @@ public class AuthorizationPreEventListen
   private void authorizeDropDatabase(PreDropDatabaseEvent context)
       throws InvalidOperationException, MetaException {
     try {
-      authorizer.authorize(new Database(context.getDatabase()),
+      tAuthorizer.get().authorize(new Database(context.getDatabase()),
           HiveOperation.DROPDATABASE.getInputRequiredPrivileges(),
           HiveOperation.DROPDATABASE.getOutputRequiredPrivileges());
     } catch (AuthorizationException e) {
@@ -142,7 +185,7 @@ public class AuthorizationPreEventListen
   private void authorizeCreateTable(PreCreateTableEvent context)
       throws InvalidOperationException, MetaException {
     try {
-      authorizer.authorize(getTableFromApiTable(context.getTable()),
+      tAuthorizer.get().authorize(getTableFromApiTable(context.getTable()),
           HiveOperation.CREATETABLE.getInputRequiredPrivileges(),
           HiveOperation.CREATETABLE.getOutputRequiredPrivileges());
     } catch (AuthorizationException e) {
@@ -155,7 +198,7 @@ public class AuthorizationPreEventListen
   private void authorizeDropTable(PreDropTableEvent context)
       throws InvalidOperationException, MetaException {
     try {
-      authorizer.authorize(getTableFromApiTable(context.getTable()),
+      tAuthorizer.get().authorize(getTableFromApiTable(context.getTable()),
           HiveOperation.DROPTABLE.getInputRequiredPrivileges(),
           HiveOperation.DROPTABLE.getOutputRequiredPrivileges());
     } catch (AuthorizationException e) {
@@ -168,7 +211,7 @@ public class AuthorizationPreEventListen
   private void authorizeAlterTable(PreAlterTableEvent context)
       throws InvalidOperationException, MetaException {
     try {
-      authorizer.authorize(getTableFromApiTable(context.getOldTable()),
+      tAuthorizer.get().authorize(getTableFromApiTable(context.getOldTable()),
           null,
           new Privilege[]{Privilege.ALTER_METADATA});
     } catch (AuthorizationException e) {
@@ -182,7 +225,7 @@ public class AuthorizationPreEventListen
       throws InvalidOperationException, MetaException {
     try {
       org.apache.hadoop.hive.metastore.api.Partition mapiPart = 
context.getPartition();
-      authorizer.authorize(getPartitionFromApiPartition(mapiPart, context),
+      tAuthorizer.get().authorize(getPartitionFromApiPartition(mapiPart, 
context),
           HiveOperation.ALTERTABLE_ADDPARTS.getInputRequiredPrivileges(),
           HiveOperation.ALTERTABLE_ADDPARTS.getOutputRequiredPrivileges());
     } catch (AuthorizationException e) {
@@ -198,7 +241,7 @@ public class AuthorizationPreEventListen
       throws InvalidOperationException, MetaException {
     try {
       org.apache.hadoop.hive.metastore.api.Partition mapiPart = 
context.getPartition();
-      authorizer.authorize(getPartitionFromApiPartition(mapiPart, context),
+      tAuthorizer.get().authorize(getPartitionFromApiPartition(mapiPart, 
context),
           HiveOperation.ALTERTABLE_DROPPARTS.getInputRequiredPrivileges(),
           HiveOperation.ALTERTABLE_DROPPARTS.getOutputRequiredPrivileges());
     } catch (AuthorizationException e) {
@@ -214,7 +257,7 @@ public class AuthorizationPreEventListen
       throws InvalidOperationException, MetaException {
     try {
       org.apache.hadoop.hive.metastore.api.Partition mapiPart = 
context.getNewPartition();
-      authorizer.authorize(getPartitionFromApiPartition(mapiPart, context),
+      tAuthorizer.get().authorize(getPartitionFromApiPartition(mapiPart, 
context),
           null,
           new Privilege[]{Privilege.ALTER_METADATA});
     } catch (AuthorizationException e) {


Reply via email to