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 java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.List;
23 import java.util.regex.Pattern;
24
25 import org.apache.hadoop.conf.Configuration;
26 import org.apache.hadoop.hbase.HConstants;
27 import org.apache.hadoop.hbase.HTableDescriptor;
28 import org.apache.hadoop.hbase.MasterNotRunningException;
29 import org.apache.hadoop.hbase.NamespaceDescriptor;
30 import org.apache.hadoop.hbase.TableName;
31 import org.apache.hadoop.hbase.ZooKeeperConnectionException;
32 import org.apache.hadoop.hbase.classification.InterfaceAudience;
33 import org.apache.hadoop.hbase.classification.InterfaceStability;
34 import org.apache.hadoop.hbase.client.Admin;
35 import org.apache.hadoop.hbase.client.ClusterConnection;
36 import org.apache.hadoop.hbase.client.Connection;
37 import org.apache.hadoop.hbase.client.ConnectionFactory;
38 import org.apache.hadoop.hbase.client.Table;
39 import org.apache.hadoop.hbase.client.security.SecurityCapability;
40 import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
41 import org.apache.hadoop.hbase.ipc.HBaseRpcController;
42 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
43 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos;
44 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService.BlockingInterface;
45 import org.apache.hadoop.hbase.util.Bytes;
46
47
48
49
50 @InterfaceAudience.Public
51 @InterfaceStability.Evolving
52 public class AccessControlClient {
53 public static final TableName ACL_TABLE_NAME =
54 TableName.valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "acl");
55
56
57
58
59
60
61
62 public static boolean isAuthorizationEnabled(Connection connection) throws IOException {
63 return connection.getAdmin().getSecurityCapabilities()
64 .contains(SecurityCapability.AUTHORIZATION);
65 }
66
67
68
69
70
71
72
73 public static boolean isCellAuthorizationEnabled(Connection connection) throws IOException {
74 return connection.getAdmin().getSecurityCapabilities()
75 .contains(SecurityCapability.CELL_AUTHORIZATION);
76 }
77
78 private static BlockingInterface getAccessControlServiceStub(Table ht)
79 throws IOException {
80 CoprocessorRpcChannel service = ht.coprocessorService(HConstants.EMPTY_START_ROW);
81 BlockingInterface protocol =
82 AccessControlProtos.AccessControlService.newBlockingStub(service);
83 return protocol;
84 }
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99 public static void grant(Connection connection, final TableName tableName, final String userName,
100 final byte[] family, final byte[] qual, boolean mergeExistingPermissions,
101 final Permission.Action... actions) throws Throwable {
102 HBaseRpcController controller =
103 ((ClusterConnection) connection).getRpcControllerFactory().newController();
104 controller.setPriority(tableName);
105 try (Table table = connection.getTable(ACL_TABLE_NAME)) {
106 ProtobufUtil.grant(controller, getAccessControlServiceStub(table), userName, tableName,
107 family, qual, mergeExistingPermissions, actions);
108 }
109 }
110
111
112
113
114
115
116
117
118
119
120
121
122 public static void grant(final Connection connection, final TableName tableName,
123 final String userName, final byte[] family, final byte[] qual,
124 final Permission.Action... actions) throws Throwable {
125 grant(connection, tableName, userName, family, qual, false, actions);
126 }
127
128
129
130
131
132
133
134
135
136
137
138
139 public static void grant(final Connection connection, final String namespace,
140 final String userName, boolean mergeExistingPermissions, final Permission.Action... actions)
141 throws Throwable {
142 HBaseRpcController controller =
143 ((ClusterConnection) connection).getRpcControllerFactory().newController();
144
145 try (Table table = connection.getTable(ACL_TABLE_NAME)) {
146 ProtobufUtil.grant(controller, getAccessControlServiceStub(table), userName, namespace,
147 mergeExistingPermissions, actions);
148 }
149 }
150
151
152
153
154
155
156
157
158
159
160 public static void grant(final Connection connection, final String namespace,
161 final String userName, final Permission.Action... actions) throws Throwable {
162 grant(connection, namespace, userName, false, actions);
163 }
164
165
166
167
168
169
170
171
172
173
174
175 public static void grant(final Connection connection, final String userName,
176 boolean mergeExistingPermissions, final Permission.Action... actions) throws Throwable {
177 HBaseRpcController controller =
178 ((ClusterConnection) connection).getRpcControllerFactory().newController();
179 try (Table table = connection.getTable(ACL_TABLE_NAME)) {
180 ProtobufUtil.grant(controller, getAccessControlServiceStub(table), userName,
181 mergeExistingPermissions, actions);
182 }
183 }
184
185
186
187
188
189
190
191
192 public static void grant(final Connection connection, final String userName,
193 final Permission.Action... actions) throws Throwable {
194 grant(connection, userName, false, actions);
195 }
196
197 public static boolean isAccessControllerRunning(final Connection connection)
198 throws MasterNotRunningException, ZooKeeperConnectionException, IOException {
199 try (Admin admin = connection.getAdmin()) {
200 return admin.isTableAvailable(ACL_TABLE_NAME);
201 }
202 }
203
204
205
206
207
208
209
210
211
212
213
214 public static void revoke(final Connection connection, final TableName tableName,
215 final String username, final byte[] family, final byte[] qualifier,
216 final Permission.Action... actions) throws Throwable {
217 HBaseRpcController controller
218 = ((ClusterConnection) connection).getRpcControllerFactory().newController();
219 controller.setPriority(tableName);
220 try (Table table = connection.getTable(ACL_TABLE_NAME)) {
221 ProtobufUtil.revoke(controller, getAccessControlServiceStub(table), username, tableName,
222 family, qualifier, actions);
223 }
224 }
225
226
227
228
229
230
231
232
233
234 public static void revoke(final Connection connection, final String namespace,
235 final String userName, final Permission.Action... actions) throws Throwable {
236 HBaseRpcController controller
237 = ((ClusterConnection) connection).getRpcControllerFactory().newController();
238 try (Table table = connection.getTable(ACL_TABLE_NAME)) {
239 ProtobufUtil.revoke(controller, getAccessControlServiceStub(table), userName, namespace,
240 actions);
241 }
242 }
243
244
245
246
247
248 public static void revoke(final Connection connection, final String userName,
249 final Permission.Action... actions) throws Throwable {
250 HBaseRpcController controller
251 = ((ClusterConnection) connection).getRpcControllerFactory().newController();
252 try (Table table = connection.getTable(ACL_TABLE_NAME)) {
253 ProtobufUtil.revoke(controller, getAccessControlServiceStub(table), userName, actions);
254 }
255 }
256
257
258
259
260
261
262
263
264 public static List<UserPermission> getUserPermissions(Connection connection, String tableRegex)
265 throws Throwable {
266 HBaseRpcController controller
267 = ((ClusterConnection) connection).getRpcControllerFactory().newController();
268 List<UserPermission> permList = new ArrayList<UserPermission>();
269 try (Table table = connection.getTable(ACL_TABLE_NAME)) {
270 try (Admin admin = connection.getAdmin()) {
271 CoprocessorRpcChannel service = table.coprocessorService(HConstants.EMPTY_START_ROW);
272 BlockingInterface protocol =
273 AccessControlProtos.AccessControlService.newBlockingStub(service);
274 HTableDescriptor[] htds = null;
275 if (tableRegex == null || tableRegex.isEmpty()) {
276 permList = ProtobufUtil.getUserPermissions(controller, protocol);
277 } else if (tableRegex.charAt(0) == '@') {
278 String namespaceRegex = tableRegex.substring(1);
279 for (NamespaceDescriptor nsds : admin.listNamespaceDescriptors()) {
280 String namespace = nsds.getName();
281 if (namespace.matches(namespaceRegex)) {
282 permList.addAll(ProtobufUtil.getUserPermissions(controller, protocol,
283 Bytes.toBytes(namespace)));
284 }
285 }
286 } else {
287 htds = admin.listTables(Pattern.compile(tableRegex), true);
288 for (HTableDescriptor hd : htds) {
289 permList.addAll(ProtobufUtil.getUserPermissions(controller, protocol,
290 hd.getTableName()));
291 }
292 }
293 }
294 }
295 return permList;
296 }
297
298
299
300
301
302
303
304
305
306
307
308
309
310 @Deprecated
311 public static void grant(Configuration conf, final TableName tableName,
312 final String userName, final byte[] family, final byte[] qual,
313 final Permission.Action... actions) throws Throwable {
314 try (Connection connection = ConnectionFactory.createConnection(conf)) {
315 grant(connection, tableName, userName, family, qual, actions);
316 }
317 }
318
319
320
321
322
323
324
325
326
327
328
329 @Deprecated
330 public static void grant(Configuration conf, final String namespace,
331 final String userName, final Permission.Action... actions) throws Throwable {
332 try (Connection connection = ConnectionFactory.createConnection(conf)) {
333 grant(connection, namespace, userName, actions);
334 }
335 }
336
337
338
339
340
341 @Deprecated
342 public static void grant(Configuration conf, final String userName,
343 final Permission.Action... actions) throws Throwable {
344 try (Connection connection = ConnectionFactory.createConnection(conf)) {
345 grant(connection, userName, actions);
346 }
347 }
348
349
350
351
352 @Deprecated
353 public static boolean isAccessControllerRunning(Configuration conf)
354 throws MasterNotRunningException, ZooKeeperConnectionException, IOException {
355 try (Connection connection = ConnectionFactory.createConnection(conf)) {
356 return isAccessControllerRunning(connection);
357 }
358 }
359
360
361
362
363
364
365
366
367
368
369
370
371
372 @Deprecated
373 public static void revoke(Configuration conf, final TableName tableName,
374 final String username, final byte[] family, final byte[] qualifier,
375 final Permission.Action... actions) throws Throwable {
376 try (Connection connection = ConnectionFactory.createConnection(conf)) {
377 revoke(connection, tableName, username, family, qualifier, actions);
378 }
379 }
380
381
382
383
384
385
386
387
388
389
390 @Deprecated
391 public static void revoke(Configuration conf, final String namespace,
392 final String userName, final Permission.Action... actions) throws Throwable {
393 try (Connection connection = ConnectionFactory.createConnection(conf)) {
394 revoke(connection, namespace, userName, actions);
395 }
396 }
397
398
399
400
401
402 @Deprecated
403 public static void revoke(Configuration conf, final String userName,
404 final Permission.Action... actions) throws Throwable {
405 try (Connection connection = ConnectionFactory.createConnection(conf)) {
406 revoke(connection, userName, actions);
407 }
408 }
409
410
411
412
413
414
415
416
417
418
419
420 @Deprecated
421 public static List<UserPermission> getUserPermissions(Configuration conf, String tableRegex)
422 throws Throwable {
423 try (Connection connection = ConnectionFactory.createConnection(conf)) {
424 return getUserPermissions(connection, tableRegex);
425 }
426 }
427 }