001
014
015 package com.liferay.portal.security.lang;
016
017 import com.liferay.portal.jndi.pacl.PACLInitialContextFactoryBuilder;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.security.pacl.PACLConstants;
021 import com.liferay.portal.kernel.security.pacl.permission.CheckMemberAccessPermission;
022 import com.liferay.portal.kernel.security.pacl.permission.PortalHookPermission;
023 import com.liferay.portal.kernel.security.pacl.permission.PortalRuntimePermission;
024 import com.liferay.portal.kernel.servlet.taglib.FileAvailabilityUtil;
025 import com.liferay.portal.kernel.util.JavaDetector;
026 import com.liferay.portal.security.pacl.PACLClassUtil;
027 import com.liferay.portal.security.pacl.PACLPolicy;
028 import com.liferay.portal.security.pacl.PACLPolicyManager;
029 import com.liferay.portal.security.pacl.checker.CheckerUtil;
030 import com.liferay.portal.util.ClassLoaderUtil;
031
032 import java.lang.reflect.Field;
033 import java.lang.reflect.Member;
034
035 import java.security.Permission;
036
037 import javax.naming.spi.InitialContextFactoryBuilder;
038 import javax.naming.spi.NamingManager;
039
040 import sun.reflect.Reflection;
041
042
054 public class PortalSecurityManager extends SecurityManager {
055
056 public PortalSecurityManager() {
057 _parentSecurityManager = System.getSecurityManager();
058
059 initClasses();
060
061 try {
062 initInitialContextFactoryBuilder();
063 }
064 catch (Exception e) {
065 if (_log.isInfoEnabled()) {
066 _log.info(
067 "Unable to override the initial context factory builder " +
068 "because one already exists. JNDI security is not " +
069 "enabled.");
070 }
071
072 if (_log.isWarnEnabled()) {
073 _log.warn(e, e);
074 }
075 }
076 }
077
078 @Override
079 public void checkMemberAccess(Class<?> clazz, int which) {
080 if (clazz == null) {
081 throw new NullPointerException();
082 }
083
084 if (which == Member.PUBLIC) {
085 return;
086 }
087
088 ClassLoader classClassLoader = ClassLoaderUtil.getClassLoader(clazz);
089
090 if (classClassLoader == null) {
091 return;
092 }
093
094 Class<?> callerClass = Reflection.getCallerClass(4);
095
096 ClassLoader callerClassLoader = ClassLoaderUtil.getClassLoader(
097 callerClass);
098
099 if (callerClassLoader == null) {
100 for (int i = 5;; i++) {
101 callerClass = Reflection.getCallerClass(i);
102
103 if (callerClass == null) {
104 break;
105 }
106
107 String className = callerClass.getName();
108
109 if (!className.startsWith("java.lang") &&
110 !className.startsWith("java.security") &&
111 !className.startsWith("sun.reflect")) {
112
113 callerClassLoader = ClassLoaderUtil.getClassLoader(
114 callerClass);
115
116 break;
117 }
118 }
119 }
120
121 if (classClassLoader == callerClassLoader) {
122 return;
123 }
124
125 Permission permission = new CheckMemberAccessPermission(
126 PACLConstants.RUNTIME_PERMISSION_ACCESS_DECLARED_MEMBERS,
127 callerClass, callerClassLoader, clazz, classClassLoader);
128
129 checkPermission(permission);
130 }
131
132 @Override
133 public void checkPermission(Permission permission) {
134 checkPermission(permission, null);
135 }
136
137 @Override
138 public void checkPermission(Permission permission, Object context) {
139 if (!PACLPolicyManager.isActive() ||
140 !PortalSecurityManagerThreadLocal.isEnabled()) {
141
142 parentCheckPermission(permission, context);
143
144 return;
145 }
146
147 PACLPolicy paclPolicy = PACLPolicyManager.getDefaultPACLPolicy();
148
149 if (!paclPolicy.isCheckablePermission(permission)) {
150 parentCheckPermission(permission, context);
151
152 return;
153 }
154
155 paclPolicy = getPACLPolicy(permission);
156
157 if ((paclPolicy == null) || !paclPolicy.isActive()) {
158 parentCheckPermission(permission, context);
159
160 return;
161 }
162
163 paclPolicy.checkPermission(permission);
164
165 parentCheckPermission(permission, context);
166 }
167
168 protected PACLPolicy getPACLPolicy(Permission permission) {
169 PACLPolicy paclPolicy =
170 PortalSecurityManagerThreadLocal.getPACLPolicy();
171
172 if (paclPolicy != null) {
173 return paclPolicy;
174 }
175
176 if (permission instanceof PortalHookPermission) {
177 PortalHookPermission portalHookPermission =
178 (PortalHookPermission)permission;
179
180 ClassLoader classLoader = portalHookPermission.getClassLoader();
181
182 paclPolicy = PACLPolicyManager.getPACLPolicy(classLoader);
183
184 if (paclPolicy == null) {
185 paclPolicy = PACLPolicyManager.getDefaultPACLPolicy();
186 }
187
188 return paclPolicy;
189 }
190 else if (permission instanceof PortalRuntimePermission) {
191 PortalRuntimePermission portalRuntimePermission =
192 (PortalRuntimePermission)permission;
193
194 String name = portalRuntimePermission.getName();
195
196 if (name.equals(
197 PACLConstants.PORTAL_RUNTIME_PERMISSION_EXPANDO_BRIDGE)) {
198
199 return PACLClassUtil.getPACLPolicyByReflection(
200 true, _log.isDebugEnabled());
201 }
202
203
214 }
215
216 return PACLClassUtil.getPACLPolicyByReflection(
217 false, _log.isDebugEnabled());
218 }
219
220 protected void initClasses() {
221
222
223
224 _log.debug("Loading " + FileAvailabilityUtil.class.getName());
225 _log.debug("Loading " + PortalHookPermission.class.getName());
226
227
228
229 CheckerUtil.isAccessControllerDoPrivileged(0);
230 PACLClassUtil.getPACLPolicyByReflection(false, false);
231 }
232
233 protected void initInitialContextFactoryBuilder() throws Exception {
234 if (!NamingManager.hasInitialContextFactoryBuilder()) {
235 PACLInitialContextFactoryBuilder paclInitialContextFactoryBuilder =
236 new PACLInitialContextFactoryBuilder();
237
238 if (_log.isInfoEnabled()) {
239 _log.info("Overriding the initial context factory builder");
240 }
241
242 NamingManager.setInitialContextFactoryBuilder(
243 paclInitialContextFactoryBuilder);
244 }
245
246 Class<?> clazz = NamingManager.class;
247
248 String fieldName = "initctx_factory_builder";
249
250 if (JavaDetector.isIBM()) {
251 fieldName = "icfb";
252 }
253
254 Field field = clazz.getDeclaredField(fieldName);
255
256 field.setAccessible(true);
257
258 InitialContextFactoryBuilder initialContextFactoryBuilder =
259 (InitialContextFactoryBuilder)field.get(null);
260
261 if (initialContextFactoryBuilder
262 instanceof PACLInitialContextFactoryBuilder) {
263
264 return;
265 }
266
267 PACLInitialContextFactoryBuilder paclInitialContextFactoryBuilder =
268 new PACLInitialContextFactoryBuilder();
269
270 paclInitialContextFactoryBuilder.setInitialContextFactoryBuilder(
271 initialContextFactoryBuilder);
272
273 field.set(null, paclInitialContextFactoryBuilder);
274
275 if (_log.isInfoEnabled()) {
276 _log.info(
277 "Overriding the initial context factory builder using " +
278 "reflection");
279 }
280 }
281
282 protected void parentCheckPermission(
283 Permission permission, Object context) {
284
285 if (_parentSecurityManager != null) {
286 if (context == null) {
287 context = getSecurityContext();
288 }
289
290 _parentSecurityManager.checkPermission(permission, context);
291 }
292 }
293
294 private static Log _log = LogFactoryUtil.getLog(
295 PortalSecurityManager.class.getName());
296
297 private SecurityManager _parentSecurityManager;
298
299 }