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