diff --git common/src/java/org/apache/hadoop/hive/conf/HiveConf.java common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
index 84ee78f..216e445 100644
--- common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
+++ common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
@@ -134,7 +134,8 @@
HiveConf.ConfVars.HMSHANDLERINTERVAL,
HiveConf.ConfVars.HMSHANDLERFORCERELOADCONF,
HiveConf.ConfVars.METASTORE_PARTITION_NAME_WHITELIST_PATTERN,
- HiveConf.ConfVars.METASTORE_DISALLOW_INCOMPATIBLE_COL_TYPE_CHANGES
+ HiveConf.ConfVars.METASTORE_DISALLOW_INCOMPATIBLE_COL_TYPE_CHANGES,
+ HiveConf.ConfVars.USERS_IN_ADMIN_ROLE
};
/**
@@ -894,7 +895,8 @@
// none is the default(past) behavior. Implies only alphaNumeric and underscore are valid characters in identifiers.
// column: implies column names can contain any character.
HIVE_QUOTEDID_SUPPORT("hive.support.quoted.identifiers", "column",
- new PatternValidator("none", "column"))
+ new PatternValidator("none", "column")),
+ USERS_IN_ADMIN_ROLE("hive.users.in.admin.role","")
;
public final String varname;
diff --git conf/hive-default.xml.template conf/hive-default.xml.template
index 66d22f9..e13e4f4 100644
--- conf/hive-default.xml.template
+++ conf/hive-default.xml.template
@@ -1537,6 +1537,13 @@
+ hive.users.in.admin.role
+
+ Comma separated list of users who are in admin role for bootstrapping.
+ More users can be added in ADMIN role later.
+
+
+
hive.security.command.whitelist
set,reset,dfs,add,delete
Comma separated list of non-SQL Hive commands users are authorized to execute
diff --git itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/TestAdminUser.java itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/TestAdminUser.java
new file mode 100644
index 0000000..f2e75f7
--- /dev/null
+++ itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/TestAdminUser.java
@@ -0,0 +1,46 @@
+/**
+ * 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.metastore;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
+import org.apache.hadoop.hive.metastore.HiveMetaStore.HMSHandler;
+import org.apache.hadoop.hive.metastore.api.PrincipalType;
+import org.apache.hadoop.hive.metastore.api.Role;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactory;
+
+public class TestAdminUser extends TestCase{
+
+ public void testCreateAdminNAddUser() throws IOException, Throwable {
+ HiveConf conf = new HiveConf();
+ conf.setVar(ConfVars.USERS_IN_ADMIN_ROLE, "adminuser");
+ conf.setVar(ConfVars.HIVE_AUTHORIZATION_MANAGER,SQLStdHiveAuthorizerFactory.class.getName());
+ RawStore rawStore = new HMSHandler("testcreateroot", conf).getMS();
+ Role adminRole = rawStore.getRole(HiveMetaStore.ADMIN);
+ assertTrue(adminRole.getOwnerName().equals(HiveMetaStore.ADMIN));
+ assertEquals(rawStore.listPrincipalGlobalGrants(HiveMetaStore.ADMIN, PrincipalType.ROLE)
+ .get(0).getPrivilege(),"All");
+ assertEquals(rawStore.listRoles("adminuser", PrincipalType.USER).get(0).getRole().
+ getRoleName(),HiveMetaStore.ADMIN);
+ assertTrue(rawStore.revokeRole(adminRole, "adminuser", PrincipalType.USER));
+ }
+}
\ No newline at end of file
diff --git metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java
index 58f9957..70dadf4 100644
--- metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java
+++ metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java
@@ -35,7 +35,6 @@
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -43,6 +42,7 @@
import java.util.Properties;
import java.util.Set;
import java.util.Timer;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
import org.apache.commons.cli.OptionBuilder;
@@ -146,6 +146,7 @@
import com.facebook.fb303.FacebookBase;
import com.facebook.fb303.fb_status;
+import com.google.common.base.Splitter;
/**
* TODO:pc remove application logic to a separate interface.
@@ -164,6 +165,7 @@
* default port on which to start the Hive server
*/
private static final int DEFAULT_HIVE_METASTORE_PORT = 9083;
+ public static final String ADMIN = "ADMIN";
private static HadoopThriftAuthBridge.Server saslServer;
private static boolean useSasl;
@@ -189,6 +191,7 @@ public TTransport getTransport(TTransport trans) {
IHMSHandler {
public static final Log LOG = HiveMetaStore.LOG;
private static boolean createDefaultDB = false;
+ private static boolean adminCreated = false;
private String rawStoreClassName;
private final HiveConf hiveConf; // stores datastore (jpox) properties,
// right now they come from jpox.properties
@@ -341,7 +344,10 @@ private boolean init() throws MetaException {
alterHandlerName), hiveConf);
wh = new Warehouse(hiveConf);
- createDefaultDB();
+ synchronized (HMSHandler.class) {
+ createDefaultDB();
+ createAdminRoleNAddUsers();
+ }
if (hiveConf.getBoolean("hive.metastore.metrics.enabled", false)) {
try {
@@ -448,22 +454,99 @@ private void createDefaultDB_core(RawStore ms) throws MetaException, InvalidObje
* @throws MetaException
*/
private void createDefaultDB() throws MetaException {
- synchronized (HMSHandler.class) {
- if (HMSHandler.createDefaultDB || !checkForDefaultDb) {
- return;
- }
+ if (HMSHandler.createDefaultDB || !checkForDefaultDb) {
+ return;
+ }
+ try {
+ createDefaultDB_core(getMS());
+ } catch (InvalidObjectException e) {
+ throw new MetaException(e.getMessage());
+ } catch (MetaException e) {
+ throw e;
+ } catch (Exception e) {
+ assert (e instanceof RuntimeException);
+ throw (RuntimeException) e;
+ }
+ }
+
+ private void createAdminRoleNAddUsers() throws MetaException {
+ if(adminCreated) {
+ return;
+ }
+ Class> authCls;
+ Class> authIface;
+ try {
+ authCls = hiveConf.getClassByName(hiveConf.getVar(ConfVars.HIVE_AUTHORIZATION_MANAGER));
+ authIface = Class.forName("org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAuthorizerFactory");
+ } catch (ClassNotFoundException e) {
+ LOG.debug("No auth manager specified", e);
+ return;
+ }
+ if(!authIface.isAssignableFrom(authCls)){
+ LOG.info("Invalid value for auth manager in config " + authCls.getName());
+ return;
+ }
+ RawStore ms = getMS();
+ try {
+ ms.addRole(ADMIN, ADMIN);
+ } catch (InvalidObjectException e) {
+ LOG.debug("admin role already exists",e);
+ } catch (NoSuchObjectException e) {
+ // This should never be thrown.
+ LOG.warn("Unexpected exception while adding ADMIN role" , e);
+ }
+ LOG.info("Added admin role in metastore");
+ // now grant all privs to admin
+ PrivilegeBag privs = new PrivilegeBag();
+ privs.addToPrivileges(new HiveObjectPrivilege( new HiveObjectRef(HiveObjectType.GLOBAL, null,
+ null, null, null), ADMIN, PrincipalType.ROLE, new PrivilegeGrantInfo("All", 0, ADMIN,
+ PrincipalType.ROLE, true)));
+ try {
+ ms.grantPrivileges(privs);
+ } catch (InvalidObjectException e) {
+ // Surprisingly these privs are already granted.
+ LOG.debug("Failed while granting global privs to admin", e);
+ } catch (NoSuchObjectException e) {
+ // Unlikely to be thrown.
+ LOG.warn("Failed while granting global privs to admin", e);
+ }
+
+ // now add pre-configured users to admin role
+ String userStr = HiveConf.getVar(hiveConf,ConfVars.USERS_IN_ADMIN_ROLE,"").trim();
+ if (userStr.isEmpty()) {
+ LOG.info("No user is added in admin role, since config is empty");
+ return;
+ }
+ // Since user names need to be valid unix user names, per IEEE Std 1003.1-2001 they cannot
+ // contain comma, so we can safely split above string on comma.
+
+ Iterator users = Splitter.on(",").trimResults().omitEmptyStrings().split(userStr).
+ iterator();
+ if (!users.hasNext()) {
+ LOG.info("No user is added in admin role, since config value "+ userStr +
+ " is in incorrect format.");
+ return;
+ }
+ LOG.info("Added " + userStr + " to admin role");
+ Role adminRole;
+ try {
+ adminRole = ms.getRole(ADMIN);
+ } catch (NoSuchObjectException e) {
+ LOG.error("Failed to retrieve just added admin role",e);
+ return;
+ }
+ while (users.hasNext()) {
+ String userName = users.next();
try {
- createDefaultDB_core(getMS());
+ ms.grantRole(adminRole, userName, PrincipalType.USER, ADMIN, PrincipalType.ROLE, true);
+ } catch (NoSuchObjectException e) {
+ LOG.error("Failed to add "+ adminRole + " in admin role",e);
} catch (InvalidObjectException e) {
- throw new MetaException(e.getMessage());
- } catch (MetaException e) {
- throw e;
- } catch (Exception e) {
- assert (e instanceof RuntimeException);
- throw (RuntimeException) e;
+ LOG.debug(userName + " already in admin role", e);
}
}
+ adminCreated = true;
}
private void logInfo(String m) {