001
014
015 package com.liferay.portal.security.pacl;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.util.AggregateClassLoader;
020 import com.liferay.portal.kernel.util.ProxyUtil;
021 import com.liferay.portal.kernel.util.ServerDetector;
022 import com.liferay.portal.kernel.util.StringPool;
023 import com.liferay.portal.kernel.util.StringUtil;
024 import com.liferay.portal.security.lang.PortalSecurityManagerThreadLocal;
025 import com.liferay.portal.spring.util.FilterClassLoader;
026
027 import java.net.URL;
028
029 import sun.reflect.Reflection;
030
031
034 public class PACLClassUtil {
035
036 public static ClassLoader getCallerClassLoader(Class<?> callerClass) {
037 boolean enabled = PortalSecurityManagerThreadLocal.isEnabled();
038
039 try {
040 PortalSecurityManagerThreadLocal.setEnabled(false);
041
042 return _instance._getCallerClassLoader(callerClass);
043 }
044 finally {
045 PortalSecurityManagerThreadLocal.setEnabled(enabled);
046 }
047 }
048
049 public static String getClassLocation(Class<?> clazz) {
050 boolean enabled = PortalSecurityManagerThreadLocal.isEnabled();
051
052 try {
053 PortalSecurityManagerThreadLocal.setEnabled(false);
054
055 ClassLoader classLoader = clazz.getClassLoader();
056
057 if (classLoader == null) {
058 return StringPool.BLANK;
059 }
060
061 String className = clazz.getName();
062
063 String name = StringUtil.replace(
064 className, StringPool.PERIOD, StringPool.SLASH);
065
066 name += ".class";
067
068 URL url = classLoader.getResource(name);
069
070 return url.toString();
071 }
072 finally {
073 PortalSecurityManagerThreadLocal.setEnabled(enabled);
074 }
075 }
076
077 public static PACLPolicy getPACLPolicy(boolean deep, boolean debug) {
078 PACLPolicy paclPolicy =
079 PortalSecurityManagerThreadLocal.getPACLPolicy();
080
081 if (paclPolicy != null) {
082 return paclPolicy;
083 }
084
085 return getPACLPolicyByReflection(deep, debug);
086 }
087
088 public static PACLPolicy getPACLPolicyByReflection(
089 boolean deep, boolean debug) {
090
091 boolean enabled = PortalSecurityManagerThreadLocal.isEnabled();
092
093 try {
094 PortalSecurityManagerThreadLocal.setEnabled(false);
095
096 return _instance._getPACLPolicyByReflection(deep, debug);
097 }
098 finally {
099 PortalSecurityManagerThreadLocal.setEnabled(enabled);
100 }
101 }
102
103 private PACLClassUtil() {
104 _systemClassLoader = ClassLoader.getSystemClassLoader();
105
106 _portalClassLoader = PACLAdvice.class.getClassLoader();
107
108 _commonClassLoader = _portalClassLoader.getParent();
109 }
110
111 private ClassLoader _getCallerClassLoader(Class<?> callerClass) {
112 ClassLoader callerClassLoader = callerClass.getClassLoader();
113
114 if (callerClassLoader == null) {
115 return null;
116 }
117
118 Class<?> callerClassLoaderClass = callerClassLoader.getClass();
119
120 String callerClassLoaderClassName = callerClassLoaderClass.getName();
121
122 if (callerClassLoader instanceof FilterClassLoader) {
123 callerClassLoader = callerClassLoader.getParent();
124
125 if (callerClassLoader instanceof AggregateClassLoader) {
126 callerClassLoader = callerClassLoader.getParent();
127 }
128 }
129
130 if (callerClassLoaderClassName.equals(_ClASS_NAME_JASPER_LOADER)) {
131 callerClassLoader = callerClassLoader.getParent();
132 }
133 else if (ServerDetector.isResin()) {
134 if (callerClassLoaderClassName.equals(
135 _ClASS_NAME_DYNAMIC_CLASS_LOADER)) {
136
137 callerClassLoader = callerClassLoader.getParent();
138 }
139 }
140 else if (ServerDetector.isWebLogic()) {
141 if (callerClassLoaderClassName.equals(
142 _CLASS_NAME_JSP_CLASS_LOADER)) {
143
144
145
146 callerClassLoader = callerClassLoader.getParent();
147
148
149
150 callerClassLoader = callerClassLoader.getParent();
151 }
152 }
153 else if (ServerDetector.isWebSphere()) {
154 if (callerClassLoaderClassName.equals(
155 _CLASS_NAME_JSP_EXTENSION_CLASS_LOADER)) {
156
157 callerClassLoader = callerClassLoader.getParent();
158 }
159 }
160
161 return callerClassLoader;
162 }
163
164 private PACLPolicy _getPACLPolicyByReflection(boolean deep, boolean debug) {
165 PACLPolicy paclPolicy = null;
166
167 boolean initialPortalClassLoaderPhase = true;
168
169
170
171 for (int i = 1;; i++) {
172 Class<?> callerClass = Reflection.getCallerClass(i);
173
174 if (callerClass == null) {
175 break;
176 }
177
178 if (debug) {
179 _log.debug(
180 "Frame " + i + " has caller class " +
181 callerClass.getName());
182 }
183
184 if (ProxyUtil.isProxyClass(callerClass)) {
185 if (debug) {
186 _log.debug("Skipping frame because it is proxy class");
187 }
188
189 continue;
190 }
191
192 ClassLoader callerClassLoader = _getCallerClassLoader(callerClass);
193
194 if (callerClassLoader == null) {
195 continue;
196 }
197
198
214
215 if (!initialPortalClassLoaderPhase &&
216 (callerClassLoader == _portalClassLoader)) {
217
218 PACLPolicy defaultPACLPolicy =
219 PACLPolicyManager.getDefaultPACLPolicy();
220
221 if (paclPolicy == null) {
222 if (debug) {
223 _log.debug(
224 "Possibly return default PACL policy " +
225 defaultPACLPolicy);
226 }
227
228 paclPolicy = defaultPACLPolicy;
229 }
230
231 if (!deep) {
232 break;
233 }
234
235 continue;
236 }
237
238 if (initialPortalClassLoaderPhase &&
239 (callerClassLoader != _portalClassLoader)) {
240
241 initialPortalClassLoaderPhase = false;
242 }
243
244 if ((callerClassLoader == _commonClassLoader) ||
245 (callerClassLoader == _portalClassLoader) ||
246 (callerClassLoader == _systemClassLoader)) {
247
248 continue;
249 }
250
251 if (debug) {
252 _log.debug(
253 "Lookup PACL policy for caller class loader " +
254 callerClassLoader);
255 }
256
257 PACLPolicy callerPACLPolicy = PACLPolicyManager.getPACLPolicy(
258 callerClassLoader);
259
260 if (callerPACLPolicy != null) {
261 paclPolicy = callerPACLPolicy;
262
263 if (debug) {
264 _log.debug("Possibly return PACL policy " + paclPolicy);
265 }
266
267 if (!deep) {
268 break;
269 }
270 }
271 }
272
273 if (debug) {
274 _log.debug("Returning PACL policy " + paclPolicy);
275 }
276
277 return paclPolicy;
278 }
279
280 private static final String _ClASS_NAME_DYNAMIC_CLASS_LOADER =
281 "com.caucho.loader.DynamicClassLoader";
282
283 private static final String _ClASS_NAME_JASPER_LOADER =
284 "org.apache.jasper.servlet.JasperLoader";
285
286 private static final String _CLASS_NAME_JSP_CLASS_LOADER =
287 "weblogic.servlet.jsp.JspClassLoader";
288
289 private static final String _CLASS_NAME_JSP_EXTENSION_CLASS_LOADER =
290 "com.ibm.ws.jsp.webcontainerext.JSPExtensionClassLoader";
291
292 private static Log _log = LogFactoryUtil.getLog(PACLClassUtil.class);
293
294 private static PACLClassUtil _instance = new PACLClassUtil();
295
296 private ClassLoader _commonClassLoader;
297 private ClassLoader _portalClassLoader;
298 private ClassLoader _systemClassLoader;
299
300 }