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 }