001    /**
002     * Copyright (c) 2000-2013 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.SecurityManagerUtil;
024    import com.liferay.portal.spring.aop.ServiceBeanAopCacheManagerUtil;
025    
026    import java.security.AccessController;
027    import java.security.PrivilegedAction;
028    
029    import java.util.HashMap;
030    import java.util.Map;
031    import java.util.Properties;
032    
033    /**
034     * @author Brian Wing Shun Chan
035     * @author Raymond Augé
036     */
037    public class PACLPolicyManager {
038    
039            public static PACLPolicy buildPACLPolicy(
040                    String servletContextName, ClassLoader classLoader,
041                    Properties properties) {
042    
043                    String value = properties.getProperty(
044                            "security-manager-enabled", "false");
045    
046                    if (value.equals("generate")) {
047                            return new GeneratingPACLPolicy(
048                                    servletContextName, classLoader, properties);
049                    }
050    
051                    if (GetterUtil.getBoolean(value)) {
052                            return new ActivePACLPolicy(
053                                    servletContextName, classLoader, properties);
054                    }
055                    else {
056                            return new InactivePACLPolicy(
057                                    servletContextName, classLoader, properties);
058                    }
059            }
060    
061            public static int getActiveCount() {
062                    return _activeCount;
063            }
064    
065            public static PACLPolicy getDefaultPACLPolicy() {
066                    return _defaultPACLPolicy;
067            }
068    
069            public static PACLPolicy getPACLPolicy(ClassLoader classLoader) {
070                    return AccessController.doPrivileged(
071                            new PACLPolicyPrivilegedAction(classLoader));
072            }
073    
074            public static boolean isActive() {
075                    if (_activeCount > 0) {
076                            return true;
077                    }
078    
079                    return false;
080            }
081    
082            public static void register(
083                    ClassLoader classLoader, PACLPolicy paclPolicy) {
084    
085                    _paclPolicies.put(classLoader, paclPolicy);
086    
087                    if (!paclPolicy.isActive()) {
088                            return;
089                    }
090    
091                    _activeCount++;
092    
093                    if (_activeCount == 1) {
094                            if (_log.isInfoEnabled()) {
095                                    _log.info("Activating PACL policy manager");
096                            }
097    
098                            _overridePortalSecurityManager();
099    
100                            ServiceBeanAopCacheManagerUtil.reset();
101                    }
102            }
103    
104            public static void unregister(ClassLoader classLoader) {
105                    PACLPolicy paclPolicy = _paclPolicies.remove(classLoader);
106    
107                    if ((paclPolicy == null) || !paclPolicy.isActive()) {
108                            return;
109                    }
110    
111                    _activeCount--;
112    
113                    if (_activeCount == 0) {
114                            if (_log.isInfoEnabled()) {
115                                    _log.info("Disabling PACL policy manager");
116                            }
117    
118                            _resetPortalSecurityManager();
119    
120                            ServiceBeanAopCacheManagerUtil.reset();
121                    }
122            }
123    
124            private static void _overridePortalSecurityManager() {
125                    _originalSecurityManager = System.getSecurityManager();
126    
127                    if (_originalSecurityManager instanceof PortalSecurityManager) {
128                            return;
129                    }
130    
131                    if (!SecurityManagerUtil.isSmart()) {
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                            SecurityManager securityManager =
154                                    (SecurityManager)SecurityManagerUtil.getPortalSecurityManager();
155    
156                            System.setSecurityManager(securityManager);
157                    }
158                    catch (SecurityException se) {
159                            _log.error(
160                                    "Unable to override the current security manager. Plugin " +
161                                            "security management is not enabled.");
162    
163                            throw se;
164                    }
165            }
166    
167            private static void _resetPortalSecurityManager() {
168                    if (_originalSecurityManager instanceof PortalSecurityManager) {
169                            return;
170                    }
171    
172                    if (!SecurityManagerUtil.isSmart()) {
173                            return;
174                    }
175    
176                    try {
177                            if (_log.isInfoEnabled()) {
178                                    _log.info("Resetting to the original security manager");
179                            }
180    
181                            System.setSecurityManager(_originalSecurityManager);
182                    }
183                    catch (SecurityException se) {
184                            _log.error("Unable to reset to the original security manager");
185    
186                            throw se;
187                    }
188            }
189    
190            private static Log _log = LogFactoryUtil.getLog(PACLPolicyManager.class);
191    
192            private static int _activeCount;
193            private static PACLPolicy _defaultPACLPolicy = new InactivePACLPolicy(
194                    StringPool.BLANK, PACLPolicyManager.class.getClassLoader(),
195                    new Properties());
196            private static SecurityManager _originalSecurityManager;
197            private static Map<ClassLoader, PACLPolicy> _paclPolicies =
198                    new HashMap<ClassLoader, PACLPolicy>();
199    
200            private static class PACLPolicyPrivilegedAction
201                    implements PrivilegedAction<PACLPolicy> {
202    
203                    public PACLPolicyPrivilegedAction(ClassLoader classLoader) {
204                            _classLoader = classLoader;
205                    }
206    
207                    public PACLPolicy run() {
208                            PACLPolicy paclPolicy = _paclPolicies.get(_classLoader);
209    
210                            while ((paclPolicy == null) && (_classLoader.getParent() != null)) {
211                                    _classLoader = _classLoader.getParent();
212    
213                                    paclPolicy = _paclPolicies.get(_classLoader);
214                            }
215    
216                            return paclPolicy;
217                    }
218    
219                    private ClassLoader _classLoader;
220    
221            }
222    
223    }