1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.security.access;
20
21 import java.io.IOException;
22 import java.util.Map;
23 import java.util.Objects;
24
25 import org.apache.hadoop.hbase.classification.InterfaceAudience;
26 import org.apache.hadoop.hbase.Cell;
27 import org.apache.hadoop.hbase.CellUtil;
28 import org.apache.hadoop.hbase.TableName;
29 import org.apache.hadoop.hbase.exceptions.DeserializationException;
30 import org.apache.hadoop.hbase.filter.FilterBase;
31 import org.apache.hadoop.hbase.security.User;
32 import org.apache.hadoop.hbase.util.ByteRange;
33 import org.apache.hadoop.hbase.util.Bytes;
34 import org.apache.hadoop.hbase.util.SimpleMutableByteRange;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 @InterfaceAudience.Private
52 class AccessControlFilter extends FilterBase {
53
54 public static enum Strategy {
55
56 CHECK_TABLE_AND_CF_ONLY,
57
58 CHECK_CELL_DEFAULT,
59 };
60
61 private TableAuthManager authManager;
62 private TableName table;
63 private User user;
64 private boolean isSystemTable;
65 private Strategy strategy;
66 private Map<ByteRange, Integer> cfVsMaxVersions;
67 private int familyMaxVersions;
68 private int currentVersions;
69 private ByteRange prevFam;
70 private ByteRange prevQual;
71
72
73
74
75 AccessControlFilter() {
76 }
77
78 AccessControlFilter(TableAuthManager mgr, User ugi, TableName tableName,
79 Strategy strategy, Map<ByteRange, Integer> cfVsMaxVersions) {
80 authManager = mgr;
81 table = tableName;
82 user = ugi;
83 isSystemTable = tableName.isSystemTable();
84 this.strategy = strategy;
85 this.cfVsMaxVersions = cfVsMaxVersions;
86 this.prevFam = new SimpleMutableByteRange();
87 this.prevQual = new SimpleMutableByteRange();
88 }
89
90 @Override
91 public ReturnCode filterKeyValue(Cell cell) {
92 if (isSystemTable) {
93 return ReturnCode.INCLUDE;
94 }
95 if (prevFam.getBytes() == null
96 || (Bytes.compareTo(prevFam.getBytes(), prevFam.getOffset(), prevFam.getLength(),
97 cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength()) != 0)) {
98 prevFam.set(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength());
99
100 familyMaxVersions = cfVsMaxVersions.get(prevFam);
101
102 prevQual.unset();
103 }
104 if (prevQual.getBytes() == null
105 || (Bytes.compareTo(prevQual.getBytes(), prevQual.getOffset(),
106 prevQual.getLength(), cell.getQualifierArray(), cell.getQualifierOffset(),
107 cell.getQualifierLength()) != 0)) {
108 prevQual.set(cell.getQualifierArray(), cell.getQualifierOffset(),
109 cell.getQualifierLength());
110 currentVersions = 0;
111 }
112 currentVersions++;
113 if (currentVersions > familyMaxVersions) {
114 return ReturnCode.SKIP;
115 }
116
117 byte[] family = CellUtil.cloneFamily(cell);
118 byte[] qualifier = CellUtil.cloneQualifier(cell);
119 switch (strategy) {
120
121 case CHECK_TABLE_AND_CF_ONLY: {
122 if (authManager.authorize(user, table, family, qualifier, Permission.Action.READ)) {
123 return ReturnCode.INCLUDE;
124 }
125 }
126 break;
127
128 case CHECK_CELL_DEFAULT: {
129 if (authManager.authorize(user, table, family, qualifier, Permission.Action.READ) ||
130 authManager.authorize(user, table, cell, Permission.Action.READ)) {
131 return ReturnCode.INCLUDE;
132 }
133 }
134 break;
135 default:
136 throw new RuntimeException("Unhandled strategy " + strategy);
137 }
138
139 return ReturnCode.SKIP;
140 }
141
142
143
144 @Override
145 public Cell transformCell(Cell v) {
146 return v;
147 }
148
149 @Override
150 public void reset() throws IOException {
151 this.prevFam.unset();
152 this.prevQual.unset();
153 this.familyMaxVersions = 0;
154 this.currentVersions = 0;
155 }
156
157
158
159
160 public byte [] toByteArray() {
161
162 throw new UnsupportedOperationException(
163 "Serialization not supported. Intended for server-side use only.");
164 }
165
166
167
168
169
170
171
172 public static AccessControlFilter parseFrom(final byte [] pbBytes)
173 throws DeserializationException {
174
175 throw new UnsupportedOperationException(
176 "Serialization not supported. Intended for server-side use only.");
177 }
178
179 @Override
180 public boolean equals(Object obj) {
181 if (!(obj instanceof AccessControlFilter)) {
182 return false;
183 }
184 if (this == obj){
185 return true;
186 }
187 AccessControlFilter f=(AccessControlFilter)obj;
188 return this.authManager.equals(f.authManager) &&
189 this.table.equals(f.table) &&
190 this.user.equals(f.user) &&
191 this.strategy.equals(f.strategy) &&
192 this.cfVsMaxVersions.equals(f.cfVsMaxVersions);
193 }
194
195 @Override
196 public int hashCode() {
197 return Objects.hash(this.authManager, this.table, this.strategy, this.user,
198 this.cfVsMaxVersions);
199 }
200 }