1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.acegisecurity.acls.domain;
16
17 import org.acegisecurity.acls.AccessControlEntry;
18 import org.acegisecurity.acls.Acl;
19 import org.acegisecurity.acls.AuditableAcl;
20 import org.acegisecurity.acls.MutableAcl;
21 import org.acegisecurity.acls.NotFoundException;
22 import org.acegisecurity.acls.OwnershipAcl;
23 import org.acegisecurity.acls.Permission;
24 import org.acegisecurity.acls.UnloadedSidException;
25 import org.acegisecurity.acls.objectidentity.ObjectIdentity;
26 import org.acegisecurity.acls.sid.Sid;
27
28 import org.springframework.util.Assert;
29
30 import java.io.Serializable;
31
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.Vector;
35
36
37
38
39
40
41
42
43 public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
44
45
46 private Acl parentAcl;
47 private AclAuthorizationStrategy aclAuthorizationStrategy;
48 private AuditLogger auditLogger;
49 private List aces = new Vector();
50 private ObjectIdentity objectIdentity;
51 private Serializable id;
52 private Sid owner;
53 private Sid[] loadedSids = null;
54 private boolean entriesInheriting = true;
55
56
57
58
59
60
61
62
63
64
65
66
67 public AclImpl(ObjectIdentity objectIdentity, Serializable id, AclAuthorizationStrategy aclAuthorizationStrategy,
68 AuditLogger auditLogger) {
69 Assert.notNull(objectIdentity, "Object Identity required");
70 Assert.notNull(id, "Id required");
71 Assert.notNull(aclAuthorizationStrategy, "AclAuthorizationStrategy required");
72 Assert.notNull(auditLogger, "AuditLogger required");
73 this.objectIdentity = objectIdentity;
74 this.id = id;
75 this.aclAuthorizationStrategy = aclAuthorizationStrategy;
76 this.auditLogger = auditLogger;
77 }
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94 public AclImpl(ObjectIdentity objectIdentity, Serializable id, AclAuthorizationStrategy aclAuthorizationStrategy,
95 AuditLogger auditLogger, Acl parentAcl, Sid[] loadedSids, boolean entriesInheriting, Sid owner) {
96 Assert.notNull(objectIdentity, "Object Identity required");
97 Assert.notNull(id, "Id required");
98 Assert.notNull(aclAuthorizationStrategy, "AclAuthorizationStrategy required");
99 Assert.notNull(owner, "Owner required");
100 Assert.notNull(auditLogger, "AuditLogger required");
101 this.objectIdentity = objectIdentity;
102 this.id = id;
103 this.aclAuthorizationStrategy = aclAuthorizationStrategy;
104 this.auditLogger = auditLogger;
105 this.parentAcl = parentAcl;
106 this.loadedSids = loadedSids;
107 this.entriesInheriting = entriesInheriting;
108 this.owner = owner;
109 }
110
111
112
113
114
115 private AclImpl() {}
116
117
118
119 public void deleteAce(Serializable aceId) throws NotFoundException {
120 aclAuthorizationStrategy.securityCheck(this, AclAuthorizationStrategy.CHANGE_GENERAL);
121
122 synchronized (aces) {
123 int offset = findAceOffset(aceId);
124
125 if (offset == -1) {
126 throw new NotFoundException("Requested ACE ID not found");
127 }
128
129 this.aces.remove(offset);
130 }
131 }
132
133 private int findAceOffset(Serializable aceId) {
134 Assert.notNull(aceId, "ACE ID is required");
135
136 synchronized (aces) {
137 for (int i = 0; i < aces.size(); i++) {
138 AccessControlEntry ace = (AccessControlEntry) aces.get(i);
139
140 if (ace.getId().equals(aceId)) {
141 return i;
142 }
143 }
144 }
145
146 return -1;
147 }
148
149 public AccessControlEntry[] getEntries() {
150
151 return (AccessControlEntry[]) aces.toArray(new AccessControlEntry[] {});
152 }
153
154 public Serializable getId() {
155 return this.id;
156 }
157
158 public ObjectIdentity getObjectIdentity() {
159 return objectIdentity;
160 }
161
162 public Sid getOwner() {
163 return this.owner;
164 }
165
166 public Acl getParentAcl() {
167 return parentAcl;
168 }
169
170 public void insertAce(Serializable afterAceId, Permission permission, Sid sid, boolean granting)
171 throws NotFoundException {
172 aclAuthorizationStrategy.securityCheck(this, AclAuthorizationStrategy.CHANGE_GENERAL);
173 Assert.notNull(permission, "Permission required");
174 Assert.notNull(sid, "Sid required");
175
176 AccessControlEntryImpl ace = new AccessControlEntryImpl(null, this, sid, permission, granting, false, false);
177
178 synchronized (aces) {
179 if (afterAceId != null) {
180 int offset = findAceOffset(afterAceId);
181
182 if (offset == -1) {
183 throw new NotFoundException("Requested ACE ID not found");
184 }
185
186 this.aces.add(offset + 1, ace);
187 } else {
188 this.aces.add(ace);
189 }
190 }
191 }
192
193 public boolean isEntriesInheriting() {
194 return entriesInheriting;
195 }
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228 public boolean isGranted(Permission[] permission, Sid[] sids, boolean administrativeMode)
229 throws NotFoundException, UnloadedSidException {
230 Assert.notEmpty(permission, "Permissions required");
231 Assert.notEmpty(sids, "SIDs required");
232
233 if (!this.isSidLoaded(sids)) {
234 throw new UnloadedSidException("ACL was not loaded for one or more SID");
235 }
236
237 AccessControlEntry firstRejection = null;
238
239 for (int i = 0; i < permission.length; i++) {
240 for (int x = 0; x < sids.length; x++) {
241
242 Iterator acesIterator = aces.iterator();
243 boolean scanNextSid = true;
244
245 while (acesIterator.hasNext()) {
246 AccessControlEntry ace = (AccessControlEntry) acesIterator.next();
247
248 if ((ace.getPermission().getMask() == permission[i].getMask()) && ace.getSid().equals(sids[x])) {
249
250 if (ace.isGranting()) {
251
252 if (!administrativeMode) {
253 auditLogger.logIfNeeded(true, ace);
254 }
255
256 return true;
257 } else {
258
259
260
261 if (firstRejection == null) {
262
263 firstRejection = ace;
264 }
265
266 scanNextSid = false;
267
268 break;
269 }
270 }
271 }
272
273 if (!scanNextSid) {
274 break;
275 }
276 }
277 }
278
279 if (firstRejection != null) {
280
281
282 if (!administrativeMode) {
283 auditLogger.logIfNeeded(false, firstRejection);
284 }
285
286 return false;
287 }
288
289
290 if (isEntriesInheriting() && (parentAcl != null)) {
291
292 return parentAcl.isGranted(permission, sids, false);
293 } else {
294
295 throw new NotFoundException("Unable to locate a matching ACE for passed permissions and SIDs");
296 }
297 }
298
299 public boolean isSidLoaded(Sid[] sids) {
300
301
302 if ((this.loadedSids == null) || (sids == null) || (sids.length == 0)) {
303 return true;
304 }
305
306
307 for (int i = 0; i < sids.length; i++) {
308 boolean found = false;
309
310 for (int y = 0; y < this.loadedSids.length; y++) {
311 if (sids[i].equals(this.loadedSids[y])) {
312
313 found = true;
314
315 break;
316 }
317 }
318
319 if (!found) {
320 return false;
321 }
322 }
323
324 return true;
325 }
326
327 public void setEntriesInheriting(boolean entriesInheriting) {
328 aclAuthorizationStrategy.securityCheck(this, AclAuthorizationStrategy.CHANGE_GENERAL);
329 this.entriesInheriting = entriesInheriting;
330 }
331
332 public void setOwner(Sid newOwner) {
333 aclAuthorizationStrategy.securityCheck(this, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
334 Assert.notNull(newOwner, "Owner required");
335 this.owner = newOwner;
336 }
337
338 public void setParent(Acl newParent) {
339 aclAuthorizationStrategy.securityCheck(this, AclAuthorizationStrategy.CHANGE_GENERAL);
340 Assert.notNull(newParent, "New Parent required");
341 Assert.isTrue(!newParent.equals(this), "Cannot be the parent of yourself");
342 this.parentAcl = newParent;
343 }
344
345 public String toString() {
346 StringBuffer sb = new StringBuffer();
347 sb.append("AclImpl[");
348 sb.append("id: ").append(this.id).append("; ");
349 sb.append("objectIdentity: ").append(this.objectIdentity).append("; ");
350 sb.append("owner: ").append(this.owner).append("; ");
351
352 Iterator iterator = this.aces.iterator();
353 int count = 0;
354
355 while (iterator.hasNext()) {
356 count++;
357
358 if (count == 1) {
359 sb.append("\r\n");
360 }
361
362 sb.append(iterator.next().toString()).append("\r\n");
363 }
364
365 if (count == 0) {
366 sb.append("no ACEs; ");
367 }
368
369 sb.append("inheriting: ").append(this.entriesInheriting).append("; ");
370 sb.append("parent: ").append((this.parentAcl == null) ? "Null" : this.parentAcl.getObjectIdentity().toString());
371 sb.append("]");
372
373 return sb.toString();
374 }
375
376 public void updateAce(Serializable aceId, Permission permission)
377 throws NotFoundException {
378 aclAuthorizationStrategy.securityCheck(this, AclAuthorizationStrategy.CHANGE_GENERAL);
379
380 synchronized (aces) {
381 int offset = findAceOffset(aceId);
382
383 if (offset == 1) {
384 throw new NotFoundException("Requested ACE ID not found");
385 }
386
387 AccessControlEntryImpl ace = (AccessControlEntryImpl) aces.get(offset);
388 ace.setPermission(permission);
389 }
390 }
391
392 public void updateAuditing(Serializable aceId, boolean auditSuccess, boolean auditFailure) {
393 aclAuthorizationStrategy.securityCheck(this, AclAuthorizationStrategy.CHANGE_AUDITING);
394
395 synchronized (aces) {
396 int offset = findAceOffset(aceId);
397
398 if (offset == 1) {
399 throw new NotFoundException("Requested ACE ID not found");
400 }
401
402 AccessControlEntryImpl ace = (AccessControlEntryImpl) aces.get(offset);
403 ace.setAuditSuccess(auditSuccess);
404 ace.setAuditFailure(auditFailure);
405 }
406 }
407 }