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.PACLClassLoaderUtil;
027 import com.liferay.portal.security.pacl.PACLClassUtil;
028 import com.liferay.portal.security.pacl.PACLPolicy;
029 import com.liferay.portal.security.pacl.PACLPolicyManager;
030 import com.liferay.portal.security.pacl.checker.CheckerUtil;
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 = PACLClassLoaderUtil.getClassLoader(
089 clazz);
090
091 if (classClassLoader == null) {
092 return;
093 }
094
095 Class<?> callerClass = Reflection.getCallerClass(4);
096
097 ClassLoader callerClassLoader = PACLClassLoaderUtil.getClassLoader(
098 callerClass);
099
100 if (callerClassLoader == null) {
101 for (int i = 5;; i++) {
102 callerClass = Reflection.getCallerClass(i);
103
104 if (callerClass == null) {
105 break;
106 }
107
108 String className = callerClass.getName();
109
110 if (!className.startsWith("java.lang") &&
111 !className.startsWith("java.security") &&
112 !className.startsWith("sun.reflect")) {
113
114 callerClassLoader = PACLClassLoaderUtil.getClassLoader(
115 callerClass);
116
117 break;
118 }
119 }
120 }
121
122 if (classClassLoader == callerClassLoader) {
123 return;
124 }
125
126 Permission permission = new CheckMemberAccessPermission(
127 PACLConstants.RUNTIME_PERMISSION_ACCESS_DECLARED_MEMBERS,
128 callerClass, callerClassLoader, clazz, classClassLoader);
129
130 checkPermission(permission);
131 }
132
133 @Override
134 public void checkPermission(Permission permission) {
135 checkPermission(permission, null);
136 }
137
138 @Override
139 public void checkPermission(Permission permission, Object context) {
140 if (!PACLPolicyManager.isActive() ||
141 !PortalSecurityManagerThreadLocal.isEnabled()) {
142
143 parentCheckPermission(permission, context);
144
145 return;
146 }
147
148 PACLPolicy paclPolicy = PACLPolicyManager.getDefaultPACLPolicy();
149
150 if (!paclPolicy.isCheckablePermission(permission)) {
151 parentCheckPermission(permission, context);
152
153 return;
154 }
155
156 paclPolicy = getPACLPolicy(permission);
157
158 if ((paclPolicy == null) || !paclPolicy.isActive()) {
159 parentCheckPermission(permission, context);
160
161 return;
162 }
163
164 paclPolicy.checkPermission(permission);
165
166 parentCheckPermission(permission, context);
167 }
168
169 protected PACLPolicy getPACLPolicy(Permission permission) {
170 PACLPolicy paclPolicy =
171 PortalSecurityManagerThreadLocal.getPACLPolicy();
172
173 if (paclPolicy != null) {
174 return paclPolicy;
175 }
176
177 if (permission instanceof PortalHookPermission) {
178 PortalHookPermission portalHookPermission =
179 (PortalHookPermission)permission;
180
181 ClassLoader classLoader = portalHookPermission.getClassLoader();
182
183 paclPolicy = PACLPolicyManager.getPACLPolicy(classLoader);
184
185 if (paclPolicy == null) {
186 paclPolicy = PACLPolicyManager.getDefaultPACLPolicy();
187 }
188
189 return paclPolicy;
190 }
191 else if (permission instanceof PortalRuntimePermission) {
192 PortalRuntimePermission portalRuntimePermission =
193 (PortalRuntimePermission)permission;
194
195 String name = portalRuntimePermission.getName();
196
197 if (name.equals(
198 PACLConstants.PORTAL_RUNTIME_PERMISSION_EXPANDO_BRIDGE)) {
199
200 return PACLClassUtil.getPACLPolicyByReflection(
201 true, _log.isDebugEnabled());
202 }
203
204
215 }
216
217 return PACLClassUtil.getPACLPolicyByReflection(
218 false, _log.isDebugEnabled());
219 }
220
221 protected void initClasses() {
222
223
224
225 _log.debug("Loading " + FileAvailabilityUtil.class.getName());
226 _log.debug("Loading " + PortalHookPermission.class.getName());
227
228
229
230 CheckerUtil.isAccessControllerDoPrivileged(0);
231 PACLClassUtil.getPACLPolicyByReflection(false, false);
232 }
233
234 protected void initInitialContextFactoryBuilder() throws Exception {
235 if (!NamingManager.hasInitialContextFactoryBuilder()) {
236 PACLInitialContextFactoryBuilder paclInitialContextFactoryBuilder =
237 new PACLInitialContextFactoryBuilder();
238
239 if (_log.isInfoEnabled()) {
240 _log.info("Overriding the initial context factory builder");
241 }
242
243 NamingManager.setInitialContextFactoryBuilder(
244 paclInitialContextFactoryBuilder);
245 }
246
247 Class<?> clazz = NamingManager.class;
248
249 String fieldName = "initctx_factory_builder";
250
251 if (JavaDetector.isIBM()) {
252 fieldName = "icfb";
253 }
254
255 Field field = clazz.getDeclaredField(fieldName);
256
257 field.setAccessible(true);
258
259 InitialContextFactoryBuilder initialContextFactoryBuilder =
260 (InitialContextFactoryBuilder)field.get(null);
261
262 if (initialContextFactoryBuilder
263 instanceof PACLInitialContextFactoryBuilder) {
264
265 return;
266 }
267
268 PACLInitialContextFactoryBuilder paclInitialContextFactoryBuilder =
269 new PACLInitialContextFactoryBuilder();
270
271 paclInitialContextFactoryBuilder.setInitialContextFactoryBuilder(
272 initialContextFactoryBuilder);
273
274 field.set(null, paclInitialContextFactoryBuilder);
275
276 if (_log.isInfoEnabled()) {
277 _log.info(
278 "Overriding the initial context factory builder using " +
279 "reflection");
280 }
281 }
282
283 protected void parentCheckPermission(
284 Permission permission, Object context) {
285
286 if (_parentSecurityManager != null) {
287 if (context == null) {
288 context = getSecurityContext();
289 }
290
291 _parentSecurityManager.checkPermission(permission, context);
292 }
293 }
294
295 private static Log _log = LogFactoryUtil.getLog(
296 PortalSecurityManager.class.getName());
297
298 private SecurityManager _parentSecurityManager;
299
300 }