View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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.Connection;
36  import org.apache.hadoop.hbase.client.ConnectionFactory;
37  import org.apache.hadoop.hbase.client.Table;
38  import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
39  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
40  import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos;
41  import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService.BlockingInterface;
42  import org.apache.hadoop.hbase.util.Bytes;
43  
44  /**
45   * Utility client for doing access control admin operations.
46   */
47  @InterfaceAudience.Public
48  @InterfaceStability.Evolving
49  public class AccessControlClient {
50    public static final TableName ACL_TABLE_NAME =
51        TableName.valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "acl");
52  
53    private static BlockingInterface getAccessControlServiceStub(Table ht)
54        throws IOException {
55      CoprocessorRpcChannel service = ht.coprocessorService(HConstants.EMPTY_START_ROW);
56      BlockingInterface protocol =
57          AccessControlProtos.AccessControlService.newBlockingStub(service);
58      return protocol;
59    }
60  
61    /**
62     * Grants permission on the specified table for the specified user
63     * @param conf
64     * @param tableName
65     * @param userName
66     * @param family
67     * @param qual
68     * @param actions
69     * @throws Throwable
70     */
71    @Deprecated
72    public static void grant(Configuration conf, final TableName tableName,
73        final String userName, final byte[] family, final byte[] qual,
74        final Permission.Action... actions) throws Throwable {
75      try (Connection connection = ConnectionFactory.createConnection(conf)) {
76        grant(connection, tableName, userName, family, qual, actions);
77      }
78    }
79  
80    /**
81     * Grants permission on the specified table for the specified user
82     * @param connection
83     * @param tableName
84     * @param userName
85     * @param family
86     * @param qual
87     * @param actions
88     * @throws Throwable
89     */
90    public static void grant(Connection connection, final TableName tableName,
91        final String userName, final byte[] family, final byte[] qual,
92        final Permission.Action... actions) throws Throwable {
93      try (Table table = connection.getTable(ACL_TABLE_NAME)) {
94        ProtobufUtil.grant(getAccessControlServiceStub(table), userName, tableName, family, qual,
95          actions);
96      }
97    }
98  
99    /**
100    * Grants permission on the specified namespace for the specified user.
101    * @param conf
102    * @param namespace
103    * @param userName
104    * @param actions
105    * @throws Throwable
106    */
107   @Deprecated
108   public static void grant(Configuration conf, final String namespace,
109       final String userName, final Permission.Action... actions) throws Throwable {
110     try (Connection connection = ConnectionFactory.createConnection(conf)) {
111       grant(connection, namespace, userName, actions);
112     }
113   }
114 
115   /**
116    * Grants permission on the specified namespace for the specified user.
117    * @param conf
118    * @param namespace
119    * @param userName
120    * @param actions
121    * @throws Throwable
122    */
123   public static void grant(Connection connection, final String namespace,
124       final String userName, final Permission.Action... actions) throws Throwable {
125     try (Table table = connection.getTable(ACL_TABLE_NAME)) {
126       ProtobufUtil.grant(getAccessControlServiceStub(table), userName, namespace, actions);
127     }
128   }
129 
130   /**
131    * Grant global permissions for the specified user.
132    */
133   @Deprecated
134   public static void grant(Configuration conf, final String userName,
135        final Permission.Action... actions) throws Throwable {
136     try (Connection connection = ConnectionFactory.createConnection(conf)) {
137       grant(connection, userName, actions);
138     }
139   }
140 
141   /**
142    * Grant global permissions for the specified user.
143    */
144   public static void grant(Connection connection, final String userName,
145        final Permission.Action... actions) throws Throwable {
146     try (Table table = connection.getTable(ACL_TABLE_NAME)) {
147       ProtobufUtil.grant(getAccessControlServiceStub(table), userName, actions);
148     }
149   }
150 
151   @Deprecated
152   public static boolean isAccessControllerRunning(Configuration conf)
153       throws MasterNotRunningException, ZooKeeperConnectionException, IOException {
154     try (Connection connection = ConnectionFactory.createConnection(conf)) {
155       return isAccessControllerRunning(connection);
156     }
157   }
158 
159   public static boolean isAccessControllerRunning(Connection connection)
160       throws MasterNotRunningException, ZooKeeperConnectionException, IOException {
161     try (Admin admin = connection.getAdmin()) {
162       return admin.isTableAvailable(ACL_TABLE_NAME);
163     }
164   }
165 
166   /**
167    * Revokes the permission on the table
168    * @param conf
169    * @param tableName
170    * @param username
171    * @param family
172    * @param qualifier
173    * @param actions
174    * @throws Throwable
175    */
176   @Deprecated
177   public static void revoke(Configuration conf, final TableName tableName,
178       final String username, final byte[] family, final byte[] qualifier,
179       final Permission.Action... actions) throws Throwable {
180     try (Connection connection = ConnectionFactory.createConnection(conf)) {
181       revoke(connection, tableName, username, family, qualifier, actions);
182     }
183   }
184 
185   /**
186    * Revokes the permission on the table
187    * @param connection
188    * @param tableName
189    * @param username
190    * @param family
191    * @param qualifier
192    * @param actions
193    * @throws Throwable
194    */
195   public static void revoke(Connection connection, final TableName tableName,
196       final String username, final byte[] family, final byte[] qualifier,
197       final Permission.Action... actions) throws Throwable {
198     try (Table table = connection.getTable(ACL_TABLE_NAME)) {
199       ProtobufUtil.revoke(getAccessControlServiceStub(table), username, tableName, family,
200         qualifier, actions);
201     }
202   }
203 
204   /**
205    * Revokes the permission on the table for the specified user.
206    * @param conf
207    * @param namespace
208    * @param userName
209    * @param actions
210    * @throws Throwable
211    */
212   @Deprecated
213   public static void revoke(Configuration conf, final String namespace,
214     final String userName, final Permission.Action... actions) throws Throwable {
215     try (Connection connection = ConnectionFactory.createConnection(conf)) {
216       revoke(connection, namespace, userName, actions);
217     }
218   }
219 
220   /**
221    * Revokes the permission on the table for the specified user.
222    * @param connection
223    * @param namespace
224    * @param userName
225    * @param actions
226    * @throws Throwable
227    */
228   public static void revoke(Connection connection, final String namespace,
229       final String userName, final Permission.Action... actions) throws Throwable {
230     try (Table table = connection.getTable(ACL_TABLE_NAME)) {
231       ProtobufUtil.revoke(getAccessControlServiceStub(table), userName, namespace, actions);
232     }
233   }
234 
235   /**
236    * Revoke global permissions for the specified user.
237    */
238   @Deprecated
239   public static void revoke(Configuration conf, final String userName,
240       final Permission.Action... actions) throws Throwable {
241     try (Connection connection = ConnectionFactory.createConnection(conf)) {
242       revoke(connection, userName, actions);
243     }
244   }
245 
246   /**
247    * Revoke global permissions for the specified user.
248    */
249   public static void revoke(Connection connection, final String userName,
250       final Permission.Action... actions) throws Throwable {
251     try (Table table = connection.getTable(ACL_TABLE_NAME)) {
252       ProtobufUtil.revoke(getAccessControlServiceStub(table), userName, actions);
253     }
254   }
255 
256   /**
257    * List all the userPermissions matching the given pattern.
258    * @param conf
259    * @param tableRegex The regular expression string to match against
260    * @return - returns an array of UserPermissions
261    * @throws Throwable
262    */
263   @Deprecated
264   public static List<UserPermission> getUserPermissions(Configuration conf, String tableRegex)
265   throws Throwable {
266     try (Connection connection = ConnectionFactory.createConnection(conf)) {
267       return getUserPermissions(connection, tableRegex);
268     }
269   }
270 
271   /**
272    * List all the userPermissions matching the given pattern.
273    * @param connection
274    * @param tableRegex The regular expression string to match against
275    * @return - returns an array of UserPermissions
276    * @throws Throwable
277    */
278   public static List<UserPermission> getUserPermissions(Connection connection, String tableRegex)
279   throws Throwable {
280     List<UserPermission> permList = new ArrayList<UserPermission>();
281     // TODO: Make it so caller passes in a Connection rather than have us do this expensive
282     // setup each time.  This class only used in test and shell at moment though.
283     try (Table table = connection.getTable(ACL_TABLE_NAME)) {
284       try (Admin admin = connection.getAdmin()) {
285         CoprocessorRpcChannel service = table.coprocessorService(HConstants.EMPTY_START_ROW);
286         BlockingInterface protocol =
287             AccessControlProtos.AccessControlService.newBlockingStub(service);
288         HTableDescriptor[] htds = null;
289         if (tableRegex == null || tableRegex.isEmpty()) {
290           permList = ProtobufUtil.getUserPermissions(protocol);
291         } else if (tableRegex.charAt(0) == '@') {
292           String namespace = tableRegex.substring(1);
293           permList = ProtobufUtil.getUserPermissions(protocol, Bytes.toBytes(namespace));
294         } else {
295           htds = admin.listTables(Pattern.compile(tableRegex), true);
296           for (HTableDescriptor hd : htds) {
297             permList.addAll(ProtobufUtil.getUserPermissions(protocol, hd.getTableName()));
298           }
299         }
300       }
301     }
302     return permList;
303   }
304 }