001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.security.access; 019 020import static org.junit.Assert.assertEquals; 021 022import java.util.List; 023import org.apache.hadoop.conf.Configuration; 024import org.apache.hadoop.hbase.Cell; 025import org.apache.hadoop.hbase.CompareOperator; 026import org.apache.hadoop.hbase.Coprocessor; 027import org.apache.hadoop.hbase.HBaseClassTestRule; 028import org.apache.hadoop.hbase.HBaseTestingUtility; 029import org.apache.hadoop.hbase.HColumnDescriptor; 030import org.apache.hadoop.hbase.HConstants; 031import org.apache.hadoop.hbase.HRegionInfo; 032import org.apache.hadoop.hbase.HTableDescriptor; 033import org.apache.hadoop.hbase.NamespaceDescriptor; 034import org.apache.hadoop.hbase.ServerName; 035import org.apache.hadoop.hbase.TableName; 036import org.apache.hadoop.hbase.TableNameTestRule; 037import org.apache.hadoop.hbase.TableNotFoundException; 038import org.apache.hadoop.hbase.client.Admin; 039import org.apache.hadoop.hbase.client.Append; 040import org.apache.hadoop.hbase.client.BalanceRequest; 041import org.apache.hadoop.hbase.client.Connection; 042import org.apache.hadoop.hbase.client.ConnectionFactory; 043import org.apache.hadoop.hbase.client.Delete; 044import org.apache.hadoop.hbase.client.Durability; 045import org.apache.hadoop.hbase.client.Get; 046import org.apache.hadoop.hbase.client.Increment; 047import org.apache.hadoop.hbase.client.Put; 048import org.apache.hadoop.hbase.client.Result; 049import org.apache.hadoop.hbase.client.ResultScanner; 050import org.apache.hadoop.hbase.client.Scan; 051import org.apache.hadoop.hbase.client.SnapshotDescription; 052import org.apache.hadoop.hbase.client.Table; 053import org.apache.hadoop.hbase.client.TableDescriptor; 054import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment; 055import org.apache.hadoop.hbase.coprocessor.ObserverContextImpl; 056import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment; 057import org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment; 058import org.apache.hadoop.hbase.filter.BinaryComparator; 059import org.apache.hadoop.hbase.master.MasterCoprocessorHost; 060import org.apache.hadoop.hbase.regionserver.FlushLifeCycleTracker; 061import org.apache.hadoop.hbase.regionserver.HRegion; 062import org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress; 063import org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost; 064import org.apache.hadoop.hbase.regionserver.RegionServerCoprocessorHost; 065import org.apache.hadoop.hbase.security.User; 066import org.apache.hadoop.hbase.security.access.Permission.Action; 067import org.apache.hadoop.hbase.testclassification.LargeTests; 068import org.apache.hadoop.hbase.testclassification.SecurityTests; 069import org.apache.hadoop.hbase.util.Bytes; 070import org.apache.hadoop.hbase.util.Pair; 071import org.apache.hadoop.hbase.wal.WALEdit; 072import org.junit.After; 073import org.junit.AfterClass; 074import org.junit.Before; 075import org.junit.BeforeClass; 076import org.junit.ClassRule; 077import org.junit.Rule; 078import org.junit.Test; 079import org.junit.experimental.categories.Category; 080import org.slf4j.Logger; 081import org.slf4j.LoggerFactory; 082 083import org.apache.hbase.thirdparty.com.google.common.collect.Lists; 084 085@Category({ SecurityTests.class, LargeTests.class }) 086public class TestWithDisabledAuthorization extends SecureTestUtil { 087 088 @ClassRule 089 public static final HBaseClassTestRule CLASS_RULE = 090 HBaseClassTestRule.forClass(TestWithDisabledAuthorization.class); 091 092 private static final Logger LOG = LoggerFactory.getLogger(TestWithDisabledAuthorization.class); 093 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); 094 095 private static final byte[] TEST_FAMILY = Bytes.toBytes("f1"); 096 private static final byte[] TEST_FAMILY2 = Bytes.toBytes("f2"); 097 private static final byte[] TEST_ROW = Bytes.toBytes("testrow"); 098 private static final byte[] TEST_Q1 = Bytes.toBytes("q1"); 099 private static final byte[] TEST_Q2 = Bytes.toBytes("q2"); 100 private static final byte[] TEST_Q3 = Bytes.toBytes("q3"); 101 private static final byte[] TEST_Q4 = Bytes.toBytes("q4"); 102 private static final byte[] ZERO = Bytes.toBytes(0L); 103 104 private static MasterCoprocessorEnvironment CP_ENV; 105 private static AccessController ACCESS_CONTROLLER; 106 private static RegionServerCoprocessorEnvironment RSCP_ENV; 107 private RegionCoprocessorEnvironment RCP_ENV; 108 109 @Rule 110 public TableNameTestRule testTable = new TableNameTestRule(); 111 112 // default users 113 114 // superuser 115 private static User SUPERUSER; 116 // user granted with all global permission 117 private static User USER_ADMIN; 118 // user with rw permissions on column family. 119 private static User USER_RW; 120 // user with read-only permissions 121 private static User USER_RO; 122 // user is table owner. will have all permissions on table 123 private static User USER_OWNER; 124 // user with create table permissions alone 125 private static User USER_CREATE; 126 // user with no permissions 127 private static User USER_NONE; 128 // user with only partial read-write perms (on family:q1 only) 129 private static User USER_QUAL; 130 131 @BeforeClass 132 public static void setupBeforeClass() throws Exception { 133 Configuration conf = TEST_UTIL.getConfiguration(); 134 // Up the handlers; this test needs more than usual. 135 TEST_UTIL.getConfiguration().setInt(HConstants.REGION_SERVER_HIGH_PRIORITY_HANDLER_COUNT, 10); 136 // Enable security 137 enableSecurity(conf); 138 // We expect 0.98 cell ACL semantics 139 conf.setBoolean(AccessControlConstants.CF_ATTRIBUTE_EARLY_OUT, false); 140 // Enable EXEC permission checking 141 conf.setBoolean(AccessControlConstants.EXEC_PERMISSION_CHECKS_KEY, true); 142 // Verify enableSecurity sets up what we require 143 verifyConfiguration(conf); 144 145 // Now, DISABLE only active authorization 146 conf.setBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, false); 147 148 // Start the minicluster 149 TEST_UTIL.startMiniCluster(); 150 MasterCoprocessorHost cpHost = 151 TEST_UTIL.getMiniHBaseCluster().getMaster().getMasterCoprocessorHost(); 152 cpHost.load(AccessController.class, Coprocessor.PRIORITY_HIGHEST, conf); 153 ACCESS_CONTROLLER = (AccessController) cpHost.findCoprocessor(AccessController.class.getName()); 154 CP_ENV = cpHost.createEnvironment(ACCESS_CONTROLLER, Coprocessor.PRIORITY_HIGHEST, 1, conf); 155 RegionServerCoprocessorHost rsHost = 156 TEST_UTIL.getMiniHBaseCluster().getRegionServer(0).getRegionServerCoprocessorHost(); 157 RSCP_ENV = rsHost.createEnvironment(ACCESS_CONTROLLER, Coprocessor.PRIORITY_HIGHEST, 1, conf); 158 159 // Wait for the ACL table to become available 160 TEST_UTIL.waitUntilAllRegionsAssigned(PermissionStorage.ACL_TABLE_NAME); 161 162 // create a set of test users 163 SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" }); 164 USER_ADMIN = User.createUserForTesting(conf, "admin2", new String[0]); 165 USER_OWNER = User.createUserForTesting(conf, "owner", new String[0]); 166 USER_CREATE = User.createUserForTesting(conf, "tbl_create", new String[0]); 167 USER_RW = User.createUserForTesting(conf, "rwuser", new String[0]); 168 USER_RO = User.createUserForTesting(conf, "rouser", new String[0]); 169 USER_QUAL = User.createUserForTesting(conf, "rwpartial", new String[0]); 170 USER_NONE = User.createUserForTesting(conf, "nouser", new String[0]); 171 } 172 173 @AfterClass 174 public static void tearDownAfterClass() throws Exception { 175 TEST_UTIL.shutdownMiniCluster(); 176 } 177 178 @Before 179 public void setUp() throws Exception { 180 // Create the test table (owner added to the _acl_ table) 181 Admin admin = TEST_UTIL.getAdmin(); 182 HTableDescriptor htd = new HTableDescriptor(testTable.getTableName()); 183 HColumnDescriptor hcd = new HColumnDescriptor(TEST_FAMILY); 184 hcd.setMaxVersions(100); 185 htd.addFamily(hcd); 186 htd.setOwner(USER_OWNER); 187 admin.createTable(htd, new byte[][] { Bytes.toBytes("s") }); 188 TEST_UTIL.waitUntilAllRegionsAssigned(testTable.getTableName()); 189 190 HRegion region = TEST_UTIL.getHBaseCluster().getRegions(testTable.getTableName()).get(0); 191 RegionCoprocessorHost rcpHost = region.getCoprocessorHost(); 192 RCP_ENV = rcpHost.createEnvironment(ACCESS_CONTROLLER, Coprocessor.PRIORITY_HIGHEST, 1, 193 TEST_UTIL.getConfiguration()); 194 195 // Set up initial grants 196 197 grantGlobal(TEST_UTIL, USER_ADMIN.getShortName(), Permission.Action.ADMIN, 198 Permission.Action.CREATE, Permission.Action.READ, Permission.Action.WRITE); 199 200 grantOnTable(TEST_UTIL, USER_RW.getShortName(), testTable.getTableName(), TEST_FAMILY, null, 201 Permission.Action.READ, Permission.Action.WRITE); 202 203 // USER_CREATE is USER_RW plus CREATE permissions 204 grantOnTable(TEST_UTIL, USER_CREATE.getShortName(), testTable.getTableName(), null, null, 205 Permission.Action.CREATE, Permission.Action.READ, Permission.Action.WRITE); 206 207 grantOnTable(TEST_UTIL, USER_RO.getShortName(), testTable.getTableName(), TEST_FAMILY, null, 208 Permission.Action.READ); 209 210 grantOnTable(TEST_UTIL, USER_QUAL.getShortName(), testTable.getTableName(), TEST_FAMILY, 211 TEST_Q1, Permission.Action.READ, Permission.Action.WRITE); 212 213 assertEquals(5, PermissionStorage 214 .getTablePermissions(TEST_UTIL.getConfiguration(), testTable.getTableName()).size()); 215 } 216 217 @After 218 public void tearDown() throws Exception { 219 // Clean the _acl_ table 220 try { 221 deleteTable(TEST_UTIL, testTable.getTableName()); 222 } catch (TableNotFoundException ex) { 223 // Test deleted the table, no problem 224 LOG.info("Test deleted table " + testTable.getTableName()); 225 } 226 // Verify all table/namespace permissions are erased 227 assertEquals(0, PermissionStorage 228 .getTablePermissions(TEST_UTIL.getConfiguration(), testTable.getTableName()).size()); 229 assertEquals(0, PermissionStorage.getNamespacePermissions(TEST_UTIL.getConfiguration(), 230 testTable.getTableName().getNamespaceAsString()).size()); 231 } 232 233 @Test 234 public void testCheckPermissions() throws Exception { 235 236 AccessTestAction checkGlobalAdmin = new AccessTestAction() { 237 @Override 238 public Void run() throws Exception { 239 checkGlobalPerms(TEST_UTIL, Permission.Action.ADMIN); 240 return null; 241 } 242 }; 243 244 verifyAllowed(checkGlobalAdmin, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, 245 USER_RO, USER_QUAL, USER_NONE); 246 247 AccessTestAction checkGlobalRead = new AccessTestAction() { 248 @Override 249 public Void run() throws Exception { 250 checkGlobalPerms(TEST_UTIL, Permission.Action.READ); 251 return null; 252 } 253 }; 254 255 verifyAllowed(checkGlobalRead, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, USER_RO, 256 USER_QUAL, USER_NONE); 257 258 AccessTestAction checkGlobalReadWrite = new AccessTestAction() { 259 @Override 260 public Void run() throws Exception { 261 checkGlobalPerms(TEST_UTIL, Permission.Action.READ, Permission.Action.WRITE); 262 return null; 263 } 264 }; 265 266 verifyAllowed(checkGlobalReadWrite, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, 267 USER_RO, USER_QUAL, USER_NONE); 268 269 AccessTestAction checkTableAdmin = new AccessTestAction() { 270 @Override 271 public Void run() throws Exception { 272 checkTablePerms(TEST_UTIL, testTable.getTableName(), null, null, Permission.Action.ADMIN); 273 return null; 274 } 275 }; 276 277 verifyAllowed(checkTableAdmin, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, USER_RO, 278 USER_QUAL, USER_NONE); 279 280 AccessTestAction checkTableCreate = new AccessTestAction() { 281 @Override 282 public Void run() throws Exception { 283 checkTablePerms(TEST_UTIL, testTable.getTableName(), null, null, Permission.Action.CREATE); 284 return null; 285 } 286 }; 287 288 verifyAllowed(checkTableCreate, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, 289 USER_RO, USER_QUAL, USER_NONE); 290 291 AccessTestAction checkTableRead = new AccessTestAction() { 292 @Override 293 public Void run() throws Exception { 294 checkTablePerms(TEST_UTIL, testTable.getTableName(), null, null, Permission.Action.READ); 295 return null; 296 } 297 }; 298 299 verifyAllowed(checkTableRead, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, USER_RO, 300 USER_QUAL, USER_NONE); 301 302 AccessTestAction checkTableReadWrite = new AccessTestAction() { 303 @Override 304 public Void run() throws Exception { 305 checkTablePerms(TEST_UTIL, testTable.getTableName(), null, null, Permission.Action.READ, 306 Permission.Action.WRITE); 307 return null; 308 } 309 }; 310 311 verifyAllowed(checkTableReadWrite, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, 312 USER_RO, USER_QUAL, USER_NONE); 313 314 AccessTestAction checkColumnRead = new AccessTestAction() { 315 @Override 316 public Void run() throws Exception { 317 checkTablePerms(TEST_UTIL, testTable.getTableName(), TEST_FAMILY, null, 318 Permission.Action.READ); 319 return null; 320 } 321 }; 322 323 verifyAllowed(checkColumnRead, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, USER_RO, 324 USER_QUAL, USER_NONE); 325 326 AccessTestAction checkColumnReadWrite = new AccessTestAction() { 327 @Override 328 public Void run() throws Exception { 329 checkTablePerms(TEST_UTIL, testTable.getTableName(), TEST_FAMILY, null, 330 Permission.Action.READ, Permission.Action.WRITE); 331 return null; 332 } 333 }; 334 335 verifyAllowed(checkColumnReadWrite, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, 336 USER_RO, USER_QUAL, USER_NONE); 337 338 AccessTestAction checkQualifierRead = new AccessTestAction() { 339 @Override 340 public Void run() throws Exception { 341 checkTablePerms(TEST_UTIL, testTable.getTableName(), TEST_FAMILY, TEST_Q1, 342 Permission.Action.READ); 343 return null; 344 } 345 }; 346 347 verifyAllowed(checkQualifierRead, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, 348 USER_RO, USER_QUAL, USER_NONE); 349 350 AccessTestAction checkQualifierReadWrite = new AccessTestAction() { 351 @Override 352 public Void run() throws Exception { 353 checkTablePerms(TEST_UTIL, testTable.getTableName(), TEST_FAMILY, TEST_Q1, 354 Permission.Action.READ, Permission.Action.WRITE); 355 return null; 356 } 357 }; 358 359 verifyAllowed(checkQualifierReadWrite, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, 360 USER_QUAL, USER_RO, USER_NONE); 361 362 AccessTestAction checkMultiQualifierRead = new AccessTestAction() { 363 @Override 364 public Void run() throws Exception { 365 checkTablePerms(TEST_UTIL, 366 new Permission[] { 367 Permission.newBuilder(testTable.getTableName()).withFamily(TEST_FAMILY) 368 .withQualifier(TEST_Q1).withActions(Action.READ).build(), 369 Permission.newBuilder(testTable.getTableName()).withFamily(TEST_FAMILY) 370 .withQualifier(TEST_Q2).withActions(Action.READ).build() }); 371 return null; 372 } 373 }; 374 375 verifyAllowed(checkMultiQualifierRead, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, 376 USER_RO, USER_QUAL, USER_NONE); 377 378 AccessTestAction checkMultiQualifierReadWrite = new AccessTestAction() { 379 @Override 380 public Void run() throws Exception { 381 checkTablePerms(TEST_UTIL, 382 new Permission[] { 383 Permission.newBuilder(testTable.getTableName()).withFamily(TEST_FAMILY) 384 .withQualifier(TEST_Q1).withActions(Permission.Action.READ, Permission.Action.WRITE) 385 .build(), 386 Permission.newBuilder(testTable.getTableName()).withFamily(TEST_FAMILY) 387 .withQualifier(TEST_Q2).withActions(Permission.Action.READ, Permission.Action.WRITE) 388 .build() }); 389 return null; 390 } 391 }; 392 393 verifyAllowed(checkMultiQualifierReadWrite, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, 394 USER_RW, USER_RO, USER_QUAL, USER_NONE); 395 } 396 397 /** Test grants and revocations with authorization disabled */ 398 @Test 399 public void testPassiveGrantRevoke() throws Exception { 400 401 // Add a test user 402 403 User tblUser = 404 User.createUserForTesting(TEST_UTIL.getConfiguration(), "tbluser", new String[0]); 405 406 // If we check now, the test user have permissions because authorization is disabled 407 408 AccessTestAction checkTableRead = new AccessTestAction() { 409 @Override 410 public Void run() throws Exception { 411 checkTablePerms(TEST_UTIL, testTable.getTableName(), TEST_FAMILY, null, 412 Permission.Action.READ); 413 return null; 414 } 415 }; 416 417 verifyAllowed(tblUser, checkTableRead); 418 419 // An actual read won't be denied 420 421 AccessTestAction tableRead = new AccessTestAction() { 422 @Override 423 public Void run() throws Exception { 424 try (Connection conn = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration()); 425 Table t = conn.getTable(testTable.getTableName())) { 426 t.get(new Get(TEST_ROW).addFamily(TEST_FAMILY)); 427 } 428 return null; 429 } 430 }; 431 432 verifyAllowed(tblUser, tableRead); 433 434 // Grant read perms to the test user 435 436 grantOnTable(TEST_UTIL, tblUser.getShortName(), testTable.getTableName(), TEST_FAMILY, null, 437 Permission.Action.READ); 438 439 // Now both the permission check and actual op will succeed 440 441 verifyAllowed(tblUser, checkTableRead); 442 verifyAllowed(tblUser, tableRead); 443 444 // Revoke read perms from the test user 445 446 revokeFromTable(TEST_UTIL, tblUser.getShortName(), testTable.getTableName(), TEST_FAMILY, null, 447 Permission.Action.READ); 448 449 // Now the permission check will indicate revocation but the actual op will still succeed 450 451 verifyAllowed(tblUser, checkTableRead); 452 verifyAllowed(tblUser, tableRead); 453 } 454 455 /** Test master observer */ 456 @Test 457 public void testPassiveMasterOperations() throws Exception { 458 459 // preCreateTable 460 verifyAllowed(new AccessTestAction() { 461 @Override 462 public Object run() throws Exception { 463 HTableDescriptor htd = new HTableDescriptor(testTable.getTableName()); 464 htd.addFamily(new HColumnDescriptor(TEST_FAMILY)); 465 ACCESS_CONTROLLER.preCreateTable(ObserverContextImpl.createAndPrepare(CP_ENV), htd, null); 466 return null; 467 } 468 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 469 470 // preModifyTable 471 verifyAllowed(new AccessTestAction() { 472 @Override 473 public Object run() throws Exception { 474 HTableDescriptor htd = new HTableDescriptor(testTable.getTableName()); 475 htd.addFamily(new HColumnDescriptor(TEST_FAMILY)); 476 htd.addFamily(new HColumnDescriptor(TEST_FAMILY2)); 477 ACCESS_CONTROLLER.preModifyTable(ObserverContextImpl.createAndPrepare(CP_ENV), 478 testTable.getTableName(), htd); 479 return null; 480 } 481 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 482 483 // preDeleteTable 484 verifyAllowed(new AccessTestAction() { 485 @Override 486 public Object run() throws Exception { 487 ACCESS_CONTROLLER.preDeleteTable(ObserverContextImpl.createAndPrepare(CP_ENV), 488 testTable.getTableName()); 489 return null; 490 } 491 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 492 493 // preTruncateTable 494 verifyAllowed(new AccessTestAction() { 495 @Override 496 public Object run() throws Exception { 497 ACCESS_CONTROLLER.preTruncateTable(ObserverContextImpl.createAndPrepare(CP_ENV), 498 testTable.getTableName()); 499 return null; 500 } 501 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 502 503 // preEnableTable 504 verifyAllowed(new AccessTestAction() { 505 @Override 506 public Object run() throws Exception { 507 ACCESS_CONTROLLER.preEnableTable(ObserverContextImpl.createAndPrepare(CP_ENV), 508 testTable.getTableName()); 509 return null; 510 } 511 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 512 513 // preDisableTable 514 verifyAllowed(new AccessTestAction() { 515 @Override 516 public Object run() throws Exception { 517 ACCESS_CONTROLLER.preDisableTable(ObserverContextImpl.createAndPrepare(CP_ENV), 518 testTable.getTableName()); 519 return null; 520 } 521 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 522 523 // preMove 524 verifyAllowed(new AccessTestAction() { 525 @Override 526 public Object run() throws Exception { 527 HRegionInfo region = new HRegionInfo(testTable.getTableName()); 528 ServerName srcServer = ServerName.valueOf("1.1.1.1", 1, 0); 529 ServerName destServer = ServerName.valueOf("2.2.2.2", 2, 0); 530 ACCESS_CONTROLLER.preMove(ObserverContextImpl.createAndPrepare(CP_ENV), region, srcServer, 531 destServer); 532 return null; 533 } 534 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 535 536 // preAssign 537 verifyAllowed(new AccessTestAction() { 538 @Override 539 public Object run() throws Exception { 540 HRegionInfo region = new HRegionInfo(testTable.getTableName()); 541 ACCESS_CONTROLLER.preAssign(ObserverContextImpl.createAndPrepare(CP_ENV), region); 542 return null; 543 } 544 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 545 546 // preUnassign 547 verifyAllowed(new AccessTestAction() { 548 @Override 549 public Object run() throws Exception { 550 HRegionInfo region = new HRegionInfo(testTable.getTableName()); 551 ACCESS_CONTROLLER.preUnassign(ObserverContextImpl.createAndPrepare(CP_ENV), region); 552 return null; 553 } 554 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 555 556 // preBalance 557 verifyAllowed(new AccessTestAction() { 558 @Override 559 public Object run() throws Exception { 560 ACCESS_CONTROLLER.preBalance(ObserverContextImpl.createAndPrepare(CP_ENV), 561 BalanceRequest.defaultInstance()); 562 return null; 563 } 564 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 565 566 // preBalanceSwitch 567 verifyAllowed(new AccessTestAction() { 568 @Override 569 public Object run() throws Exception { 570 ACCESS_CONTROLLER.preBalanceSwitch(ObserverContextImpl.createAndPrepare(CP_ENV), true); 571 return null; 572 } 573 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 574 575 // preSnapshot 576 verifyAllowed(new AccessTestAction() { 577 @Override 578 public Object run() throws Exception { 579 SnapshotDescription snapshot = new SnapshotDescription("foo"); 580 HTableDescriptor htd = new HTableDescriptor(testTable.getTableName()); 581 ACCESS_CONTROLLER.preSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV), snapshot, htd); 582 return null; 583 } 584 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 585 586 // preListSnapshot 587 verifyAllowed(new AccessTestAction() { 588 @Override 589 public Object run() throws Exception { 590 SnapshotDescription snapshot = new SnapshotDescription("foo"); 591 ACCESS_CONTROLLER.preListSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV), snapshot); 592 return null; 593 } 594 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 595 596 // preCloneSnapshot 597 verifyAllowed(new AccessTestAction() { 598 @Override 599 public Object run() throws Exception { 600 SnapshotDescription snapshot = new SnapshotDescription("foo"); 601 HTableDescriptor htd = new HTableDescriptor(testTable.getTableName()); 602 ACCESS_CONTROLLER.preCloneSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV), snapshot, 603 htd); 604 return null; 605 } 606 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 607 608 // preRestoreSnapshot 609 verifyAllowed(new AccessTestAction() { 610 @Override 611 public Object run() throws Exception { 612 SnapshotDescription snapshot = new SnapshotDescription("foo"); 613 HTableDescriptor htd = new HTableDescriptor(testTable.getTableName()); 614 ACCESS_CONTROLLER.preRestoreSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV), snapshot, 615 htd); 616 return null; 617 } 618 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 619 620 // preDeleteSnapshot 621 verifyAllowed(new AccessTestAction() { 622 @Override 623 public Object run() throws Exception { 624 SnapshotDescription snapshot = new SnapshotDescription("foo"); 625 ACCESS_CONTROLLER.preDeleteSnapshot(ObserverContextImpl.createAndPrepare(CP_ENV), snapshot); 626 return null; 627 } 628 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 629 630 // preGetTableDescriptors 631 verifyAllowed(new AccessTestAction() { 632 @Override 633 public Object run() throws Exception { 634 List<TableName> tableNamesList = Lists.newArrayList(); 635 tableNamesList.add(testTable.getTableName()); 636 List<TableDescriptor> descriptors = Lists.newArrayList(); 637 ACCESS_CONTROLLER.preGetTableDescriptors(ObserverContextImpl.createAndPrepare(CP_ENV), 638 tableNamesList, descriptors, ".+"); 639 return null; 640 } 641 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 642 643 // preGetTableNames 644 verifyAllowed(new AccessTestAction() { 645 @Override 646 public Object run() throws Exception { 647 List<TableDescriptor> descriptors = Lists.newArrayList(); 648 ACCESS_CONTROLLER.preGetTableNames(ObserverContextImpl.createAndPrepare(CP_ENV), 649 descriptors, ".+"); 650 return null; 651 } 652 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 653 654 // preCreateNamespace 655 verifyAllowed(new AccessTestAction() { 656 @Override 657 public Object run() throws Exception { 658 NamespaceDescriptor ns = NamespaceDescriptor.create("test").build(); 659 ACCESS_CONTROLLER.preCreateNamespace(ObserverContextImpl.createAndPrepare(CP_ENV), ns); 660 return null; 661 } 662 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 663 664 // preDeleteNamespace 665 verifyAllowed(new AccessTestAction() { 666 @Override 667 public Object run() throws Exception { 668 ACCESS_CONTROLLER.preDeleteNamespace(ObserverContextImpl.createAndPrepare(CP_ENV), "test"); 669 return null; 670 } 671 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 672 673 // preModifyNamespace 674 verifyAllowed(new AccessTestAction() { 675 @Override 676 public Object run() throws Exception { 677 NamespaceDescriptor ns = NamespaceDescriptor.create("test").build(); 678 ACCESS_CONTROLLER.preModifyNamespace(ObserverContextImpl.createAndPrepare(CP_ENV), ns); 679 return null; 680 } 681 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 682 683 // preGetNamespaceDescriptor 684 verifyAllowed(new AccessTestAction() { 685 @Override 686 public Object run() throws Exception { 687 ACCESS_CONTROLLER.preGetNamespaceDescriptor(ObserverContextImpl.createAndPrepare(CP_ENV), 688 "test"); 689 return null; 690 } 691 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 692 693 // preListNamespaceDescriptors 694 verifyAllowed(new AccessTestAction() { 695 @Override 696 public Object run() throws Exception { 697 List<NamespaceDescriptor> descriptors = Lists.newArrayList(); 698 ACCESS_CONTROLLER.preListNamespaceDescriptors(ObserverContextImpl.createAndPrepare(CP_ENV), 699 descriptors); 700 return null; 701 } 702 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 703 704 // preSplit 705 verifyAllowed(new AccessTestAction() { 706 @Override 707 public Object run() throws Exception { 708 ACCESS_CONTROLLER.preSplitRegion(ObserverContextImpl.createAndPrepare(CP_ENV), 709 testTable.getTableName(), Bytes.toBytes("ss")); 710 return null; 711 } 712 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 713 714 // preSetUserQuota 715 verifyAllowed(new AccessTestAction() { 716 @Override 717 public Object run() throws Exception { 718 ACCESS_CONTROLLER.preSetUserQuota(ObserverContextImpl.createAndPrepare(CP_ENV), "testuser", 719 null); 720 return null; 721 } 722 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 723 724 // preSetTableQuota 725 verifyAllowed(new AccessTestAction() { 726 @Override 727 public Object run() throws Exception { 728 ACCESS_CONTROLLER.preSetTableQuota(ObserverContextImpl.createAndPrepare(CP_ENV), 729 testTable.getTableName(), null); 730 return null; 731 } 732 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 733 734 // preSetNamespaceQuota 735 verifyAllowed(new AccessTestAction() { 736 @Override 737 public Object run() throws Exception { 738 ACCESS_CONTROLLER.preSetNamespaceQuota(ObserverContextImpl.createAndPrepare(CP_ENV), "test", 739 null); 740 return null; 741 } 742 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 743 744 } 745 746 /** Test region server observer */ 747 @Test 748 public void testPassiveRegionServerOperations() throws Exception { 749 // preStopRegionServer 750 verifyAllowed(new AccessTestAction() { 751 @Override 752 public Object run() throws Exception { 753 ACCESS_CONTROLLER.preStopRegionServer(ObserverContextImpl.createAndPrepare(RSCP_ENV)); 754 return null; 755 } 756 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 757 758 // preRollWALWriterRequest 759 verifyAllowed(new AccessTestAction() { 760 @Override 761 public Object run() throws Exception { 762 ACCESS_CONTROLLER.preRollWALWriterRequest(ObserverContextImpl.createAndPrepare(RSCP_ENV)); 763 return null; 764 } 765 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 766 767 } 768 769 /** Test region observer */ 770 @Test 771 public void testPassiveRegionOperations() throws Exception { 772 773 // preOpen 774 verifyAllowed(new AccessTestAction() { 775 @Override 776 public Object run() throws Exception { 777 ACCESS_CONTROLLER.preOpen(ObserverContextImpl.createAndPrepare(RCP_ENV)); 778 return null; 779 } 780 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 781 782 // preFlush 783 verifyAllowed(new AccessTestAction() { 784 @Override 785 public Object run() throws Exception { 786 ACCESS_CONTROLLER.preFlush(ObserverContextImpl.createAndPrepare(RCP_ENV), 787 FlushLifeCycleTracker.DUMMY); 788 return null; 789 } 790 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 791 792 // preGetOp 793 verifyAllowed(new AccessTestAction() { 794 @Override 795 public Object run() throws Exception { 796 List<Cell> cells = Lists.newArrayList(); 797 ACCESS_CONTROLLER.preGetOp(ObserverContextImpl.createAndPrepare(RCP_ENV), new Get(TEST_ROW), 798 cells); 799 return null; 800 } 801 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 802 803 // preExists 804 verifyAllowed(new AccessTestAction() { 805 @Override 806 public Object run() throws Exception { 807 ACCESS_CONTROLLER.preExists(ObserverContextImpl.createAndPrepare(RCP_ENV), 808 new Get(TEST_ROW), true); 809 return null; 810 } 811 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 812 813 // prePut 814 verifyAllowed(new AccessTestAction() { 815 @Override 816 public Object run() throws Exception { 817 ACCESS_CONTROLLER.prePut(ObserverContextImpl.createAndPrepare(RCP_ENV), new Put(TEST_ROW), 818 new WALEdit(), Durability.USE_DEFAULT); 819 return null; 820 } 821 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 822 823 // preDelete 824 verifyAllowed(new AccessTestAction() { 825 @Override 826 public Object run() throws Exception { 827 ACCESS_CONTROLLER.preDelete(ObserverContextImpl.createAndPrepare(RCP_ENV), 828 new Delete(TEST_ROW), new WALEdit(), Durability.USE_DEFAULT); 829 return null; 830 } 831 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 832 833 // preBatchMutate 834 verifyAllowed(new AccessTestAction() { 835 @Override 836 public Object run() throws Exception { 837 ACCESS_CONTROLLER.preBatchMutate(ObserverContextImpl.createAndPrepare(RCP_ENV), 838 new MiniBatchOperationInProgress<>(null, null, null, 0, 0, 0)); 839 return null; 840 } 841 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 842 843 // preCheckAndPut 844 verifyAllowed(new AccessTestAction() { 845 @Override 846 public Object run() throws Exception { 847 ACCESS_CONTROLLER.preCheckAndPut(ObserverContextImpl.createAndPrepare(RCP_ENV), TEST_ROW, 848 TEST_FAMILY, TEST_Q1, CompareOperator.EQUAL, new BinaryComparator("foo".getBytes()), 849 new Put(TEST_ROW), true); 850 return null; 851 } 852 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 853 854 // preCheckAndDelete 855 verifyAllowed(new AccessTestAction() { 856 @Override 857 public Object run() throws Exception { 858 ACCESS_CONTROLLER.preCheckAndDelete(ObserverContextImpl.createAndPrepare(RCP_ENV), TEST_ROW, 859 TEST_FAMILY, TEST_Q1, CompareOperator.EQUAL, new BinaryComparator("foo".getBytes()), 860 new Delete(TEST_ROW), true); 861 return null; 862 } 863 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 864 865 // preAppend 866 verifyAllowed(new AccessTestAction() { 867 @Override 868 public Object run() throws Exception { 869 ACCESS_CONTROLLER.preAppend(ObserverContextImpl.createAndPrepare(RCP_ENV), 870 new Append(TEST_ROW)); 871 return null; 872 } 873 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 874 875 // preIncrement 876 verifyAllowed(new AccessTestAction() { 877 @Override 878 public Object run() throws Exception { 879 ACCESS_CONTROLLER.preIncrement(ObserverContextImpl.createAndPrepare(RCP_ENV), 880 new Increment(TEST_ROW)); 881 return null; 882 } 883 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 884 885 // preScannerOpen 886 verifyAllowed(new AccessTestAction() { 887 @Override 888 public Object run() throws Exception { 889 ACCESS_CONTROLLER.preScannerOpen(ObserverContextImpl.createAndPrepare(RCP_ENV), new Scan()); 890 return null; 891 } 892 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 893 894 // preBulkLoadHFile 895 verifyAllowed(new AccessTestAction() { 896 @Override 897 public Object run() throws Exception { 898 List<Pair<byte[], String>> paths = Lists.newArrayList(); 899 ACCESS_CONTROLLER.preBulkLoadHFile(ObserverContextImpl.createAndPrepare(RCP_ENV), paths); 900 return null; 901 } 902 }, SUPERUSER, USER_ADMIN, USER_RW, USER_RO, USER_OWNER, USER_CREATE, USER_QUAL, USER_NONE); 903 904 } 905 906 @Test 907 public void testPassiveCellPermissions() throws Exception { 908 final Configuration conf = TEST_UTIL.getConfiguration(); 909 910 // store two sets of values, one store with a cell level ACL, and one without 911 verifyAllowed(new AccessTestAction() { 912 @Override 913 public Object run() throws Exception { 914 try (Connection connection = ConnectionFactory.createConnection(conf); 915 Table t = connection.getTable(testTable.getTableName())) { 916 Put p; 917 // with ro ACL 918 p = new Put(TEST_ROW).addColumn(TEST_FAMILY, TEST_Q1, ZERO); 919 p.setACL(USER_NONE.getShortName(), new Permission(Action.READ)); 920 t.put(p); 921 // with rw ACL 922 p = new Put(TEST_ROW).addColumn(TEST_FAMILY, TEST_Q2, ZERO); 923 p.setACL(USER_NONE.getShortName(), new Permission(Action.READ, Action.WRITE)); 924 t.put(p); 925 // no ACL 926 p = new Put(TEST_ROW).addColumn(TEST_FAMILY, TEST_Q3, ZERO).addColumn(TEST_FAMILY, 927 TEST_Q4, ZERO); 928 t.put(p); 929 } 930 return null; 931 } 932 }, USER_OWNER); 933 934 // check that a scan over the test data returns the expected number of KVs 935 936 final List<Cell> scanResults = Lists.newArrayList(); 937 938 AccessTestAction scanAction = new AccessTestAction() { 939 @Override 940 public List<Cell> run() throws Exception { 941 Scan scan = new Scan(); 942 scan.setStartRow(TEST_ROW); 943 scan.setStopRow(Bytes.add(TEST_ROW, new byte[] { 0 })); 944 scan.addFamily(TEST_FAMILY); 945 Connection connection = ConnectionFactory.createConnection(conf); 946 Table t = connection.getTable(testTable.getTableName()); 947 try { 948 ResultScanner scanner = t.getScanner(scan); 949 Result result = null; 950 do { 951 result = scanner.next(); 952 if (result != null) { 953 scanResults.addAll(result.listCells()); 954 } 955 } while (result != null); 956 } finally { 957 t.close(); 958 connection.close(); 959 } 960 return scanResults; 961 } 962 }; 963 964 // owner will see all values 965 scanResults.clear(); 966 verifyAllowed(scanAction, USER_OWNER); 967 assertEquals(4, scanResults.size()); 968 969 // other user will also see 4 values 970 // if cell filtering was active, we would only see 2 values 971 scanResults.clear(); 972 verifyAllowed(scanAction, USER_NONE); 973 assertEquals(4, scanResults.size()); 974 } 975 976}