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.hbase.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
173
174 @SuppressWarnings({ "rawtypes", "unchecked" })
175 public static <T> T runAsLoginUser(PrivilegedExceptionAction<T> action) throws IOException {
176 return doAsUser(UserGroupInformation.getLoginUser(), action);
177 }
178
179 private static <T> T doAsUser(UserGroupInformation ugi,
180 PrivilegedExceptionAction<T> action) throws IOException {
181 try {
182 return ugi.doAs(action);
183 } catch (InterruptedException ie) {
184 throw new IOException(ie);
185 }
186 }
187
188
189
190
191
192
193 public static User create(UserGroupInformation ugi) {
194 if (ugi == null) {
195 return null;
196 }
197 return new SecureHadoopUser(ugi);
198 }
199
200
201
202
203
204
205
206 public static User createUserForTesting(Configuration conf,
207 String name, String[] groups) {
208 return SecureHadoopUser.createUserForTesting(conf, name, groups);
209 }
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227 public static void login(Configuration conf, String fileConfKey,
228 String principalConfKey, String localhost) throws IOException {
229 SecureHadoopUser.login(conf, fileConfKey, principalConfKey, localhost);
230 }
231
232
233
234
235
236
237
238 public static boolean isSecurityEnabled() {
239 return SecureHadoopUser.isSecurityEnabled();
240 }
241
242
243
244
245
246
247 public static boolean isHBaseSecurityEnabled(Configuration conf) {
248 return "kerberos".equalsIgnoreCase(conf.get(HBASE_SECURITY_CONF_KEY));
249 }
250
251
252
253
254
255
256
257
258 private static class SecureHadoopUser extends User {
259 private String shortName;
260
261 private SecureHadoopUser() throws IOException {
262 ugi = UserGroupInformation.getCurrentUser();
263 }
264
265 private SecureHadoopUser(UserGroupInformation ugi) {
266 this.ugi = ugi;
267 }
268
269 @Override
270 public String getShortName() {
271 if (shortName != null) return shortName;
272 try {
273 shortName = ugi.getShortUserName();
274 return shortName;
275 } catch (Exception e) {
276 throw new RuntimeException("Unexpected error getting user short name",
277 e);
278 }
279 }
280
281 @Override
282 public <T> T runAs(PrivilegedAction<T> action) {
283 return ugi.doAs(action);
284 }
285
286 @Override
287 public <T> T runAs(PrivilegedExceptionAction<T> action)
288 throws IOException, InterruptedException {
289 return ugi.doAs(action);
290 }
291
292 @Override
293 public void obtainAuthTokenForJob(Configuration conf, Job job)
294 throws IOException, InterruptedException {
295 try {
296 Class<?> c = Class.forName(
297 "org.apache.hadoop.hbase.security.token.TokenUtil");
298 Methods.call(c, null, "obtainTokenForJob",
299 new Class[]{Configuration.class, UserGroupInformation.class,
300 Job.class},
301 new Object[]{conf, ugi, job});
302 } catch (ClassNotFoundException cnfe) {
303 throw new RuntimeException("Failure loading TokenUtil class, "
304 +"is secure RPC available?", cnfe);
305 } catch (IOException ioe) {
306 throw ioe;
307 } catch (InterruptedException ie) {
308 throw ie;
309 } catch (RuntimeException re) {
310 throw re;
311 } catch (Exception e) {
312 throw new UndeclaredThrowableException(e,
313 "Unexpected error calling TokenUtil.obtainAndCacheToken()");
314 }
315 }
316
317 @Override
318 public void obtainAuthTokenForJob(JobConf job)
319 throws IOException, InterruptedException {
320 try {
321 Class<?> c = Class.forName(
322 "org.apache.hadoop.hbase.security.token.TokenUtil");
323 Methods.call(c, null, "obtainTokenForJob",
324 new Class[]{JobConf.class, UserGroupInformation.class},
325 new Object[]{job, ugi});
326 } catch (ClassNotFoundException cnfe) {
327 throw new RuntimeException("Failure loading TokenUtil class, "
328 +"is secure RPC available?", cnfe);
329 } catch (IOException ioe) {
330 throw ioe;
331 } catch (InterruptedException ie) {
332 throw ie;
333 } catch (RuntimeException re) {
334 throw re;
335 } catch (Exception e) {
336 throw new UndeclaredThrowableException(e,
337 "Unexpected error calling TokenUtil.obtainAndCacheToken()");
338 }
339 }
340
341
342 public static User createUserForTesting(Configuration conf,
343 String name, String[] groups) {
344 return new SecureHadoopUser(UserGroupInformation.createUserForTesting(name, groups));
345 }
346
347
348
349
350
351
352
353
354
355
356
357
358
359 public static void login(Configuration conf, String fileConfKey,
360 String principalConfKey, String localhost) throws IOException {
361 if (isSecurityEnabled()) {
362 SecurityUtil.login(conf, fileConfKey, principalConfKey, localhost);
363 }
364 }
365
366
367
368
369 public static boolean isSecurityEnabled() {
370 return UserGroupInformation.isSecurityEnabled();
371 }
372 }
373 }