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.Map;
24 import java.util.regex.Pattern;
25
26 import org.apache.hadoop.classification.InterfaceAudience;
27 import org.apache.hadoop.classification.InterfaceStability;
28 import org.apache.hadoop.conf.Configuration;
29 import org.apache.hadoop.hbase.HConstants;
30 import org.apache.hadoop.hbase.HTableDescriptor;
31 import org.apache.hadoop.hbase.MasterNotRunningException;
32 import org.apache.hadoop.hbase.NamespaceDescriptor;
33 import org.apache.hadoop.hbase.TableName;
34 import org.apache.hadoop.hbase.ZooKeeperConnectionException;
35 import org.apache.hadoop.hbase.client.HBaseAdmin;
36 import org.apache.hadoop.hbase.client.HTable;
37 import org.apache.hadoop.hbase.client.coprocessor.Batch;
38 import org.apache.hadoop.hbase.ipc.BlockingRpcCallback;
39 import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
40 import org.apache.hadoop.hbase.ipc.ServerRpcController;
41 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
42 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos;
43 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService;
44 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService.BlockingInterface;
45 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.GrantRequest;
46 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.GrantResponse;
47 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.RevokeRequest;
48 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.RevokeResponse;
49 import org.apache.hadoop.hbase.util.ByteStringer;
50
51 import com.google.protobuf.ByteString;
52
53
54
55
56 @InterfaceAudience.Public
57 @InterfaceStability.Evolving
58 public class AccessControlClient {
59
60
61
62
63
64
65
66
67
68
69
70 public static GrantResponse grant(Configuration conf, final TableName tableName,
71 final String userName, final byte[] family, final byte[] qual,
72 final AccessControlProtos.Permission.Action... actions) throws Throwable {
73 HTable ht = null;
74 try {
75 TableName aclTableName =
76 TableName.valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "acl");
77 ht = new HTable(conf, aclTableName.getName());
78 Batch.Call<AccessControlService, GrantResponse> callable =
79 new Batch.Call<AccessControlService, GrantResponse>() {
80 ServerRpcController controller = new ServerRpcController();
81 BlockingRpcCallback<GrantResponse> rpcCallback =
82 new BlockingRpcCallback<GrantResponse>();
83
84 @Override
85 public GrantResponse call(AccessControlService service) throws IOException {
86 GrantRequest.Builder builder = GrantRequest.newBuilder();
87 AccessControlProtos.Permission.Builder ret =
88 AccessControlProtos.Permission.newBuilder();
89 AccessControlProtos.TablePermission.Builder permissionBuilder =
90 AccessControlProtos.TablePermission
91 .newBuilder();
92 for (AccessControlProtos.Permission.Action a : actions) {
93 permissionBuilder.addAction(a);
94 }
95 permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName));
96
97 if (family != null) {
98 permissionBuilder.setFamily(ByteStringer.wrap(family));
99 }
100 if (qual != null) {
101 permissionBuilder.setQualifier(ByteStringer.wrap(qual));
102 }
103 ret.setType(AccessControlProtos.Permission.Type.Table).setTablePermission(
104 permissionBuilder);
105 builder.setUserPermission(AccessControlProtos.UserPermission.newBuilder()
106 .setUser(ByteString.copyFromUtf8(userName)).setPermission(ret));
107 service.grant(controller, builder.build(), rpcCallback);
108 return rpcCallback.get();
109 }
110 };
111 Map<byte[], GrantResponse> result = ht.coprocessorService(AccessControlService.class,
112 HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, callable);
113 return result.values().iterator().next();
114
115
116
117 } finally {
118 if (ht != null) {
119 ht.close();
120 }
121 }
122 }
123
124 public static boolean isAccessControllerRunning(Configuration conf)
125 throws MasterNotRunningException, ZooKeeperConnectionException, IOException {
126 TableName aclTableName = TableName
127 .valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "acl");
128 HBaseAdmin ha = null;
129 try {
130 ha = new HBaseAdmin(conf);
131 return ha.isTableAvailable(aclTableName.getNameAsString());
132 } finally {
133 if (ha != null) {
134 ha.close();
135 }
136 }
137 }
138
139
140
141
142
143
144
145
146
147
148
149
150 public static RevokeResponse revoke(Configuration conf, final String username,
151 final TableName tableName, final byte[] family, final byte[] qualifier,
152 final AccessControlProtos.Permission.Action... actions) throws Throwable {
153 HTable ht = null;
154 try {
155 TableName aclTableName = TableName.valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR,
156 "acl");
157 ht = new HTable(conf, aclTableName.getName());
158 Batch.Call<AccessControlService, AccessControlProtos.RevokeResponse> callable =
159 new Batch.Call<AccessControlService, AccessControlProtos.RevokeResponse>() {
160 ServerRpcController controller = new ServerRpcController();
161 BlockingRpcCallback<AccessControlProtos.RevokeResponse> rpcCallback =
162 new BlockingRpcCallback<AccessControlProtos.RevokeResponse>();
163
164 @Override
165 public RevokeResponse call(AccessControlService service) throws IOException {
166 AccessControlProtos.Permission.Builder ret =
167 AccessControlProtos.Permission.newBuilder();
168 AccessControlProtos.TablePermission.Builder permissionBuilder =
169 AccessControlProtos.TablePermission.newBuilder();
170 for (AccessControlProtos.Permission.Action a : actions) {
171 permissionBuilder.addAction(a);
172 }
173 if (tableName != null) {
174 permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName));
175 }
176 if (family != null) {
177 permissionBuilder.setFamily(ByteStringer.wrap(family));
178 }
179 if (qualifier != null) {
180 permissionBuilder.setQualifier(ByteStringer.wrap(qualifier));
181 }
182 ret.setType(AccessControlProtos.Permission.Type.Table).setTablePermission(
183 permissionBuilder);
184 RevokeRequest builder = AccessControlProtos.RevokeRequest
185 .newBuilder()
186 .setUserPermission(
187 AccessControlProtos.UserPermission.newBuilder()
188 .setUser(ByteString.copyFromUtf8(username)).setPermission(ret)).build();
189 service.revoke(controller, builder, rpcCallback);
190 return rpcCallback.get();
191 }
192 };
193 Map<byte[], RevokeResponse> result = ht.coprocessorService(AccessControlService.class,
194 HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, callable);
195 return result.values().iterator().next();
196
197 } finally {
198 if (ht != null) {
199 ht.close();
200 }
201 }
202 }
203
204
205
206
207
208
209
210
211 public static List<UserPermission> getUserPermissions(Configuration conf, String tableRegex)
212 throws Throwable {
213 List<UserPermission> permList = new ArrayList<UserPermission>();
214 HTable ht = null;
215 HBaseAdmin ha = null;
216 try {
217 TableName aclTableName =
218 TableName.valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "acl");
219 ha = new HBaseAdmin(conf);
220 ht = new HTable(conf, aclTableName.getName());
221 CoprocessorRpcChannel service = ht.coprocessorService(HConstants.EMPTY_START_ROW);
222 BlockingInterface protocol =
223 AccessControlProtos.AccessControlService.newBlockingStub(service);
224 HTableDescriptor[] htds = null;
225
226 if (tableRegex != null) {
227 htds = ha.listTables(Pattern.compile(tableRegex));
228 for (HTableDescriptor hd: htds) {
229 permList.addAll(ProtobufUtil.getUserPermissions(protocol, hd.getTableName()));
230 }
231 } else {
232 permList = ProtobufUtil.getUserPermissions(protocol);
233 }
234 } finally {
235 if (ht != null) {
236 ht.close();
237 }
238 if (ha != null) {
239 ha.close();
240 }
241 }
242 return permList;
243 }
244
245 }