hive-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From the...@apache.org
Subject svn commit: r1578350 [1/2] - in /hive/branches/branch-0.13: ./ itests/hive-unit/src/test/java/org/apache/hive/service/cli/thrift/ jdbc/src/java/org/apache/hive/jdbc/ ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/ service/sr...
Date Mon, 17 Mar 2014 13:04:29 GMT
Author: thejas
Date: Mon Mar 17 13:04:29 2014
New Revision: 1578350

URL: http://svn.apache.org/r1578350
Log:
HIVE-4764 : Support Kerberos HTTP authentication for HiveServer2 running in http mode (Vaibhav Gumashta via Thejas Nair)

Added:
    hive/branches/branch-0.13/jdbc/src/java/org/apache/hive/jdbc/HttpKerberosRequestInterceptor.java
    hive/branches/branch-0.13/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAccessController.java.orig
    hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HttpAuthUtils.java
    hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HttpAuthenticationException.java
    hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HttpCLIServiceUGIProcessor.java
Modified:
    hive/branches/branch-0.13/itests/hive-unit/src/test/java/org/apache/hive/service/cli/thrift/TestThriftHttpCLIService.java
    hive/branches/branch-0.13/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java
    hive/branches/branch-0.13/jdbc/src/java/org/apache/hive/jdbc/HttpBasicAuthInterceptor.java
    hive/branches/branch-0.13/pom.xml
    hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HiveAuthFactory.java
    hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/CLIService.java
    hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/session/SessionManager.java
    hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/thrift/ThriftCLIService.java
    hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpCLIService.java
    hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpServlet.java
    hive/branches/branch-0.13/shims/common-secure/src/main/java/org/apache/hadoop/hive/thrift/HadoopThriftAuthBridge20S.java
    hive/branches/branch-0.13/shims/common/src/main/java/org/apache/hadoop/hive/shims/HadoopShims.java
    hive/branches/branch-0.13/shims/common/src/main/java/org/apache/hadoop/hive/thrift/HadoopThriftAuthBridge.java

Modified: hive/branches/branch-0.13/itests/hive-unit/src/test/java/org/apache/hive/service/cli/thrift/TestThriftHttpCLIService.java
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.13/itests/hive-unit/src/test/java/org/apache/hive/service/cli/thrift/TestThriftHttpCLIService.java?rev=1578350&r1=1578349&r2=1578350&view=diff
==============================================================================
--- hive/branches/branch-0.13/itests/hive-unit/src/test/java/org/apache/hive/service/cli/thrift/TestThriftHttpCLIService.java (original)
+++ hive/branches/branch-0.13/itests/hive-unit/src/test/java/org/apache/hive/service/cli/thrift/TestThriftHttpCLIService.java Mon Mar 17 13:04:29 2014
@@ -24,7 +24,6 @@ import static org.junit.Assert.fail;
 import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
 import org.apache.hive.jdbc.HttpBasicAuthInterceptor;
 import org.apache.hive.service.auth.HiveAuthFactory.AuthTypes;
-import org.apache.hive.service.server.HiveServer2;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.thrift.transport.THttpClient;
 import org.apache.thrift.transport.TTransport;
@@ -170,40 +169,6 @@ public class TestThriftHttpCLIService ex
     }
   }
 
-
-  private void testWithAuthMode(AuthTypes authType) throws Exception {
-    // Stop and restart HiveServer2 in given incorrect auth mode
-    stopHiveServer2();
-    hiveConf.setVar(ConfVars.HIVE_SERVER2_AUTHENTICATION, authType.toString());
-    hiveServer2 = new HiveServer2();
-    // HiveServer2 in Http mode will not start using KERBEROS/LDAP/CUSTOM auth types
-    startHiveServer2WithConf(hiveConf);
-
-    // This will throw an expected exception since Http server is not running
-    testOpenSessionExpectedException();
-
-    // Stop and restart back with the original config
-    stopHiveServer2();
-    hiveConf.setVar(ConfVars.HIVE_SERVER2_AUTHENTICATION, AuthTypes.NOSASL.toString());
-    hiveServer2 = new HiveServer2();
-    startHiveServer2WithConf(hiveConf);
-  }
-
-  @Test
-  public void testKerberosMode()  throws Exception {
-    testWithAuthMode(AuthTypes.KERBEROS);
-  }
-
-  @Test
-  public void testLDAPMode()  throws Exception {
-    testWithAuthMode(AuthTypes.LDAP);
-  }
-
-  @Test
-  public void testCustomMode()  throws Exception {
-    testWithAuthMode(AuthTypes.CUSTOM);
-  }
-
   private static TTransport createHttpTransport() throws Exception {
     DefaultHttpClient httpClient = new DefaultHttpClient();
     String httpUrl = transportMode + "://" + host + ":" + port +

Modified: hive/branches/branch-0.13/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.13/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java?rev=1578350&r1=1578349&r2=1578350&view=diff
==============================================================================
--- hive/branches/branch-0.13/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java (original)
+++ hive/branches/branch-0.13/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java Mon Mar 17 13:04:29 2014
@@ -47,7 +47,6 @@ import java.util.Properties;
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 
-import javax.net.ssl.SSLContext;
 import javax.security.sasl.Sasl;
 import javax.security.sasl.SaslException;
 
@@ -74,10 +73,9 @@ import org.apache.hive.service.cli.thrif
 import org.apache.hive.service.cli.thrift.TRenewDelegationTokenResp;
 import org.apache.hive.service.cli.thrift.TSessionHandle;
 import org.apache.http.HttpRequestInterceptor;
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
-import org.apache.http.conn.ssl.SSLContexts;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.thrift.TException;
 import org.apache.thrift.protocol.TBinaryProtocol;
 import org.apache.thrift.transport.THttpClient;
@@ -197,6 +195,7 @@ public class HiveConnection implements j
   }
 
   private void openTransport() throws SQLException {
+    // TODO: Refactor transport creation to a factory, it's getting uber messy here
     transport = isHttpTransportMode() ? createHttpTransport() : createBinaryTransport();
     try {
       if (!transport.isOpen()) {
@@ -208,8 +207,10 @@ public class HiveConnection implements j
     }
   }
 
-  private TTransport createHttpTransport() throws SQLException {
-    CloseableHttpClient httpClient;
+  private String getServerHttpUrl(boolean useSsl) {
+    // Create the http/https url
+    // JDBC driver will set up an https url if ssl is enabled, otherwise http
+    String schemeName = useSsl ? "https" : "http";
     // http path should begin with "/"
     String httpPath;
     httpPath = hiveConfMap.get(
@@ -217,21 +218,28 @@ public class HiveConnection implements j
     if(httpPath == null) {
       httpPath = "/";
     }
-    if(!httpPath.startsWith("/")) {
+    else if(!httpPath.startsWith("/")) {
       httpPath = "/" + httpPath;
     }
+    return schemeName +  "://" + host + ":" + port + httpPath;
+  }
+
+  private TTransport createHttpTransport() throws SQLException {
+    DefaultHttpClient httpClient;
 
-    boolean useSsl = "true".equalsIgnoreCase(sessConfMap.get(HIVE_USE_SSL));
+    boolean useSsl = isSslConnection();
 
     // Create an http client from the configs
-    httpClient = getHttpClient(useSsl);
+    try {
+      httpClient = getHttpClient(useSsl);
+    } catch (Exception e) {
+      String msg =  "Could not create http connection to " +
+          jdbcURI + ". " + e.getMessage();
+      throw new SQLException(msg, " 08S01", e);
+    }
 
-    // Create the http/https url
-    // JDBC driver will set up an https url if ssl is enabled, otherwise http
-    String schemeName = useSsl ? "https" : "http";
-    String httpUrl = schemeName +  "://" + host + ":" + port + httpPath;
     try {
-      transport = new THttpClient(httpUrl, httpClient);
+      transport = new THttpClient(getServerHttpUrl(useSsl), httpClient);
     }
     catch (TTransportException e) {
       String msg =  "Could not create http connection to " +
@@ -241,29 +249,53 @@ public class HiveConnection implements j
     return transport;
   }
 
-  private CloseableHttpClient getHttpClient(Boolean useSsl) throws SQLException {
-    // Add an interceptor to pass username/password in the header
-    // for basic preemtive http authentication at the server
-    // In https mode, the entire information is encrypted
-    HttpRequestInterceptor authInterceptor = new HttpBasicAuthInterceptor(
-        getUserName(), getPasswd());
-    if (useSsl) {
-      String sslTrustStorePath = sessConfMap.get(HIVE_SSL_TRUST_STORE);
-      String sslTrustStorePassword = sessConfMap.get(
-          HIVE_SSL_TRUST_STORE_PASSWORD);
-      KeyStore sslTrustStore;
-      SSLContext sslContext;
-      if (sslTrustStorePath == null || sslTrustStorePath.isEmpty()) {
-        // Create a default client context based on standard JSSE trust material
-        sslContext = SSLContexts.createDefault();
-      } else {
-        // Pick trust store config from the given path
+  private DefaultHttpClient getHttpClient(Boolean useSsl) throws SQLException {
+    DefaultHttpClient httpClient = new DefaultHttpClient();
+    // Request interceptor for any request pre-processing logic
+    HttpRequestInterceptor requestInterceptor;
+    // If Kerberos
+    if (isKerberosAuthMode()) {
+      if (useSsl) {
+        String msg = "SSL encryption is currently not supported with " +
+            "kerberos authentication";
+        throw new SQLException(msg, " 08S01");
+      }
+      /**
+       * Add an interceptor which sets the appropriate header in the request.
+       * It does the kerberos authentication and get the final service ticket,
+       * for sending to the server before every request.
+       */
+      requestInterceptor = new HttpKerberosRequestInterceptor(
+          sessConfMap.get(HIVE_AUTH_PRINCIPAL), host, getServerHttpUrl(false));
+    }
+    else {
+      /**
+       * Add an interceptor to pass username/password in the header.
+       * In https mode, the entire information is encrypted
+       */
+      requestInterceptor = new HttpBasicAuthInterceptor(getUserName(), getPassword());
+      // Configure httpClient for SSL
+      if (useSsl) {
+        String sslTrustStorePath = sessConfMap.get(HIVE_SSL_TRUST_STORE);
+        String sslTrustStorePassword = sessConfMap.get(
+            HIVE_SSL_TRUST_STORE_PASSWORD);
+        KeyStore sslTrustStore;
+        SSLSocketFactory socketFactory;
         try {
-          sslTrustStore = KeyStore.getInstance(HIVE_SSL_TRUST_STORE_TYPE);
-          sslTrustStore.load(new FileInputStream(sslTrustStorePath),
-              sslTrustStorePassword.toCharArray());
-          sslContext = SSLContexts.custom().loadTrustMaterial(
-              sslTrustStore).build();
+          if (sslTrustStorePath == null || sslTrustStorePath.isEmpty()) {
+            // Create a default socket factory based on standard JSSE trust material
+            socketFactory = SSLSocketFactory.getSocketFactory();
+          }
+          else {
+            // Pick trust store config from the given path
+            sslTrustStore = KeyStore.getInstance(HIVE_SSL_TRUST_STORE_TYPE);
+            sslTrustStore.load(new FileInputStream(sslTrustStorePath),
+                sslTrustStorePassword.toCharArray());
+            socketFactory = new SSLSocketFactory(sslTrustStore);
+          }
+          socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+          Scheme sslScheme = new Scheme("https", 443, socketFactory);
+          httpClient.getConnectionManager().getSchemeRegistry().register(sslScheme);
         }
         catch (Exception e) {
           String msg =  "Could not create an https connection to " +
@@ -271,13 +303,9 @@ public class HiveConnection implements j
           throw new SQLException(msg, " 08S01", e);
         }
       }
-      return HttpClients.custom().setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER).setSslcontext(
-          sslContext).addInterceptorFirst(authInterceptor).build();
-    }
-    else {
-      // Create a plain http client
-      return HttpClients.custom().addInterceptorFirst(authInterceptor).build();
     }
+    httpClient.addRequestInterceptor(requestInterceptor);
+    return httpClient;
   }
 
   /**
@@ -319,19 +347,12 @@ public class HiveConnection implements j
           String tokenStr = getClientDelegationToken(sessConfMap);
           if (tokenStr != null) {
             transport = KerberosSaslHelper.getTokenTransport(tokenStr,
-                  host, HiveAuthFactory.getSocketTransport(host, port, loginTimeout), saslProps);
+                host, HiveAuthFactory.getSocketTransport(host, port, loginTimeout), saslProps);
           } else {
             // we are using PLAIN Sasl connection with user/password
-            String userName = sessConfMap.get(HIVE_AUTH_USER);
-            if ((userName == null) || userName.isEmpty()) {
-              userName = HIVE_ANONYMOUS_USER;
-            }
-            String passwd = sessConfMap.get(HIVE_AUTH_PASSWD);
-            if ((passwd == null) || passwd.isEmpty()) {
-              passwd = HIVE_ANONYMOUS_PASSWD;
-            }
-            String useSslStr = sessConfMap.get(HIVE_USE_SSL);
-            if ("true".equalsIgnoreCase(useSslStr)) {
+            String userName = getUserName();
+            String passwd = getPassword();
+            if (isSslConnection()) {
               // get SSL socket
               String sslTrustStore = sessConfMap.get(HIVE_SSL_TRUST_STORE);
               String sslTrustStorePassword = sessConfMap.get(HIVE_SSL_TRUST_STORE_PASSWORD);
@@ -339,14 +360,14 @@ public class HiveConnection implements j
                 transport = HiveAuthFactory.getSSLSocket(host, port, loginTimeout);
               } else {
                 transport = HiveAuthFactory.getSSLSocket(host, port, loginTimeout,
-                  sslTrustStore, sslTrustStorePassword);
+                    sslTrustStore, sslTrustStorePassword);
               }
             } else {
               // get non-SSL socket transport
               transport = HiveAuthFactory.getSocketTransport(host, port, loginTimeout);
             }
-          // Overlay the SASL transport on top of the base socket transport (SSL or non-SSL)
-          transport = PlainSaslHelper.getPlainTransport(userName, passwd, transport);
+            // Overlay the SASL transport on top of the base socket transport (SSL or non-SSL)
+            transport = PlainSaslHelper.getPlainTransport(userName, passwd, transport);
           }
         }
       } else {
@@ -363,16 +384,6 @@ public class HiveConnection implements j
     return transport;
   }
 
-
-  private boolean isHttpTransportMode() {
-    String transportMode =
-        hiveConfMap.get(HiveConf.ConfVars.HIVE_SERVER2_TRANSPORT_MODE.varname);
-    if(transportMode != null && (transportMode.equalsIgnoreCase("http"))) {
-      return true;
-    }
-    return false;
-  }
-
   // Lookup the delegation token. First in the connection URL, then Configuration
   private String getClientDelegationToken(Map<String, String> jdbcConnConf)
       throws SQLException {
@@ -453,10 +464,28 @@ public class HiveConnection implements j
   /**
    * @return password from sessConfMap
    */
-  private String getPasswd() {
+  private String getPassword() {
     return getSessionValue(HIVE_AUTH_PASSWD, HIVE_ANONYMOUS_PASSWD);
   }
 
+  private boolean isSslConnection() {
+    return "true".equalsIgnoreCase(sessConfMap.get(HIVE_USE_SSL));
+  }
+
+  private boolean isKerberosAuthMode() {
+    return !HIVE_AUTH_SIMPLE.equals(sessConfMap.get(HIVE_AUTH_TYPE))
+        && sessConfMap.containsKey(HIVE_AUTH_PRINCIPAL);
+  }
+
+  private boolean isHttpTransportMode() {
+    String transportMode =
+        hiveConfMap.get(HiveConf.ConfVars.HIVE_SERVER2_TRANSPORT_MODE.varname);
+    if(transportMode != null && (transportMode.equalsIgnoreCase("http"))) {
+      return true;
+    }
+    return false;
+  }
+
   /**
    * Lookup varName in sessConfMap, if its null or empty return the default
    * value varDefault
@@ -495,7 +524,7 @@ public class HiveConnection implements j
       return tokenResp.getDelegationToken();
     } catch (TException e) {
       throw new SQLException("Could not retrieve token: " +
-            e.getMessage(), " 08S01", e);
+          e.getMessage(), " 08S01", e);
     }
   }
 
@@ -503,12 +532,12 @@ public class HiveConnection implements j
     TCancelDelegationTokenReq cancelReq = new TCancelDelegationTokenReq(sessHandle, tokenStr);
     try {
       TCancelDelegationTokenResp cancelResp =
-              client.CancelDelegationToken(cancelReq);
+          client.CancelDelegationToken(cancelReq);
       Utils.verifySuccess(cancelResp.getStatus());
       return;
     } catch (TException e) {
       throw new SQLException("Could not cancel token: " +
-            e.getMessage(), " 08S01", e);
+          e.getMessage(), " 08S01", e);
     }
   }
 
@@ -516,12 +545,12 @@ public class HiveConnection implements j
     TRenewDelegationTokenReq cancelReq = new TRenewDelegationTokenReq(sessHandle, tokenStr);
     try {
       TRenewDelegationTokenResp renewResp =
-              client.RenewDelegationToken(cancelReq);
+          client.RenewDelegationToken(cancelReq);
       Utils.verifySuccess(renewResp.getStatus());
       return;
     } catch (TException e) {
       throw new SQLException("Could not renew token: " +
-            e.getMessage(), " 08S01", e);
+          e.getMessage(), " 08S01", e);
     }
   }
 

Modified: hive/branches/branch-0.13/jdbc/src/java/org/apache/hive/jdbc/HttpBasicAuthInterceptor.java
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.13/jdbc/src/java/org/apache/hive/jdbc/HttpBasicAuthInterceptor.java?rev=1578350&r1=1578349&r2=1578350&view=diff
==============================================================================
--- hive/branches/branch-0.13/jdbc/src/java/org/apache/hive/jdbc/HttpBasicAuthInterceptor.java (original)
+++ hive/branches/branch-0.13/jdbc/src/java/org/apache/hive/jdbc/HttpBasicAuthInterceptor.java Mon Mar 17 13:04:29 2014
@@ -25,6 +25,7 @@ import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.impl.auth.AuthSchemeBase;
 import org.apache.http.impl.auth.BasicScheme;
 import org.apache.http.protocol.HttpContext;
 
@@ -34,20 +35,22 @@ import org.apache.http.protocol.HttpCont
  *
  */
 public class HttpBasicAuthInterceptor implements HttpRequestInterceptor {
+  UsernamePasswordCredentials credentials;
+  AuthSchemeBase authScheme;
 
-  Header basicAuthHeader;
-  public HttpBasicAuthInterceptor(String username, String password){
+  public HttpBasicAuthInterceptor(String username, String password) {
     if(username != null){
-      UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);
-      basicAuthHeader = BasicScheme.authenticate(creds, "UTF-8", false);
+      credentials = new UsernamePasswordCredentials(username, password);
     }
+    authScheme = new BasicScheme();
   }
 
   @Override
-  public void process(HttpRequest httpRequest, HttpContext httpContext) throws HttpException, IOException {
-    if(basicAuthHeader != null){
-      httpRequest.addHeader(basicAuthHeader);
-    }
+  public void process(HttpRequest httpRequest, HttpContext httpContext)
+      throws HttpException, IOException {
+    Header basicAuthHeader = authScheme.authenticate(
+        credentials, httpRequest, httpContext);
+    httpRequest.addHeader(basicAuthHeader);
   }
 
 }

Added: hive/branches/branch-0.13/jdbc/src/java/org/apache/hive/jdbc/HttpKerberosRequestInterceptor.java
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.13/jdbc/src/java/org/apache/hive/jdbc/HttpKerberosRequestInterceptor.java?rev=1578350&view=auto
==============================================================================
--- hive/branches/branch-0.13/jdbc/src/java/org/apache/hive/jdbc/HttpKerberosRequestInterceptor.java (added)
+++ hive/branches/branch-0.13/jdbc/src/java/org/apache/hive/jdbc/HttpKerberosRequestInterceptor.java Mon Mar 17 13:04:29 2014
@@ -0,0 +1,65 @@
+/**
+* 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.hive.jdbc;
+
+import java.io.IOException;
+
+import org.apache.hive.service.auth.HttpAuthUtils;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.protocol.HttpContext;
+
+/**
+*
+* Authentication interceptor which adds Base64 encoded payload,
+* containing the username and kerberos service ticket,
+* to the outgoing http request header.
+*
+*/
+public class HttpKerberosRequestInterceptor implements HttpRequestInterceptor {
+
+String principal;
+String host;
+String serverHttpUrl;
+
+public HttpKerberosRequestInterceptor(String principal, String host,
+    String serverHttpUrl) {
+  this.principal = principal;
+  this.host = host;
+  this.serverHttpUrl = serverHttpUrl;
+}
+
+@Override
+public void process(HttpRequest httpRequest, HttpContext httpContext)
+    throws HttpException, IOException {
+  String kerberosAuthHeader;
+  try {
+    // Generate the service ticket for sending to the server.
+    kerberosAuthHeader = HttpAuthUtils.getKerberosServiceTicket(
+        principal, host, serverHttpUrl);
+    // Set the session key token (Base64 encoded) in the headers
+    httpRequest.addHeader(HttpAuthUtils.AUTHORIZATION + ": " +
+        HttpAuthUtils.NEGOTIATE + " ", kerberosAuthHeader);
+  } catch (Exception e) {
+    throw new HttpException(e.getMessage(), e);
+  }
+}
+
+}

Modified: hive/branches/branch-0.13/pom.xml
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.13/pom.xml?rev=1578350&r1=1578349&r2=1578350&view=diff
==============================================================================
--- hive/branches/branch-0.13/pom.xml (original)
+++ hive/branches/branch-0.13/pom.xml Mon Mar 17 13:04:29 2014
@@ -106,8 +106,8 @@
     <hbase.hadoop1.version>0.96.0-hadoop1</hbase.hadoop1.version>
     <hbase.hadoop2.version>0.96.0-hadoop2</hbase.hadoop2.version>
     <!-- httpcomponents are not always in version sync -->
-    <httpcomponents.client.version>4.3.2</httpcomponents.client.version>
-    <httpcomponents.core.version>4.3.1</httpcomponents.core.version>
+    <httpcomponents.client.version>4.2.5</httpcomponents.client.version>
+    <httpcomponents.core.version>4.2.5</httpcomponents.core.version>
     <jackson.version>1.9.2</jackson.version>
     <javaewah.version>0.3.2</javaewah.version>
     <javolution.version>5.5.1</javolution.version>

Added: hive/branches/branch-0.13/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAccessController.java.orig
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.13/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAccessController.java.orig?rev=1578350&view=auto
==============================================================================
--- hive/branches/branch-0.13/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAccessController.java.orig (added)
+++ hive/branches/branch-0.13/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/sqlstd/SQLStdHiveAccessController.java.orig Mon Mar 17 13:04:29 2014
@@ -0,0 +1,497 @@
+/**
+ * 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.hadoop.hive.ql.security.authorization.plugin.sqlstd;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.hadoop.classification.InterfaceAudience.Private;
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.metastore.HiveMetaStore;
+import org.apache.hadoop.hive.metastore.IMetaStoreClient;
+import org.apache.hadoop.hive.metastore.api.GetPrincipalsInRoleRequest;
+import org.apache.hadoop.hive.metastore.api.GetPrincipalsInRoleResponse;
+import org.apache.hadoop.hive.metastore.api.HiveObjectPrivilege;
+import org.apache.hadoop.hive.metastore.api.HiveObjectRef;
+import org.apache.hadoop.hive.metastore.api.HiveObjectType;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.api.PrincipalType;
+import org.apache.hadoop.hive.metastore.api.PrivilegeBag;
+import org.apache.hadoop.hive.metastore.api.PrivilegeGrantInfo;
+import org.apache.hadoop.hive.metastore.api.Role;
+import org.apache.hadoop.hive.metastore.api.RolePrincipalGrant;
+import org.apache.hadoop.hive.ql.security.HiveAuthenticationProvider;
+import org.apache.hadoop.hive.ql.security.authorization.AuthorizationUtils;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAccessControlException;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAccessController;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthzPluginException;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveMetastoreClientFactory;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrincipal;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilege;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeInfo;
+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.security.authorization.plugin.HiveRole;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveRoleGrant;
+import org.apache.thrift.TException;
+
+/**
+ * Implements functionality of access control statements for sql standard based
+ * authorization
+ */
+@Private
+public class SQLStdHiveAccessController implements HiveAccessController {
+
+  private final HiveMetastoreClientFactory metastoreClientFactory;
+  private final HiveAuthenticationProvider authenticator;
+  private String currentUserName;
+  private List<HiveRole> currentRoles;
+  private HiveRole adminRole;
+  private final String ADMIN_ONLY_MSG = "User has to belong to ADMIN role and "
+      + "have it as current role, for this action.";
+  private final String HAS_ADMIN_PRIV_MSG = "grantor need to have ADMIN privileges on role being"
+      + " granted and have it as a current role for this action.";
+
+  SQLStdHiveAccessController(HiveMetastoreClientFactory metastoreClientFactory, HiveConf conf,
+      HiveAuthenticationProvider authenticator) throws HiveAuthzPluginException {
+    this.metastoreClientFactory = metastoreClientFactory;
+    this.authenticator = authenticator;
+    initUserRoles();
+  }
+
+  /**
+   * (Re-)initialize currentRoleNames if necessary.
+   * @throws HiveAuthzPluginException
+   */
+  private void initUserRoles() throws HiveAuthzPluginException {
+    //to aid in testing through .q files, authenticator is passed as argument to
+    // the interface. this helps in being able to switch the user within a session.
+    // so we need to check if the user has changed
+    String newUserName = authenticator.getUserName();
+    if(currentUserName == newUserName){
+      //no need to (re-)initialize the currentUserName, currentRoles fields
+      return;
+    }
+    this.currentUserName = newUserName;
+    this.currentRoles = getRolesFromMS();
+  }
+
+  private List<HiveRole> getRolesFromMS() throws HiveAuthzPluginException {
+    List<Role> roles;
+    try {
+      roles = metastoreClientFactory.getHiveMetastoreClient().list_roles(currentUserName,
+          PrincipalType.USER);
+      Map<String, HiveRole> name2Rolesmap = new HashMap<String, HiveRole>();
+      getAllRoleAncestors(name2Rolesmap, roles);
+      List<HiveRole> currentRoles = new ArrayList<HiveRole>(roles.size());
+      for (HiveRole role : name2Rolesmap.values()) {
+        if (!HiveMetaStore.ADMIN.equalsIgnoreCase(role.getRoleName())) {
+          currentRoles.add(role);
+        } else {
+          this.adminRole = role;
+        }
+      }
+      return currentRoles;
+    } catch (Exception e) {
+      throw new HiveAuthzPluginException("Failed to retrieve roles for " + currentUserName + ": "
+          + e.getMessage(), e);
+    }
+  }
+
+  /**
+   * Add role names of parentRoles and its parents to processedRolesMap
+   *
+   * @param processedRolesMap
+   * @param parentRoles
+   * @throws TException
+   * @throws HiveAuthzPluginException
+   * @throws MetaException
+   */
+  private void getAllRoleAncestors(Map<String, HiveRole> processedRolesMap, List<Role> parentRoles)
+      throws MetaException, HiveAuthzPluginException, TException {
+    for (Role parentRole : parentRoles) {
+      String parentRoleName = parentRole.getRoleName();
+      if (processedRolesMap.get(parentRoleName) == null) {
+        // unprocessed role: get its parents, add it to processed, and call this
+        // function recursively
+        List<Role> nextParentRoles = metastoreClientFactory.getHiveMetastoreClient().list_roles(
+            parentRoleName, PrincipalType.ROLE);
+        processedRolesMap.put(parentRoleName, new HiveRole(parentRole));
+        getAllRoleAncestors(processedRolesMap, nextParentRoles);
+      }
+    }
+  }
+
+  @Override
+  public void grantPrivileges(List<HivePrincipal> hivePrincipals,
+      List<HivePrivilege> hivePrivileges, HivePrivilegeObject hivePrivObject,
+      HivePrincipal grantorPrincipal, boolean grantOption)
+          throws HiveAuthzPluginException, HiveAccessControlException {
+
+    hivePrivileges = expandAndValidatePrivileges(hivePrivileges);
+
+    IMetaStoreClient metastoreClient = metastoreClientFactory.getHiveMetastoreClient();
+    // authorize the grant
+    GrantPrivAuthUtils.authorize(hivePrincipals, hivePrivileges, hivePrivObject, grantOption,
+        metastoreClient, authenticator.getUserName(), getCurrentRoles(), isUserAdmin());
+
+    // grant
+    PrivilegeBag privBag = SQLAuthorizationUtils.getThriftPrivilegesBag(hivePrincipals, hivePrivileges, hivePrivObject,
+        grantorPrincipal, grantOption);
+    try {
+      metastoreClient.grant_privileges(privBag);
+    } catch (Exception e) {
+      throw new HiveAuthzPluginException("Error granting privileges: " + e.getMessage(), e);
+    }
+  }
+
+  private List<HivePrivilege> expandAndValidatePrivileges(List<HivePrivilege> hivePrivileges)
+      throws HiveAuthzPluginException {
+    // expand ALL privileges, if any
+    hivePrivileges = expandAllPrivileges(hivePrivileges);
+    SQLAuthorizationUtils.validatePrivileges(hivePrivileges);
+    return hivePrivileges;
+  }
+
+  private List<HivePrivilege> expandAllPrivileges(List<HivePrivilege> hivePrivileges) {
+    Set<HivePrivilege> hivePrivSet = new HashSet<HivePrivilege>();
+    for (HivePrivilege hivePrivilege : hivePrivileges) {
+      if (hivePrivilege.getName().equals("ALL")) {
+        // expand to all supported privileges
+        for (SQLPrivilegeType privType : SQLPrivilegeType.values()) {
+          hivePrivSet.add(new HivePrivilege(privType.name(), hivePrivilege.getColumns()));
+        }
+      } else {
+        hivePrivSet.add(hivePrivilege);
+      }
+    }
+    return new ArrayList<HivePrivilege>(hivePrivSet);
+  }
+
+
+  @Override
+  public void revokePrivileges(List<HivePrincipal> hivePrincipals,
+      List<HivePrivilege> hivePrivileges, HivePrivilegeObject hivePrivObject,
+      HivePrincipal grantorPrincipal, boolean grantOption)
+          throws HiveAuthzPluginException, HiveAccessControlException {
+
+    hivePrivileges = expandAndValidatePrivileges(hivePrivileges);
+
+    IMetaStoreClient metastoreClient = metastoreClientFactory.getHiveMetastoreClient();
+    // authorize the revoke, and get the set of privileges to be revoked
+    List<HiveObjectPrivilege> revokePrivs = RevokePrivAuthUtils
+        .authorizeAndGetRevokePrivileges(hivePrincipals, hivePrivileges, hivePrivObject,
+            grantOption, metastoreClient, authenticator.getUserName());
+
+    try {
+      // unfortunately, the metastore api revokes all privileges that match on
+      // principal, privilege object type it does not filter on the grator
+      // username.
+      // So this will revoke privileges that are granted by other users.This is
+      // not SQL compliant behavior. Need to change/add a metastore api
+      // that has desired behavior.
+      metastoreClient.revoke_privileges(new PrivilegeBag(revokePrivs));
+    } catch (Exception e) {
+      throw new HiveAuthzPluginException("Error revoking privileges", e);
+    }
+  }
+
+  @Override
+  public void createRole(String roleName, HivePrincipal adminGrantor)
+      throws HiveAuthzPluginException, HiveAccessControlException {
+    // only user belonging to admin role can create new roles.
+    if (!isUserAdmin()) {
+      throw new HiveAccessControlException("Current user : " + currentUserName+ " is not"
+      + " allowed to add roles. " + ADMIN_ONLY_MSG);
+    }
+    try {
+      String grantorName = adminGrantor == null ? null : adminGrantor.getName();
+      metastoreClientFactory.getHiveMetastoreClient().create_role(
+        new Role(roleName, 0, grantorName));
+    } catch (Exception e) {
+      throw new HiveAuthzPluginException("Error create role", e);
+    }
+  }
+
+  @Override
+  public void dropRole(String roleName) throws HiveAuthzPluginException, HiveAccessControlException {
+    // only user belonging to admin role can drop existing role
+    if (!isUserAdmin()) {
+      throw new HiveAccessControlException("Current user : " + currentUserName+ " is not"
+      + " allowed to drop role. " + ADMIN_ONLY_MSG);
+    }
+    try {
+      metastoreClientFactory.getHiveMetastoreClient().drop_role(roleName);
+    } catch (Exception e) {
+      throw new HiveAuthzPluginException("Error dropping role", e);
+    }
+  }
+
+  @Override
+  public List<HiveRole> getRoles(HivePrincipal hivePrincipal) throws HiveAuthzPluginException {
+    try {
+      List<Role> roles = metastoreClientFactory.getHiveMetastoreClient().list_roles(
+          hivePrincipal.getName(), AuthorizationUtils.getThriftPrincipalType(hivePrincipal.getType()));
+      List<HiveRole> hiveRoles = new ArrayList<HiveRole>(roles.size());
+      for (Role role : roles){
+        hiveRoles.add(new HiveRole(role));
+      }
+      return hiveRoles;
+    } catch (Exception e) {
+      throw new HiveAuthzPluginException("Error listing roles for user "
+          + hivePrincipal.getName() + ": " + e.getMessage(), e);
+    }
+  }
+
+  @Override
+  public void grantRole(List<HivePrincipal> hivePrincipals, List<String> roleNames,
+    boolean grantOption, HivePrincipal grantorPrinc) throws HiveAuthzPluginException,
+    HiveAccessControlException {
+    if (!(isUserAdmin() || doesUserHasAdminOption(roleNames))) {
+      throw new HiveAccessControlException("Current user : " + currentUserName+ " is not"
+        + " allowed to grant role. " + ADMIN_ONLY_MSG + " Otherwise, " + HAS_ADMIN_PRIV_MSG);
+    }
+    for (HivePrincipal hivePrincipal : hivePrincipals) {
+      for (String roleName : roleNames) {
+        try {
+          IMetaStoreClient mClient = metastoreClientFactory.getHiveMetastoreClient();
+          mClient.grant_role(roleName, hivePrincipal.getName(),
+              AuthorizationUtils.getThriftPrincipalType(hivePrincipal.getType()),
+              grantorPrinc.getName(),
+              AuthorizationUtils.getThriftPrincipalType(grantorPrinc.getType()), grantOption);
+        } catch (MetaException e) {
+          throw new HiveAuthzPluginException(e.getMessage(), e);
+        } catch (Exception e) {
+          String msg = "Error granting roles for " + hivePrincipal.getName() + " to role "
+              + roleName + ": " + e.getMessage();
+          throw new HiveAuthzPluginException(msg, e);
+        }
+      }
+    }
+  }
+
+  @Override
+  public void revokeRole(List<HivePrincipal> hivePrincipals, List<String> roleNames,
+    boolean grantOption, HivePrincipal grantorPrinc) throws HiveAuthzPluginException,
+    HiveAccessControlException {
+    if (grantOption) {
+      // removing grant privileges only is not supported in metastore api
+      throw new HiveAuthzPluginException("Revoking only the admin privileges on "
+        + "role is not currently supported");
+    }
+    if (!(isUserAdmin() || doesUserHasAdminOption(roleNames))) {
+      throw new HiveAccessControlException("Current user : " + currentUserName+ " is not"
+          + " allowed to revoke role. " + ADMIN_ONLY_MSG + " Otherwise, " + HAS_ADMIN_PRIV_MSG);
+    }
+    for (HivePrincipal hivePrincipal : hivePrincipals) {
+      for (String roleName : roleNames) {
+        try {
+          IMetaStoreClient mClient = metastoreClientFactory.getHiveMetastoreClient();
+          mClient.revoke_role(roleName, hivePrincipal.getName(),
+              AuthorizationUtils.getThriftPrincipalType(hivePrincipal.getType()));
+        } catch (Exception e) {
+          String msg = "Error revoking roles for " + hivePrincipal.getName() + " to role "
+              + roleName + ": " + e.getMessage();
+          throw new HiveAuthzPluginException(msg, e);
+        }
+      }
+    }
+  }
+
+  @Override
+  public List<String> getAllRoles() throws HiveAuthzPluginException, HiveAccessControlException {
+    // only user belonging to admin role can list role
+    if (!isUserAdmin()) {
+      throw new HiveAccessControlException("Current user : " + currentUserName+ " is not"
+        + " allowed to list roles. " + ADMIN_ONLY_MSG);
+    }
+    try {
+      return metastoreClientFactory.getHiveMetastoreClient().listRoleNames();
+    } catch (Exception e) {
+      throw new HiveAuthzPluginException("Error listing all roles", e);
+    }
+  }
+
+
+  @Override
+  public List<HiveRoleGrant> getPrincipalsInRoleInfo(String roleName) throws HiveAuthzPluginException, HiveAccessControlException {
+    // only user belonging to admin role can list role
+    if (!isUserAdmin()) {
+      throw new HiveAccessControlException("Current user : " + currentUserName+ " is not"
+        + " allowed get principals in a role. " + ADMIN_ONLY_MSG);
+    }
+    try {
+      GetPrincipalsInRoleResponse princGrantInfo =
+          metastoreClientFactory.getHiveMetastoreClient().get_principals_in_role(new GetPrincipalsInRoleRequest(roleName));
+
+      List<HiveRoleGrant> hiveRoleGrants = new ArrayList<HiveRoleGrant>();
+      for(RolePrincipalGrant thriftRoleGrant :  princGrantInfo.getPrincipalGrants()){
+        hiveRoleGrants.add(new HiveRoleGrant(thriftRoleGrant));
+      }
+      return hiveRoleGrants;
+    } catch (Exception e) {
+      throw new HiveAuthzPluginException("Error getting principals for all roles", e);
+    }
+  }
+
+  @Override
+  public List<HivePrivilegeInfo> showPrivileges(HivePrincipal principal, HivePrivilegeObject privObj)
+      throws HiveAuthzPluginException {
+    try {
+      IMetaStoreClient mClient = metastoreClientFactory.getHiveMetastoreClient();
+      List<HivePrivilegeInfo> resPrivInfos = new ArrayList<HivePrivilegeInfo>();
+      // get metastore/thrift privilege object using metastore api
+      List<HiveObjectPrivilege> msObjPrivs = mClient.list_privileges(principal.getName(),
+          AuthorizationUtils.getThriftPrincipalType(principal.getType()),
+          SQLAuthorizationUtils.getThriftHiveObjectRef(privObj));
+
+
+      // convert the metastore thrift objects to result objects
+      for (HiveObjectPrivilege msObjPriv : msObjPrivs) {
+        // result principal
+        HivePrincipal resPrincipal = new HivePrincipal(msObjPriv.getPrincipalName(),
+            AuthorizationUtils.getHivePrincipalType(msObjPriv.getPrincipalType()));
+
+        // result privilege
+        PrivilegeGrantInfo msGrantInfo = msObjPriv.getGrantInfo();
+        HivePrivilege resPrivilege = new HivePrivilege(msGrantInfo.getPrivilege(), null);
+
+        // result object
+        HiveObjectRef msObjRef = msObjPriv.getHiveObject();
+        HivePrivilegeObject resPrivObj = new HivePrivilegeObject(
+            getPluginObjType(msObjRef.getObjectType()), msObjRef.getDbName(),
+            msObjRef.getObjectName());
+
+        // result grantor principal
+        HivePrincipal grantorPrincipal = new HivePrincipal(msGrantInfo.getGrantor(),
+            AuthorizationUtils.getHivePrincipalType(msGrantInfo.getGrantorType()));
+
+        HivePrivilegeInfo resPrivInfo = new HivePrivilegeInfo(resPrincipal, resPrivilege,
+            resPrivObj, grantorPrincipal, msGrantInfo.isGrantOption(), msGrantInfo.getCreateTime());
+        resPrivInfos.add(resPrivInfo);
+      }
+      return resPrivInfos;
+
+    } catch (Exception e) {
+      throw new HiveAuthzPluginException("Error showing privileges: "+ e.getMessage(), e);
+    }
+
+  }
+
+  private HivePrivilegeObjectType getPluginObjType(HiveObjectType objectType)
+      throws HiveAuthzPluginException {
+    switch (objectType) {
+    case DATABASE:
+      return HivePrivilegeObjectType.DATABASE;
+    case TABLE:
+      return HivePrivilegeObjectType.TABLE_OR_VIEW;
+    case COLUMN:
+    case GLOBAL:
+    case PARTITION:
+      throw new HiveAuthzPluginException("Unsupported object type " + objectType);
+    default:
+      throw new AssertionError("Unexpected object type " + objectType);
+    }
+  }
+
+  @Override
+  public void setCurrentRole(String roleName) throws HiveAccessControlException,
+    HiveAuthzPluginException {
+
+    initUserRoles();
+    if ("NONE".equalsIgnoreCase(roleName)) {
+      // for set role NONE, reset roles to default roles.
+      currentRoles.clear();
+      currentRoles.addAll(getRolesFromMS());
+      return;
+    }
+    for (HiveRole role : getRolesFromMS()) {
+      // set to one of the roles user belongs to.
+      if (role.getRoleName().equalsIgnoreCase(roleName)) {
+        currentRoles.clear();
+        currentRoles.add(role);
+        return;
+      }
+    }
+    // set to ADMIN role, if user belongs there.
+    if (HiveMetaStore.ADMIN.equalsIgnoreCase(roleName) && null != this.adminRole) {
+      currentRoles.clear();
+      currentRoles.add(adminRole);
+      return;
+    }
+    // If we are here it means, user is requesting a role he doesn't belong to.
+    throw new HiveAccessControlException(currentUserName +" doesn't belong to role "
+      +roleName);
+  }
+
+  @Override
+  public List<HiveRole> getCurrentRoles() throws HiveAuthzPluginException {
+    initUserRoles();
+    return currentRoles;
+  }
+
+  /**
+   * @return true only if current role of user is Admin
+   * @throws HiveAuthzPluginException
+   */
+  boolean isUserAdmin() throws HiveAuthzPluginException {
+    List<HiveRole> roles;
+    try {
+      roles = getCurrentRoles();
+    } catch (Exception e) {
+      throw new HiveAuthzPluginException(e);
+    }
+    for (HiveRole role : roles) {
+      if (role.getRoleName().equalsIgnoreCase(HiveMetaStore.ADMIN)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private boolean doesUserHasAdminOption(List<String> roleNames) throws HiveAuthzPluginException {
+    List<HiveRole> currentRoles;
+    try {
+      currentRoles = getCurrentRoles();
+    } catch (Exception e) {
+        throw new HiveAuthzPluginException(e);
+    }
+    for (String roleName : roleNames) {
+      boolean roleFound = false;
+      for (HiveRole currentRole : currentRoles) {
+        if (roleName.equalsIgnoreCase(currentRole.getRoleName())) {
+          roleFound = true;
+          if (!currentRole.isGrantOption()) {
+            return false;
+          } else {
+              break;
+          }
+        }
+      }
+      if (!roleFound) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+}

Modified: hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HiveAuthFactory.java
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HiveAuthFactory.java?rev=1578350&r1=1578349&r2=1578350&view=diff
==============================================================================
--- hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HiveAuthFactory.java (original)
+++ hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HiveAuthFactory.java Mon Mar 17 13:04:29 2014
@@ -32,9 +32,9 @@ import org.apache.hadoop.hive.conf.HiveC
 import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
 import org.apache.hadoop.hive.shims.ShimLoader;
 import org.apache.hadoop.hive.thrift.HadoopThriftAuthBridge;
+import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hive.service.cli.HiveSQLException;
 import org.apache.hive.service.cli.thrift.ThriftCLIService;
-import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.thrift.TProcessorFactory;
 import org.apache.thrift.transport.TSSLTransportFactory;
 import org.apache.thrift.transport.TServerSocket;
@@ -55,7 +55,7 @@ public class HiveAuthFactory {
     KERBEROS("KERBEROS"),
     CUSTOM("CUSTOM");
 
-    private String authType; // Auth type for SASL
+    private String authType;
 
     AuthTypes(String authType) {
       this.authType = authType;
@@ -69,6 +69,7 @@ public class HiveAuthFactory {
 
   private HadoopThriftAuthBridge.Server saslServer = null;
   private String authTypeStr;
+  private String transportMode;
   private final HiveConf conf;
 
   public static final String HS2_PROXY_USER = "hive.server2.proxy.user";
@@ -76,40 +77,48 @@ public class HiveAuthFactory {
 
   public HiveAuthFactory() throws TTransportException {
     conf = new HiveConf();
-
+    transportMode = conf.getVar(HiveConf.ConfVars.HIVE_SERVER2_TRANSPORT_MODE);
     authTypeStr = conf.getVar(HiveConf.ConfVars.HIVE_SERVER2_AUTHENTICATION);
-    if (authTypeStr == null) {
-      authTypeStr = AuthTypes.NONE.getAuthName();
+
+    // In http mode we use NOSASL as the default auth type
+    if (transportMode.equalsIgnoreCase("http")) {
+      if (authTypeStr == null) {
+        authTypeStr = AuthTypes.NOSASL.getAuthName();
+      }
     }
-    if (authTypeStr.equalsIgnoreCase(AuthTypes.KERBEROS.getAuthName())
-        && ShimLoader.getHadoopShims().isSecureShimImpl()) {
-      saslServer = ShimLoader.getHadoopThriftAuthBridge().createServer(
-        conf.getVar(ConfVars.HIVE_SERVER2_KERBEROS_KEYTAB),
-        conf.getVar(ConfVars.HIVE_SERVER2_KERBEROS_PRINCIPAL)
-        );
-      // start delegation token manager
-      try {
-        saslServer.startDelegationTokenSecretManager(conf, null);
-      } catch (IOException e) {
-        throw new TTransportException("Failed to start token manager", e);
+    else {
+      if (authTypeStr == null) {
+        authTypeStr = AuthTypes.NONE.getAuthName();
+      }
+      if (authTypeStr.equalsIgnoreCase(AuthTypes.KERBEROS.getAuthName())
+          && ShimLoader.getHadoopShims().isSecureShimImpl()) {
+        saslServer = ShimLoader.getHadoopThriftAuthBridge().createServer(
+            conf.getVar(ConfVars.HIVE_SERVER2_KERBEROS_KEYTAB),
+            conf.getVar(ConfVars.HIVE_SERVER2_KERBEROS_PRINCIPAL)
+            );
+        // start delegation token manager
+        try {
+          saslServer.startDelegationTokenSecretManager(conf, null);
+        } catch (IOException e) {
+          throw new TTransportException("Failed to start token manager", e);
+        }
       }
-
     }
   }
 
   public Map<String, String> getSaslProperties() {
     Map<String, String> saslProps = new HashMap<String, String>();
     SaslQOP saslQOP =
-            SaslQOP.fromString(conf.getVar(ConfVars.HIVE_SERVER2_THRIFT_SASL_QOP));
+        SaslQOP.fromString(conf.getVar(ConfVars.HIVE_SERVER2_THRIFT_SASL_QOP));
     // hadoop.rpc.protection being set to a higher level than hive.server2.thrift.rpc.protection
     // does not make sense in most situations. Log warning message in such cases.
     Map<String, String> hadoopSaslProps =  ShimLoader.getHadoopThriftAuthBridge().
-            getHadoopSaslProperties(conf);
+        getHadoopSaslProperties(conf);
     SaslQOP hadoopSaslQOP = SaslQOP.fromString(hadoopSaslProps.get(Sasl.QOP));
     if(hadoopSaslQOP.ordinal() > saslQOP.ordinal()) {
       LOG.warn(MessageFormat.format("\"hadoop.rpc.protection\" is set to higher security level " +
-              "{0} then {1} which is set to {2}", hadoopSaslQOP.toString(),
-              ConfVars.HIVE_SERVER2_THRIFT_SASL_QOP.varname, saslQOP.toString()));
+          "{0} then {1} which is set to {2}", hadoopSaslQOP.toString(),
+          ConfVars.HIVE_SERVER2_THRIFT_SASL_QOP.varname, saslQOP.toString()));
     }
     saslProps.put(Sasl.QOP, saslQOP.toString());
     saslProps.put(Sasl.SERVER_AUTH, "true");
@@ -142,10 +151,15 @@ public class HiveAuthFactory {
 
   public TProcessorFactory getAuthProcFactory(ThriftCLIService service)
       throws LoginException {
-    if (authTypeStr.equalsIgnoreCase(AuthTypes.KERBEROS.getAuthName())) {
-      return KerberosSaslHelper.getKerberosProcessorFactory(saslServer, service);
-    } else {
-      return PlainSaslHelper.getPlainProcessorFactory(service);
+    if (transportMode.equalsIgnoreCase("http")) {
+      return HttpAuthUtils.getAuthProcFactory(service);
+    }
+    else {
+      if (authTypeStr.equalsIgnoreCase(AuthTypes.KERBEROS.getAuthName())) {
+        return KerberosSaslHelper.getKerberosProcessorFactory(saslServer, service);
+      } else {
+        return PlainSaslHelper.getPlainProcessorFactory(service);
+      }
     }
   }
 
@@ -161,14 +175,11 @@ public class HiveAuthFactory {
     return saslServer != null ? saslServer.getRemoteAddress().toString() : null;
   }
 
-  /* perform kerberos login using the hadoop shim API if the configuration is available */
+  // Perform kerberos login using the hadoop shim API if the configuration is available
   public static void loginFromKeytab(HiveConf hiveConf) throws IOException {
     String principal = hiveConf.getVar(ConfVars.HIVE_SERVER2_KERBEROS_PRINCIPAL);
     String keyTabFile = hiveConf.getVar(ConfVars.HIVE_SERVER2_KERBEROS_KEYTAB);
-    if (principal.isEmpty() && keyTabFile.isEmpty()) {
-      // no security configuration available
-      return;
-    } else if (!principal.isEmpty() && !keyTabFile.isEmpty()) {
+    if (!principal.isEmpty() && !keyTabFile.isEmpty()) {
       ShimLoader.getHadoopShims().loginUserFromKeytab(principal, keyTabFile);
     } else {
       throw new IOException ("HiveServer2 kerberos principal or keytab is not correctly configured");
@@ -289,7 +300,7 @@ public class HiveAuthFactory {
       }
       if (!proxyUser.equalsIgnoreCase(realUser)) {
         ShimLoader.getHadoopShims().
-          authorizeProxyAccess(proxyUser, sessionUgi, ipAddress, hiveConf);
+        authorizeProxyAccess(proxyUser, sessionUgi, ipAddress, hiveConf);
       }
     } catch (IOException e) {
       throw new HiveSQLException("Failed to validate proxy privilage of " + realUser +

Added: hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HttpAuthUtils.java
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HttpAuthUtils.java?rev=1578350&view=auto
==============================================================================
--- hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HttpAuthUtils.java (added)
+++ hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HttpAuthUtils.java Mon Mar 17 13:04:29 2014
@@ -0,0 +1,191 @@
+/**
+ * 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.hive.service.auth;
+
+import java.io.IOException;
+import java.security.PrivilegedExceptionAction;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.shims.ShimLoader;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hive.service.cli.thrift.TCLIService;
+import org.apache.hive.service.cli.thrift.TCLIService.Iface;
+import org.apache.hive.service.cli.thrift.ThriftCLIService;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HttpContext;
+import org.apache.thrift.TProcessor;
+import org.apache.thrift.TProcessorFactory;
+import org.apache.thrift.transport.TTransport;
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.Oid;
+
+/**
+ *
+ * Utility functions for http mode authentication
+ *
+ */
+public class HttpAuthUtils {
+
+  public static final String WWW_AUTHENTICATE = "WWW-Authenticate";
+  public static final String AUTHORIZATION = "Authorization";
+  public static final String BASIC = "Basic";
+  public static final String NEGOTIATE = "Negotiate";
+
+  public static class HttpCLIServiceProcessorFactory extends TProcessorFactory {
+    private final ThriftCLIService service;
+    private final HiveConf hiveConf;
+    private final boolean isDoAsEnabled;
+
+    public HttpCLIServiceProcessorFactory(ThriftCLIService service) {
+      super(null);
+      this.service = service;
+      this.hiveConf = service.getHiveConf();
+      this.isDoAsEnabled = hiveConf.getBoolVar(
+          HiveConf.ConfVars.HIVE_SERVER2_ENABLE_DOAS);
+    }
+
+    @Override
+    public TProcessor getProcessor(TTransport trans) {
+      TProcessor baseProcessor = new TCLIService.Processor<Iface>(service);
+      return isDoAsEnabled ? new HttpCLIServiceUGIProcessor(baseProcessor) :
+        baseProcessor;
+    }
+  }
+
+  public static TProcessorFactory getAuthProcFactory(ThriftCLIService service) {
+    return new HttpCLIServiceProcessorFactory(service);
+  }
+
+  /**
+   *
+   * @return Stringified Base64 encoded kerberosAuthHeader on success
+   * @throws GSSException
+   * @throws IOException
+   * @throws InterruptedException
+   */
+  public static String getKerberosServiceTicket(String principal,
+      String host, String serverHttpUrl)
+          throws GSSException, IOException, InterruptedException {
+    UserGroupInformation clientUGI = getClientUGI("kerberos");
+    String serverPrincipal = getServerPrincipal(principal, host);
+    // Uses the Ticket Granting Ticket in the UserGroupInformation
+    return clientUGI.doAs(new HttpKerberosClientAction(serverPrincipal,
+        clientUGI.getShortUserName(), serverHttpUrl));
+  }
+
+  /**
+   * Get server pricipal and verify that hostname is present
+   * @return
+   * @throws IOException
+   */
+  private static String getServerPrincipal(String principal, String host)
+      throws IOException {
+    return ShimLoader.getHadoopThriftAuthBridge().getServerPrincipal(
+        principal, host);
+  }
+
+  /**
+   * JAAS login to setup the client UserGroupInformation.
+   * Sets up the kerberos Ticket Granting Ticket,
+   * in the client UserGroupInformation object
+   * @return Client's UserGroupInformation
+   * @throws IOException
+   */
+  public static UserGroupInformation getClientUGI(String authType)
+      throws IOException {
+    return ShimLoader.getHadoopThriftAuthBridge().getCurrentUGIWithConf(authType);
+  }
+
+  /**
+   *
+   * HttpKerberosClientAction
+   *
+   */
+  public static class HttpKerberosClientAction implements
+  PrivilegedExceptionAction<String> {
+    String serverPrincipal;
+    String clientUserName;
+    String serverHttpUrl;
+    private final Base64 base64codec;
+    public static final String HTTP_RESPONSE = "HTTP_RESPONSE";
+    public static final String SERVER_HTTP_URL = "SERVER_HTTP_URL";
+    private final HttpContext httpContext;
+
+    public HttpKerberosClientAction(String serverPrincipal,
+        String clientUserName, String serverHttpUrl) {
+      this.serverPrincipal = serverPrincipal;
+      this.clientUserName = clientUserName;
+      this.serverHttpUrl = serverHttpUrl;
+      this.base64codec = new Base64(0);
+      this.httpContext = new BasicHttpContext();
+      httpContext.setAttribute(SERVER_HTTP_URL, serverHttpUrl);
+    }
+
+    @Override
+    public String run() throws Exception {
+      // This Oid for Kerberos GSS-API mechanism.
+      Oid mechOid = new Oid("1.2.840.113554.1.2.2");
+      // Oid for kerberos principal name
+      Oid krb5PrincipalOid = new Oid("1.2.840.113554.1.2.2.1");
+
+      GSSManager manager = GSSManager.getInstance();
+
+      // GSS name for client
+      GSSName clientName = manager.createName(clientUserName, GSSName.NT_USER_NAME);
+      // GSS name for server
+      GSSName serverName = manager.createName(serverPrincipal, krb5PrincipalOid);
+
+      // GSS credentials for client
+      GSSCredential clientCreds = manager.createCredential(clientName,
+          GSSCredential.DEFAULT_LIFETIME, mechOid,
+          GSSCredential.INITIATE_ONLY);
+
+      /*
+       * Create a GSSContext for mutual authentication with the
+       * server.
+       *    - serverName is the GSSName that represents the server.
+       *    - krb5Oid is the Oid that represents the mechanism to
+       *      use. The client chooses the mechanism to use.
+       *    - clientCreds are the client credentials
+       */
+      GSSContext gssContext = manager.createContext(serverName,
+          mechOid, clientCreds, GSSContext.DEFAULT_LIFETIME);
+
+      // Mutual authentication not r
+      gssContext.requestMutualAuth(false);
+
+      // Estabilish context
+      byte[] inToken = new byte[0];
+      byte[] outToken;
+
+      outToken = gssContext.initSecContext(inToken, 0, inToken.length);
+
+      gssContext.dispose();
+      // Base64 encoded and stringified token for server
+      String authHeaderBase64String = new String(base64codec.encode(outToken));
+      return authHeaderBase64String;
+    }
+  }
+}

Added: hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HttpAuthenticationException.java
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HttpAuthenticationException.java?rev=1578350&view=auto
==============================================================================
--- hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HttpAuthenticationException.java (added)
+++ hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HttpAuthenticationException.java Mon Mar 17 13:04:29 2014
@@ -0,0 +1,42 @@
+/**
+ * Licensed 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. See accompanying LICENSE file.
+ */
+
+package org.apache.hive.service.auth;
+
+public class HttpAuthenticationException extends Exception{
+  static final long serialVersionUID = 0;
+
+  /**
+   * @param cause original exception.
+   */
+  public HttpAuthenticationException(Throwable cause) {
+    super(cause);
+  }
+
+  /**
+   * @param msg exception message.
+   */
+  public HttpAuthenticationException(String msg) {
+    super(msg);
+  }
+
+  /**
+   * @param msg exception message.
+   * @param cause original exception.
+   */
+  public HttpAuthenticationException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+
+}

Added: hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HttpCLIServiceUGIProcessor.java
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HttpCLIServiceUGIProcessor.java?rev=1578350&view=auto
==============================================================================
--- hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HttpCLIServiceUGIProcessor.java (added)
+++ hive/branches/branch-0.13/service/src/java/org/apache/hive/service/auth/HttpCLIServiceUGIProcessor.java Mon Mar 17 13:04:29 2014
@@ -0,0 +1,83 @@
+/**
+ * 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.hive.service.auth;
+
+import java.io.IOException;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+
+import org.apache.hadoop.hive.shims.HadoopShims;
+import org.apache.hadoop.hive.shims.ShimLoader;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hive.service.cli.session.SessionManager;
+import org.apache.thrift.TException;
+import org.apache.thrift.TProcessor;
+import org.apache.thrift.protocol.TProtocol;
+
+/**
+ *
+ * Wraps the underlying thrift processor's process call,
+ * to assume the client user's UGI/Subject for the doAs calls.
+ * Gets the client's username from a threadlocal in SessionManager which is
+ * set in the ThriftHttpServlet, and constructs a client UGI object from that.
+ *
+ */
+
+public class HttpCLIServiceUGIProcessor implements TProcessor {
+
+  private final TProcessor underlyingProcessor;
+  private final HadoopShims shim;
+
+  public HttpCLIServiceUGIProcessor(TProcessor underlyingProcessor) {
+    this.underlyingProcessor = underlyingProcessor;
+    this.shim = ShimLoader.getHadoopShims();
+  }
+
+  @Override
+  public boolean process(final TProtocol in, final TProtocol out) throws TException {
+    /**
+     * Build the client UGI from threadlocal username [SessionManager.getUserName()].
+     * The threadlocal username is set in the ThriftHttpServlet.
+     */
+    UserGroupInformation clientUgi = null;
+    try {
+      clientUgi = shim.createRemoteUser(SessionManager.getUserName(), new ArrayList<String>());
+      return shim.doAs(clientUgi, new PrivilegedExceptionAction<Boolean>() {
+        @Override
+        public Boolean run() {
+          try {
+            return underlyingProcessor.process(in, out);
+          } catch (TException te) {
+            throw new RuntimeException(te);
+          }
+        }
+      });
+    }
+    catch (RuntimeException rte) {
+      if (rte.getCause() instanceof TException) {
+        throw (TException)rte.getCause();
+      }
+      throw rte;
+    } catch (InterruptedException ie) {
+      throw new RuntimeException(ie); // unexpected!
+    } catch (IOException ioe) {
+      throw new RuntimeException(ioe); // unexpected!
+    }
+  }
+}

Modified: hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/CLIService.java
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/CLIService.java?rev=1578350&r1=1578349&r2=1578350&view=diff
==============================================================================
--- hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/CLIService.java (original)
+++ hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/CLIService.java Mon Mar 17 13:04:29 2014
@@ -34,11 +34,13 @@ import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.fs.permission.FsPermission;
 import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
 import org.apache.hadoop.hive.metastore.HiveMetaStoreClient;
 import org.apache.hadoop.hive.metastore.IMetaStoreClient;
 import org.apache.hadoop.hive.ql.metadata.Hive;
 import org.apache.hadoop.hive.ql.metadata.HiveException;
 import org.apache.hadoop.hive.shims.ShimLoader;
+import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hive.service.CompositeService;
 import org.apache.hive.service.ServiceException;
 import org.apache.hive.service.auth.HiveAuthFactory;
@@ -64,8 +66,7 @@ public class CLIService extends Composit
   private HiveConf hiveConf;
   private SessionManager sessionManager;
   private IMetaStoreClient metastoreClient;
-  private String serverUserName = null;
-
+  private UserGroupInformation serviceUGI;
 
   public CLIService() {
     super("CLIService");
@@ -74,21 +75,29 @@ public class CLIService extends Composit
   @Override
   public synchronized void init(HiveConf hiveConf) {
     this.hiveConf = hiveConf;
-
     sessionManager = new SessionManager();
     addService(sessionManager);
-    try {
-      HiveAuthFactory.loginFromKeytab(hiveConf);
-      serverUserName = ShimLoader.getHadoopShims().
-          getShortUserName(ShimLoader.getHadoopShims().getUGIForConf(hiveConf));
-    } catch (IOException e) {
-      throw new ServiceException("Unable to login to kerberos with given principal/keytab", e);
-    } catch (LoginException e) {
-      throw new ServiceException("Unable to login to kerberos with given principal/keytab", e);
+    /**
+     * If auth mode is Kerberos, do a kerberos login for the service from the keytab
+     */
+    if (hiveConf.getVar(ConfVars.HIVE_SERVER2_AUTHENTICATION).equalsIgnoreCase(
+        HiveAuthFactory.AuthTypes.KERBEROS.toString())) {
+      try {
+        HiveAuthFactory.loginFromKeytab(hiveConf);
+        this.serviceUGI = ShimLoader.getHadoopShims().getUGIForConf(hiveConf);
+      } catch (IOException e) {
+        throw new ServiceException("Unable to login to kerberos with given principal/keytab", e);
+      } catch (LoginException e) {
+        throw new ServiceException("Unable to login to kerberos with given principal/keytab", e);
+      }
     }
     super.init(hiveConf);
   }
 
+  public UserGroupInformation getServiceUGI() {
+    return this.serviceUGI;
+  }
+
   @Override
   public synchronized void start() {
     super.start();
@@ -441,7 +450,7 @@ public class CLIService extends Composit
   public void cancelDelegationToken(SessionHandle sessionHandle, HiveAuthFactory authFactory,
       String tokenStr) throws HiveSQLException {
     sessionManager.getSession(sessionHandle).
-        cancelDelegationToken(authFactory, tokenStr);
+    cancelDelegationToken(authFactory, tokenStr);
     LOG.info(sessionHandle  + ": cancelDelegationToken()");
   }
 

Modified: hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/session/SessionManager.java
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/session/SessionManager.java?rev=1578350&r1=1578349&r2=1578350&view=diff
==============================================================================
--- hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/session/SessionManager.java (original)
+++ hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/session/SessionManager.java Mon Mar 17 13:04:29 2014
@@ -101,7 +101,7 @@ public class SessionManager extends Comp
 
   public SessionHandle openSession(TProtocolVersion protocol, String username, String password,
       Map<String, String> sessionConf, boolean withImpersonation, String delegationToken)
-      throws HiveSQLException {
+          throws HiveSQLException {
     HiveSession session;
     if (withImpersonation) {
       HiveSessionImplwithUGI hiveSessionUgi = new HiveSessionImplwithUGI(protocol, username, password,
@@ -145,6 +145,44 @@ public class SessionManager extends Comp
     return operationManager;
   }
 
+  private static ThreadLocal<String> threadLocalIpAddress = new ThreadLocal<String>() {
+    @Override
+    protected synchronized String initialValue() {
+      return null;
+    }
+  };
+
+  public static void setIpAddress(String ipAddress) {
+    threadLocalIpAddress.set(ipAddress);
+  }
+
+  public static void clearIpAddress() {
+    threadLocalIpAddress.remove();
+  }
+
+  public static String getIpAddress() {
+    return threadLocalIpAddress.get();
+  }
+
+  private static ThreadLocal<String> threadLocalUserName = new ThreadLocal<String>(){
+    @Override
+    protected synchronized String initialValue() {
+      return null;
+    }
+  };
+
+  public static void setUserName(String userName) {
+    threadLocalUserName.set(userName);
+  }
+
+  public static void clearUserName() {
+    threadLocalUserName.remove();
+  }
+
+  public static String getUserName() {
+    return threadLocalUserName.get();
+  }
+
   // execute session hooks
   private void executeSessionHooks(HiveSession session) throws Exception {
     List<HiveSessionHook> sessionHooks = HookUtils.getHooks(hiveConf,

Modified: hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/thrift/ThriftCLIService.java
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/thrift/ThriftCLIService.java?rev=1578350&r1=1578349&r2=1578350&view=diff
==============================================================================
--- hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/thrift/ThriftCLIService.java (original)
+++ hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/thrift/ThriftCLIService.java Mon Mar 17 13:04:29 2014
@@ -220,12 +220,20 @@ public abstract class ThriftCLIService e
     return getProxyUser(userName, req.getConfiguration(), getIpAddress());
   }
 
+  /**
+   * Create a session handle
+   * @param req
+   * @param res
+   * @return
+   * @throws HiveSQLException
+   * @throws LoginException
+   * @throws IOException
+   */
   SessionHandle getSessionHandle(TOpenSessionReq req, TOpenSessionResp res)
       throws HiveSQLException, LoginException, IOException {
-
     String userName = getUserName(req);
-    TProtocolVersion protocol = getMinVersion(CLIService.SERVER_VERSION, req.getClient_protocol());
-
+    TProtocolVersion protocol = getMinVersion(CLIService.SERVER_VERSION,
+        req.getClient_protocol());
     SessionHandle sessionHandle;
     if (cliService.getHiveConf().getBoolVar(ConfVars.HIVE_SERVER2_ENABLE_DOAS) &&
         (userName != null)) {

Modified: hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpCLIService.java
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpCLIService.java?rev=1578350&r1=1578349&r2=1578350&view=diff
==============================================================================
--- hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpCLIService.java (original)
+++ hive/branches/branch-0.13/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpCLIService.java Mon Mar 17 13:04:29 2014
@@ -20,9 +20,13 @@ package org.apache.hive.service.cli.thri
 
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
+import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.util.Shell;
+import org.apache.hive.service.auth.HiveAuthFactory;
 import org.apache.hive.service.auth.HiveAuthFactory.AuthTypes;
 import org.apache.hive.service.cli.CLIService;
+import org.apache.thrift.TProcessor;
+import org.apache.thrift.TProcessorFactory;
 import org.apache.thrift.protocol.TBinaryProtocol;
 import org.apache.thrift.protocol.TProtocolFactory;
 import org.apache.thrift.server.TServlet;
@@ -59,32 +63,20 @@ public class ThriftHttpCLIService extend
       minWorkerThreads = hiveConf.getIntVar(ConfVars.HIVE_SERVER2_THRIFT_HTTP_MIN_WORKER_THREADS);
       maxWorkerThreads = hiveConf.getIntVar(ConfVars.HIVE_SERVER2_THRIFT_HTTP_MAX_WORKER_THREADS);
 
-      String httpPath =  hiveConf.getVar(HiveConf.ConfVars.HIVE_SERVER2_THRIFT_HTTP_PATH);
-      // The config parameter can be like "path", "/path", "/path/", "path/*", "/path1/path2/*" and so on.
-      // httpPath should end up as "/*", "/path/*" or "/path1/../pathN/*"
-      if(httpPath == null || httpPath.equals("")) {
-        httpPath = "/*";
-      }
-      else {
-        if(!httpPath.startsWith("/")) {
-          httpPath = "/" + httpPath;
-        }
-        if(httpPath.endsWith("/")) {
-          httpPath = httpPath + "*";
-        }
-        if(!httpPath.endsWith("/*")) {
-          httpPath = httpPath + "/*";
-        }
-      }
+      String httpPath =  getHttpPath(hiveConf.getVar(HiveConf.ConfVars.HIVE_SERVER2_THRIFT_HTTP_PATH));
 
       httpServer = new org.eclipse.jetty.server.Server();
       QueuedThreadPool threadPool = new QueuedThreadPool();
       threadPool.setMinThreads(minWorkerThreads);
       threadPool.setMaxThreads(maxWorkerThreads);
       httpServer.setThreadPool(threadPool);
-      SelectChannelConnector connector;
-      Boolean useSsl = hiveConf.getBoolVar(ConfVars.HIVE_SERVER2_USE_SSL);
+
+      SelectChannelConnector connector = new SelectChannelConnector();;
+      boolean useSsl = hiveConf.getBoolVar(ConfVars.HIVE_SERVER2_USE_SSL);
       String schemeName = useSsl ? "https" : "http";
+      String authType = hiveConf.getVar(ConfVars.HIVE_SERVER2_AUTHENTICATION);
+      // Set during the init phase of HiveServer2 if auth mode is kerberos
+      UserGroupInformation serviceUGI = cliService.getServiceUGI();
 
       if (useSsl) {
         String keyStorePath = hiveConf.getVar(ConfVars.HIVE_SERVER2_SSL_KEYSTORE_PATH).trim();
@@ -97,8 +89,6 @@ public class ThriftHttpCLIService extend
         sslContextFactory.setKeyStorePath(keyStorePath);
         sslContextFactory.setKeyStorePassword(keyStorePassword);
         connector = new SslSelectChannelConnector(sslContextFactory);
-      } else {
-        connector = new SelectChannelConnector();
       }
 
       connector.setPort(portNum);
@@ -106,14 +96,18 @@ public class ThriftHttpCLIService extend
       connector.setReuseAddress(!Shell.WINDOWS);
       httpServer.addConnector(connector);
 
-      TCLIService.Processor<ThriftCLIService> processor =
-          new TCLIService.Processor<ThriftCLIService>(new EmbeddedThriftBinaryCLIService());
+      hiveAuthFactory = new HiveAuthFactory();
+      TProcessorFactory processorFactory = hiveAuthFactory.getAuthProcFactory(this);
+      TProcessor processor = processorFactory.getProcessor(null);
 
       TProtocolFactory protocolFactory = new TBinaryProtocol.Factory();
-      TServlet thriftHttpServlet = new ThriftHttpServlet(processor, protocolFactory);
+      TServlet thriftHttpServlet = new ThriftHttpServlet(processor, protocolFactory,
+          authType, serviceUGI);
 
-      final ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
+      final ServletContextHandler context = new ServletContextHandler(
+          ServletContextHandler.SESSIONS);
       context.setContextPath("/");
+
       httpServer.setHandler(context);
       context.addServlet(new ServletHolder(thriftHttpServlet), httpPath);
 
@@ -130,39 +124,53 @@ public class ThriftHttpCLIService extend
   }
 
   /**
+   * The config parameter can be like "path", "/path", "/path/", "path/*", "/path1/path2/*" and so on.
+   * httpPath should end up as "/*", "/path/*" or "/path1/../pathN/*"
+   * @param httpPath
+   * @return
+   */
+  private String getHttpPath(String httpPath) {
+    if(httpPath == null || httpPath.equals("")) {
+      httpPath = "/*";
+    }
+    else {
+      if(!httpPath.startsWith("/")) {
+        httpPath = "/" + httpPath;
+      }
+      if(httpPath.endsWith("/")) {
+        httpPath = httpPath + "*";
+      }
+      if(!httpPath.endsWith("/*")) {
+        httpPath = httpPath + "/*";
+      }
+    }
+    return httpPath;
+  }
+
+  /**
    * Verify that this configuration is supported by transportMode of HTTP
    * @param hiveConf
    */
   private static void verifyHttpConfiguration(HiveConf hiveConf) {
     String authType = hiveConf.getVar(ConfVars.HIVE_SERVER2_AUTHENTICATION);
 
-    // error out if KERBEROS or LDAP mode is being used, it is not supported
-    if(authType.equalsIgnoreCase(AuthTypes.KERBEROS.toString()) ||
-        authType.equalsIgnoreCase(AuthTypes.LDAP.toString()) ||
-        authType.equalsIgnoreCase(AuthTypes.CUSTOM.toString())) {
+    // Error out if KERBEROS auth mode is being used and use SSL is also set to true
+    if(authType.equalsIgnoreCase(AuthTypes.KERBEROS.toString()) &&
+        hiveConf.getBoolVar(ConfVars.HIVE_SERVER2_USE_SSL)) {
       String msg = ConfVars.HIVE_SERVER2_AUTHENTICATION + " setting of " +
-          authType + " is currently not supported with " +
-          ConfVars.HIVE_SERVER2_TRANSPORT_MODE + " setting of http";
+          authType + " is not supported with " +
+          ConfVars.HIVE_SERVER2_USE_SSL + " set to true";
       LOG.fatal(msg);
       throw new RuntimeException(msg);
     }
 
-    // Throw exception here
+    // Warn that SASL is not used in http mode
     if(authType.equalsIgnoreCase(AuthTypes.NONE.toString())) {
       // NONE in case of thrift mode uses SASL
       LOG.warn(ConfVars.HIVE_SERVER2_AUTHENTICATION + " setting to " +
-          authType + ". SASL is not supported with http transportMode," +
+          authType + ". SASL is not supported with http transport mode," +
           " so using equivalent of " + AuthTypes.NOSASL);
     }
-
-    // doAs is currently not supported with http
-    if(hiveConf.getBoolVar(ConfVars.HIVE_SERVER2_ENABLE_DOAS)) {
-      String msg = ConfVars.HIVE_SERVER2_ENABLE_DOAS + " setting of " +
-          "true is currently not supported with " +
-          ConfVars.HIVE_SERVER2_TRANSPORT_MODE + " setting of http";
-      LOG.fatal(msg);
-      throw new RuntimeException(msg);
-    }
   }
 
 }
\ No newline at end of file



Mime
View raw message