1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.security.access;
20
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.fail;
25
26 import java.io.IOException;
27 import java.lang.reflect.UndeclaredThrowableException;
28 import java.security.PrivilegedActionException;
29 import java.security.PrivilegedExceptionAction;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.NavigableMap;
33
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36 import org.apache.hadoop.conf.Configuration;
37 import org.apache.hadoop.fs.FileStatus;
38 import org.apache.hadoop.fs.FileSystem;
39 import org.apache.hadoop.fs.Path;
40 import org.apache.hadoop.fs.permission.FsPermission;
41 import org.apache.hadoop.hbase.Coprocessor;
42 import org.apache.hadoop.hbase.TableName;
43 import org.apache.hadoop.hbase.HBaseTestingUtility;
44 import org.apache.hadoop.hbase.HColumnDescriptor;
45 import org.apache.hadoop.hbase.HConstants;
46 import org.apache.hadoop.hbase.HRegionInfo;
47 import org.apache.hadoop.hbase.HTableDescriptor;
48 import org.apache.hadoop.hbase.KeyValue;
49 import org.apache.hadoop.hbase.LargeTests;
50 import org.apache.hadoop.hbase.MiniHBaseCluster;
51 import org.apache.hadoop.hbase.ServerName;
52 import org.apache.hadoop.hbase.TableNotFoundException;
53 import org.apache.hadoop.hbase.client.Append;
54 import org.apache.hadoop.hbase.client.Delete;
55 import org.apache.hadoop.hbase.client.Get;
56 import org.apache.hadoop.hbase.client.HBaseAdmin;
57 import org.apache.hadoop.hbase.client.HTable;
58 import org.apache.hadoop.hbase.client.Increment;
59 import org.apache.hadoop.hbase.client.Put;
60 import org.apache.hadoop.hbase.client.Result;
61 import org.apache.hadoop.hbase.client.ResultScanner;
62 import org.apache.hadoop.hbase.client.RetriesExhaustedWithDetailsException;
63 import org.apache.hadoop.hbase.client.Scan;
64 import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
65 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
66 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
67 import org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment;
68 import org.apache.hadoop.hbase.io.hfile.CacheConfig;
69 import org.apache.hadoop.hbase.io.hfile.HFile;
70 import org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles;
71 import org.apache.hadoop.hbase.master.MasterCoprocessorHost;
72 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
73 import org.apache.hadoop.hbase.protobuf.RequestConverter;
74 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos;
75 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService;
76 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.CheckPermissionsRequest;
77 import org.apache.hadoop.hbase.regionserver.HRegion;
78 import org.apache.hadoop.hbase.regionserver.HRegionServer;
79 import org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost;
80 import org.apache.hadoop.hbase.regionserver.RegionServerCoprocessorHost;
81 import org.apache.hadoop.hbase.regionserver.ScanType;
82 import org.apache.hadoop.hbase.security.AccessDeniedException;
83 import org.apache.hadoop.hbase.security.User;
84 import org.apache.hadoop.hbase.security.access.Permission.Action;
85 import org.apache.hadoop.hbase.util.Bytes;
86 import org.apache.hadoop.hbase.util.JVMClusterUtil;
87 import org.apache.hadoop.hbase.util.TestTableName;
88
89 import org.junit.After;
90 import org.junit.AfterClass;
91 import org.junit.Before;
92 import org.junit.BeforeClass;
93 import org.junit.Rule;
94 import org.junit.Test;
95 import org.junit.experimental.categories.Category;
96
97 import com.google.protobuf.BlockingRpcChannel;
98 import com.google.protobuf.ServiceException;
99
100
101
102
103
104 @Category(LargeTests.class)
105 @SuppressWarnings("rawtypes")
106 public class TestAccessController extends SecureTestUtil {
107 private static final Log LOG = LogFactory.getLog(TestAccessController.class);
108 @Rule public TestTableName TEST_TABLE = new TestTableName();
109 private static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
110 private static Configuration conf;
111
112
113 private static User SUPERUSER;
114
115 private static User USER_ADMIN;
116
117 private static User USER_RW;
118
119 private static User USER_RO;
120
121 private static User USER_OWNER;
122
123 private static User USER_CREATE;
124
125 private static User USER_NONE;
126
127 private static TableName TEST_TABLE2 =
128 TableName.valueOf("testtable2");
129 private static byte[] TEST_FAMILY = Bytes.toBytes("f1");
130
131 private static MasterCoprocessorEnvironment CP_ENV;
132 private static AccessController ACCESS_CONTROLLER;
133 private static RegionServerCoprocessorEnvironment RSCP_ENV;
134 private RegionCoprocessorEnvironment RCP_ENV;
135
136 @BeforeClass
137 public static void setupBeforeClass() throws Exception {
138
139 conf = TEST_UTIL.getConfiguration();
140 conf.set("hbase.master.hfilecleaner.plugins",
141 "org.apache.hadoop.hbase.master.cleaner.HFileLinkCleaner," +
142 "org.apache.hadoop.hbase.master.snapshot.SnapshotHFileCleaner");
143 conf.set("hbase.master.logcleaner.plugins",
144 "org.apache.hadoop.hbase.master.snapshot.SnapshotLogCleaner");
145 SecureTestUtil.enableSecurity(conf);
146
147 TEST_UTIL.startMiniCluster();
148 MasterCoprocessorHost cpHost = TEST_UTIL.getMiniHBaseCluster().getMaster().getCoprocessorHost();
149 cpHost.load(AccessController.class, Coprocessor.PRIORITY_HIGHEST, conf);
150 ACCESS_CONTROLLER = (AccessController) cpHost.findCoprocessor(AccessController.class.getName());
151 CP_ENV = cpHost.createEnvironment(AccessController.class, ACCESS_CONTROLLER,
152 Coprocessor.PRIORITY_HIGHEST, 1, conf);
153 RegionServerCoprocessorHost rsHost = TEST_UTIL.getMiniHBaseCluster().getRegionServer(0)
154 .getCoprocessorHost();
155 RSCP_ENV = rsHost.createEnvironment(AccessController.class, ACCESS_CONTROLLER,
156 Coprocessor.PRIORITY_HIGHEST, 1, conf);
157
158
159 TEST_UTIL.waitTableEnabled(AccessControlLists.ACL_TABLE_NAME.getName());
160
161
162 SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
163 USER_ADMIN = User.createUserForTesting(conf, "admin2", new String[0]);
164 USER_RW = User.createUserForTesting(conf, "rwuser", new String[0]);
165 USER_RO = User.createUserForTesting(conf, "rouser", new String[0]);
166 USER_OWNER = User.createUserForTesting(conf, "owner", new String[0]);
167 USER_CREATE = User.createUserForTesting(conf, "tbl_create", new String[0]);
168 USER_NONE = User.createUserForTesting(conf, "nouser", new String[0]);
169 }
170
171 @AfterClass
172 public static void tearDownAfterClass() throws Exception {
173 TEST_UTIL.shutdownMiniCluster();
174 }
175
176 @Before
177 public void setUp() throws Exception {
178
179 HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
180 HTableDescriptor htd = new HTableDescriptor(TEST_TABLE.getTableName());
181 htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
182 htd.setOwner(USER_OWNER);
183 admin.createTable(htd);
184 TEST_UTIL.waitTableEnabled(TEST_TABLE.getTableName().getName());
185
186 HRegion region = TEST_UTIL.getHBaseCluster().getRegions(TEST_TABLE.getTableName()).get(0);
187 RegionCoprocessorHost rcpHost = region.getCoprocessorHost();
188 RCP_ENV = rcpHost.createEnvironment(AccessController.class, ACCESS_CONTROLLER,
189 Coprocessor.PRIORITY_HIGHEST, 1, conf);
190
191
192 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
193 try {
194 BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getTableName().getName());
195 AccessControlService.BlockingInterface protocol =
196 AccessControlService.newBlockingStub(service);
197
198 protocol.grant(null, RequestConverter.buildGrantRequest(USER_ADMIN.getShortName(),
199 AccessControlProtos.Permission.Action.ADMIN,
200 AccessControlProtos.Permission.Action.CREATE,
201 AccessControlProtos.Permission.Action.READ,
202 AccessControlProtos.Permission.Action.WRITE));
203
204 protocol.grant(null, RequestConverter.buildGrantRequest(USER_RW.getShortName(),
205 TEST_TABLE.getTableName(), TEST_FAMILY, null,
206 AccessControlProtos.Permission.Action.READ,
207 AccessControlProtos.Permission.Action.WRITE));
208
209
210 protocol.grant(null, RequestConverter.buildGrantRequest(USER_CREATE.getShortName(),
211 TEST_TABLE.getTableName(), null, null,
212 AccessControlProtos.Permission.Action.CREATE,
213 AccessControlProtos.Permission.Action.READ,
214 AccessControlProtos.Permission.Action.WRITE));
215
216 protocol.grant(null, RequestConverter.buildGrantRequest(USER_RO.getShortName(), TEST_TABLE.getTableName(),
217 TEST_FAMILY, null, AccessControlProtos.Permission.Action.READ));
218
219 assertEquals(4, AccessControlLists.getTablePermissions(conf, TEST_TABLE.getTableName()).size());
220 } finally {
221 acl.close();
222 }
223 }
224
225 @After
226 public void tearDown() throws Exception {
227
228 try {
229 TEST_UTIL.deleteTable(TEST_TABLE.getTableName());
230 } catch (TableNotFoundException ex) {
231
232 LOG.info("Test deleted table " + TEST_TABLE.getTableName());
233 }
234 assertEquals(0, AccessControlLists.getTablePermissions(conf, TEST_TABLE.getTableName()).size());
235 }
236
237 public void verifyAllowed(PrivilegedExceptionAction action, User... users) throws Exception {
238 for (User user : users) {
239 verifyAllowed(user, action);
240 }
241 }
242
243 public void verifyDenied(User user, PrivilegedExceptionAction... actions) throws Exception {
244 for (PrivilegedExceptionAction action : actions) {
245 try {
246 user.runAs(action);
247 fail("Expected AccessDeniedException for user '" + user.getShortName() + "'");
248 } catch (IOException e) {
249 boolean isAccessDeniedException = false;
250 if(e instanceof RetriesExhaustedWithDetailsException) {
251
252
253
254 for(Throwable ex : ((RetriesExhaustedWithDetailsException) e).getCauses()) {
255 if (ex instanceof AccessDeniedException) {
256 isAccessDeniedException = true;
257 break;
258 }
259 }
260 }
261 else {
262
263
264 Throwable ex = e;
265 do {
266 if (ex instanceof AccessDeniedException) {
267 isAccessDeniedException = true;
268 break;
269 }
270 } while((ex = ex.getCause()) != null);
271 }
272 if (!isAccessDeniedException) {
273 fail("Not receiving AccessDeniedException for user '" + user.getShortName() + "'");
274 }
275 } catch (UndeclaredThrowableException ute) {
276
277 Throwable ex = ute.getUndeclaredThrowable();
278 if (ex instanceof PrivilegedActionException) {
279 ex = ((PrivilegedActionException) ex).getException();
280 }
281 if (ex instanceof ServiceException) {
282 ServiceException se = (ServiceException)ex;
283 if (se.getCause() != null && se.getCause() instanceof AccessDeniedException) {
284
285 return;
286 }
287 }
288 fail("Not receiving AccessDeniedException for user '" + user.getShortName() + "'");
289 }
290 }
291 }
292
293 public void verifyDenied(PrivilegedExceptionAction action, User... users) throws Exception {
294 for (User user : users) {
295 verifyDenied(user, action);
296 }
297 }
298
299 @Test
300 public void testTableCreate() throws Exception {
301 PrivilegedExceptionAction createTable = new PrivilegedExceptionAction() {
302 public Object run() throws Exception {
303 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("testnewtable"));
304 htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
305 ACCESS_CONTROLLER.preCreateTable(ObserverContext.createAndPrepare(CP_ENV, null), htd, null);
306 return null;
307 }
308 };
309
310
311 verifyAllowed(createTable, SUPERUSER, USER_ADMIN);
312
313
314 verifyDenied(createTable, USER_CREATE, USER_RW, USER_RO, USER_NONE);
315 }
316
317 @Test
318 public void testTableModify() throws Exception {
319 PrivilegedExceptionAction modifyTable = new PrivilegedExceptionAction() {
320 public Object run() throws Exception {
321 HTableDescriptor htd = new HTableDescriptor(TEST_TABLE.getTableName());
322 htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
323 htd.addFamily(new HColumnDescriptor("fam_" + User.getCurrent().getShortName()));
324 ACCESS_CONTROLLER.preModifyTable(ObserverContext.createAndPrepare(CP_ENV, null),
325 TEST_TABLE.getTableName(), htd);
326 return null;
327 }
328 };
329
330 verifyAllowed(modifyTable, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER);
331 verifyDenied(modifyTable, USER_RW, USER_RO, USER_NONE);
332 }
333
334 @Test
335 public void testTableDelete() throws Exception {
336 PrivilegedExceptionAction deleteTable = new PrivilegedExceptionAction() {
337 public Object run() throws Exception {
338 ACCESS_CONTROLLER
339 .preDeleteTable(ObserverContext.createAndPrepare(CP_ENV, null), TEST_TABLE.getTableName());
340 return null;
341 }
342 };
343
344 verifyAllowed(deleteTable, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER);
345 verifyDenied(deleteTable, USER_RW, USER_RO, USER_NONE);
346 }
347
348 @Test
349 public void testAddColumn() throws Exception {
350 final HColumnDescriptor hcd = new HColumnDescriptor("fam_new");
351 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
352 public Object run() throws Exception {
353 ACCESS_CONTROLLER.preAddColumn(ObserverContext.createAndPrepare(CP_ENV, null), TEST_TABLE.getTableName(),
354 hcd);
355 return null;
356 }
357 };
358
359 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER);
360 verifyDenied(action, USER_RW, USER_RO, USER_NONE);
361 }
362
363 @Test
364 public void testModifyColumn() throws Exception {
365 final HColumnDescriptor hcd = new HColumnDescriptor(TEST_FAMILY);
366 hcd.setMaxVersions(10);
367 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
368 public Object run() throws Exception {
369 ACCESS_CONTROLLER.preModifyColumn(ObserverContext.createAndPrepare(CP_ENV, null),
370 TEST_TABLE.getTableName(), hcd);
371 return null;
372 }
373 };
374
375 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER);
376 verifyDenied(action, USER_RW, USER_RO, USER_NONE);
377 }
378
379 @Test
380 public void testDeleteColumn() throws Exception {
381 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
382 public Object run() throws Exception {
383 ACCESS_CONTROLLER.preDeleteColumn(ObserverContext.createAndPrepare(CP_ENV, null),
384 TEST_TABLE.getTableName(), TEST_FAMILY);
385 return null;
386 }
387 };
388
389 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER);
390 verifyDenied(action, USER_RW, USER_RO, USER_NONE);
391 }
392
393 @Test
394 public void testTableDisable() throws Exception {
395 PrivilegedExceptionAction disableTable = new PrivilegedExceptionAction() {
396 public Object run() throws Exception {
397 ACCESS_CONTROLLER.preDisableTable(ObserverContext.createAndPrepare(CP_ENV, null),
398 TEST_TABLE.getTableName());
399 return null;
400 }
401 };
402
403 PrivilegedExceptionAction disableAclTable = new PrivilegedExceptionAction() {
404 public Object run() throws Exception {
405 ACCESS_CONTROLLER.preDisableTable(ObserverContext.createAndPrepare(CP_ENV, null),
406 AccessControlLists.ACL_TABLE_NAME);
407 return null;
408 }
409 };
410
411 verifyAllowed(disableTable, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER);
412 verifyDenied(disableTable, USER_RW, USER_RO, USER_NONE);
413
414
415 verifyDenied(disableAclTable, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER, USER_RW, USER_RO);
416 }
417
418 @Test
419 public void testTableEnable() throws Exception {
420 PrivilegedExceptionAction enableTable = new PrivilegedExceptionAction() {
421 public Object run() throws Exception {
422 ACCESS_CONTROLLER
423 .preEnableTable(ObserverContext.createAndPrepare(CP_ENV, null), TEST_TABLE.getTableName());
424 return null;
425 }
426 };
427
428 verifyAllowed(enableTable, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER);
429 verifyDenied(enableTable, USER_RW, USER_RO, USER_NONE);
430 }
431
432 @Test
433 public void testMove() throws Exception {
434 Map<HRegionInfo, ServerName> regions;
435 HTable table = new HTable(TEST_UTIL.getConfiguration(), TEST_TABLE.getTableName());
436 try {
437 regions = table.getRegionLocations();
438 } finally {
439 table.close();
440 }
441 final Map.Entry<HRegionInfo, ServerName> firstRegion = regions.entrySet().iterator().next();
442 final ServerName server = TEST_UTIL.getHBaseCluster().getRegionServer(0).getServerName();
443 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
444 public Object run() throws Exception {
445 ACCESS_CONTROLLER.preMove(ObserverContext.createAndPrepare(CP_ENV, null),
446 firstRegion.getKey(), server, server);
447 return null;
448 }
449 };
450
451 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
452 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
453 }
454
455 @Test
456 public void testAssign() throws Exception {
457 Map<HRegionInfo, ServerName> regions;
458 HTable table = new HTable(TEST_UTIL.getConfiguration(), TEST_TABLE.getTableName());
459 try {
460 regions = table.getRegionLocations();
461 } finally {
462 table.close();
463 }
464 final Map.Entry<HRegionInfo, ServerName> firstRegion = regions.entrySet().iterator().next();
465
466 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
467 public Object run() throws Exception {
468 ACCESS_CONTROLLER.preAssign(ObserverContext.createAndPrepare(CP_ENV, null),
469 firstRegion.getKey());
470 return null;
471 }
472 };
473
474 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
475 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
476 }
477
478 @Test
479 public void testUnassign() throws Exception {
480 Map<HRegionInfo, ServerName> regions;
481 HTable table = new HTable(TEST_UTIL.getConfiguration(), TEST_TABLE.getTableName());
482 try {
483 regions = table.getRegionLocations();
484 } finally {
485 table.close();
486 }
487 final Map.Entry<HRegionInfo, ServerName> firstRegion = regions.entrySet().iterator().next();
488
489 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
490 public Object run() throws Exception {
491 ACCESS_CONTROLLER.preUnassign(ObserverContext.createAndPrepare(CP_ENV, null),
492 firstRegion.getKey(), false);
493 return null;
494 }
495 };
496
497 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
498 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
499 }
500
501 @Test
502 public void testRegionOffline() throws Exception {
503 Map<HRegionInfo, ServerName> regions;
504 HTable table = new HTable(TEST_UTIL.getConfiguration(), TEST_TABLE.getTableName());
505 try {
506 regions = table.getRegionLocations();
507 } finally {
508 table.close();
509 }
510 final Map.Entry<HRegionInfo, ServerName> firstRegion = regions.entrySet().iterator().next();
511
512 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
513 public Object run() throws Exception {
514 ACCESS_CONTROLLER.preRegionOffline(ObserverContext.createAndPrepare(CP_ENV, null),
515 firstRegion.getKey());
516 return null;
517 }
518 };
519
520 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
521 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
522 }
523
524 @Test
525 public void testBalance() throws Exception {
526 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
527 public Object run() throws Exception {
528 ACCESS_CONTROLLER.preBalance(ObserverContext.createAndPrepare(CP_ENV, null));
529 return null;
530 }
531 };
532
533 verifyAllowed(action, SUPERUSER, USER_ADMIN);
534 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE);
535 }
536
537 @Test
538 public void testBalanceSwitch() throws Exception {
539 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
540 public Object run() throws Exception {
541 ACCESS_CONTROLLER.preBalanceSwitch(ObserverContext.createAndPrepare(CP_ENV, null), true);
542 return null;
543 }
544 };
545
546 verifyAllowed(action, SUPERUSER, USER_ADMIN);
547 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE);
548 }
549
550 @Test
551 public void testShutdown() throws Exception {
552 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
553 public Object run() throws Exception {
554 ACCESS_CONTROLLER.preShutdown(ObserverContext.createAndPrepare(CP_ENV, null));
555 return null;
556 }
557 };
558
559 verifyAllowed(action, SUPERUSER, USER_ADMIN);
560 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE);
561 }
562
563 @Test
564 public void testStopMaster() throws Exception {
565 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
566 public Object run() throws Exception {
567 ACCESS_CONTROLLER.preStopMaster(ObserverContext.createAndPrepare(CP_ENV, null));
568 return null;
569 }
570 };
571
572 verifyAllowed(action, SUPERUSER, USER_ADMIN);
573 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE);
574 }
575
576 private void verifyWrite(PrivilegedExceptionAction action) throws Exception {
577 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW);
578 verifyDenied(action, USER_NONE, USER_RO);
579 }
580
581 @Test
582 public void testSplit() throws Exception {
583 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
584 public Object run() throws Exception {
585 ACCESS_CONTROLLER.preSplit(ObserverContext.createAndPrepare(RCP_ENV, null));
586 return null;
587 }
588 };
589
590 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
591 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
592 }
593
594 @Test
595 public void testSplitWithSplitRow() throws Exception {
596 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
597 public Object run() throws Exception {
598 ACCESS_CONTROLLER.preSplit(
599 ObserverContext.createAndPrepare(RCP_ENV, null),
600 Bytes.toBytes("row2"));
601 return null;
602 }
603 };
604
605 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
606 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
607 }
608
609
610 @Test
611 public void testFlush() throws Exception {
612 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
613 public Object run() throws Exception {
614 ACCESS_CONTROLLER.preFlush(ObserverContext.createAndPrepare(RCP_ENV, null));
615 return null;
616 }
617 };
618
619 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
620 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
621 }
622
623 @Test
624 public void testCompact() throws Exception {
625 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
626 public Object run() throws Exception {
627 ACCESS_CONTROLLER.preCompact(ObserverContext.createAndPrepare(RCP_ENV, null), null, null,
628 ScanType.COMPACT_RETAIN_DELETES);
629 return null;
630 }
631 };
632
633 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
634 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
635 }
636
637 @Test
638 public void testPreCompactSelection() throws Exception {
639 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
640 public Object run() throws Exception {
641 ACCESS_CONTROLLER.preCompactSelection(ObserverContext.createAndPrepare(RCP_ENV, null), null, null);
642 return null;
643 }
644 };
645
646 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER);
647 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE);
648 }
649
650 private void verifyRead(PrivilegedExceptionAction action) throws Exception {
651 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW, USER_RO);
652 verifyDenied(action, USER_NONE);
653 }
654
655 private void verifyReadWrite(PrivilegedExceptionAction action) throws Exception {
656 verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW);
657 verifyDenied(action, USER_NONE, USER_RO);
658 }
659
660 @Test
661 public void testRead() throws Exception {
662
663 PrivilegedExceptionAction getAction = new PrivilegedExceptionAction() {
664 public Object run() throws Exception {
665 Get g = new Get(Bytes.toBytes("random_row"));
666 g.addFamily(TEST_FAMILY);
667 HTable t = new HTable(conf, TEST_TABLE.getTableName());
668 try {
669 t.get(g);
670 } finally {
671 t.close();
672 }
673 return null;
674 }
675 };
676 verifyRead(getAction);
677
678
679 PrivilegedExceptionAction scanAction = new PrivilegedExceptionAction() {
680 public Object run() throws Exception {
681 Scan s = new Scan();
682 s.addFamily(TEST_FAMILY);
683
684 HTable table = new HTable(conf, TEST_TABLE.getTableName());
685 try {
686 ResultScanner scanner = table.getScanner(s);
687 try {
688 for (Result r = scanner.next(); r != null; r = scanner.next()) {
689
690 }
691 } catch (IOException e) {
692 } finally {
693 scanner.close();
694 }
695 } finally {
696 table.close();
697 }
698 return null;
699 }
700 };
701 verifyRead(scanAction);
702 }
703
704 @Test
705
706 public void testWrite() throws Exception {
707
708 PrivilegedExceptionAction putAction = new PrivilegedExceptionAction() {
709 public Object run() throws Exception {
710 Put p = new Put(Bytes.toBytes("random_row"));
711 p.add(TEST_FAMILY, Bytes.toBytes("Qualifier"), Bytes.toBytes(1));
712 HTable t = new HTable(conf, TEST_TABLE.getTableName());
713 try {
714 t.put(p);
715 } finally {
716 t.close();
717 }
718 return null;
719 }
720 };
721 verifyWrite(putAction);
722
723
724 PrivilegedExceptionAction deleteAction = new PrivilegedExceptionAction() {
725 public Object run() throws Exception {
726 Delete d = new Delete(Bytes.toBytes("random_row"));
727 d.deleteFamily(TEST_FAMILY);
728 HTable t = new HTable(conf, TEST_TABLE.getTableName());
729 try {
730 t.delete(d);
731 } finally {
732 t.close();
733 }
734 return null;
735 }
736 };
737 verifyWrite(deleteAction);
738
739
740 PrivilegedExceptionAction incrementAction = new PrivilegedExceptionAction() {
741 public Object run() throws Exception {
742 Increment inc = new Increment(Bytes.toBytes("random_row"));
743 inc.addColumn(TEST_FAMILY, Bytes.toBytes("Qualifier"), 1);
744 HTable t = new HTable(conf, TEST_TABLE.getTableName());
745 try {
746 t.increment(inc);
747 } finally {
748 t.close();
749 }
750 return null;
751 }
752 };
753 verifyWrite(incrementAction);
754 }
755
756 @Test
757 public void testReadWrite() throws Exception {
758
759 PrivilegedExceptionAction checkAndDeleteAction = new PrivilegedExceptionAction() {
760 public Object run() throws Exception {
761 Delete d = new Delete(Bytes.toBytes("random_row"));
762 d.deleteFamily(TEST_FAMILY);
763 HTable t = new HTable(conf, TEST_TABLE.getTableName());
764 try {
765 t.checkAndDelete(Bytes.toBytes("random_row"), TEST_FAMILY, Bytes.toBytes("q"),
766 Bytes.toBytes("test_value"), d);
767 } finally {
768 t.close();
769 }
770 return null;
771 }
772 };
773 verifyReadWrite(checkAndDeleteAction);
774
775
776 PrivilegedExceptionAction checkAndPut = new PrivilegedExceptionAction() {
777 public Object run() throws Exception {
778 Put p = new Put(Bytes.toBytes("random_row"));
779 p.add(TEST_FAMILY, Bytes.toBytes("Qualifier"), Bytes.toBytes(1));
780 HTable t = new HTable(conf, TEST_TABLE.getTableName());
781 try {
782 t.checkAndPut(Bytes.toBytes("random_row"), TEST_FAMILY, Bytes.toBytes("q"),
783 Bytes.toBytes("test_value"), p);
784 } finally {
785 t.close();
786 }
787 return null;
788 }
789 };
790 verifyReadWrite(checkAndPut);
791 }
792
793 @Test
794 public void testBulkLoad() throws Exception {
795 FileSystem fs = TEST_UTIL.getTestFileSystem();
796 final Path dir = TEST_UTIL.getDataTestDir("testBulkLoad");
797 fs.mkdirs(dir);
798
799
800 fs.setPermission(dir, FsPermission.valueOf("-rwxrwxrwx"));
801
802 PrivilegedExceptionAction bulkLoadAction = new PrivilegedExceptionAction() {
803 public Object run() throws Exception {
804 int numRows = 3;
805
806
807 byte[][][] hfileRanges = {{{(byte)0}, {(byte)9}}};
808
809 Path bulkLoadBasePath = new Path(dir, new Path(User.getCurrent().getName()));
810 new BulkLoadHelper(bulkLoadBasePath)
811 .bulkLoadHFile(TEST_TABLE.getTableName(), TEST_FAMILY, Bytes.toBytes("q"), hfileRanges, numRows);
812
813 return null;
814 }
815 };
816
817
818
819 verifyAllowed(bulkLoadAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE);
820 verifyDenied(bulkLoadAction, USER_RW, USER_NONE, USER_RO);
821
822
823 TEST_UTIL.getHBaseAdmin().disableTable(TEST_TABLE.getTableName());
824 TEST_UTIL.getHBaseAdmin().enableTable(TEST_TABLE.getTableName());
825 }
826
827 public class BulkLoadHelper {
828 private final FileSystem fs;
829 private final Path loadPath;
830 private final Configuration conf;
831
832 public BulkLoadHelper(Path loadPath) throws IOException {
833 fs = TEST_UTIL.getTestFileSystem();
834 conf = TEST_UTIL.getConfiguration();
835 loadPath = loadPath.makeQualified(fs);
836 this.loadPath = loadPath;
837 }
838
839 private void createHFile(Path path,
840 byte[] family, byte[] qualifier,
841 byte[] startKey, byte[] endKey, int numRows) throws IOException {
842
843 HFile.Writer writer = null;
844 long now = System.currentTimeMillis();
845 try {
846 writer = HFile.getWriterFactory(conf, new CacheConfig(conf))
847 .withPath(fs, path)
848 .withComparator(KeyValue.KEY_COMPARATOR)
849 .create();
850
851 for (byte[] key : Bytes.iterateOnSplits(startKey, endKey, true, numRows-2)) {
852 KeyValue kv = new KeyValue(key, family, qualifier, now, key);
853 writer.append(kv);
854 }
855 } finally {
856 if(writer != null)
857 writer.close();
858 }
859 }
860
861 private void bulkLoadHFile(
862 TableName tableName,
863 byte[] family,
864 byte[] qualifier,
865 byte[][][] hfileRanges,
866 int numRowsPerRange) throws Exception {
867
868 Path familyDir = new Path(loadPath, Bytes.toString(family));
869 fs.mkdirs(familyDir);
870 int hfileIdx = 0;
871 for (byte[][] range : hfileRanges) {
872 byte[] from = range[0];
873 byte[] to = range[1];
874 createHFile(new Path(familyDir, "hfile_"+(hfileIdx++)),
875 family, qualifier, from, to, numRowsPerRange);
876 }
877
878 setPermission(loadPath, FsPermission.valueOf("-rwxrwxrwx"));
879
880 HTable table = new HTable(conf, tableName);
881 try {
882 HBaseAdmin admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
883 TEST_UTIL.waitTableEnabled(admin, tableName.getName());
884 LoadIncrementalHFiles loader = new LoadIncrementalHFiles(conf);
885 loader.doBulkLoad(loadPath, table);
886 } finally {
887 table.close();
888 }
889 }
890
891 public void setPermission(Path dir, FsPermission perm) throws IOException {
892 if(!fs.getFileStatus(dir).isDir()) {
893 fs.setPermission(dir,perm);
894 }
895 else {
896 for(FileStatus el : fs.listStatus(dir)) {
897 fs.setPermission(el.getPath(), perm);
898 setPermission(el.getPath() , perm);
899 }
900 }
901 }
902 }
903
904 @Test
905 public void testAppend() throws Exception {
906
907 PrivilegedExceptionAction appendAction = new PrivilegedExceptionAction() {
908 public Object run() throws Exception {
909 byte[] row = Bytes.toBytes("random_row");
910 byte[] qualifier = Bytes.toBytes("q");
911 Put put = new Put(row);
912 put.add(TEST_FAMILY, qualifier, Bytes.toBytes(1));
913 Append append = new Append(row);
914 append.add(TEST_FAMILY, qualifier, Bytes.toBytes(2));
915 HTable t = new HTable(conf, TEST_TABLE.getTableName());
916 try {
917 t.put(put);
918 t.append(append);
919 } finally {
920 t.close();
921 }
922 return null;
923 }
924 };
925
926 verifyAllowed(appendAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_RW);
927 verifyDenied(appendAction, USER_RO, USER_NONE);
928 }
929
930 @Test
931 public void testGrantRevoke() throws Exception {
932
933 PrivilegedExceptionAction grantAction = new PrivilegedExceptionAction() {
934 public Object run() throws Exception {
935 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
936 try {
937 BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getTableName().getName());
938 AccessControlService.BlockingInterface protocol =
939 AccessControlService.newBlockingStub(service);
940 ProtobufUtil.grant(protocol, USER_RO.getShortName(), TEST_TABLE.getTableName(),
941 TEST_FAMILY, null, Action.READ);
942 } finally {
943 acl.close();
944 }
945 return null;
946 }
947 };
948
949 PrivilegedExceptionAction revokeAction = new PrivilegedExceptionAction() {
950 public Object run() throws Exception {
951 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
952 try {
953 BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getTableName().getName());
954 AccessControlService.BlockingInterface protocol =
955 AccessControlService.newBlockingStub(service);
956 ProtobufUtil.revoke(protocol, USER_RO.getShortName(), TEST_TABLE.getTableName(),
957 TEST_FAMILY, null, Action.READ);
958 } finally {
959 acl.close();
960 }
961 return null;
962 }
963 };
964
965 PrivilegedExceptionAction getPermissionsAction = new PrivilegedExceptionAction() {
966 public Object run() throws Exception {
967 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
968 try {
969 BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getTableName().getName());
970 AccessControlService.BlockingInterface protocol =
971 AccessControlService.newBlockingStub(service);
972 ProtobufUtil.getUserPermissions(protocol, TEST_TABLE.getTableName());
973 } finally {
974 acl.close();
975 }
976 return null;
977 }
978 };
979
980 verifyAllowed(grantAction, SUPERUSER, USER_ADMIN, USER_OWNER);
981 verifyDenied(grantAction, USER_CREATE, USER_RW, USER_RO, USER_NONE);
982
983 verifyAllowed(revokeAction, SUPERUSER, USER_ADMIN, USER_OWNER);
984 verifyDenied(revokeAction, USER_CREATE, USER_RW, USER_RO, USER_NONE);
985
986 verifyAllowed(getPermissionsAction, SUPERUSER, USER_ADMIN, USER_OWNER);
987 verifyDenied(getPermissionsAction, USER_CREATE, USER_RW, USER_RO, USER_NONE);
988 }
989
990 @Test
991 public void testPostGrantRevoke() throws Exception {
992 final TableName tableName =
993 TableName.valueOf("TempTable");
994 final byte[] family1 = Bytes.toBytes("f1");
995 final byte[] family2 = Bytes.toBytes("f2");
996 final byte[] qualifier = Bytes.toBytes("q");
997
998
999 HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
1000 if (admin.tableExists(tableName)) {
1001 admin.disableTable(tableName);
1002 admin.deleteTable(tableName);
1003 }
1004 HTableDescriptor htd = new HTableDescriptor(tableName);
1005 htd.addFamily(new HColumnDescriptor(family1));
1006 htd.addFamily(new HColumnDescriptor(family2));
1007 admin.createTable(htd);
1008
1009
1010 User tblUser = User
1011 .createUserForTesting(TEST_UTIL.getConfiguration(), "tbluser", new String[0]);
1012 User gblUser = User
1013 .createUserForTesting(TEST_UTIL.getConfiguration(), "gbluser", new String[0]);
1014
1015
1016 PrivilegedExceptionAction putActionAll = new PrivilegedExceptionAction() {
1017 public Object run() throws Exception {
1018 Put p = new Put(Bytes.toBytes("a"));
1019 p.add(family1, qualifier, Bytes.toBytes("v1"));
1020 p.add(family2, qualifier, Bytes.toBytes("v2"));
1021 HTable t = new HTable(conf, tableName);
1022 try {
1023 t.put(p);
1024 } finally {
1025 t.close();
1026 }
1027 return null;
1028 }
1029 };
1030 PrivilegedExceptionAction putAction1 = new PrivilegedExceptionAction() {
1031 public Object run() throws Exception {
1032 Put p = new Put(Bytes.toBytes("a"));
1033 p.add(family1, qualifier, Bytes.toBytes("v1"));
1034 HTable t = new HTable(conf, tableName);
1035 try {
1036 t.put(p);
1037 } finally {
1038 t.close();
1039 }
1040 return null;
1041 }
1042 };
1043 PrivilegedExceptionAction putAction2 = new PrivilegedExceptionAction() {
1044 public Object run() throws Exception {
1045 Put p = new Put(Bytes.toBytes("a"));
1046 p.add(family2, qualifier, Bytes.toBytes("v2"));
1047 HTable t = new HTable(conf, tableName);
1048 try {
1049 t.put(p);
1050 } finally {
1051 t.close();
1052 }
1053 return null;
1054 }
1055 };
1056 PrivilegedExceptionAction getActionAll = new PrivilegedExceptionAction() {
1057 public Object run() throws Exception {
1058 Get g = new Get(Bytes.toBytes("random_row"));
1059 g.addFamily(family1);
1060 g.addFamily(family2);
1061 HTable t = new HTable(conf, tableName);
1062 try {
1063 t.get(g);
1064 } finally {
1065 t.close();
1066 }
1067 return null;
1068 }
1069 };
1070 PrivilegedExceptionAction getAction1 = new PrivilegedExceptionAction() {
1071 public Object run() throws Exception {
1072 Get g = new Get(Bytes.toBytes("random_row"));
1073 g.addFamily(family1);
1074 HTable t = new HTable(conf, tableName);
1075 try {
1076 t.get(g);
1077 } finally {
1078 t.close();
1079 }
1080 return null;
1081 }
1082 };
1083 PrivilegedExceptionAction getAction2 = new PrivilegedExceptionAction() {
1084 public Object run() throws Exception {
1085 Get g = new Get(Bytes.toBytes("random_row"));
1086 g.addFamily(family2);
1087 HTable t = new HTable(conf, tableName);
1088 try {
1089 t.get(g);
1090 } finally {
1091 t.close();
1092 }
1093 return null;
1094 }
1095 };
1096 PrivilegedExceptionAction deleteActionAll = new PrivilegedExceptionAction() {
1097 public Object run() throws Exception {
1098 Delete d = new Delete(Bytes.toBytes("random_row"));
1099 d.deleteFamily(family1);
1100 d.deleteFamily(family2);
1101 HTable t = new HTable(conf, tableName);
1102 try {
1103 t.delete(d);
1104 } finally {
1105 t.close();
1106 }
1107 return null;
1108 }
1109 };
1110 PrivilegedExceptionAction deleteAction1 = new PrivilegedExceptionAction() {
1111 public Object run() throws Exception {
1112 Delete d = new Delete(Bytes.toBytes("random_row"));
1113 d.deleteFamily(family1);
1114 HTable t = new HTable(conf, tableName);
1115 try {
1116 t.delete(d);
1117 } finally {
1118 t.close();
1119 }
1120 return null;
1121 }
1122 };
1123 PrivilegedExceptionAction deleteAction2 = new PrivilegedExceptionAction() {
1124 public Object run() throws Exception {
1125 Delete d = new Delete(Bytes.toBytes("random_row"));
1126 d.deleteFamily(family2);
1127 HTable t = new HTable(conf, tableName);
1128 try {
1129 t.delete(d);
1130 } finally {
1131 t.close();
1132 }
1133 return null;
1134 }
1135 };
1136
1137
1138 verifyDenied(tblUser, getActionAll, getAction1, getAction2);
1139 verifyDenied(tblUser, putActionAll, putAction1, putAction2);
1140 verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2);
1141
1142 verifyDenied(gblUser, getActionAll, getAction1, getAction2);
1143 verifyDenied(gblUser, putActionAll, putAction1, putAction2);
1144 verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2);
1145
1146
1147 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1148 try {
1149 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1150 AccessControlService.BlockingInterface protocol =
1151 AccessControlService.newBlockingStub(service);
1152 ProtobufUtil.grant(protocol, tblUser.getShortName(),
1153 tableName, null, null, Permission.Action.READ);
1154 ProtobufUtil.grant(protocol, gblUser.getShortName(),
1155 Permission.Action.READ);
1156 } finally {
1157 acl.close();
1158 }
1159
1160 Thread.sleep(100);
1161
1162 verifyAllowed(tblUser, getActionAll, getAction1, getAction2);
1163 verifyDenied(tblUser, putActionAll, putAction1, putAction2);
1164 verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2);
1165
1166 verifyAllowed(gblUser, getActionAll, getAction1, getAction2);
1167 verifyDenied(gblUser, putActionAll, putAction1, putAction2);
1168 verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2);
1169
1170
1171 acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1172 try {
1173 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1174 AccessControlService.BlockingInterface protocol =
1175 AccessControlService.newBlockingStub(service);
1176 ProtobufUtil.grant(protocol, tblUser.getShortName(),
1177 tableName, null, null, Permission.Action.WRITE);
1178 ProtobufUtil.grant(protocol, gblUser.getShortName(),
1179 Permission.Action.WRITE);
1180 } finally {
1181 acl.close();
1182 }
1183
1184 Thread.sleep(100);
1185
1186 verifyDenied(tblUser, getActionAll, getAction1, getAction2);
1187 verifyAllowed(tblUser, putActionAll, putAction1, putAction2);
1188 verifyAllowed(tblUser, deleteActionAll, deleteAction1, deleteAction2);
1189
1190 verifyDenied(gblUser, getActionAll, getAction1, getAction2);
1191 verifyAllowed(gblUser, putActionAll, putAction1, putAction2);
1192 verifyAllowed(gblUser, deleteActionAll, deleteAction1, deleteAction2);
1193
1194
1195 acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1196 try {
1197 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1198 AccessControlService.BlockingInterface protocol =
1199 AccessControlService.newBlockingStub(service);
1200 ProtobufUtil.grant(protocol, tblUser.getShortName(), tableName, null, null,
1201 Permission.Action.READ, Permission.Action.WRITE);
1202 ProtobufUtil.revoke(protocol, tblUser.getShortName(), tableName, null, null);
1203 ProtobufUtil.revoke(protocol, gblUser.getShortName());
1204 } finally {
1205 acl.close();
1206 }
1207
1208 Thread.sleep(100);
1209
1210 verifyDenied(tblUser, getActionAll, getAction1, getAction2);
1211 verifyDenied(tblUser, putActionAll, putAction1, putAction2);
1212 verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2);
1213
1214 verifyDenied(gblUser, getActionAll, getAction1, getAction2);
1215 verifyDenied(gblUser, putActionAll, putAction1, putAction2);
1216 verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2);
1217
1218
1219 acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1220 try {
1221 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1222 AccessControlService.BlockingInterface protocol =
1223 AccessControlService.newBlockingStub(service);
1224 ProtobufUtil.grant(protocol, tblUser.getShortName(),
1225 tableName, family1, null, Permission.Action.READ);
1226 ProtobufUtil.grant(protocol, gblUser.getShortName(),
1227 Permission.Action.READ);
1228 } finally {
1229 acl.close();
1230 }
1231
1232 Thread.sleep(100);
1233
1234
1235 verifyAllowed(tblUser, getActionAll, getAction1);
1236 verifyDenied(tblUser, getAction2);
1237 verifyDenied(tblUser, putActionAll, putAction1, putAction2);
1238 verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2);
1239
1240 verifyAllowed(gblUser, getActionAll, getAction1, getAction2);
1241 verifyDenied(gblUser, putActionAll, putAction1, putAction2);
1242 verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2);
1243
1244
1245 acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1246 try {
1247 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1248 AccessControlService.BlockingInterface protocol =
1249 AccessControlService.newBlockingStub(service);
1250 ProtobufUtil.grant(protocol, tblUser.getShortName(),
1251 tableName, family2, null, Permission.Action.WRITE);
1252 ProtobufUtil.grant(protocol, gblUser.getShortName(),
1253 Permission.Action.WRITE);
1254 } finally {
1255 acl.close();
1256 }
1257
1258 Thread.sleep(100);
1259
1260
1261 verifyAllowed(tblUser, getActionAll, getAction1);
1262 verifyAllowed(tblUser, putAction2, deleteAction2);
1263 verifyDenied(tblUser, getAction2);
1264 verifyDenied(tblUser, putActionAll, putAction1);
1265 verifyDenied(tblUser, deleteActionAll, deleteAction1);
1266
1267 verifyDenied(gblUser, getActionAll, getAction1, getAction2);
1268 verifyAllowed(gblUser, putActionAll, putAction1, putAction2);
1269 verifyAllowed(gblUser, deleteActionAll, deleteAction1, deleteAction2);
1270
1271
1272 acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1273 try {
1274 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1275 AccessControlService.BlockingInterface protocol =
1276 AccessControlService.newBlockingStub(service);
1277 ProtobufUtil.revoke(protocol, tblUser.getShortName(), tableName, family2, null);
1278 ProtobufUtil.revoke(protocol, gblUser.getShortName());
1279 } finally {
1280 acl.close();
1281 }
1282
1283 Thread.sleep(100);
1284
1285
1286 verifyAllowed(tblUser, getActionAll, getAction1);
1287 verifyDenied(tblUser, getAction2);
1288 verifyDenied(tblUser, putActionAll, putAction1, putAction2);
1289 verifyDenied(tblUser, deleteActionAll, deleteAction1, deleteAction2);
1290
1291
1292 verifyDenied(gblUser, getActionAll, getAction1, getAction2);
1293 verifyDenied(gblUser, putActionAll, putAction1, putAction2);
1294 verifyDenied(gblUser, deleteActionAll, deleteAction1, deleteAction2);
1295
1296
1297 admin.disableTable(tableName);
1298 admin.deleteTable(tableName);
1299 }
1300
1301 private boolean hasFoundUserPermission(UserPermission userPermission, List<UserPermission> perms) {
1302 return perms.contains(userPermission);
1303 }
1304
1305 @Test
1306 public void testPostGrantRevokeAtQualifierLevel() throws Exception {
1307 final TableName tableName =
1308 TableName.valueOf("testGrantRevokeAtQualifierLevel");
1309 final byte[] family1 = Bytes.toBytes("f1");
1310 final byte[] family2 = Bytes.toBytes("f2");
1311 final byte[] qualifier = Bytes.toBytes("q");
1312
1313
1314 HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
1315 if (admin.tableExists(tableName)) {
1316 admin.disableTable(tableName);
1317 admin.deleteTable(tableName);
1318 }
1319 HTableDescriptor htd = new HTableDescriptor(tableName);
1320 htd.addFamily(new HColumnDescriptor(family1));
1321 htd.addFamily(new HColumnDescriptor(family2));
1322 admin.createTable(htd);
1323
1324
1325 User user = User.createUserForTesting(TEST_UTIL.getConfiguration(), "user", new String[0]);
1326
1327 PrivilegedExceptionAction getQualifierAction = new PrivilegedExceptionAction() {
1328 public Object run() throws Exception {
1329 Get g = new Get(Bytes.toBytes("random_row"));
1330 g.addColumn(family1, qualifier);
1331 HTable t = new HTable(conf, tableName);
1332 try {
1333 t.get(g);
1334 } finally {
1335 t.close();
1336 }
1337 return null;
1338 }
1339 };
1340 PrivilegedExceptionAction putQualifierAction = new PrivilegedExceptionAction() {
1341 public Object run() throws Exception {
1342 Put p = new Put(Bytes.toBytes("random_row"));
1343 p.add(family1, qualifier, Bytes.toBytes("v1"));
1344 HTable t = new HTable(conf, tableName);
1345 try {
1346 t.put(p);
1347 } finally {
1348 t.close();
1349 }
1350 return null;
1351 }
1352 };
1353 PrivilegedExceptionAction deleteQualifierAction = new PrivilegedExceptionAction() {
1354 public Object run() throws Exception {
1355 Delete d = new Delete(Bytes.toBytes("random_row"));
1356 d.deleteColumn(family1, qualifier);
1357
1358 HTable t = new HTable(conf, tableName);
1359 try {
1360 t.delete(d);
1361 } finally {
1362 t.close();
1363 }
1364 return null;
1365 }
1366 };
1367
1368 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1369 try {
1370 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1371 AccessControlService.BlockingInterface protocol =
1372 AccessControlService.newBlockingStub(service);
1373 ProtobufUtil.revoke(protocol, user.getShortName(), tableName, family1, null);
1374 } finally {
1375 acl.close();
1376 }
1377
1378 Thread.sleep(100);
1379
1380 verifyDenied(user, getQualifierAction);
1381 verifyDenied(user, putQualifierAction);
1382 verifyDenied(user, deleteQualifierAction);
1383
1384 acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1385 try {
1386 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1387 AccessControlService.BlockingInterface protocol =
1388 AccessControlService.newBlockingStub(service);
1389 ProtobufUtil.grant(protocol, user.getShortName(),
1390 tableName, family1, qualifier, Permission.Action.READ);
1391 } finally {
1392 acl.close();
1393 }
1394
1395 Thread.sleep(100);
1396
1397 verifyAllowed(user, getQualifierAction);
1398 verifyDenied(user, putQualifierAction);
1399 verifyDenied(user, deleteQualifierAction);
1400
1401
1402
1403 acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1404 try {
1405 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1406 AccessControlService.BlockingInterface protocol =
1407 AccessControlService.newBlockingStub(service);
1408 ProtobufUtil.grant(protocol, user.getShortName(),
1409 tableName, family1, qualifier, Permission.Action.WRITE);
1410 } finally {
1411 acl.close();
1412 }
1413
1414 Thread.sleep(100);
1415
1416 verifyDenied(user, getQualifierAction);
1417 verifyAllowed(user, putQualifierAction);
1418 verifyAllowed(user, deleteQualifierAction);
1419
1420
1421 acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1422 try {
1423 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1424 AccessControlService.BlockingInterface protocol =
1425 AccessControlService.newBlockingStub(service);
1426 ProtobufUtil.grant(protocol, user.getShortName(),
1427 tableName, family1, qualifier,
1428 Permission.Action.READ, Permission.Action.WRITE);
1429 } finally {
1430 acl.close();
1431 }
1432
1433 Thread.sleep(100);
1434
1435 verifyAllowed(user, getQualifierAction);
1436 verifyAllowed(user, putQualifierAction);
1437 verifyAllowed(user, deleteQualifierAction);
1438
1439
1440 acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1441 try {
1442 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1443 AccessControlService.BlockingInterface protocol =
1444 AccessControlService.newBlockingStub(service);
1445 ProtobufUtil.revoke(protocol, user.getShortName(),
1446 tableName, family1, qualifier);
1447 } finally {
1448 acl.close();
1449 }
1450
1451 Thread.sleep(100);
1452
1453 verifyDenied(user, getQualifierAction);
1454 verifyDenied(user, putQualifierAction);
1455 verifyDenied(user, deleteQualifierAction);
1456
1457
1458 admin.disableTable(tableName);
1459 admin.deleteTable(tableName);
1460 }
1461
1462 @Test
1463 public void testPermissionList() throws Exception {
1464 final TableName tableName =
1465 TableName.valueOf("testPermissionList");
1466 final byte[] family1 = Bytes.toBytes("f1");
1467 final byte[] family2 = Bytes.toBytes("f2");
1468 final byte[] qualifier = Bytes.toBytes("q");
1469
1470
1471 HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
1472 if (admin.tableExists(tableName)) {
1473 admin.disableTable(tableName);
1474 admin.deleteTable(tableName);
1475 }
1476 HTableDescriptor htd = new HTableDescriptor(tableName);
1477 htd.addFamily(new HColumnDescriptor(family1));
1478 htd.addFamily(new HColumnDescriptor(family2));
1479 htd.setOwner(USER_OWNER);
1480 admin.createTable(htd);
1481
1482 List<UserPermission> perms;
1483
1484 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1485 try {
1486 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1487 AccessControlService.BlockingInterface protocol =
1488 AccessControlService.newBlockingStub(service);
1489 perms = ProtobufUtil.getUserPermissions(protocol, tableName);
1490 } finally {
1491 acl.close();
1492 }
1493
1494 UserPermission ownerperm = new UserPermission(
1495 Bytes.toBytes(USER_OWNER.getName()), tableName, null, Action.values());
1496 assertTrue("Owner should have all permissions on table",
1497 hasFoundUserPermission(ownerperm, perms));
1498
1499 User user = User.createUserForTesting(TEST_UTIL.getConfiguration(), "user", new String[0]);
1500 byte[] userName = Bytes.toBytes(user.getShortName());
1501
1502 UserPermission up = new UserPermission(userName,
1503 tableName, family1, qualifier, Permission.Action.READ);
1504 assertFalse("User should not be granted permission: " + up.toString(),
1505 hasFoundUserPermission(up, perms));
1506
1507
1508 acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1509 try {
1510 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1511 AccessControlService.BlockingInterface protocol =
1512 AccessControlService.newBlockingStub(service);
1513 ProtobufUtil.grant(protocol, user.getShortName(),
1514 tableName, family1, qualifier, Permission.Action.READ);
1515 perms = ProtobufUtil.getUserPermissions(protocol, tableName);
1516 } finally {
1517 acl.close();
1518 }
1519
1520 UserPermission upToVerify = new UserPermission(
1521 userName, tableName, family1, qualifier, Permission.Action.READ);
1522 assertTrue("User should be granted permission: " + upToVerify.toString(),
1523 hasFoundUserPermission(upToVerify, perms));
1524
1525 upToVerify = new UserPermission(
1526 userName, tableName, family1, qualifier, Permission.Action.WRITE);
1527 assertFalse("User should not be granted permission: " + upToVerify.toString(),
1528 hasFoundUserPermission(upToVerify, perms));
1529
1530
1531 acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1532 try {
1533 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1534 AccessControlService.BlockingInterface protocol =
1535 AccessControlService.newBlockingStub(service);
1536 ProtobufUtil.grant(protocol, user.getShortName(),
1537 tableName, family1, qualifier,
1538 Permission.Action.WRITE, Permission.Action.READ);
1539 perms = ProtobufUtil.getUserPermissions(protocol, tableName);
1540 } finally {
1541 acl.close();
1542 }
1543
1544 upToVerify = new UserPermission(userName, tableName, family1,
1545 qualifier, Permission.Action.WRITE, Permission.Action.READ);
1546 assertTrue("User should be granted permission: " + upToVerify.toString(),
1547 hasFoundUserPermission(upToVerify, perms));
1548
1549 acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1550 try {
1551 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1552 AccessControlService.BlockingInterface protocol =
1553 AccessControlService.newBlockingStub(service);
1554 ProtobufUtil.revoke(protocol, user.getShortName(), tableName, family1, qualifier,
1555 Permission.Action.WRITE, Permission.Action.READ);
1556 perms = ProtobufUtil.getUserPermissions(protocol, tableName);
1557 } finally {
1558 acl.close();
1559 }
1560
1561 assertFalse("User should not be granted permission: " + upToVerify.toString(),
1562 hasFoundUserPermission(upToVerify, perms));
1563
1564
1565 admin.disableTable(tableName);
1566
1567 User newOwner = User.createUserForTesting(conf, "new_owner", new String[] {});
1568 htd.setOwner(newOwner);
1569 admin.modifyTable(tableName, htd);
1570
1571 acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1572 try {
1573 BlockingRpcChannel service = acl.coprocessorService(tableName.getName());
1574 AccessControlService.BlockingInterface protocol =
1575 AccessControlService.newBlockingStub(service);
1576 perms = ProtobufUtil.getUserPermissions(protocol, tableName);
1577 } finally {
1578 acl.close();
1579 }
1580
1581 UserPermission newOwnerperm = new UserPermission(
1582 Bytes.toBytes(newOwner.getName()), tableName, null, Action.values());
1583 assertTrue("New owner should have all permissions on table",
1584 hasFoundUserPermission(newOwnerperm, perms));
1585
1586
1587 admin.deleteTable(tableName);
1588 }
1589
1590 @Test
1591 public void testGlobalPermissionList() throws Exception {
1592 List<UserPermission> perms;
1593 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1594 try {
1595 BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
1596 AccessControlService.BlockingInterface protocol =
1597 AccessControlService.newBlockingStub(service);
1598 perms = ProtobufUtil.getUserPermissions(protocol);
1599 } finally {
1600 acl.close();
1601 }
1602 UserPermission adminPerm = new UserPermission(Bytes.toBytes(USER_ADMIN.getShortName()),
1603 AccessControlLists.ACL_TABLE_NAME, null, null, Bytes.toBytes("ACRW"));
1604 assertTrue("Only user admin has permission on table _acl_ per setup",
1605 perms.size() == 1 && hasFoundUserPermission(adminPerm, perms));
1606 }
1607
1608
1609 private void verifyGlobal(PrivilegedExceptionAction<?> action) throws Exception {
1610 verifyAllowed(action, SUPERUSER);
1611
1612 verifyDenied(action, USER_CREATE, USER_RW, USER_NONE, USER_RO);
1613 }
1614
1615 public void checkGlobalPerms(Permission.Action... actions) throws IOException {
1616 Permission[] perms = new Permission[actions.length];
1617 for (int i = 0; i < actions.length; i++) {
1618 perms[i] = new Permission(actions[i]);
1619 }
1620 CheckPermissionsRequest.Builder request = CheckPermissionsRequest.newBuilder();
1621 for (Action a : actions) {
1622 request.addPermission(AccessControlProtos.Permission.newBuilder()
1623 .setType(AccessControlProtos.Permission.Type.Global)
1624 .setGlobalPermission(
1625 AccessControlProtos.GlobalPermission.newBuilder()
1626 .addAction(ProtobufUtil.toPermissionAction(a)).build()));
1627 }
1628 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1629 try {
1630 BlockingRpcChannel channel = acl.coprocessorService(new byte[0]);
1631 AccessControlService.BlockingInterface protocol =
1632 AccessControlService.newBlockingStub(channel);
1633 try {
1634 protocol.checkPermissions(null, request.build());
1635 } catch (ServiceException se) {
1636 ProtobufUtil.toIOException(se);
1637 }
1638 } finally {
1639 acl.close();
1640 }
1641 }
1642
1643 public void checkTablePerms(TableName table, byte[] family, byte[] column,
1644 Permission.Action... actions) throws IOException {
1645 Permission[] perms = new Permission[actions.length];
1646 for (int i = 0; i < actions.length; i++) {
1647 perms[i] = new TablePermission(table, family, column, actions[i]);
1648 }
1649
1650 checkTablePerms(table, perms);
1651 }
1652
1653 public void checkTablePerms(TableName table, Permission... perms) throws IOException {
1654 CheckPermissionsRequest.Builder request = CheckPermissionsRequest.newBuilder();
1655 for (Permission p : perms) {
1656 request.addPermission(ProtobufUtil.toPermission(p));
1657 }
1658 HTable acl = new HTable(conf, table);
1659 try {
1660 AccessControlService.BlockingInterface protocol =
1661 AccessControlService.newBlockingStub(acl.coprocessorService(new byte[0]));
1662 try {
1663 protocol.checkPermissions(null, request.build());
1664 } catch (ServiceException se) {
1665 ProtobufUtil.toIOException(se);
1666 }
1667 } finally {
1668 acl.close();
1669 }
1670 }
1671
1672 @Test
1673 public void testCheckPermissions() throws Exception {
1674
1675
1676 PrivilegedExceptionAction<Void> globalAdmin = new PrivilegedExceptionAction<Void>() {
1677 @Override
1678 public Void run() throws Exception {
1679 checkGlobalPerms(Permission.Action.ADMIN);
1680 return null;
1681 }
1682 };
1683
1684 verifyGlobal(globalAdmin);
1685
1686
1687
1688 PrivilegedExceptionAction<Void> globalReadWrite = new PrivilegedExceptionAction<Void>() {
1689 @Override
1690 public Void run() throws Exception {
1691 checkGlobalPerms(Permission.Action.READ, Permission.Action.WRITE);
1692 return null;
1693 }
1694 };
1695
1696 verifyGlobal(globalReadWrite);
1697
1698
1699
1700 final byte[] TEST_Q1 = Bytes.toBytes("q1");
1701 final byte[] TEST_Q2 = Bytes.toBytes("q2");
1702
1703 User userTable = User.createUserForTesting(conf, "user_check_perms_table", new String[0]);
1704 User userColumn = User.createUserForTesting(conf, "user_check_perms_family", new String[0]);
1705 User userQualifier = User.createUserForTesting(conf, "user_check_perms_q", new String[0]);
1706
1707 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1708 try {
1709 BlockingRpcChannel channel = acl.coprocessorService(new byte[0]);
1710 AccessControlService.BlockingInterface protocol =
1711 AccessControlService.newBlockingStub(channel);
1712 ProtobufUtil.grant(protocol, userTable.getShortName(),
1713 TEST_TABLE.getTableName(), null, null, Permission.Action.READ);
1714 ProtobufUtil.grant(protocol, userColumn.getShortName(),
1715 TEST_TABLE.getTableName(), TEST_FAMILY, null, Permission.Action.READ);
1716 ProtobufUtil.grant(protocol, userQualifier.getShortName(),
1717 TEST_TABLE.getTableName(), TEST_FAMILY, TEST_Q1, Permission.Action.READ);
1718 } finally {
1719 acl.close();
1720 }
1721
1722 PrivilegedExceptionAction<Void> tableRead = new PrivilegedExceptionAction<Void>() {
1723 @Override
1724 public Void run() throws Exception {
1725 checkTablePerms(TEST_TABLE.getTableName(), null, null, Permission.Action.READ);
1726 return null;
1727 }
1728 };
1729
1730 PrivilegedExceptionAction<Void> columnRead = new PrivilegedExceptionAction<Void>() {
1731 @Override
1732 public Void run() throws Exception {
1733 checkTablePerms(TEST_TABLE.getTableName(), TEST_FAMILY, null, Permission.Action.READ);
1734 return null;
1735 }
1736 };
1737
1738 PrivilegedExceptionAction<Void> qualifierRead = new PrivilegedExceptionAction<Void>() {
1739 @Override
1740 public Void run() throws Exception {
1741 checkTablePerms(TEST_TABLE.getTableName(), TEST_FAMILY, TEST_Q1, Permission.Action.READ);
1742 return null;
1743 }
1744 };
1745
1746 PrivilegedExceptionAction<Void> multiQualifierRead = new PrivilegedExceptionAction<Void>() {
1747 @Override
1748 public Void run() throws Exception {
1749 checkTablePerms(TEST_TABLE.getTableName(), new Permission[] {
1750 new TablePermission(TEST_TABLE.getTableName(), TEST_FAMILY, TEST_Q1, Permission.Action.READ),
1751 new TablePermission(TEST_TABLE.getTableName(), TEST_FAMILY, TEST_Q2, Permission.Action.READ), });
1752 return null;
1753 }
1754 };
1755
1756 PrivilegedExceptionAction<Void> globalAndTableRead = new PrivilegedExceptionAction<Void>() {
1757 @Override
1758 public Void run() throws Exception {
1759 checkTablePerms(TEST_TABLE.getTableName(), new Permission[] { new Permission(Permission.Action.READ),
1760 new TablePermission(TEST_TABLE.getTableName(), null, (byte[]) null, Permission.Action.READ), });
1761 return null;
1762 }
1763 };
1764
1765 PrivilegedExceptionAction<Void> noCheck = new PrivilegedExceptionAction<Void>() {
1766 @Override
1767 public Void run() throws Exception {
1768 checkTablePerms(TEST_TABLE.getTableName(), new Permission[0]);
1769 return null;
1770 }
1771 };
1772
1773 verifyAllowed(tableRead, SUPERUSER, userTable);
1774 verifyDenied(tableRead, userColumn, userQualifier);
1775
1776 verifyAllowed(columnRead, SUPERUSER, userTable, userColumn);
1777 verifyDenied(columnRead, userQualifier);
1778
1779 verifyAllowed(qualifierRead, SUPERUSER, userTable, userColumn, userQualifier);
1780
1781 verifyAllowed(multiQualifierRead, SUPERUSER, userTable, userColumn);
1782 verifyDenied(multiQualifierRead, userQualifier);
1783
1784 verifyAllowed(globalAndTableRead, SUPERUSER);
1785 verifyDenied(globalAndTableRead, userTable, userColumn, userQualifier);
1786
1787 verifyAllowed(noCheck, SUPERUSER, userTable, userColumn, userQualifier);
1788
1789
1790
1791 PrivilegedExceptionAction<Void> familyReadWrite = new PrivilegedExceptionAction<Void>() {
1792 @Override
1793 public Void run() throws Exception {
1794 checkTablePerms(TEST_TABLE.getTableName(), TEST_FAMILY, null, Permission.Action.READ,
1795 Permission.Action.WRITE);
1796 return null;
1797 }
1798 };
1799
1800 verifyAllowed(familyReadWrite, SUPERUSER, USER_OWNER, USER_CREATE, USER_RW);
1801 verifyDenied(familyReadWrite, USER_NONE, USER_RO);
1802
1803
1804
1805 CheckPermissionsRequest checkRequest = CheckPermissionsRequest.newBuilder()
1806 .addPermission(AccessControlProtos.Permission.newBuilder()
1807 .setType(AccessControlProtos.Permission.Type.Table)
1808 .setTablePermission(
1809 AccessControlProtos.TablePermission.newBuilder()
1810 .setTableName(ProtobufUtil.toProtoTableName(TEST_TABLE.getTableName()))
1811 .addAction(AccessControlProtos.Permission.Action.CREATE))
1812 ).build();
1813 acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1814 try {
1815 BlockingRpcChannel channel = acl.coprocessorService(new byte[0]);
1816 AccessControlService.BlockingInterface protocol =
1817 AccessControlService.newBlockingStub(channel);
1818 try {
1819
1820 protocol.checkPermissions(null, checkRequest);
1821 fail("this should have thrown CoprocessorException");
1822 } catch (ServiceException ex) {
1823
1824 }
1825 } finally {
1826 acl.close();
1827 }
1828 }
1829
1830 @Test
1831 public void testStopRegionServer() throws Exception {
1832 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
1833 public Object run() throws Exception {
1834 ACCESS_CONTROLLER.preStopRegionServer(ObserverContext.createAndPrepare(RSCP_ENV, null));
1835 return null;
1836 }
1837 };
1838
1839 verifyAllowed(action, SUPERUSER, USER_ADMIN);
1840 verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE);
1841 }
1842
1843 @Test
1844 public void testOpenRegion() throws Exception {
1845 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
1846 public Object run() throws Exception {
1847 ACCESS_CONTROLLER.preOpen(ObserverContext.createAndPrepare(RCP_ENV, null));
1848 return null;
1849 }
1850 };
1851
1852 verifyAllowed(action, SUPERUSER, USER_ADMIN);
1853 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
1854 }
1855
1856 @Test
1857 public void testCloseRegion() throws Exception {
1858 PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
1859 public Object run() throws Exception {
1860 ACCESS_CONTROLLER.preClose(ObserverContext.createAndPrepare(RCP_ENV, null), false);
1861 return null;
1862 }
1863 };
1864
1865 verifyAllowed(action, SUPERUSER, USER_ADMIN);
1866 verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
1867 }
1868
1869 @Test
1870 public void testSnapshot() throws Exception {
1871 PrivilegedExceptionAction snapshotAction = new PrivilegedExceptionAction() {
1872 public Object run() throws Exception {
1873 ACCESS_CONTROLLER.preSnapshot(ObserverContext.createAndPrepare(CP_ENV, null),
1874 null, null);
1875 return null;
1876 }
1877 };
1878
1879 PrivilegedExceptionAction deleteAction = new PrivilegedExceptionAction() {
1880 public Object run() throws Exception {
1881 ACCESS_CONTROLLER.preDeleteSnapshot(ObserverContext.createAndPrepare(CP_ENV, null),
1882 null);
1883 return null;
1884 }
1885 };
1886
1887 PrivilegedExceptionAction restoreAction = new PrivilegedExceptionAction() {
1888 public Object run() throws Exception {
1889 ACCESS_CONTROLLER.preRestoreSnapshot(ObserverContext.createAndPrepare(CP_ENV, null),
1890 null, null);
1891 return null;
1892 }
1893 };
1894
1895 PrivilegedExceptionAction cloneAction = new PrivilegedExceptionAction() {
1896 public Object run() throws Exception {
1897 ACCESS_CONTROLLER.preCloneSnapshot(ObserverContext.createAndPrepare(CP_ENV, null),
1898 null, null);
1899 return null;
1900 }
1901 };
1902
1903 verifyAllowed(snapshotAction, SUPERUSER, USER_ADMIN);
1904 verifyDenied(snapshotAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
1905
1906 verifyAllowed(cloneAction, SUPERUSER, USER_ADMIN);
1907 verifyDenied(deleteAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
1908
1909 verifyAllowed(restoreAction, SUPERUSER, USER_ADMIN);
1910 verifyDenied(restoreAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
1911
1912 verifyAllowed(deleteAction, SUPERUSER, USER_ADMIN);
1913 verifyDenied(cloneAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
1914 }
1915
1916 @Test
1917 public void testGlobalAuthorizationForNewRegisteredRS() throws Exception {
1918 LOG.debug("Test for global authorization for a new registered RegionServer.");
1919 MiniHBaseCluster hbaseCluster = TEST_UTIL.getHBaseCluster();
1920
1921
1922
1923 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
1924 try {
1925 BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getTableName().getName());
1926 AccessControlService.BlockingInterface protocol =
1927 AccessControlService.newBlockingStub(service);
1928 String currentUser = User.getCurrent().getShortName();
1929
1930 String activeUserForNewRs = currentUser + ".hfs."
1931 + hbaseCluster.getLiveRegionServerThreads().size();
1932 ProtobufUtil.grant(protocol, activeUserForNewRs,
1933 Permission.Action.ADMIN, Permission.Action.CREATE,
1934 Permission.Action.READ, Permission.Action.WRITE);
1935 } finally {
1936 acl.close();
1937 }
1938 HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
1939 HTableDescriptor htd = new HTableDescriptor(TEST_TABLE2);
1940 htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
1941 admin.createTable(htd);
1942
1943
1944 JVMClusterUtil.RegionServerThread newRsThread = hbaseCluster
1945 .startRegionServer();
1946 final HRegionServer newRs = newRsThread.getRegionServer();
1947
1948
1949 HTable table = new HTable(TEST_UTIL.getConfiguration(), TEST_TABLE2);
1950 try {
1951 NavigableMap<HRegionInfo, ServerName> regions = table
1952 .getRegionLocations();
1953 final Map.Entry<HRegionInfo, ServerName> firstRegion = regions.entrySet()
1954 .iterator().next();
1955
1956 PrivilegedExceptionAction moveAction = new PrivilegedExceptionAction() {
1957 public Object run() throws Exception {
1958 HBaseAdmin admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
1959 admin.move(firstRegion.getKey().getEncodedNameAsBytes(),
1960 Bytes.toBytes(newRs.getServerName().getServerName()));
1961 return null;
1962 }
1963 };
1964 SUPERUSER.runAs(moveAction);
1965
1966 final int RETRIES_LIMIT = 10;
1967 int retries = 0;
1968 while (newRs.getOnlineRegions(TEST_TABLE2).size() < 1 && retries < RETRIES_LIMIT) {
1969 LOG.debug("Waiting for region to be opened. Already retried " + retries
1970 + " times.");
1971 try {
1972 Thread.sleep(1000);
1973 } catch (InterruptedException e) {
1974 }
1975 retries++;
1976 if (retries == RETRIES_LIMIT - 1) {
1977 fail("Retry exhaust for waiting region to be opened.");
1978 }
1979 }
1980
1981
1982 PrivilegedExceptionAction putAction = new PrivilegedExceptionAction() {
1983 public Object run() throws Exception {
1984 HTable table = new HTable(TEST_UTIL.getConfiguration(), TEST_TABLE2);
1985 Put put = new Put(Bytes.toBytes("test"));
1986 put.add(TEST_FAMILY, Bytes.toBytes("qual"), Bytes.toBytes("value"));
1987 table.put(put);
1988 return null;
1989 }
1990 };
1991 USER_ADMIN.runAs(putAction);
1992 } finally {
1993 table.close();
1994 }
1995 }
1996
1997 @Test
1998 public void testTableDescriptorsEnumeration() throws Exception {
1999 User TABLE_ADMIN = User.createUserForTesting(conf, "UserA", new String[0]);
2000
2001
2002 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
2003 try {
2004 BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getTableName().getName());
2005 AccessControlService.BlockingInterface protocol =
2006 AccessControlService.newBlockingStub(service);
2007 ProtobufUtil.grant(protocol, TABLE_ADMIN.getShortName(), TEST_TABLE.getTableName(),
2008 null, null, Permission.Action.ADMIN);
2009 } finally {
2010 acl.close();
2011 }
2012
2013 PrivilegedExceptionAction listTablesAction = new PrivilegedExceptionAction() {
2014 public Object run() throws Exception {
2015 HBaseAdmin admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
2016 try {
2017 admin.listTables();
2018 } finally {
2019 admin.close();
2020 }
2021 return null;
2022 }
2023 };
2024
2025 PrivilegedExceptionAction getTableDescAction = new PrivilegedExceptionAction() {
2026 public Object run() throws Exception {
2027 HBaseAdmin admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
2028 try {
2029 admin.getTableDescriptor(TEST_TABLE.getTableName());
2030 } finally {
2031 admin.close();
2032 }
2033 return null;
2034 }
2035 };
2036
2037 verifyAllowed(listTablesAction, SUPERUSER, USER_ADMIN);
2038 verifyDenied(listTablesAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, TABLE_ADMIN);
2039
2040 verifyAllowed(getTableDescAction, SUPERUSER, USER_ADMIN, USER_CREATE, TABLE_ADMIN);
2041 verifyDenied(getTableDescAction, USER_RW, USER_RO, USER_NONE);
2042 }
2043
2044 @Test
2045 public void testTableDeletion() throws Exception {
2046 User TABLE_ADMIN = User.createUserForTesting(conf, "TestUser", new String[0]);
2047
2048
2049 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
2050 try {
2051 BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getTableName().getName());
2052 AccessControlService.BlockingInterface protocol =
2053 AccessControlService.newBlockingStub(service);
2054 ProtobufUtil.grant(protocol, TABLE_ADMIN.getShortName(), TEST_TABLE.getTableName(),
2055 null, null, Permission.Action.ADMIN);
2056 } finally {
2057 acl.close();
2058 }
2059
2060 PrivilegedExceptionAction deleteTableAction = new PrivilegedExceptionAction() {
2061 public Object run() throws Exception {
2062 HBaseAdmin admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
2063 try {
2064 admin.disableTable(TEST_TABLE.getTableName());
2065 admin.deleteTable(TEST_TABLE.getTableName());
2066 } finally {
2067 admin.close();
2068 }
2069 return null;
2070 }
2071 };
2072
2073 verifyDenied(deleteTableAction, USER_RW, USER_RO, USER_NONE);
2074 verifyAllowed(deleteTableAction, TABLE_ADMIN);
2075 }
2076
2077 }