HBASE-11886 The creator of the table should have all permissions on the table (Devaraj Das and Andrew Purtell)

This commit is contained in:
Andrew Purtell 2014-09-03 18:30:52 -07:00
parent bcfc6d65af
commit f77ebcf191
2 changed files with 123 additions and 2 deletions

View File

@ -20,6 +20,7 @@ package org.apache.hadoop.hbase.master.handler;
import java.io.IOException; import java.io.IOException;
import java.io.InterruptedIOException; import java.io.InterruptedIOException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -40,6 +41,7 @@ import org.apache.hadoop.hbase.client.RegionReplicaUtil;
import org.apache.hadoop.hbase.MetaTableAccessor; import org.apache.hadoop.hbase.MetaTableAccessor;
import org.apache.hadoop.hbase.executor.EventHandler; import org.apache.hadoop.hbase.executor.EventHandler;
import org.apache.hadoop.hbase.executor.EventType; import org.apache.hadoop.hbase.executor.EventType;
import org.apache.hadoop.hbase.ipc.RequestContext;
import org.apache.hadoop.hbase.master.AssignmentManager; import org.apache.hadoop.hbase.master.AssignmentManager;
import org.apache.hadoop.hbase.master.HMaster; import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.master.MasterCoprocessorHost; import org.apache.hadoop.hbase.master.MasterCoprocessorHost;
@ -48,6 +50,8 @@ import org.apache.hadoop.hbase.master.MasterServices;
import org.apache.hadoop.hbase.master.TableLockManager; import org.apache.hadoop.hbase.master.TableLockManager;
import org.apache.hadoop.hbase.master.TableLockManager.TableLock; import org.apache.hadoop.hbase.master.TableLockManager.TableLock;
import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos; import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.security.UserProvider;
import org.apache.hadoop.hbase.util.FSTableDescriptors; import org.apache.hadoop.hbase.util.FSTableDescriptors;
import org.apache.hadoop.hbase.util.FSUtils; import org.apache.hadoop.hbase.util.FSUtils;
import org.apache.hadoop.hbase.util.ModifyRegionUtils; import org.apache.hadoop.hbase.util.ModifyRegionUtils;
@ -66,6 +70,7 @@ public class CreateTableHandler extends EventHandler {
private final TableLockManager tableLockManager; private final TableLockManager tableLockManager;
private final HRegionInfo [] newRegions; private final HRegionInfo [] newRegions;
private final TableLock tableLock; private final TableLock tableLock;
private User activeUser;
public CreateTableHandler(Server server, MasterFileSystem fileSystemManager, public CreateTableHandler(Server server, MasterFileSystem fileSystemManager,
HTableDescriptor hTableDescriptor, Configuration conf, HRegionInfo [] newRegions, HTableDescriptor hTableDescriptor, Configuration conf, HRegionInfo [] newRegions,
@ -93,6 +98,14 @@ public class CreateTableHandler extends EventHandler {
server.getZooKeeper(), timeout) == null) { server.getZooKeeper(), timeout) == null) {
throw new NotAllMetaRegionsOnlineException(); throw new NotAllMetaRegionsOnlineException();
} }
// If we are creating the table in service to an RPC request, record the
// active user for later, so proper permissions will be applied to the
// new table by the AccessController if it is active
if (RequestContext.isInRequestContext()) {
this.activeUser = RequestContext.getRequestUser();
} else {
this.activeUser = UserProvider.instantiate(conf).getCurrent();
}
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOG.warn("Interrupted waiting for meta availability", e); LOG.warn("Interrupted waiting for meta availability", e);
InterruptedIOException ie = new InterruptedIOException(e.getMessage()); InterruptedIOException ie = new InterruptedIOException(e.getMessage());
@ -176,14 +189,20 @@ public class CreateTableHandler extends EventHandler {
LOG.info("Create table " + tableName); LOG.info("Create table " + tableName);
try { try {
MasterCoprocessorHost cpHost = ((HMaster) this.server).getMasterCoprocessorHost(); final MasterCoprocessorHost cpHost = ((HMaster) this.server).getMasterCoprocessorHost();
if (cpHost != null) { if (cpHost != null) {
cpHost.preCreateTableHandler(this.hTableDescriptor, this.newRegions); cpHost.preCreateTableHandler(this.hTableDescriptor, this.newRegions);
} }
handleCreateTable(tableName); handleCreateTable(tableName);
completed(null); completed(null);
if (cpHost != null) { if (cpHost != null) {
cpHost.postCreateTableHandler(this.hTableDescriptor, this.newRegions); this.activeUser.runAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
cpHost.postCreateTableHandler(hTableDescriptor, newRegions);
return null;
}
});
} }
} catch (Throwable e) { } catch (Throwable e) {
LOG.error("Error trying to create the table " + tableName, e); LOG.error("Error trying to create the table " + tableName, e);

View File

@ -0,0 +1,102 @@
/*
* 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.hbase.security.access;
import static org.junit.Assert.*;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.LargeTests;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.security.access.Permission.Action;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.TestTableName;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
@Category(LargeTests.class)
public class TestAccessController2 extends SecureTestUtil {
private static final byte[] TEST_FAMILY = Bytes.toBytes("f");
private static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
private static Configuration conf;
@Rule public TestTableName TEST_TABLE = new TestTableName();
@BeforeClass
public static void setupBeforeClass() throws Exception {
conf = TEST_UTIL.getConfiguration();
// Enable security
enableSecurity(conf);
// Verify enableSecurity sets up what we require
verifyConfiguration(conf);
TEST_UTIL.startMiniCluster();
// Wait for the ACL table to become available
TEST_UTIL.waitTableEnabled(AccessControlLists.ACL_TABLE_NAME.getName());
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
TEST_UTIL.shutdownMiniCluster();
}
@Test
public void testCreateWithCorrectOwner() throws Exception {
// Create a test user
User testUser = User.createUserForTesting(TEST_UTIL.getConfiguration(), "TestUser",
new String[0]);
// Grant the test user the ability to create tables
SecureTestUtil.grantGlobal(TEST_UTIL, testUser.getShortName(), Action.CREATE);
verifyAllowed(new AccessTestAction() {
@Override
public Object run() throws Exception {
HTableDescriptor desc = new HTableDescriptor(TEST_TABLE.getTableName());
desc.addFamily(new HColumnDescriptor(TEST_FAMILY));
HBaseAdmin admin = new HBaseAdmin(conf);
try {
admin.createTable(desc);
} finally {
admin.close();
}
return null;
}
}, testUser);
TEST_UTIL.waitTableEnabled(TEST_TABLE.getTableName().getName());
// Verify that owner permissions have been granted to the test user on the
// table just created
List<TablePermission> perms = AccessControlLists.getTablePermissions(conf, TEST_TABLE.getTableName())
.get(testUser.getShortName());
assertNotNull(perms);
assertFalse(perms.isEmpty());
// Should be RWXCA
assertTrue(perms.get(0).implies(Permission.Action.READ));
assertTrue(perms.get(0).implies(Permission.Action.WRITE));
assertTrue(perms.get(0).implies(Permission.Action.EXEC));
assertTrue(perms.get(0).implies(Permission.Action.CREATE));
assertTrue(perms.get(0).implies(Permission.Action.ADMIN));
}
}