diff --git a/hcatalog/core/src/main/java/org/apache/hive/hcatalog/cli/HCatCli.java b/hcatalog/core/src/main/java/org/apache/hive/hcatalog/cli/HCatCli.java index c1fdf6e..ba08545 100644 --- a/hcatalog/core/src/main/java/org/apache/hive/hcatalog/cli/HCatCli.java +++ b/hcatalog/core/src/main/java/org/apache/hive/hcatalog/cli/HCatCli.java @@ -76,8 +76,6 @@ public static void main(String[] args) { HiveConf.setVar(conf, ConfVars.SEMANTIC_ANALYZER_HOOK, HCatSemanticAnalyzer.class.getName()); - SessionState.start(ss); - Options options = new Options(); // -e 'quoted-query-string' @@ -126,19 +124,30 @@ public static void main(String[] args) { cmdLine = parser.parse(options, args); } catch (ParseException e) { - printUsage(options, ss.err); + printUsage(options, System.err); + // Note, we print to System.err instead of ss.err, because if we can't parse our + // commandline, we haven't even begun, and therefore cannot be expected to have + // reasonably constructed or started the SessionState. System.exit(1); } - // -e - String execString = (String) cmdLine.getOptionValue('e'); - // -f - String fileName = (String) cmdLine.getOptionValue('f'); + + // -D : process these first, so that we can instantiate SessionState appropriately. + setConfProperties(conf, cmdLine.getOptionProperties("D")); + + // Now that the properties are in, we can instantiate SessionState. + SessionState.start(ss); + // -h if (cmdLine.hasOption('h')) { printUsage(options, ss.out); System.exit(0); } + // -e + String execString = (String) cmdLine.getOptionValue('e'); + + // -f + String fileName = (String) cmdLine.getOptionValue('f'); if (execString != null && fileName != null) { ss.err.println("The '-e' and '-f' options cannot be specified simultaneously"); printUsage(options, ss.err); @@ -157,8 +166,7 @@ public static void main(String[] args) { conf.set(HCatConstants.HCAT_GROUP, grp); } - // -D - setConfProperties(conf, cmdLine.getOptionProperties("D")); + // all done parsing, let's run stuff! if (execString != null) { System.exit(processLine(execString)); diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/HadoopDefaultAuthenticator.java b/ql/src/java/org/apache/hadoop/hive/ql/security/HadoopDefaultAuthenticator.java index 8b474c0..b5306a1 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/security/HadoopDefaultAuthenticator.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/HadoopDefaultAuthenticator.java @@ -28,10 +28,10 @@ public class HadoopDefaultAuthenticator implements HiveAuthenticationProvider { - private String userName; - private List groupNames; + protected String userName; + protected List groupNames; - private Configuration conf; + protected Configuration conf; @Override public List getGroupNames() { diff --git a/ql/src/java/org/apache/hadoop/hive/ql/security/ProxyUserAuthenticator.java b/ql/src/java/org/apache/hadoop/hive/ql/security/ProxyUserAuthenticator.java new file mode 100644 index 0000000..7c89f96 --- /dev/null +++ b/ql/src/java/org/apache/hadoop/hive/ql/security/ProxyUserAuthenticator.java @@ -0,0 +1,68 @@ +/** + * 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; + +import java.util.Arrays; +import java.util.List; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hive.shims.ShimLoader; +import org.apache.hadoop.security.UserGroupInformation; + +/** + * ProxyUserAuthenticator extends HadoopDefaultAuthenticator + * but honours a proxy config setting proxy.user.name instead of the + * current user if set. This allows server processes like webhcat which + * proxy other users to easily specify an override if allowed. + */ +public class ProxyUserAuthenticator extends HadoopDefaultAuthenticator { + + private static final String PROXY_USER_NAME = "proxy.user.name"; + + @Override + public void setConf(Configuration conf) { + this.conf = conf; + UserGroupInformation ugi = null; + String proxyUser = conf.get(PROXY_USER_NAME); + + if (proxyUser == null){ + super.setConf(conf); + return; + } + + // If we're here, proxy user is set. + + try { + ugi = ShimLoader.getHadoopShims().createRemoteUser(proxyUser,null); + } catch (Exception e) { + throw new RuntimeException(e); + } + + if (ugi == null) { + throw new RuntimeException( + "Can not initialize ProxyUserAuthenticator for user ["+proxyUser+"]"); + } + + this.userName = ShimLoader.getHadoopShims().getShortUserName(ugi); + if (ugi.getGroupNames() != null) { + this.groupNames = Arrays.asList(ugi.getGroupNames()); + } + } + +}