1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.security.access;
19
20 import static org.apache.hadoop.hbase.AuthUtil.toGroupEntry;
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertTrue;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.apache.hadoop.conf.Configuration;
27 import org.apache.hadoop.hbase.Coprocessor;
28 import org.apache.hadoop.hbase.CoprocessorEnvironment;
29 import org.apache.hadoop.hbase.HBaseTestingUtility;
30 import org.apache.hadoop.hbase.HColumnDescriptor;
31 import org.apache.hadoop.hbase.HConstants;
32 import org.apache.hadoop.hbase.HTableDescriptor;
33 import org.apache.hadoop.hbase.TableName;
34 import org.apache.hadoop.hbase.TableNotFoundException;
35 import org.apache.hadoop.hbase.client.HBaseAdmin;
36 import org.apache.hadoop.hbase.client.HConnection;
37 import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
38 import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
39 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
40 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
41 import org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment;
42 import org.apache.hadoop.hbase.master.MasterCoprocessorHost;
43 import org.apache.hadoop.hbase.regionserver.HRegionServer;
44 import org.apache.hadoop.hbase.regionserver.HRegion;
45 import org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost;
46 import org.apache.hadoop.hbase.regionserver.RegionServerCoprocessorHost;
47 import org.apache.hadoop.hbase.security.User;
48 import org.apache.hadoop.hbase.testclassification.MediumTests;
49 import org.apache.hadoop.hbase.util.Bytes;
50 import org.apache.hadoop.hbase.util.JVMClusterUtil;
51 import org.apache.log4j.Level;
52 import org.apache.log4j.Logger;
53 import org.junit.AfterClass;
54 import org.junit.BeforeClass;
55 import org.junit.Test;
56 import org.junit.experimental.categories.Category;
57
58
59
60
61 @Category({MediumTests.class})
62 public class TestAccessController3 extends SecureTestUtil {
63 private static final Log LOG = LogFactory.getLog(TestAccessController.class);
64
65 static {
66 Logger.getLogger(AccessController.class).setLevel(Level.TRACE);
67 Logger.getLogger(AccessControlFilter.class).setLevel(Level.TRACE);
68 Logger.getLogger(TableAuthManager.class).setLevel(Level.TRACE);
69 }
70
71 private static TableName TEST_TABLE = TableName.valueOf("testtable1");
72 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
73 private static Configuration conf;
74
75
76 private static User SUPERUSER;
77
78 private static User USER_ADMIN;
79
80 private static User USER_RW;
81
82 private static User USER_RO;
83
84 private static User USER_OWNER;
85
86 private static User USER_CREATE;
87
88 private static User USER_NONE;
89
90 private static User USER_ADMIN_CF;
91
92 private static final String GROUP_ADMIN = "group_admin";
93 private static final String GROUP_CREATE = "group_create";
94 private static final String GROUP_READ = "group_read";
95 private static final String GROUP_WRITE = "group_write";
96
97 private static User USER_GROUP_ADMIN;
98 private static User USER_GROUP_CREATE;
99 private static User USER_GROUP_READ;
100 private static User USER_GROUP_WRITE;
101
102
103
104
105
106 private static byte[] TEST_FAMILY = Bytes.toBytes("f1");
107
108 private static MasterCoprocessorEnvironment CP_ENV;
109 private static AccessController ACCESS_CONTROLLER;
110 private static RegionServerCoprocessorEnvironment RSCP_ENV;
111 private static RegionCoprocessorEnvironment RCP_ENV;
112
113 private static boolean callSuperTwice = true;
114
115
116 public static class FaultyAccessController extends AccessController {
117 public FaultyAccessController() {
118 }
119
120 @Override
121 public void stop(CoprocessorEnvironment env) {
122 super.stop(env);
123 if (callSuperTwice) {
124 super.stop(env);
125 }
126 }
127 }
128
129 @BeforeClass
130 public static void setupBeforeClass() throws Exception {
131
132 conf = TEST_UTIL.getConfiguration();
133
134 enableSecurity(conf);
135 String accessControllerClassName = FaultyAccessController.class.getName();
136
137
138 conf.set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, accessControllerClassName);
139
140 verifyConfiguration(conf);
141
142
143 conf.setBoolean(AccessControlConstants.EXEC_PERMISSION_CHECKS_KEY, true);
144
145 TEST_UTIL.startMiniCluster();
146 MasterCoprocessorHost cpHost =
147 TEST_UTIL.getMiniHBaseCluster().getMaster().getCoprocessorHost();
148 cpHost.load(FaultyAccessController.class, Coprocessor.PRIORITY_HIGHEST, conf);
149 ACCESS_CONTROLLER = (AccessController) cpHost.findCoprocessor(accessControllerClassName);
150 CP_ENV = cpHost.createEnvironment(AccessController.class, ACCESS_CONTROLLER,
151 Coprocessor.PRIORITY_HIGHEST, 1, conf);
152 RegionServerCoprocessorHost rsHost;
153 do {
154 rsHost = TEST_UTIL.getMiniHBaseCluster().getRegionServer(0)
155 .getCoprocessorHost();
156 } while (rsHost == null);
157 RSCP_ENV = rsHost.createEnvironment(AccessController.class, ACCESS_CONTROLLER,
158 Coprocessor.PRIORITY_HIGHEST, 1, conf);
159
160
161 TEST_UTIL.waitUntilAllRegionsAssigned(AccessControlLists.ACL_TABLE_NAME);
162
163
164 SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
165 USER_ADMIN = User.createUserForTesting(conf, "admin2", new String[0]);
166 USER_RW = User.createUserForTesting(conf, "rwuser", new String[0]);
167 USER_RO = User.createUserForTesting(conf, "rouser", new String[0]);
168 USER_OWNER = User.createUserForTesting(conf, "owner", new String[0]);
169 USER_CREATE = User.createUserForTesting(conf, "tbl_create", new String[0]);
170 USER_NONE = User.createUserForTesting(conf, "nouser", new String[0]);
171 USER_ADMIN_CF = User.createUserForTesting(conf, "col_family_admin", new String[0]);
172
173 USER_GROUP_ADMIN =
174 User.createUserForTesting(conf, "user_group_admin", new String[] { GROUP_ADMIN });
175 USER_GROUP_CREATE =
176 User.createUserForTesting(conf, "user_group_create", new String[] { GROUP_CREATE });
177 USER_GROUP_READ =
178 User.createUserForTesting(conf, "user_group_read", new String[] { GROUP_READ });
179 USER_GROUP_WRITE =
180 User.createUserForTesting(conf, "user_group_write", new String[] { GROUP_WRITE });
181
182 setUpTableAndUserPermissions();
183 }
184
185 @AfterClass
186 public static void tearDownAfterClass() throws Exception {
187 HRegionServer rs = null;
188 for (JVMClusterUtil.RegionServerThread thread:
189 TEST_UTIL.getMiniHBaseCluster().getRegionServerThreads()) {
190 rs = thread.getRegionServer();
191 }
192 cleanUp();
193 TEST_UTIL.shutdownMiniCluster();
194 assertTrue("region server should have aborted due to FaultyAccessController", rs.isAborted());
195 }
196
197 private static void setUpTableAndUserPermissions() throws Exception {
198 HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
199 HTableDescriptor htd = new HTableDescriptor(TEST_TABLE);
200 HColumnDescriptor hcd = new HColumnDescriptor(TEST_FAMILY);
201 hcd.setMaxVersions(100);
202 htd.addFamily(hcd);
203 htd.setOwner(USER_OWNER);
204 admin.createTable(htd, new byte[][] { Bytes.toBytes("s") });
205
206 HRegion region = TEST_UTIL.getHBaseCluster().getRegions(TEST_TABLE).get(0);
207 RegionCoprocessorHost rcpHost = region.getCoprocessorHost();
208 RCP_ENV = rcpHost.createEnvironment(AccessController.class, ACCESS_CONTROLLER,
209 Coprocessor.PRIORITY_HIGHEST, 1, conf);
210
211
212
213 grantGlobal(TEST_UTIL, USER_ADMIN.getShortName(),
214 Permission.Action.ADMIN,
215 Permission.Action.CREATE,
216 Permission.Action.READ,
217 Permission.Action.WRITE);
218
219 grantOnTable(TEST_UTIL, USER_RW.getShortName(),
220 TEST_TABLE, TEST_FAMILY, null,
221 Permission.Action.READ,
222 Permission.Action.WRITE);
223
224
225 grantOnTable(TEST_UTIL, USER_CREATE.getShortName(),
226 TEST_TABLE, null, null,
227 Permission.Action.CREATE,
228 Permission.Action.READ,
229 Permission.Action.WRITE);
230
231 grantOnTable(TEST_UTIL, USER_RO.getShortName(),
232 TEST_TABLE, TEST_FAMILY, null,
233 Permission.Action.READ);
234
235 grantOnTable(TEST_UTIL, USER_ADMIN_CF.getShortName(),
236 TEST_TABLE, TEST_FAMILY,
237 null, Permission.Action.ADMIN, Permission.Action.CREATE);
238
239 grantGlobal(TEST_UTIL, toGroupEntry(GROUP_ADMIN), Permission.Action.ADMIN);
240 grantGlobal(TEST_UTIL, toGroupEntry(GROUP_CREATE), Permission.Action.CREATE);
241 grantGlobal(TEST_UTIL, toGroupEntry(GROUP_READ), Permission.Action.READ);
242 grantGlobal(TEST_UTIL, toGroupEntry(GROUP_WRITE), Permission.Action.WRITE);
243
244 assertEquals(5, AccessControlLists.getTablePermissions(conf, TEST_TABLE).size());
245 }
246
247 private static void cleanUp() throws Exception {
248
249 try {
250 TEST_UTIL.deleteTable(TEST_TABLE);
251 } catch (TableNotFoundException ex) {
252
253 LOG.info("Test deleted table " + TEST_TABLE);
254 }
255
256 assertEquals(0, AccessControlLists.getTablePermissions(conf, TEST_TABLE).size());
257 assertEquals(
258 0,
259 AccessControlLists.getNamespacePermissions(conf,
260 TEST_TABLE.getNamespaceAsString()).size());
261 }
262
263 @Test
264 public void testTableCreate() throws Exception {
265 AccessTestAction createTable = new AccessTestAction() {
266 @Override
267 public Object run() throws Exception {
268 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("testnewtable"));
269 htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
270 ACCESS_CONTROLLER.preCreateTable(ObserverContext.createAndPrepare(CP_ENV, null), htd, null);
271 return null;
272 }
273 };
274
275
276 verifyAllowed(createTable, SUPERUSER, USER_ADMIN, USER_GROUP_CREATE);
277
278
279 verifyDenied(createTable, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_ADMIN,
280 USER_GROUP_READ, USER_GROUP_WRITE);
281 }
282
283 }