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