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.HBaseAdmin;
36  import org.apache.hadoop.hbase.client.HTable;
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 HTable getAclTable(Configuration conf) throws IOException {
54      return new HTable(conf, ACL_TABLE_NAME);
55    }
56  
57    private static BlockingInterface getAccessControlServiceStub(HTable ht)
58        throws IOException {
59      CoprocessorRpcChannel service = ht.coprocessorService(HConstants.EMPTY_START_ROW);
60      BlockingInterface protocol =
61          AccessControlProtos.AccessControlService.newBlockingStub(service);
62      return protocol;
63    }
64  
65    /**
66     * Grants permission on the specified table for the specified user
67     * @param conf
68     * @param tableName
69     * @param userName
70     * @param family
71     * @param qual
72     * @param actions
73     * @throws Throwable
74     */
75    public static void grant(Configuration conf, final TableName tableName,
76        final String userName, final byte[] family, final byte[] qual,
77        final Permission.Action... actions) throws Throwable {
78      HTable ht = null;
79      try {
80        ht = getAclTable(conf);
81        ProtobufUtil.grant(getAccessControlServiceStub(ht), userName, tableName, family, qual,
82            actions);
83      } finally {
84        if (ht != null) {
85          ht.close();
86        }
87      }
88    }
89  
90    /**
91     * Grants permission on the specified namespace for the specified user.
92     * @param conf
93     * @param namespace
94     * @param userName
95     * @param actions
96     * @throws Throwable
97     */
98    public static void grant(Configuration conf, final String namespace,
99        final String userName, final Permission.Action... actions) throws Throwable {
100     HTable ht = null;
101     try {
102       ht = getAclTable(conf);
103       ProtobufUtil.grant(getAccessControlServiceStub(ht), userName, namespace, actions);
104     } finally {
105       if (ht != null) {
106         ht.close();
107       }
108     }
109   }
110 
111   public static boolean isAccessControllerRunning(Configuration conf)
112       throws MasterNotRunningException, ZooKeeperConnectionException, IOException {
113     HBaseAdmin ha = null;
114     try {
115       ha = new HBaseAdmin(conf);
116       return ha.isTableAvailable(ACL_TABLE_NAME);
117     } finally {
118       if (ha != null) {
119         ha.close();
120       }
121     }
122   }
123 
124   /**
125    * Revokes the permission on the table
126    * @param conf
127    * @param tableName
128    * @param username
129    * @param family
130    * @param qualifier
131    * @param actions
132    * @throws Throwable
133    */
134   public static void revoke(Configuration conf, final TableName tableName,
135       final String username, final byte[] family, final byte[] qualifier,
136       final Permission.Action... actions) throws Throwable {
137     HTable ht = null;
138     try {
139       ht = getAclTable(conf);
140       ProtobufUtil.revoke(getAccessControlServiceStub(ht), username, tableName, family, qualifier,
141           actions);
142     } finally {
143       if (ht != null) {
144         ht.close();
145       }
146     }
147   }
148 
149   /**
150    * Revokes the permission on the table for the specified user.
151    * @param conf
152    * @param namespace
153    * @param userName
154    * @param actions
155    * @throws Throwable
156    */
157   public static void revoke(Configuration conf, final String namespace,
158     final String userName, final Permission.Action... actions) throws Throwable {
159     HTable ht = null;
160     try {
161       ht = getAclTable(conf);
162       ProtobufUtil.revoke(getAccessControlServiceStub(ht), userName, namespace, actions);
163     } finally {
164       if (ht != null) {
165         ht.close();
166       }
167     }
168   }
169 
170   /**
171    * List all the userPermissions matching the given pattern.
172    * @param conf
173    * @param tableRegex The regular expression string to match against
174    * @return - returns an array of UserPermissions
175    * @throws Throwable
176    */
177   public static List<UserPermission> getUserPermissions(Configuration conf, String tableRegex)
178       throws Throwable {
179     List<UserPermission> permList = new ArrayList<UserPermission>();
180     Table ht = null;
181     Admin ha = null;
182     try {
183       ha = new HBaseAdmin(conf);
184       ht = new HTable(conf, ACL_TABLE_NAME);
185       CoprocessorRpcChannel service = ht.coprocessorService(HConstants.EMPTY_START_ROW);
186       BlockingInterface protocol = AccessControlProtos.AccessControlService
187           .newBlockingStub(service);
188       HTableDescriptor[] htds = null;
189 
190       if (tableRegex == null || tableRegex.isEmpty()) {
191         permList = ProtobufUtil.getUserPermissions(protocol);
192       } else if (tableRegex.charAt(0) == '@') {
193         String namespace = tableRegex.substring(1);
194         permList = ProtobufUtil.getUserPermissions(protocol, Bytes.toBytes(namespace));
195       } else {
196         htds = ha.listTables(Pattern.compile(tableRegex));
197         for (HTableDescriptor hd : htds) {
198           permList.addAll(ProtobufUtil.getUserPermissions(protocol, hd.getTableName()));
199         }
200       }
201     } finally {
202       if (ht != null) {
203         ht.close();
204       }
205       if (ha != null) {
206         ha.close();
207       }
208     }
209     return permList;
210   }
211 
212 }