001 /*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License"). You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at
010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 * Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 * Copyright 2008 Sun Microsystems, Inc.
026 */
027
028 package org.opends.server.authorization.dseecompat;
029
030 import org.opends.server.types.*;
031 import org.opends.server.api.ClientConnection;
032 import org.opends.server.api.Group;
033 import org.opends.server.core.AddOperationBasis;
034 import org.opends.server.api.ConnectionSecurityProvider;
035 import org.opends.server.core.SearchOperation;
036 import org.opends.server.extensions.TLSConnectionSecurityProvider;
037 import org.opends.server.types.Operation;
038 import java.net.InetAddress;
039 import java.util.LinkedList;
040 import java.util.List;
041 import java.util.HashMap;
042
043 import static org.opends.server.authorization.dseecompat.Aci.*;
044 import static org.opends.server.authorization.dseecompat.AciHandler.*;
045 import org.opends.server.controls.GetEffectiveRights;
046 import static org.opends.server.util.ServerConstants.OID_GET_EFFECTIVE_RIGHTS;
047
048 /**
049 * The AciContainer class contains all of the needed information to perform
050 * both target match and evaluate an ACI. Target matching is the process
051 * of testing if an ACI is applicable to an operation, and evaluation is
052 * the actual access evaluation of the ACI.
053 */
054 public abstract class AciContainer
055 implements AciTargetMatchContext, AciEvalContext {
056
057 /*
058 * The allow and deny lists.
059 */
060 private LinkedList<Aci> denyList, allowList;
061
062 /*
063 * The attribute type in the resource entry currently being evaluated.
064 */
065 private AttributeType attributeType;
066
067 /*
068 * The attribute type value in the resource entry currently being
069 * evaluated.
070 */
071 private AttributeValue attributeValue;
072
073 /*
074 * True if this is the first attribute type in the resource entry being
075 * evaluated.
076 */
077 private boolean isFirst = false;
078
079 /*
080 * True if an entry test rule was seen during target matching of an ACI
081 * entry. A entry test rule is an ACI with targetattrs target keyword.
082 */
083 private boolean isEntryTestRule = false;
084
085 /*
086 * True if the evaluation of an ACI is from the deny list.
087 */
088 private boolean isDenyEval;
089
090 /*
091 * True if the evaluation is a result of an LDAP add operation.
092 */
093 private boolean isAddOp=false;
094
095 /*
096 * The rights to use in the evaluation of the LDAP operation.
097 */
098 private int rights;
099
100 /*
101 * The entry being evaluated (resource entry).
102 */
103 private Entry resourceEntry;
104
105 /*
106 * Saves the resource entry. Used in geteffectiverights evaluation to
107 * restore the current resource entry state after a read right was
108 * evaluated.
109 */
110 private final Entry saveResourceEntry;
111
112 /*
113 * The client connection information.
114 */
115 private final ClientConnection clientConnection;
116
117 /*
118 * The operation being evaluated.
119 */
120 private final Operation operation;
121
122 /*
123 * True if a targattrfilters match was found.
124 */
125 private boolean targAttrFiltersMatch=false;
126
127 /*
128 * The authorization entry currently being evaluated. If proxied
129 * authorization is being used and the handler is doing a proxy access
130 * check, then this entry will switched to the original authorization entry
131 * rather than the proxy ID entry. If the check succeeds, it will be
132 * switched back for non-proxy access checking. If proxied authentication
133 * is not being used then this entry never changes.
134 */
135 private Entry authorizationEntry;
136
137 /*
138 * Used to save the current authorization entry when the authorization
139 * entry is switched during a proxy access check.
140 */
141 private final Entry saveAuthorizationEntry;
142
143 /*
144 * This entry is only used if proxied authorization is being used. It is
145 * the original authorization entry before the proxied authorization change.
146 */
147 private Entry origAuthorizationEntry=null;
148
149 /*
150 * True if proxied authorization is being used.
151 */
152 private boolean proxiedAuthorization=false;
153
154 /*
155 * Used by proxied authorization processing. True if the entry has already
156 * been processed by an access proxy check. Some operations might perform
157 * several access checks on the same entry (modify DN), this
158 * flag is used to bypass the proxy check after the initial evaluation.
159 */
160 private boolean seenEntry=false;
161
162 /*
163 * True if geteffectiverights evaluation is in progress.
164 */
165 private boolean isGetEffectiveRightsEval=false;
166
167 /*
168 * True if the operation has a geteffectiverights control.
169 */
170 private boolean hasGetEffectiveRightsControl=false;
171
172 /*
173 * The geteffectiverights authzID in DN format.
174 */
175 private DN authzid=null;
176
177 /*
178 * True if the authZid should be used as the client DN, only used in
179 * geteffectiverights evaluation.
180 */
181 private boolean useAuthzid=false;
182
183 /*
184 * The list of specific attributes to get rights for, in addition to
185 * any attributes requested in the search.
186 */
187 private List<AttributeType> specificAttrs=null;
188
189 /*
190 * The entry with all of its attributes available. Used in
191 * geteffectiverights read entry level evaluation.
192 */
193 private Entry fullEntry=null;
194
195 /*
196 * Table of ACIs that have targattrfilter keywords that matched. Used
197 * in geteffectiverights attributeLevel write evaluation.
198 */
199 private final HashMap<Aci,Aci> targAttrFilterAcis=new HashMap<Aci, Aci>();
200
201 /*
202 * The name of a ACI that decided an evaluation and contained a
203 * targattrfilter keyword. Used in geteffectiverights attributeLevel
204 * write evaluation.
205 */
206 private String targAttrFiltersAciName=null;
207
208 /*
209 * Value that is used to store the allow/deny result of a deciding ACI
210 * containing a targattrfilter keyword. Used in geteffectiverights
211 * attributeLevel write evaluation.
212 */
213 private int targAttrMatch=0;
214
215 /*
216 * The ACI that decided the last evaluation. Used in geteffectiverights
217 * loginfo processing.
218 */
219 private Aci decidingAci=null;
220
221 /*
222 * The reason the last evaluation decision was made. Used both
223 * in geteffectiverights loginfo processing and attributeLevel write
224 * evaluation.
225 */
226 private EnumEvalReason evalReason=null;
227
228 /*
229 * A summary string holding the last evaluation information in textual
230 * format. Used in geteffectiverights loginfo processing.
231 */
232 private String summaryString=null;
233
234 /*
235 * Flag used to determine if ACI all attributes target matched.
236 */
237 private int evalAllAttributes=0;
238
239 /*
240 * String used to hold a control OID string.
241 */
242 private String controlOID;
243
244 /*
245 * String used to hold an extended operation OID string.
246 */
247 private String extOpOID;
248
249 /**
250 * This constructor is used by all currently supported LDAP operations.
251 *
252 * @param operation The Operation object being evaluated and target
253 * matching.
254 *
255 * @param rights The rights array to use in evaluation and target matching.
256 *
257 * @param entry The current entry being evaluated and target matched.
258 */
259 protected AciContainer(Operation operation, int rights, Entry entry) {
260 this.resourceEntry=entry;
261 this.operation=operation;
262 this.clientConnection=operation.getClientConnection();
263 if(operation instanceof AddOperationBasis)
264 this.isAddOp=true;
265
266 //If the proxied authorization control was processed, then the operation
267 //will contain an attachment containing the original authorization entry.
268 this.origAuthorizationEntry =
269 (Entry) operation.getAttachment(ORIG_AUTH_ENTRY);
270 if(origAuthorizationEntry != null)
271 this.proxiedAuthorization=true;
272 this.authorizationEntry=operation.getAuthorizationEntry();
273 //The ACI_READ right at constructor time can only be the result of the
274 //AciHandler.filterEntry method. This method processes the
275 //geteffectiverights control, so it needs to check for it. There are
276 //two other checks done, because the resource entry passed to that method
277 //is filtered (it may not contain enough attribute information
278 //to evaluate correctly). See the the comments below.
279 if(operation instanceof SearchOperation && (rights == ACI_READ)) {
280 //Checks if a geteffectiverights control was sent and
281 //sets up the structures needed.
282 GetEffectiveRights getEffectiveRightsControl =
283 (GetEffectiveRights)
284 operation.getAttachment(OID_GET_EFFECTIVE_RIGHTS);
285 if(getEffectiveRightsControl != null) {
286 hasGetEffectiveRightsControl=true;
287 if(getEffectiveRightsControl.getAuthzDN() == null)
288 this.authzid=getClientDN();
289 else
290 this.authzid=getEffectiveRightsControl.getAuthzDN();
291 this.specificAttrs=getEffectiveRightsControl.getAttributes();
292 }
293 //If an ACI evaluated because of an Targetattr="*", then the
294 //AciHandler.maySend method signaled this via adding this attachment
295 //string.
296 String allUserAttrs=
297 (String)operation.getAttachment(ALL_USER_ATTRS_MATCHED);
298 if(allUserAttrs != null)
299 evalAllAttributes |= ACI_USER_ATTR_STAR_MATCHED;
300 //If an ACI evaluated because of an Targetattr="+", then the
301 //AciHandler.maySend method signaled this via adding this attachment
302 //string.
303 String allOpAttrs=(String)operation.getAttachment(ALL_OP_ATTRS_MATCHED);
304 if(allOpAttrs != null)
305 evalAllAttributes |= ACI_OP_ATTR_PLUS_MATCHED;
306
307 //The AciHandler.maySend method also adds the full attribute version of
308 //the resource entry in this attachment.
309 fullEntry=(Entry)operation.getAttachment(ALL_ATTRS_RESOURCE_ENTRY);
310 } else
311 fullEntry=this.resourceEntry;
312 //Reference the current authorization entry, so it can be put back
313 //if an access proxy check was performed.
314 this.saveAuthorizationEntry=this.authorizationEntry;
315 this.saveResourceEntry=this.resourceEntry;
316 this.rights = rights;
317 }
318
319 /**
320 * Returns true if an entry has already been processed by an access proxy
321 * check.
322 *
323 * @return True if an entry has already been processed by an access proxy
324 * check.
325 */
326 public boolean hasSeenEntry() {
327 return this.seenEntry;
328 }
329
330 /**
331 * Set to true if an entry has already been processsed by an access proxy
332 * check.
333 *
334 * @param val The value to set the seenEntry boolean to.
335 */
336 public void setSeenEntry(boolean val) {
337 this.seenEntry=val;
338 }
339
340 /**
341 * {@inheritDoc}
342 */
343 public boolean isProxiedAuthorization() {
344 return this.proxiedAuthorization;
345 }
346
347 /**
348 * {@inheritDoc}
349 */
350 public boolean isGetEffectiveRightsEval() {
351 return this.isGetEffectiveRightsEval;
352 }
353
354 /**
355 * The container is going to be used in a geteffectiverights evaluation, set
356 * the flag isGetEffectiveRightsEval to true.
357 */
358 public void setGetEffectiveRightsEval() {
359 this.isGetEffectiveRightsEval=true;
360 }
361
362 /**
363 * Return true if the container is being used in a geteffectiverights
364 * evaluation.
365 *
366 * @return True if the container is being used in a geteffectiverights
367 * evaluation.
368 */
369 public boolean hasGetEffectiveRightsControl() {
370 return this.hasGetEffectiveRightsControl;
371 }
372
373 /**
374 * Use the DN from the geteffectiverights control's authzId as the
375 * client DN, rather than the authorization entry's DN.
376 *
377 * @param v The valued to set the useAuthzid to.
378 */
379 public void useAuthzid(boolean v) {
380 this.useAuthzid=v;
381 }
382
383 /**
384 * Return the list of additional attributes specified in the
385 * geteffectiveritghts control.
386 *
387 * @return The list of attributes to return rights information about in the
388 * entry.
389 */
390 public List<AttributeType> getSpecificAttributes() {
391 return this.specificAttrs;
392 }
393
394 /**
395 * During the geteffectiverights entrylevel read evaluation, an entry with all
396 * of the attributes used in the AciHandler's maysend method evaluation is
397 * needed to perform the evaluation over again. This entry was saved
398 * in the operation's attachment mechanism when the container was created
399 * during the SearchOperation read evaluation.
400 *
401 * This method is used to replace the current resource entry with that saved
402 * entry to perform the entrylevel read evaluation described above and to
403 * switch back to the current resource entry when needed.
404 *
405 * @param val Specifies if the saved entry should be used or not. True if it
406 * should be used, false if the original resource entry should be used.
407 *
408 */
409 public void useFullResourceEntry(boolean val) {
410 if(val)
411 resourceEntry=fullEntry;
412 else
413 resourceEntry=saveResourceEntry;
414 }
415
416 /**
417 * {@inheritDoc}
418 */
419 public void addTargAttrFiltersMatchAci(Aci aci) {
420 this.targAttrFilterAcis.put(aci, aci);
421 }
422
423 /**
424 * {@inheritDoc}
425 */
426 public boolean hasTargAttrFiltersMatchAci(Aci aci) {
427 return this.targAttrFilterAcis.containsKey(aci);
428 }
429
430 /**
431 * {@inheritDoc}
432 */
433 public boolean isTargAttrFilterMatchAciEmpty() {
434 return this.targAttrFilterAcis.isEmpty();
435 }
436
437 /**
438 * Reset the values used by the geteffectiverights evaluation to
439 * original values. The geteffectiverights evaluation uses the same container
440 * repeatedly for different rights evaluations (read, write, proxy,...) and
441 * this method resets variables that are specific to a single evaluation.
442 */
443 public void resetEffectiveRightsParams() {
444 this.targAttrFilterAcis.clear();
445 this.decidingAci=null;
446 this.evalReason=null;
447 this.targAttrFiltersMatch=false;
448 this.summaryString=null;
449 this.targAttrMatch=0;
450 }
451
452 /**
453 * {@inheritDoc}
454 */
455 public void setTargAttrFiltersAciName(String name) {
456 this.targAttrFiltersAciName=name;
457 }
458
459 /**
460 * {@inheritDoc}
461 */
462 public String getTargAttrFiltersAciName() {
463 return this.targAttrFiltersAciName;
464 }
465
466 /**
467 * {@inheritDoc}
468 */
469 public void setTargAttrFiltersMatchOp(int flag) {
470 this.targAttrMatch |= flag;
471 }
472
473 /**
474 * {@inheritDoc}
475 */
476 public boolean hasTargAttrFiltersMatchOp(int flag) {
477 return (this.targAttrMatch & flag) != 0;
478 }
479
480 /**
481 * {@inheritDoc}
482 */
483 public void setDecidingAci(Aci aci) {
484 this.decidingAci=aci;
485 }
486
487 /**
488 * {@inheritDoc}
489 */
490 public String getDecidingAciName() {
491 if(this.decidingAci != null)
492 return this.decidingAci.getName();
493 else return null;
494 }
495
496 /**
497 * {@inheritDoc}
498 */
499 public void setEvalReason(EnumEvalReason reason) {
500 this.evalReason=reason;
501 }
502
503 /**
504 * {@inheritDoc}
505 */
506 public EnumEvalReason getEvalReason() {
507 return this.evalReason;
508 }
509
510 /**
511 * {@inheritDoc}
512 */
513 public void setEvalSummary(String summary) {
514 this.summaryString=summary;
515 }
516
517 /**
518 * {@inheritDoc}
519 */
520 public String getEvalSummary() {
521 return this.summaryString;
522 }
523
524 /**
525 * Returns true if the geteffectiverights control's authZid DN is equal to the
526 * authoritzation entry's DN.
527 *
528 * @return True if the authZid is equal to the authorization entry's DN.
529 */
530 public boolean isAuthzidAuthorizationDN() {
531 return this.authzid.equals(this.authorizationEntry.getDN());
532 }
533
534 /**
535 * If the specified value is true, then the original authorization entry,
536 * which is the entry before the switch performed by the proxied
537 * authorization control processing should be set to the current
538 * authorization entry. If the specified value is false then the proxied
539 * authorization entry is switched back using the saved copy.
540 * @param val The value used to select the authorization entry to use.
541 */
542 public void useOrigAuthorizationEntry(boolean val) {
543 if(val)
544 authorizationEntry=origAuthorizationEntry;
545 else
546 authorizationEntry=saveAuthorizationEntry;
547 }
548
549 /**
550 * {@inheritDoc}
551 */
552 public void setDenyList(LinkedList<Aci> denys) {
553 denyList=denys;
554 }
555
556 /**
557 * {@inheritDoc}
558 */
559 public void setAllowList(LinkedList<Aci> allows) {
560 allowList=allows;
561 }
562
563 /**
564 * {@inheritDoc}
565 */
566 public AttributeType getCurrentAttributeType() {
567 return attributeType;
568 }
569
570 /**
571 * {@inheritDoc}
572 */
573 public AttributeValue getCurrentAttributeValue() {
574 return attributeValue;
575 }
576
577 /**
578 * {@inheritDoc}
579 */
580 public void setCurrentAttributeType(AttributeType type) {
581 attributeType=type;
582 }
583
584 /**
585 * {@inheritDoc}
586 */
587 public void setCurrentAttributeValue(AttributeValue value) {
588 attributeValue=value;
589 }
590
591 /**
592 * {@inheritDoc}
593 */
594 public boolean isFirstAttribute() {
595 return isFirst;
596 }
597
598 /**
599 * {@inheritDoc}
600 */
601 public void setIsFirstAttribute(boolean val) {
602 isFirst=val;
603 }
604
605 /**
606 * {@inheritDoc}
607 */
608 public boolean hasEntryTestRule() {
609 return isEntryTestRule;
610 }
611
612 /**
613 * {@inheritDoc}
614 */
615 public void setEntryTestRule(boolean val) {
616 isEntryTestRule=val;
617 }
618
619 /**
620 * {@inheritDoc}
621 */
622 public Entry getResourceEntry() {
623 return resourceEntry;
624 }
625
626 /**
627 * {@inheritDoc}
628 */
629 public Entry getClientEntry() {
630 return this.authorizationEntry;
631 }
632
633 /**
634 * {@inheritDoc}
635 */
636 public LinkedList<Aci> getDenyList() {
637 return denyList;
638 }
639
640 /**
641 * {@inheritDoc}
642 */
643 public LinkedList<Aci> getAllowList() {
644 return allowList;
645 }
646
647 /**
648 * {@inheritDoc}
649 */
650 public boolean isDenyEval() {
651 return isDenyEval;
652 }
653
654 /**
655 * {@inheritDoc}
656 */
657 public boolean isAnonymousUser() {
658 return !clientConnection.getAuthenticationInfo().isAuthenticated();
659 }
660
661 /**
662 * {@inheritDoc}
663 */
664 public void setDenyEval(boolean val) {
665 isDenyEval = val;
666 }
667
668 /**
669 * {@inheritDoc}
670 */
671 public DN getClientDN() {
672 if(this.useAuthzid)
673 return this.authzid;
674 else
675 if (this.authorizationEntry == null)
676 return DN.nullDN();
677 else
678 return this.authorizationEntry.getDN();
679 }
680
681 /**
682 * {@inheritDoc}
683 */
684 public DN getResourceDN() {
685 return resourceEntry.getDN();
686 }
687
688 /**
689 * {@inheritDoc}
690 */
691 public boolean hasRights(int rights) {
692 return (this.rights & rights) != 0;
693 }
694
695 /**
696 * {@inheritDoc}
697 */
698 public int getRights() {
699 return this.rights;
700 }
701
702 /**
703 * {@inheritDoc}
704 */
705 public void setRights(int rights) {
706 this.rights=rights;
707 }
708
709 /**
710 * {@inheritDoc}
711 */
712 public String getHostName() {
713 return clientConnection.getRemoteAddress().getCanonicalHostName();
714 }
715
716 /**
717 * {@inheritDoc}
718 */
719 public InetAddress getRemoteAddress() {
720 return clientConnection.getRemoteAddress();
721 }
722
723 /**
724 * {@inheritDoc}
725 */
726 public boolean isAddOperation() {
727 return isAddOp;
728 }
729
730 /**
731 * {@inheritDoc}
732 */
733 public void setTargAttrFiltersMatch(boolean v) {
734 this.targAttrFiltersMatch=v;
735 }
736
737 /**
738 * {@inheritDoc}
739 */
740 public boolean getTargAttrFiltersMatch() {
741 return targAttrFiltersMatch;
742 }
743
744 /**
745 * {@inheritDoc}
746 */
747 public String getControlOID() {
748 return controlOID;
749 }
750
751 /**
752 * {@inheritDoc}
753 */
754 public String getExtOpOID() {
755 return extOpOID;
756 }
757
758 /**
759 * Set the the controlOID value to the specified oid string.
760 *
761 * @param oid The control oid string.
762 */
763 protected void setControlOID(String oid) {
764 this.controlOID=oid;
765 }
766
767
768 /**
769 * Set the extended operation OID value to the specified oid string.
770 *
771 * @param oid The extended operation oid string.
772 */
773 protected void setExtOpOID(String oid) {
774 this.extOpOID=oid;
775 }
776
777 /**
778 * {@inheritDoc}
779 */
780 public EnumEvalResult hasAuthenticationMethod(EnumAuthMethod authMethod,
781 String saslMech) {
782 EnumEvalResult matched=EnumEvalResult.FALSE;
783
784 if(authMethod==EnumAuthMethod.AUTHMETHOD_NONE) {
785 /**
786 * None actually means any, in that we don't care what method was used.
787 * This doesn't seem very intuitive or useful, but that's the way it is.
788 */
789 matched = EnumEvalResult.TRUE;
790 } else {
791 /*
792 * Some kind of authentication is required.
793 */
794 AuthenticationInfo authInfo=clientConnection.getAuthenticationInfo();
795 if(authInfo.isAuthenticated()) {
796 if(authMethod==EnumAuthMethod.AUTHMETHOD_SIMPLE) {
797 if(authInfo.hasAuthenticationType(AuthenticationType.SIMPLE)) {
798 matched = EnumEvalResult.TRUE;
799 }
800 } else if(authMethod == EnumAuthMethod.AUTHMETHOD_SSL) {
801 /*
802 * This means authentication using a certificate over TLS.
803 *
804 * We check the following:
805 * - SASL EXTERNAL has been used, and
806 * - TLS is the security provider, and
807 * - The client provided a certificate.
808 */
809 if (authInfo.hasAuthenticationType(AuthenticationType.SASL) &&
810 authInfo.hasSASLMechanism(saslMech)) {
811 ConnectionSecurityProvider provider =
812 clientConnection.getConnectionSecurityProvider();
813 if (provider instanceof TLSConnectionSecurityProvider) {
814 TLSConnectionSecurityProvider tlsProvider =
815 (TLSConnectionSecurityProvider) provider;
816 if (tlsProvider.getClientCertificateChain() != null) {
817 matched = EnumEvalResult.TRUE;
818 }
819 }
820 }
821 } else {
822 // A particular SASL mechanism.
823 if (authInfo.hasAuthenticationType(AuthenticationType.SASL) &&
824 authInfo.hasSASLMechanism(saslMech)) {
825 matched = EnumEvalResult.TRUE;
826 }
827 }
828 }
829 }
830 return matched;
831 }
832
833 /**
834 * {@inheritDoc}
835 */
836 public boolean isMemberOf(Group group) {
837 boolean ret;
838 try {
839 ret=group.isMember(getClientDN());
840 } catch (DirectoryException ex) {
841 ret=false;
842 }
843 return ret;
844 }
845
846 /**
847 * {@inheritDoc}
848 */
849 public String rightToString() {
850 if(hasRights(ACI_SEARCH))
851 return "search";
852 else if(hasRights(ACI_COMPARE))
853 return "compare";
854 else if(hasRights(ACI_READ))
855 return "read";
856 else if(hasRights(ACI_DELETE))
857 return "delete";
858 else if(hasRights(ACI_ADD))
859 return "add";
860 else if(hasRights(ACI_WRITE))
861 return "write";
862 else if(hasRights(ACI_PROXY))
863 return "proxy";
864 else if(hasRights(ACI_IMPORT))
865 return "import";
866 else if(hasRights(ACI_EXPORT))
867 return "export";
868 else if(hasRights(ACI_WRITE) &&
869 hasRights(ACI_SELF))
870 return "selfwrite";
871 return null;
872 }
873
874 /**
875 * {@inheritDoc}
876 */
877 public void setEvalUserAttributes(int v) {
878 if(operation instanceof SearchOperation && (rights == ACI_READ)) {
879 if(v == ACI_FOUND_USER_ATTR_RULE) {
880 evalAllAttributes |= ACI_FOUND_USER_ATTR_RULE;
881 evalAllAttributes &= ~ACI_USER_ATTR_STAR_MATCHED;
882 } else
883 evalAllAttributes |= ACI_USER_ATTR_STAR_MATCHED;
884 }
885 }
886
887 /**
888 * {@inheritDoc}
889 */
890 public void setEvalOpAttributes(int v) {
891 if(operation instanceof SearchOperation && (rights == ACI_READ)) {
892 if(v == ACI_FOUND_OP_ATTR_RULE) {
893 evalAllAttributes |= ACI_FOUND_OP_ATTR_RULE;
894 evalAllAttributes &= ~ACI_OP_ATTR_PLUS_MATCHED;
895 } else
896 evalAllAttributes |= ACI_OP_ATTR_PLUS_MATCHED;
897 }
898 }
899
900 /**
901 * {@inheritDoc}
902 */
903 public boolean hasEvalUserAttributes() {
904 return (evalAllAttributes & ACI_FOUND_USER_ATTR_RULE) ==
905 ACI_FOUND_USER_ATTR_RULE;
906 }
907
908 /**
909 * {@inheritDoc}
910 */
911 public boolean hasEvalOpAttributes() {
912 return (evalAllAttributes & ACI_FOUND_OP_ATTR_RULE) ==
913 ACI_FOUND_OP_ATTR_RULE;
914 }
915
916 /**
917 * Return true if the evaluating ACI contained a targetattr all
918 * user attributes rule match.
919 *
920 * @return True if the above condition was seen.
921 **/
922 public boolean hasAllUserAttributes() {
923 return (evalAllAttributes & ACI_USER_ATTR_STAR_MATCHED) ==
924 ACI_USER_ATTR_STAR_MATCHED;
925 }
926
927 /**
928 * Return true if the evaluating ACI contained a targetattr all
929 * operational attributes rule match.
930 *
931 * @return True if the above condition was seen.
932 **/
933 public boolean hasAllOpAttributes() {
934 return (evalAllAttributes & ACI_OP_ATTR_PLUS_MATCHED) ==
935 ACI_OP_ATTR_PLUS_MATCHED;
936 }
937
938 /**
939 * {@inheritDoc}
940 */
941 public void clearEvalAttributes(int v) {
942 if(v == 0)
943 evalAllAttributes=0;
944 else
945 evalAllAttributes &= ~v;
946 }
947 }