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     */
034    public class PACLPolicyManager {
035    
036            public static PACLPolicy buildPACLPolicy(
037                    String servletContextName, ClassLoader classLoader,
038                    Properties properties) {
039    
040                    boolean active = GetterUtil.getBoolean(
041                            properties.get("security-manager-enabled"));
042    
043                    PACLPolicy paclPolicy = null;
044    
045                    if (active) {
046                            paclPolicy = new ActivePACLPolicy(
047                                    servletContextName, classLoader, properties);
048                    }
049                    else {
050                            paclPolicy = new InactivePACLPolicy(
051                                    servletContextName, classLoader, properties);
052                    }
053    
054                    return paclPolicy;
055            }
056    
057            public static int getActiveCount() {
058                    return _activeCount;
059            }
060    
061            public static PACLPolicy getDefaultPACLPolicy() {
062                    return _defaultPACLPolicy;
063            }
064    
065            public static PACLPolicy getPACLPolicy(ClassLoader classLoader) {
066                    return _paclPolicies.get(classLoader);
067            }
068    
069            public static boolean isActive() {
070                    if (_activeCount > 0) {
071                            return true;
072                    }
073    
074                    return false;
075            }
076    
077            public static void register(
078                    ClassLoader classLoader, PACLPolicy paclPolicy) {
079    
080                    _paclPolicies.put(classLoader, paclPolicy);
081    
082                    if (!paclPolicy.isActive()) {
083                            return;
084                    }
085    
086                    _activeCount++;
087    
088                    if (_activeCount == 1) {
089                            if (_log.isInfoEnabled()) {
090                                    _log.info("Activating PACL policy manager");
091                            }
092    
093                            _overridePortalSecurityManager();
094    
095                            ServiceBeanAopCacheManagerUtil.reset();
096                    }
097            }
098    
099            public static void unregister(ClassLoader classLoader) {
100                    PACLPolicy paclPolicy = _paclPolicies.remove(classLoader);
101    
102                    if ((paclPolicy == null) || !paclPolicy.isActive()) {
103                            return;
104                    }
105    
106                    _activeCount--;
107    
108                    if (_activeCount == 0) {
109                            if (_log.isInfoEnabled()) {
110                                    _log.info("Disabling PACL policy manager");
111                            }
112    
113                            _resetPortalSecurityManager();
114    
115                            ServiceBeanAopCacheManagerUtil.reset();
116                    }
117            }
118    
119            private static void _overridePortalSecurityManager() {
120                    _originalSecurityManager = System.getSecurityManager();
121    
122                    if (_originalSecurityManager instanceof PortalSecurityManager) {
123                            return;
124                    }
125    
126                    String portalSecurityManagerStrategy =
127                            PropsValues.PORTAL_SECURITY_MANAGER_STRATEGY;
128    
129                    if (!portalSecurityManagerStrategy.equals("smart")) {
130                            if (_log.isInfoEnabled()) {
131                                    StringBundler sb = new StringBundler(4);
132    
133                                    sb.append("Plugin security management is not enabled. To ");
134                                    sb.append("enable plugin security management, set the ");
135                                    sb.append("property \"portal.security.manager.strategy\" in ");
136                                    sb.append("portal.properties to \"liferay\" or \"smart\".");
137    
138                                    _log.info(sb.toString());
139                            }
140    
141                            return;
142                    }
143    
144                    try {
145                            if (_log.isInfoEnabled()) {
146                                    _log.info(
147                                            "Overriding the current security manager to enable " +
148                                                    "plugin security management");
149                            }
150    
151                            System.setSecurityManager(new PortalSecurityManager());
152                    }
153                    catch (SecurityException se) {
154                            _log.error(
155                                    "Unable to override the current security manager. Plugin " +
156                                            "security management is not enabled.");
157    
158                            throw se;
159                    }
160            }
161    
162            private static void _resetPortalSecurityManager() {
163                    if (_originalSecurityManager instanceof PortalSecurityManager) {
164                            return;
165                    }
166    
167                    String portalSecurityManagerStrategy =
168                            PropsValues.PORTAL_SECURITY_MANAGER_STRATEGY;
169    
170                    if (!portalSecurityManagerStrategy.equals("smart")) {
171                            return;
172                    }
173    
174                    try {
175                            if (_log.isInfoEnabled()) {
176                                    _log.info("Resetting to the original security manager");
177                            }
178    
179                            boolean enabled = PortalSecurityManagerThreadLocal.isEnabled();
180    
181                            try {
182                                    PortalSecurityManagerThreadLocal.setEnabled(false);
183    
184                                    System.setSecurityManager(_originalSecurityManager);
185                            }
186                            finally {
187                                    PortalSecurityManagerThreadLocal.setEnabled(enabled);
188                            }
189                    }
190                    catch (SecurityException se) {
191                            _log.error("Unable to reset to the original security manager");
192    
193                            throw se;
194                    }
195            }
196    
197            private static Log _log = LogFactoryUtil.getLog(PACLPolicyManager.class);
198    
199            private static int _activeCount;
200            private static PACLPolicy _defaultPACLPolicy = new InactivePACLPolicy(
201                    StringPool.BLANK, PACLPolicyManager.class.getClassLoader(),
202                    new Properties());
203            private static SecurityManager _originalSecurityManager;
204            private static Map<ClassLoader, PACLPolicy> _paclPolicies =
205                    new HashMap<ClassLoader, PACLPolicy>();
206    
207    }