001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
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.GetterUtil;
020    import com.liferay.portal.kernel.util.StringBundler;
021    import com.liferay.portal.kernel.util.StringPool;
022    import com.liferay.portal.security.lang.PortalSecurityManager;
023    import com.liferay.portal.security.lang.PortalSecurityManagerThreadLocal;
024    import com.liferay.portal.spring.aop.ServiceBeanAopCacheManagerUtil;
025    import com.liferay.portal.util.PropsValues;
026    
027    import java.util.HashMap;
028    import java.util.Map;
029    import java.util.Properties;
030    
031    /**
032     * @author Brian Wing Shun Chan
033     * @author Raymond Augé
034     */
035    public class PACLPolicyManager {
036    
037            public static PACLPolicy buildPACLPolicy(
038                    String servletContextName, ClassLoader classLoader,
039                    Properties properties) {
040    
041                    String value = properties.getProperty(
042                            "security-manager-enabled", "false");
043    
044                    if (value.equals("generate")) {
045                            return new GeneratingPACLPolicy(
046                                    servletContextName, classLoader, properties);
047                    }
048    
049                    if (GetterUtil.getBoolean(value)) {
050                            return new ActivePACLPolicy(
051                                    servletContextName, classLoader, properties);
052                    }
053                    else {
054                            return new InactivePACLPolicy(
055                                    servletContextName, classLoader, properties);
056                    }
057            }
058    
059            public static int getActiveCount() {
060                    return _activeCount;
061            }
062    
063            public static PACLPolicy getDefaultPACLPolicy() {
064                    return _defaultPACLPolicy;
065            }
066    
067            public static PACLPolicy getPACLPolicy(ClassLoader classLoader) {
068                    return _paclPolicies.get(classLoader);
069            }
070    
071            public static boolean isActive() {
072                    if (_activeCount > 0) {
073                            return true;
074                    }
075    
076                    return false;
077            }
078    
079            public static void register(
080                    ClassLoader classLoader, PACLPolicy paclPolicy) {
081    
082                    _paclPolicies.put(classLoader, paclPolicy);
083    
084                    if (!paclPolicy.isActive()) {
085                            return;
086                    }
087    
088                    _activeCount++;
089    
090                    if (_activeCount == 1) {
091                            if (_log.isInfoEnabled()) {
092                                    _log.info("Activating PACL policy manager");
093                            }
094    
095                            _overridePortalSecurityManager();
096    
097                            ServiceBeanAopCacheManagerUtil.reset();
098                    }
099            }
100    
101            public static void unregister(ClassLoader classLoader) {
102                    PACLPolicy paclPolicy = _paclPolicies.remove(classLoader);
103    
104                    if ((paclPolicy == null) || !paclPolicy.isActive()) {
105                            return;
106                    }
107    
108                    _activeCount--;
109    
110                    if (_activeCount == 0) {
111                            if (_log.isInfoEnabled()) {
112                                    _log.info("Disabling PACL policy manager");
113                            }
114    
115                            _resetPortalSecurityManager();
116    
117                            ServiceBeanAopCacheManagerUtil.reset();
118                    }
119            }
120    
121            private static void _overridePortalSecurityManager() {
122                    _originalSecurityManager = System.getSecurityManager();
123    
124                    if (_originalSecurityManager instanceof PortalSecurityManager) {
125                            return;
126                    }
127    
128                    String portalSecurityManagerStrategy =
129                            PropsValues.PORTAL_SECURITY_MANAGER_STRATEGY;
130    
131                    if (!portalSecurityManagerStrategy.equals("smart")) {
132                            if (_log.isInfoEnabled()) {
133                                    StringBundler sb = new StringBundler(4);
134    
135                                    sb.append("Plugin security management is not enabled. To ");
136                                    sb.append("enable plugin security management, set the ");
137                                    sb.append("property \"portal.security.manager.strategy\" in ");
138                                    sb.append("portal.properties to \"liferay\" or \"smart\".");
139    
140                                    _log.info(sb.toString());
141                            }
142    
143                            return;
144                    }
145    
146                    try {
147                            if (_log.isInfoEnabled()) {
148                                    _log.info(
149                                            "Overriding the current security manager to enable " +
150                                                    "plugin security management");
151                            }
152    
153                            System.setSecurityManager(new PortalSecurityManager());
154                    }
155                    catch (SecurityException se) {
156                            _log.error(
157                                    "Unable to override the current security manager. Plugin " +
158                                            "security management is not enabled.");
159    
160                            throw se;
161                    }
162            }
163    
164            private static void _resetPortalSecurityManager() {
165                    if (_originalSecurityManager instanceof PortalSecurityManager) {
166                            return;
167                    }
168    
169                    String portalSecurityManagerStrategy =
170                            PropsValues.PORTAL_SECURITY_MANAGER_STRATEGY;
171    
172                    if (!portalSecurityManagerStrategy.equals("smart")) {
173                            return;
174                    }
175    
176                    try {
177                            if (_log.isInfoEnabled()) {
178                                    _log.info("Resetting to the original security manager");
179                            }
180    
181                            boolean enabled = PortalSecurityManagerThreadLocal.isEnabled();
182    
183                            try {
184                                    PortalSecurityManagerThreadLocal.setEnabled(false);
185    
186                                    System.setSecurityManager(_originalSecurityManager);
187                            }
188                            finally {
189                                    PortalSecurityManagerThreadLocal.setEnabled(enabled);
190                            }
191                    }
192                    catch (SecurityException se) {
193                            _log.error("Unable to reset to the original security manager");
194    
195                            throw se;
196                    }
197            }
198    
199            private static Log _log = LogFactoryUtil.getLog(PACLPolicyManager.class);
200    
201            private static int _activeCount;
202            private static PACLPolicy _defaultPACLPolicy = new InactivePACLPolicy(
203                    StringPool.BLANK, PACLPolicyManager.class.getClassLoader(),
204                    new Properties());
205            private static SecurityManager _originalSecurityManager;
206            private static Map<ClassLoader, PACLPolicy> _paclPolicies =
207                    new HashMap<ClassLoader, PACLPolicy>();
208    
209    }