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