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