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