001
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.FileUtil;
020 import com.liferay.portal.kernel.util.StringBundler;
021 import com.liferay.portal.kernel.util.StringPool;
022 import com.liferay.portal.security.pacl.checker.AuthorizationProperty;
023 import com.liferay.portal.security.pacl.checker.Checker;
024 import com.liferay.portal.security.pacl.checker.JNDIChecker;
025 import com.liferay.portal.security.pacl.checker.SQLChecker;
026 import com.liferay.portal.util.PropsValues;
027
028 import java.io.IOException;
029
030 import java.security.AccessController;
031 import java.security.Permission;
032 import java.security.PrivilegedAction;
033
034 import java.util.Enumeration;
035 import java.util.Map;
036 import java.util.Properties;
037 import java.util.Set;
038 import java.util.concurrent.ConcurrentSkipListMap;
039 import java.util.concurrent.locks.ReentrantLock;
040
041
044 public class GeneratingPACLPolicy extends ActivePACLPolicy {
045
046 public GeneratingPACLPolicy(
047 String servletContextName, ClassLoader classLoader,
048 Properties properties) {
049
050 super(servletContextName, classLoader, properties);
051 }
052
053 @Override
054 public boolean hasJNDI(String name) {
055 JNDIChecker jndiChecker = getJndiChecker();
056
057 if (!jndiChecker.hasJNDI(name)) {
058 AuthorizationProperty authorizationProperty =
059 jndiChecker.generateAuthorizationProperty(name);
060
061 mergeAuthorizationProperty(authorizationProperty);
062 }
063
064 return true;
065 }
066
067 @Override
068 public boolean hasSQL(String sql) {
069 SQLChecker sqlChecker = getSqlChecker();
070
071 if (!sqlChecker.hasSQL(sql)) {
072 AuthorizationProperty authorizationProperty =
073 sqlChecker.generateAuthorizationProperty(sql);
074
075 mergeAuthorizationProperty(authorizationProperty);
076 }
077
078 return true;
079 }
080
081 @Override
082 public boolean implies(Permission permission) {
083 Checker checker = getChecker(permission.getClass());
084
085 if (checker.implies(permission)) {
086 return true;
087 }
088
089 try {
090 AuthorizationProperty authorizationProperty =
091 checker.generateAuthorizationProperty(permission);
092
093 mergeAuthorizationProperty(authorizationProperty);
094 }
095 catch (Exception e) {
096 return false;
097 }
098
099 return true;
100 }
101
102 protected void mergeAuthorizationProperty(
103 AuthorizationProperty authorizationProperty) {
104
105 if (authorizationProperty == null) {
106 return;
107 }
108
109 AccessController.doPrivileged(
110 new AuthorizationPropertyPrivilegedAction(authorizationProperty));
111 }
112
113 protected void mergeExistingProperties() {
114
115
116
117
118
119 Properties properties = getProperties();
120
121 Enumeration<Object> enumeration = properties.keys();
122
123 while (enumeration.hasMoreElements()) {
124 String key = (String)enumeration.nextElement();
125
126 if (_properties.containsKey(key) ||
127 !key.startsWith("security-manager-") ||
128 key.equals("security-manager-enabled")) {
129
130 continue;
131 }
132
133 _properties.put(key, getPropertySet(key));
134 }
135 }
136
137 protected void writePACLPolicyFile() {
138 try {
139 StringBundler sb = new StringBundler();
140
141 for (Map.Entry<String, Set<String>> entry :
142 _properties.entrySet()) {
143
144 String key = entry.getKey();
145
146 sb.append(key);
147 sb.append(StringPool.EQUAL);
148
149 Set<String> values = entry.getValue();
150
151 for (String value : values) {
152 sb.append(StringPool.BACK_SLASH);
153 sb.append(StringPool.NEW_LINE);
154 sb.append(StringPool.FOUR_SPACES);
155 sb.append(value);
156 sb.append(StringPool.COMMA);
157 }
158
159 sb.setIndex(sb.index() - 1);
160
161 sb.append(StringPool.NEW_LINE + StringPool.NEW_LINE);
162 }
163
164 if (sb.length() > 0) {
165 sb.setIndex(sb.index() - 1);
166 }
167
168 FileUtil.write(
169 PropsValues.LIFERAY_HOME + "/pacl-policy",
170 getServletContextName() + ".pacl-policy", sb.toString());
171 }
172 catch (IOException ioe) {
173 _log.error(ioe, ioe);
174 }
175 }
176
177 private static Log _log = LogFactoryUtil.getLog(GeneratingPACLPolicy.class);
178
179 private Map<String, Set<String>> _properties =
180 new ConcurrentSkipListMap<String, Set<String>>();
181 private ReentrantLock _reentrantLock = new ReentrantLock();
182
183 private class AuthorizationPropertyPrivilegedAction
184 implements PrivilegedAction<Void> {
185
186 public AuthorizationPropertyPrivilegedAction(
187 AuthorizationProperty authorizationProperty) {
188
189 _authorizationProperty = authorizationProperty;
190 }
191
192 public Void run() {
193 String key = _authorizationProperty.getKey();
194
195 Set<String> values = _properties.get(key);
196
197 boolean modified = false;
198
199 if (values == null) {
200 values = getPropertySet(key);
201
202 modified = true;
203 }
204
205 for (String value : _authorizationProperty.getValues()) {
206 if (!values.contains(value)) {
207 values.add(value);
208
209 modified = true;
210 }
211 }
212
213 if (!modified) {
214 return null;
215 }
216
217 _reentrantLock.lock();
218
219 try {
220 if (_log.isDebugEnabled()) {
221 _log.debug(
222 getServletContextName() +
223 " generated authorization property " +
224 _authorizationProperty);
225 }
226
227 _properties.put(key, values);
228
229 mergeExistingProperties();
230
231 writePACLPolicyFile();
232 }
233 finally {
234 _reentrantLock.unlock();
235 }
236
237 return null;
238 }
239
240 private AuthorizationProperty _authorizationProperty;
241
242 }
243
244 }