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