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