1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.security;
21
22 import java.io.IOException;
23 import java.lang.reflect.UndeclaredThrowableException;
24 import java.security.PrivilegedAction;
25 import java.security.PrivilegedExceptionAction;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.hadoop.classification.InterfaceAudience;
30 import org.apache.hadoop.conf.Configuration;
31 import org.apache.hadoop.hbase.util.Methods;
32 import org.apache.hadoop.mapred.JobConf;
33 import org.apache.hadoop.mapreduce.Job;
34 import org.apache.hadoop.security.SecurityUtil;
35 import org.apache.hadoop.security.UserGroupInformation;
36 import org.apache.hadoop.security.token.Token;
37
38
39
40
41
42
43
44
45
46
47
48
49 @InterfaceAudience.Private
50 public abstract class User {
51 public static final String HBASE_SECURITY_CONF_KEY =
52 "hbase.security.authentication";
53
54 private static Log LOG = LogFactory.getLog(User.class);
55
56 protected UserGroupInformation ugi;
57
58 public UserGroupInformation getUGI() {
59 return ugi;
60 }
61
62
63
64
65
66
67 public String getName() {
68 return ugi.getUserName();
69 }
70
71
72
73
74
75
76 public String[] getGroupNames() {
77 return ugi.getGroupNames();
78 }
79
80
81
82
83
84
85 public abstract String getShortName();
86
87
88
89
90 public abstract <T> T runAs(PrivilegedAction<T> action);
91
92
93
94
95 public abstract <T> T runAs(PrivilegedExceptionAction<T> action)
96 throws IOException, InterruptedException;
97
98
99
100
101
102
103
104 public abstract void obtainAuthTokenForJob(Configuration conf, Job job)
105 throws IOException, InterruptedException;
106
107
108
109
110
111
112
113 public abstract void obtainAuthTokenForJob(JobConf job)
114 throws IOException, InterruptedException;
115
116
117
118
119
120
121
122
123
124 public Token<?> getToken(String kind, String service) throws IOException {
125 for (Token<?> token: ugi.getTokens()) {
126 if (token.getKind().toString().equals(kind) &&
127 (service != null && token.getService().toString().equals(service)))
128 {
129 return token;
130 }
131 }
132 return null;
133 }
134
135 @Override
136 public boolean equals(Object o) {
137 if (this == o) {
138 return true;
139 }
140 if (o == null || getClass() != o.getClass()) {
141 return false;
142 }
143 return ugi.equals(((User) o).ugi);
144 }
145
146 @Override
147 public int hashCode() {
148 return ugi.hashCode();
149 }
150
151 @Override
152 public String toString() {
153 return ugi.toString();
154 }
155
156
157
158
159 public static User getCurrent() throws IOException {
160 User user = new SecureHadoopUser();
161 if (user.getUGI() == null) {
162 return null;
163 }
164 return user;
165 }
166
167
168
169
170
171
172 public static User create(UserGroupInformation ugi) {
173 if (ugi == null) {
174 return null;
175 }
176 return new SecureHadoopUser(ugi);
177 }
178
179
180
181
182
183
184
185 public static User createUserForTesting(Configuration conf,
186 String name, String[] groups) {
187 return SecureHadoopUser.createUserForTesting(conf, name, groups);
188 }
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206 public static void login(Configuration conf, String fileConfKey,
207 String principalConfKey, String localhost) throws IOException {
208 SecureHadoopUser.login(conf, fileConfKey, principalConfKey, localhost);
209 }
210
211
212
213
214
215
216
217 public static boolean isSecurityEnabled() {
218 return SecureHadoopUser.isSecurityEnabled();
219 }
220
221
222
223
224
225
226 public static boolean isHBaseSecurityEnabled(Configuration conf) {
227 return "kerberos".equalsIgnoreCase(conf.get(HBASE_SECURITY_CONF_KEY));
228 }
229
230
231
232
233
234
235
236
237 private static class SecureHadoopUser extends User {
238 private String shortName;
239
240 private SecureHadoopUser() throws IOException {
241 ugi = UserGroupInformation.getCurrentUser();
242 }
243
244 private SecureHadoopUser(UserGroupInformation ugi) {
245 this.ugi = ugi;
246 }
247
248 @Override
249 public String getShortName() {
250 if (shortName != null) return shortName;
251 try {
252 shortName = ugi.getShortUserName();
253 return shortName;
254 } catch (Exception e) {
255 throw new RuntimeException("Unexpected error getting user short name",
256 e);
257 }
258 }
259
260 @Override
261 public <T> T runAs(PrivilegedAction<T> action) {
262 return ugi.doAs(action);
263 }
264
265 @Override
266 public <T> T runAs(PrivilegedExceptionAction<T> action)
267 throws IOException, InterruptedException {
268 return ugi.doAs(action);
269 }
270
271 @Override
272 public void obtainAuthTokenForJob(Configuration conf, Job job)
273 throws IOException, InterruptedException {
274 try {
275 Class<?> c = Class.forName(
276 "org.apache.hadoop.hbase.security.token.TokenUtil");
277 Methods.call(c, null, "obtainTokenForJob",
278 new Class[]{Configuration.class, UserGroupInformation.class,
279 Job.class},
280 new Object[]{conf, ugi, job});
281 } catch (ClassNotFoundException cnfe) {
282 throw new RuntimeException("Failure loading TokenUtil class, "
283 +"is secure RPC available?", cnfe);
284 } catch (IOException ioe) {
285 throw ioe;
286 } catch (InterruptedException ie) {
287 throw ie;
288 } catch (RuntimeException re) {
289 throw re;
290 } catch (Exception e) {
291 throw new UndeclaredThrowableException(e,
292 "Unexpected error calling TokenUtil.obtainAndCacheToken()");
293 }
294 }
295
296 @Override
297 public void obtainAuthTokenForJob(JobConf job)
298 throws IOException, InterruptedException {
299 try {
300 Class<?> c = Class.forName(
301 "org.apache.hadoop.hbase.security.token.TokenUtil");
302 Methods.call(c, null, "obtainTokenForJob",
303 new Class[]{JobConf.class, UserGroupInformation.class},
304 new Object[]{job, ugi});
305 } catch (ClassNotFoundException cnfe) {
306 throw new RuntimeException("Failure loading TokenUtil class, "
307 +"is secure RPC available?", cnfe);
308 } catch (IOException ioe) {
309 throw ioe;
310 } catch (InterruptedException ie) {
311 throw ie;
312 } catch (RuntimeException re) {
313 throw re;
314 } catch (Exception e) {
315 throw new UndeclaredThrowableException(e,
316 "Unexpected error calling TokenUtil.obtainAndCacheToken()");
317 }
318 }
319
320
321 public static User createUserForTesting(Configuration conf,
322 String name, String[] groups) {
323 return new SecureHadoopUser(UserGroupInformation.createUserForTesting(name, groups));
324 }
325
326
327
328
329
330
331
332
333
334
335
336
337
338 public static void login(Configuration conf, String fileConfKey,
339 String principalConfKey, String localhost) throws IOException {
340 if (isSecurityEnabled()) {
341 SecurityUtil.login(conf, fileConfKey, principalConfKey, localhost);
342 }
343 }
344
345
346
347
348 public static boolean isSecurityEnabled() {
349 return UserGroupInformation.isSecurityEnabled();
350 }
351 }
352 }