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
213 Region region = TEST_UTIL.getHBaseCluster().getRegions(TEST_TABLE).get(0);
214 RegionCoprocessorHost rcpHost = region.getCoprocessorHost();
215 RCP_ENV = rcpHost.createEnvironment(AccessController.class, ACCESS_CONTROLLER,
216 Coprocessor.PRIORITY_HIGHEST, 1, conf);
217
218
219
220 grantGlobal(TEST_UTIL, USER_ADMIN.getShortName(),
221 Permission.Action.ADMIN,
222 Permission.Action.CREATE,
223 Permission.Action.READ,
224 Permission.Action.WRITE);
225
226 grantOnTable(TEST_UTIL, USER_RW.getShortName(),
227 TEST_TABLE, TEST_FAMILY, null,
228 Permission.Action.READ,
229 Permission.Action.WRITE);
230
231
232 grantOnTable(TEST_UTIL, USER_CREATE.getShortName(),
233 TEST_TABLE, null, null,
234 Permission.Action.CREATE,
235 Permission.Action.READ,
236 Permission.Action.WRITE);
237
238 grantOnTable(TEST_UTIL, USER_RO.getShortName(),
239 TEST_TABLE, TEST_FAMILY, null,
240 Permission.Action.READ);
241
242 grantOnTable(TEST_UTIL, USER_ADMIN_CF.getShortName(),
243 TEST_TABLE, TEST_FAMILY,
244 null, Permission.Action.ADMIN, Permission.Action.CREATE);
245
246 grantGlobal(TEST_UTIL, toGroupEntry(GROUP_ADMIN), Permission.Action.ADMIN);
247 grantGlobal(TEST_UTIL, toGroupEntry(GROUP_CREATE), Permission.Action.CREATE);
248 grantGlobal(TEST_UTIL, toGroupEntry(GROUP_READ), Permission.Action.READ);
249 grantGlobal(TEST_UTIL, toGroupEntry(GROUP_WRITE), Permission.Action.WRITE);
250
251 assertEquals(5, AccessControlLists.getTablePermissions(conf, TEST_TABLE).size());
252 try {
253 assertEquals(5, AccessControlClient.getUserPermissions(systemUserConnection,
254 TEST_TABLE.toString()).size());
255 } catch (Throwable e) {
256 LOG.error("error during call of AccessControlClient.getUserPermissions. ", e);
257 }
258 }
259
260 private static void cleanUp() throws Exception {
261
262 try {
263 deleteTable(TEST_UTIL, TEST_TABLE);
264 } catch (TableNotFoundException ex) {
265
266 LOG.info("Test deleted table " + TEST_TABLE);
267 }
268
269 assertEquals(0, AccessControlLists.getTablePermissions(conf, TEST_TABLE).size());
270 assertEquals(
271 0,
272 AccessControlLists.getNamespacePermissions(conf,
273 TEST_TABLE.getNamespaceAsString()).size());
274 }
275
276 @Test
277 public void testTableCreate() throws Exception {
278 AccessTestAction createTable = new AccessTestAction() {
279 @Override
280 public Object run() throws Exception {
281 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("testnewtable"));
282 htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
283 ACCESS_CONTROLLER.preCreateTable(ObserverContext.createAndPrepare(CP_ENV, null), htd, null);
284 return null;
285 }
286 };
287
288
289 verifyAllowed(createTable, SUPERUSER, USER_ADMIN, USER_GROUP_CREATE);
290
291
292 verifyDenied(createTable, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_ADMIN,
293 USER_GROUP_READ, USER_GROUP_WRITE);
294 }
295
296 }