1 package org.apache.hadoop.hbase.security;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 import java.io.IOException;
22 import java.lang.reflect.InvocationTargetException;
23 import java.lang.reflect.Method;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.hadoop.conf.Configuration;
28 import org.apache.hadoop.security.UserGroupInformation;
29
30 public class HBaseMultiRealmUserAuthentication {
31
32 private static final Log LOG = LogFactory.getLog(HBaseMultiRealmUserAuthentication.class);
33
34 public static String KERBEROS_USER_REALM_PRINCIPAL =
35 "hadoop.security.authentication.userrealm.principal";
36 public static String KERBEROS_USER_REALM ="hadoop.security.authentication.userrealm";
37
38
39 private static UserGroupInformation ugi;
40
41 private static boolean isInitialized;
42 private static boolean isEnabled;
43 private static Method isAUserInADifferentRealmMethod;
44 private static Method getServerUGIForUserRealmMethod;
45 private static Method loginServerFromCurrentKeytabAndReturnUGIMethod;
46 private static Method replaceRealmWithUserRealmMethod;
47
48 private static synchronized void initialize(boolean isEnabled) throws IOException {
49 if (!isEnabled) {
50 return;
51 }
52 String className = "org.apache.hadoop.security.MultiRealmUserAuthentication";
53 try {
54 Class c = Class.forName(className, true, UserGroupInformation.class.getClassLoader());
55 isAUserInADifferentRealmMethod = c.getDeclaredMethod(
56 "isAUserInADifferentRealm", UserGroupInformation.class, Configuration.class);
57 getServerUGIForUserRealmMethod = c.getDeclaredMethod(
58 "getServerUGIForUserRealm", Configuration.class);
59 replaceRealmWithUserRealmMethod = c.getDeclaredMethod(
60 "replaceRealmWithUserRealm", String.class, Configuration.class);
61 loginServerFromCurrentKeytabAndReturnUGIMethod = UserGroupInformation.class
62 .getDeclaredMethod("loginServerFromCurrentKeytabAndReturnUGI", String.class);
63 } catch (Throwable t) {
64 LOG.warn("Failed to load the required class" + className + " or get methods: " + t);
65 throw new IOException("Underlying Hadoop version doesn't support multi-realm " +
66 "authentication", t);
67 }
68 return;
69 }
70
71 private static void ensureInitialized(Configuration conf) throws IOException {
72 if (!isInitialized) {
73 isEnabled = conf.get(KERBEROS_USER_REALM) == null ? false : true;
74 initialize(isEnabled);
75 isInitialized = true;
76 }
77 }
78
79
80 public static boolean isAUserInADifferentRealm(UserGroupInformation ticket, Configuration conf)
81 throws IOException {
82 ensureInitialized(conf);
83 if (!isEnabled) {
84 return false;
85 }
86 try {
87 return ((Boolean)isAUserInADifferentRealmMethod.invoke(null, ticket, conf)).booleanValue();
88 } catch (IllegalAccessException iae) {
89 throw new IOException("Hadoop version does not support multi-realm", iae);
90 } catch (InvocationTargetException ite) {
91 throw new IOException(ite.getTargetException());
92 }
93 }
94
95
96
97
98
99
100
101
102
103 public static synchronized UserGroupInformation getServerUGIForUserRealm(Configuration conf)
104 throws IOException {
105 ensureInitialized(conf);
106 if (ugi != null) return ugi;
107
108
109 String kurp = conf.get(KERBEROS_USER_REALM_PRINCIPAL);
110 try {
111 if (kurp != null) {
112 try {
113 ugi = (UserGroupInformation)
114 loginServerFromCurrentKeytabAndReturnUGIMethod.invoke(null, kurp);
115 } catch (InvocationTargetException ite) {
116 LOG.warn("Current user information cannot be obtained", ite);
117 }
118 } else {
119 try {
120 ugi = (UserGroupInformation)getServerUGIForUserRealmMethod.invoke(null, conf);
121 } catch (InvocationTargetException ite) {
122 throw new IOException(ite.getTargetException());
123 }
124 }
125 } catch (IllegalAccessException iae) {
126 throw new IOException("Hadoop version does not support multi-realm", iae);
127 }
128 return ugi;
129 }
130
131
132
133
134
135
136
137
138 public static String replaceRealmWithUserRealm(String principalName, Configuration conf)
139 throws IOException {
140 ensureInitialized(conf);
141 String kurp = conf.get(KERBEROS_USER_REALM_PRINCIPAL);
142 if (kurp != null) return kurp;
143 try {
144 return (String)replaceRealmWithUserRealmMethod.invoke(null, principalName, conf);
145 } catch (IllegalAccessException iae) {
146 throw new IOException("Hadoop version does not support multi-realm", iae);
147 } catch (InvocationTargetException ite) {
148 throw new IOException(ite.getTargetException());
149 }
150 }
151 }