001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.geronimo.security.jacc;
019
020 import java.security.Permission;
021 import java.security.PermissionCollection;
022 import java.security.Permissions;
023 import java.security.Principal;
024 import java.security.ProtectionDomain;
025 import java.util.Enumeration;
026 import java.util.HashMap;
027 import java.util.HashSet;
028 import java.util.Iterator;
029 import java.util.Map;
030
031 import javax.security.jacc.PolicyContextException;
032
033
034 /**
035 * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
036 */
037 public class PolicyConfigurationGeneric implements GeronimoPolicyConfiguration {
038 final static int OPEN = 1;
039 final static int IN_SERVICE = 2;
040 final static int DELETED = 3;
041
042 private final String contextID;
043 private int state;
044 private final HashMap rolePermissionsMap = new HashMap();
045 private final HashMap principalRoleMapping = new HashMap();
046 private Permissions unchecked = null;
047 private Permissions excluded = null;
048
049 private final HashMap principalPermissionsMap = new HashMap();
050
051 PolicyConfigurationGeneric(String contextID) {
052 this.contextID = contextID;
053 this.state = OPEN;
054 }
055
056 public String getContextID() throws PolicyContextException {
057 return contextID;
058 }
059
060 public boolean implies(ProtectionDomain domain, Permission permission) {
061
062 if (excluded != null && excluded.implies(permission)) return false;
063
064 if (unchecked != null && unchecked.implies(permission)) return true;
065
066 Principal[] principals = domain.getPrincipals();
067 if (principals.length == 0) return false;
068
069 for (int i = 0; i < principals.length; i++) {
070 Principal principal = principals[i];
071
072 Permissions permissions = (Permissions) principalPermissionsMap.get(principal);
073
074 if (permissions != null && permissions.implies(permission)) return true;
075 }
076
077 return false;
078 }
079
080 public void setPrincipalRoleMapping(Map principalRoleMap) throws PolicyContextException {
081 principalRoleMapping.clear();
082 principalRoleMapping.putAll(principalRoleMap);
083 }
084
085 public void addToRole(String roleName, PermissionCollection permissions) throws PolicyContextException {
086 if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
087
088 Enumeration e = permissions.elements();
089 while (e.hasMoreElements()) {
090 addToRole(roleName, (Permission) e.nextElement());
091 }
092 }
093
094 public void addToRole(String roleName, Permission permission) throws PolicyContextException {
095 if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
096
097 Permissions permissions = (Permissions) rolePermissionsMap.get(roleName);
098 if (permissions == null) {
099 permissions = new Permissions();
100 rolePermissionsMap.put(roleName, permissions);
101 }
102 permissions.add(permission);
103 }
104
105 public void addToUncheckedPolicy(PermissionCollection permissions) throws PolicyContextException {
106 if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
107
108 Enumeration e = permissions.elements();
109 while (e.hasMoreElements()) {
110 addToUncheckedPolicy((Permission) e.nextElement());
111 }
112 }
113
114 public void addToUncheckedPolicy(Permission permission) throws PolicyContextException {
115 if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
116
117 if (unchecked == null) unchecked = new Permissions();
118
119 unchecked.add(permission);
120 }
121
122 public void addToExcludedPolicy(PermissionCollection permissions) throws PolicyContextException {
123 if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
124
125 Enumeration e = permissions.elements();
126 while (e.hasMoreElements()) {
127 addToExcludedPolicy((Permission) e.nextElement());
128 }
129 }
130
131 public void addToExcludedPolicy(Permission permission) throws PolicyContextException {
132 if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
133
134 if (excluded == null) excluded = new Permissions();
135
136 excluded.add(permission);
137 }
138
139 public void removeRole(String roleName) throws PolicyContextException {
140 if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
141
142 rolePermissionsMap.remove(roleName);
143 }
144
145 public void removeUncheckedPolicy() throws PolicyContextException {
146 if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
147
148 unchecked = null;
149 }
150
151 public void removeExcludedPolicy() throws PolicyContextException {
152 if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
153
154 excluded = null;
155 }
156
157 public void linkConfiguration(javax.security.jacc.PolicyConfiguration link) throws PolicyContextException {
158 if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
159 }
160
161 public void delete() throws PolicyContextException {
162 state = DELETED;
163 }
164
165 public void commit() throws PolicyContextException {
166 if (state != OPEN) throw new UnsupportedOperationException("Not in an open state");
167
168 for (Iterator principalEntries = principalRoleMapping.entrySet().iterator(); principalEntries.hasNext(); ) {
169 Map.Entry principalEntry = (Map.Entry) principalEntries.next();
170 Principal principal = (Principal) principalEntry.getKey();
171 Permissions principalPermissions = (Permissions) principalPermissionsMap.get(principal);
172
173 if (principalPermissions == null) {
174 principalPermissions = new Permissions();
175 principalPermissionsMap.put(principal, principalPermissions);
176 }
177
178 HashSet roleSet = (HashSet) principalEntry.getValue();
179 for (Iterator roles = roleSet.iterator(); roles.hasNext(); ) {
180 Permissions permissions = (Permissions) rolePermissionsMap.get(roles.next());
181 if (permissions == null) continue;
182 for (Enumeration rolePermissions = permissions.elements(); rolePermissions.hasMoreElements(); ) {
183 principalPermissions.add((Permission) rolePermissions.nextElement());
184 }
185 }
186
187 }
188 state = IN_SERVICE;
189 }
190
191 public boolean inService() throws PolicyContextException {
192 return (state == IN_SERVICE);
193 }
194
195 //TODO I have no idea what side effects this might have, but it's needed in some form from GeronimoPolicyConfigurationFactory.
196 //see JACC spec 1.0 section 3.1.1.1 discussion of in service and deleted.
197 //spec p. 31 3.1.7 on the effects of remove:
198 //If the getPolicyConfiguration method is used, the value true should be passed as the second
199 // argument to cause the corresponding policy statements to be deleted from the context.
200 public void open(boolean remove) {
201 if (remove) {
202 rolePermissionsMap.clear();
203 principalRoleMapping.clear();
204 unchecked = null;
205 excluded = null;
206 principalPermissionsMap.clear();
207 }
208 state = OPEN;
209 }
210
211 int getState() {
212 return state;
213 }
214 }