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