001/* 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved 005 * 006 * The contents of this file are subject to the terms 007 * of the Common Development and Distribution License 008 * (the License). You may not use this file except in 009 * compliance with the License. 010 * 011 * You can obtain a copy of the License at 012 * https://opensso.dev.java.net/public/CDDLv1.0.html or 013 * opensso/legal/CDDLv1.0.txt 014 * See the License for the specific language governing 015 * permission and limitations under the License. 016 * 017 * When distributing Covered Code, include this CDDL 018 * Header Notice in each file and include the License file 019 * at opensso/legal/CDDLv1.0.txt. 020 * If applicable, add the following below the CDDL Header, 021 * with the fields enclosed by brackets [] replaced by 022 * your own identifying information: 023 * "Portions Copyrighted [year] [name of copyright owner]" 024 * 025 * $Id: Policy.java,v 1.9 2010/01/10 01:19:35 veiming Exp $ 026 * 027 * Portions Copyrighted 2011-2015 ForgeRock AS. 028 */ 029 030package com.sun.identity.policy; 031 032import java.util.Collection; 033import java.util.Collections; 034import java.util.HashMap; 035import java.util.HashSet; 036import java.util.Iterator; 037import java.util.Map; 038import java.util.Set; 039import java.util.StringTokenizer; 040 041import com.iplanet.am.sdk.AMCommonUtils; 042import com.iplanet.am.util.Cache; 043import com.iplanet.sso.SSOException; 044import com.iplanet.sso.SSOToken; 045import com.sun.identity.policy.interfaces.Condition; 046import com.sun.identity.policy.interfaces.Referral; 047import com.sun.identity.policy.interfaces.ResponseProvider; 048import com.sun.identity.policy.interfaces.Subject; 049import com.sun.identity.policy.plugins.OrgReferral; 050import com.sun.identity.shared.debug.Debug; 051import com.sun.identity.shared.xml.XMLUtils; 052import com.sun.identity.sm.AttributeSchema; 053import org.forgerock.openam.ldap.LDAPUtils; 054import org.w3c.dom.Node; 055 056/** 057 * The class <code>Policy</code> represents a policy definition. 058 * A policy contains a set of rules associated with a collection of 059 * users and conditions. The policy object is saved in the data store 060 * only when the <code>store</code> method of the <code>Policy</code> is 061 * called, or if the methods <code>addPolicy</code> or <code>replacePolicy 062 * </code> of <code>PolicyManager</code> instance is invoked with this policy. 063 * The <code>Policy</code> object is accessible to policy evaluation and 064 * enforcement points only after it is saved in data store. 065 * 066 * @supported.api 067 * @deprecated since 12.0.0 068 */ 069@Deprecated 070public class Policy implements Cloneable { 071 072 static final String REFERRAL_POLICY = "referralPolicy"; 073 static final String ACTIVE_FLAG = "active"; 074 075 private static final int SUBJECTS_CONDITIONS_RULES = 1; 076 private static final int CONDITIONS_SUBJECTS_RULES = 2; 077 private static final int RULES_SUBJECTS_CONDITIONS = 3; 078 private static final int RULES_CONDITIONS_SUBJECTS = 4; 079 private static final int SUBJECTS_RULES_CONDITIONS = 5; 080 private static final int CONDITIONS_RULES_SUBJECTS = 6; 081 082 private static String EVALUATION_WEIGHTS = null; 083 private static String DEFAULT_EVALUATION_WEIGHTS = "10:10:10"; 084 private final static String EVALUATION_WEIGHTS_KEY 085 = "com.sun.identity.policy.Policy.policy_evaluation_weights"; 086 private static final Debug DEBUG = PolicyManager.debug; 087 088 private int evaluationOrder = RULES_SUBJECTS_CONDITIONS; 089 090 private static int ruleWeight; 091 private static int conditionWeight; 092 private static int subjectWeight; 093 094 private int prWeight; 095 private int pcWeight; 096 private int psWeight; 097 098 static { 099 initializeStaticEvaluationWeights(); 100 } 101 102 private String origPolicyName; 103 private String policyName; 104 private String description = ""; 105 private String createdBy; 106 private String lastModifiedBy; 107 private long creationDate; 108 private long lastModifiedDate; 109 private boolean referralPolicy=false; 110 private boolean active = true; 111 112 private int priority; 113 private Map rules = new HashMap(); 114 private Subjects users = new Subjects(); 115 private Conditions conditions = new Conditions(); 116 private ResponseProviders respProviders = new ResponseProviders(); 117 private Referrals referrals = new Referrals(); 118 private String organizationName; 119 private final static int MATCHED_RULE_RESULTS_CACHE_SIZE = 1000; 120 private final static int MATCHED_REFERRAL_RULES_CACHE_SIZE = 100; 121 private Cache matchRulesResultsCache 122 = new Cache(MATCHED_RULE_RESULTS_CACHE_SIZE); 123 private String subjectRealm; 124 125 /** 126 * No-arg constructor. 127 */ 128 private Policy() { 129 // do nothing 130 } 131 132 /** 133 * Constructs a policy given the policy name. 134 * 135 * @param policyName name of the policy 136 * 137 * @exception InvalidNameException if policy name is not valid 138 * 139 * @supported.api 140 * 141 */ 142 public Policy(String policyName) throws InvalidNameException { 143 this(policyName, null); 144 } 145 146 /** 147 * Constructs a policy given the policy name and priority. 148 * 149 * @param policyName name of the policy 150 * @param priority priority assigned to the policy 151 * 152 * @exception InvalidNameException if policy name is not valid 153 */ 154 private Policy(String policyName, int priority) throws InvalidNameException 155 { 156 validateName(policyName); 157 this.policyName = policyName; 158 // Set the policy priority 159 this.priority = priority; 160 } 161 162 /** 163 * Constructs a policy given the policy name and description. 164 * 165 * @param policyName name of the policy 166 * @param description description for the policy 167 * 168 * @exception InvalidNameException if policy name is not valid 169 * 170 * @supported.api 171 * 172 */ 173 public Policy(String policyName, String description) 174 throws InvalidNameException { 175 176 this(policyName, description, false, true); 177 } 178 179 /** 180 * Constructs a policy given the policy name,description and a 181 * referralPolicy flag. 182 * 183 * @param policyName name of the policy 184 * @param description description for the policy 185 * @param referralPolicy indicates whether the policy is a 186 * referral policy or a standard policy. 187 * A referral policy is used only to delegate policy definitions to 188 * sub/peer organizations. A referral policy does not make use of any 189 * action values 190 * 191 * 192 * @exception InvalidNameException if policy name is not valid 193 * 194 * @supported.api 195 * 196 */ 197 public Policy(String policyName, String description, 198 boolean referralPolicy) throws InvalidNameException 199 { 200 this(policyName, description, referralPolicy, true); 201 } 202 203 /** 204 * Constructs a policy given the policy name , description, 205 * referralPolicy flag, and active flag 206 * 207 * @param policyName name of the policy 208 * @param description description for the policy 209 * @param referralPolicy indicates whether the policy is a 210 * referral policy or a standard policy. 211 * @param active indicates if the policy is active or not. 212 * A referral policy is used only to delegate policy definitions to 213 * sub/peer organizations. A referral policy does not make use of any 214 * action values 215 * 216 * @exception InvalidNameException if policy name is not valid 217 * 218 * @supported.api 219 * 220 */ 221 public Policy(String policyName, String description, 222 boolean referralPolicy, boolean active) throws InvalidNameException 223 { 224 validateName(policyName); 225 this.policyName = policyName; 226 if (description != null) { 227 this.description = description; 228 } 229 this.referralPolicy = referralPolicy; 230 this.active = active; 231 } 232 233 /** 234 * Constructs a policy given the Policy Node. 235 * This is used by PolicyManager 236 * @param pm <code>PolicyManager</code> requesting the operation 237 * 238 * @param policyNode XML node in W3C DOM format representing 239 * the policy object which needs to be created. 240 * @exception InvalidFormatException, InvalidNameException, 241 * NameNotFoundException, PolicyException 242 */ 243 public Policy(PolicyManager pm, Node policyNode) 244 throws InvalidFormatException, InvalidNameException, 245 NameNotFoundException, PolicyException { 246 // Check if the node name is PolicyManager.POLICY_ROOT_NODE 247 if (!policyNode.getNodeName().equalsIgnoreCase( 248 PolicyManager.POLICY_ROOT_NODE)) { 249 if (PolicyManager.debug.warningEnabled()) { 250 PolicyManager.debug.warning( 251 "invalid policy xml blob given to construct policy"); 252 } 253 throw (new InvalidFormatException(ResBundleUtils.rbName, 254 "invalid_xml_policy_root_node", null, "", 255 PolicyException.POLICY)); 256 } 257 258 // Get the policy name 259 policyName = XMLUtils.getNodeAttributeValue(policyNode, 260 PolicyManager.NAME_ATTRIBUTE); 261 validateName(policyName); 262 263 // Get descrition, can be null 264 description = XMLUtils.getNodeAttributeValue(policyNode, 265 PolicyManager.DESCRIPTION_ATTRIBUTE); 266 267 getModificationInfo(policyNode); 268 269 // Get referralPolicy flag 270 String referralPolicy = XMLUtils.getNodeAttributeValue(policyNode, 271 Policy.REFERRAL_POLICY); 272 if ( (referralPolicy != null) && 273 (referralPolicy.equalsIgnoreCase("true")) ) { 274 this.referralPolicy = true; 275 } 276 277 // Get active flag 278 String active = XMLUtils.getNodeAttributeValue(policyNode, 279 Policy.ACTIVE_FLAG); 280 if ( (active != null) && 281 (active.equalsIgnoreCase("false")) ) { 282 this.active = false; 283 } 284 285 // Get priority 286 String pri = XMLUtils.getNodeAttributeValue(policyNode, 287 PolicyManager.PRIORITY_ATTRIBUTE); 288 if (pri != null) { 289 try { 290 priority = Integer.parseInt(pri); 291 } catch (NumberFormatException nfe) { 292 // write to debug and continue 293 PolicyManager.debug.error("Number format exception in " + 294 "determining policy's priority: " + pri, nfe); 295 } 296 } 297 298 299 // Get the rule nodes and instantiate them 300 Set ruleNodes = XMLUtils.getChildNodes(policyNode, 301 PolicyManager.POLICY_RULE_NODE); 302 if ( ruleNodes != null ) { 303 Iterator items = ruleNodes.iterator(); 304 while (items.hasNext()) { 305 Node ruleNode = (Node) items.next(); 306 Rule rule = new Rule(ruleNode); 307 addRule(rule); 308 } 309 } 310 311 if (!this.referralPolicy) { 312 // Get the users collection and instantiate Subjects 313 Node subjectsNode = XMLUtils.getChildNode(policyNode, 314 PolicyManager.POLICY_SUBJECTS_NODE); 315 if ( subjectsNode != null ) { 316 users = new Subjects(pm, subjectsNode); 317 } 318 319 // Get the conditions collection and instantiate Conditions 320 Node conditionsNode = XMLUtils.getChildNode(policyNode, 321 PolicyManager.POLICY_CONDITIONS_NODE); 322 if ( conditionsNode != null ) { 323 conditions = new Conditions(pm.getConditionTypeManager(), 324 conditionsNode); 325 } 326 // Get the respProviders collection and instantiate 327 // ResponseProviders 328 Node respProvidersNode = XMLUtils.getChildNode(policyNode, 329 PolicyManager.POLICY_RESP_PROVIDERS_NODE); 330 if ( respProvidersNode != null ) { 331 respProviders = new ResponseProviders( 332 pm.getResponseProviderTypeManager(), 333 respProvidersNode); 334 } 335 } else { 336 // Get the referrals collection and instantiate Referrals 337 Node referralsNode = XMLUtils.getChildNode(policyNode, 338 PolicyManager.POLICY_REFERRALS_NODE); 339 if ( referralsNode != null ) { 340 referrals = new Referrals(pm, referralsNode); 341 } 342 } 343 } 344 345 private void getModificationInfo(Node policyNode) { 346 String strCreationDate = XMLUtils.getNodeAttributeValue(policyNode, 347 PolicyManager.CREATION_DATE_ATTRIBUTE); 348 if ((strCreationDate != null) && (strCreationDate.length() > 0)) { 349 try { 350 creationDate = Long.parseLong(strCreationDate); 351 } catch (NumberFormatException e) { 352 //ignore 353 } 354 } 355 String strLastModifiediDate = XMLUtils.getNodeAttributeValue( 356 policyNode, PolicyManager.LAST_MODIFIED_DATE_ATTRIBUTE); 357 if ((strLastModifiediDate != null) && 358 (strLastModifiediDate.length() > 0) 359 ) { 360 try { 361 lastModifiedDate = Long.parseLong(strLastModifiediDate); 362 } catch (NumberFormatException e) { 363 //ignore 364 } 365 } 366 367 createdBy = XMLUtils.getNodeAttributeValue(policyNode, 368 PolicyManager.CREATED_BY_ATTRIBUTE); 369 lastModifiedBy = XMLUtils.getNodeAttributeValue(policyNode, 370 PolicyManager.LAST_MODIFIED_BY_ATTRIBUTE); 371 } 372 373 /** 374 * Gets the name of the policy. 375 * 376 * @return name of the policy 377 * 378 * @supported.api 379 * 380 */ 381 public String getName() { 382 return (policyName); 383 } 384 385 /** 386 * Sets the name of the policy. 387 * 388 * @param policyName name of the policy. 389 * @exception InvalidNameException if <code>policyName</code> is an invalid 390 * name. 391 * 392 * @supported.api 393 * 394 */ 395 public void setName(String policyName) throws InvalidNameException { 396 validateName(policyName); 397 if (this.policyName.equals(policyName)) { 398 return; 399 } 400 if (origPolicyName == null) { 401 origPolicyName = this.policyName; 402 } 403 this.policyName = policyName; 404 } 405 406 /** 407 * Gets the original policy name. 408 * This is used to track policies called via 409 * <code>PolicyManager::replacePolicy()</code> 410 * with the changed policy name. 411 * 412 * @return the policy name that was present when 413 * the object was instantiated 414 */ 415 protected String getOriginalName() { 416 return (origPolicyName); 417 } 418 419 /** 420 * Sets the organization name under which the policy is created 421 * This would be set only for policies that have been read from data store. 422 * Otherwise this would be <code>null</code> 423 * 424 * @param organizationName name of the organization name in which the 425 * policy is created. 426 */ 427 void setOrganizationName(String organizationName) { 428 this.organizationName = organizationName; 429 } 430 431 /** 432 * Gets the organization name under which the policy is created 433 * This would be set only for policies that have been read from data store. 434 * Otherwise this would be <code>null</code> 435 * 436 * @return the organization name under which the policy is created 437 * 438 * @supported.api 439 * 440 */ 441 public String getOrganizationName() { 442 return organizationName; 443 } 444 445 /** 446 * Resets the original policy name 447 */ 448 protected void resetOriginalName() { 449 origPolicyName = null; 450 } 451 452 /** 453 * Gets the description for the policy. 454 * If the description for the policy has not been set 455 * the method will return an empty string; not <code> 456 * null</code>. 457 * 458 * @return description of the policy 459 * 460 * @supported.api 461 * 462 */ 463 public String getDescription() { 464 return description; 465 } 466 467 /** 468 * Sets the description for the policy. 469 * 470 * @param description description for the policy 471 * @exception InvalidNameException if the description is invalid 472 * 473 * @supported.api 474 * 475 */ 476 public void setDescription(String description) 477 throws InvalidNameException { 478 if (description != null) { 479 this.description = description; 480 } 481 } 482 483 /** 484 * Checks whether the policy is a referral policy. 485 * A referral policy is used only to delegate policy definitions to 486 * sub/peer organizations. A referral policy does not make use of any 487 * action values 488 * 489 * @return <code>true</code> if this is a referral policy. 490 * Otherwise returns <code>false</code> 491 * 492 * @supported.api 493 * 494 */ 495 public boolean isReferralPolicy() { 496 return referralPolicy; 497 } 498 499 /** 500 * Checks whether the policy is active or inactive 501 * An inactive policy is not used to make policy evaluations. 502 * 503 * @return <code>true</code> if this is an active policy. 504 * Otherwise returns <code>false</code> 505 * 506 * @supported.api 507 * 508 */ 509 public boolean isActive() { 510 return active; 511 } 512 513 /** 514 * Set the active flag for policy. 515 * An inactive policy is not used to make policy evaluations. 516 * @param active <code>boolean</code> representing active or inactive. 517 * 518 * @supported.api 519 * 520 */ 521 public void setActive(boolean active) { 522 this.active = active; 523 } 524 525 /** 526 * Gets the priority of the policy. 527 * 528 * @return priority of the policy 529 */ 530 public int getPriority() { 531 return (priority); 532 } 533 534 /** 535 * Sets a priority of the policy. 536 * 537 * @param priority priority of the policy 538 */ 539 public void setPriority(int priority) { 540 this.priority = priority; 541 } 542 543 /** 544 * Gets the set of rule names associated with the policy. 545 * 546 * @return <code>Set</code> of rule names 547 * 548 * @supported.api 549 * 550 */ 551 public Set getRuleNames() { 552 return (new HashSet(rules.keySet())); 553 } 554 555 /** 556 * Gets the rule object identified by name. 557 * 558 * @param ruleName name of rule. 559 * 560 * @return <code>Rule</code> object. 561 * 562 * @exception NameNotFoundException if a <code>Rule</code> with the given 563 * name does not exist 564 * @supported.api 565 * 566 */ 567 public Rule getRule(String ruleName) throws NameNotFoundException { 568 Rule rule = (Rule) rules.get(ruleName); 569 if (rule == null) { 570 throw (new NameNotFoundException(ResBundleUtils.rbName, 571 "rule_not_found", null, ruleName, PolicyException.RULE)); 572 } 573 return (rule); 574 } 575 576 /** 577 * Adds a new policy rule. 578 * 579 * @param rule rule object to be added to the policy 580 * @exception NameAlreadyExistsException a rule with the given name 581 * already exists 582 * @exception InvalidNameException if the rule name is invalid 583 * same service name as the policy 584 * @supported.api 585 * 586 */ 587 public void addRule(Rule rule) throws NameAlreadyExistsException , 588 InvalidNameException { 589 // Since 5.0 does not support rule name, it can be null 590 if (rule.getName() == null) { 591 // Assign a name dynamically 592 rule.setName("rule" + ServiceTypeManager.generateRandomName()); 593 } 594 595 // Check if the rule name or rule itself already exists 596 if (rules.containsKey(rule.getName())) { 597 throw (new NameAlreadyExistsException(ResBundleUtils.rbName, 598 "rule_name_already_present", null, rule.getName(), 599 PolicyException.RULE)); 600 } else if (rules.containsValue(rule)) { 601 throw (new NameAlreadyExistsException(ResBundleUtils.rbName, 602 "rule_already_present", null, rule.getName(), 603 PolicyException.RULE)); 604 } 605 606 rules.put(rule.getName(), rule); 607 } 608 609 /** 610 * Replaces an existing rule with the same name by the 611 * current one. If a <code>Rule</code> with the same name does not exist, 612 * it will be added. 613 * 614 * @param rule <code>Rule</code> that will replace an existing rule 615 * with the same name 616 * 617 * @exception InvalidNameException if <code>Rule</code> name is invalid 618 * 619 * @supported.api 620 * 621 */ 622 public void replaceRule(Rule rule) throws InvalidNameException { 623 // Since 5.0 does not support rule name, it can be null 624 if (rule.getName() == null) { 625 // Assign a name dynamically 626 rule.setName("rule" + ServiceTypeManager.generateRandomName()); 627 } 628 629 rules.put(rule.getName(), rule); 630 } 631 632 /** 633 * Removes the <code>Rule</code> with the given name. 634 * 635 * @param ruleName name of the rule 636 * 637 * @return returns the <code>Rule</code> object being removed; 638 * if not present returns <code>null</code> 639 * 640 * @supported.api 641 * 642 */ 643 public Rule removeRule(String ruleName) { 644 return ((Rule) rules.remove(ruleName)); 645 } 646 647 /** 648 * Returns a <code>Subjects</code> object that contains 649 * a set of <code>Subject</code> instances for which the 650 * policy is applied. 651 * 652 * @return Subjects object of the policy 653 */ 654 Subjects getSubjects() { 655 return (users); 656 } 657 658 /** 659 * Get the <code>Set</code> of subject names associated with the policy. 660 * 661 * @return <code>Set</code> of String objects representing subject names 662 * 663 * @supported.api 664 * 665 */ 666 public Set getSubjectNames() { 667 return users.getSubjectNames(); 668 } 669 670 /** 671 * Gets the Subject object identified by name. 672 * 673 * @param subjectName name of subject. 674 * 675 * @return <code>Subject</code> object 676 * 677 * @exception NameNotFoundException if a Subject with the given name 678 * does not exist 679 * 680 * @supported.api 681 * 682 */ 683 public Subject getSubject(String subjectName) throws NameNotFoundException { 684 return users.getSubject(subjectName); 685 } 686 687 /** 688 * Adds a new policy subject. 689 * The subject is added as a normal (non exclusive) subject. 690 * So, policy will apply to members of the subject. 691 * The policy will apply to a user if he is a member of 692 * any normal (non exclusive) subject in the policy 693 * or not a member of any exclusive subject in the policy. 694 * 695 * @param name name of the Subject instance 696 * @param subject Subject object to be added to the policy 697 * 698 * @exception NameAlreadyExistsException if a Subject with the given name 699 * already exists 700 * @exception InvalidNameException if the subject name is invalid 701 * 702 * @supported.api 703 * 704 */ 705 public void addSubject(String name, Subject subject) 706 throws NameAlreadyExistsException, InvalidNameException { 707 users.addSubject(name, subject, false); 708 } 709 710 /** 711 * Adds a reference in the policy to a Subject defined at the realm. 712 * 713 * 714 * @param token SSOToken of the user adding the subject 715 * @param subjectName name of the Subject as defined at the realm 716 * @param realmName name of the realm in which the subject is defined 717 * 718 * @exception NameAlreadyExistsException if a Subject with the given name 719 * already exists in the policy 720 * @exception InvalidNameException if the subject name is invalid 721 * or the subject is not found at the realm 722 * @exception SSOException if the SSO token is invalid 723 * @exception PolicyException if the subject could not be added 724 * for any other reason 725 * 726 * @supported.api 727 * 728 */ 729 public void addRealmSubject(SSOToken token, String subjectName, 730 String realmName, boolean exclusive) 731 throws NameAlreadyExistsException, InvalidNameException, 732 PolicyException, SSOException { 733 PolicyManager pm = new PolicyManager(token, realmName); 734 SubjectTypeManager stm = pm.getSubjectTypeManager(); 735 addRealmSubject(subjectName, stm, exclusive); 736 } 737 738 /** 739 * Adds a reference in the policy to a Subject defined at the realm. 740 * 741 * 742 * @param subjectName name of the Subject as defined at the realm 743 * @param stm <code>SubjectTypeManager<code> of the realm. 744 * You have to pass the SubjectTypeManager of realm in which 745 * you would save the policy. Trying to save the policy at 746 * a different realm would throw PolicyException. 747 * 748 * @exception NameAlreadyExistsException if a Subject with the given name 749 * already exists in the policy 750 * @exception InvalidNameException if the subject name is invalid 751 * or the subject is not found at the realm 752 * @exception SSOException if the SSO token is invalid 753 * @exception PolicyException if the subject could not be added 754 * for any other reason 755 * 756 * @supported.api 757 * 758 */ 759 public void addRealmSubject(String subjectName, SubjectTypeManager stm, 760 boolean exclusive) 761 throws NameAlreadyExistsException, InvalidNameException, 762 PolicyException, SSOException { 763 String realmName = stm.getPolicyManager().getOrganizationDN(); 764 realmName = LDAPUtils.formatToRFC(realmName); 765 if ((subjectRealm != null) && !subjectRealm.equals(realmName)) { 766 String[] objs = {realmName, subjectRealm}; 767 if (DEBUG.messageEnabled()) { 768 DEBUG.message("Policy.addRealmSubject():can not add" 769 + " realm subject " + subjectName 770 + " , from realm : " + realmName 771 + " , policy already has subject from different realm:" 772 + subjectRealm); 773 } 774 775 throw (new InvalidNameException(ResBundleUtils.rbName, 776 "policy_realms_do_not_match", objs, null, realmName, 777 PolicyException.POLICY)); 778 } 779 if (subjectRealm == null) { 780 subjectRealm = realmName; 781 } 782 /** 783 * would result in NameNotFoundException if the subject does not exist 784 * we would propogate the exception without catching 785 */ 786 stm.getSubjectByName(subjectName); 787 788 users.addSubject(subjectName, stm.getSharedSubject(subjectName), 789 exclusive); 790 791 if (DEBUG.messageEnabled()) { 792 DEBUG.message("Policy.addRealmSubject():added " 793 + " realm subject " + subjectName 794 + " , from realm : " + realmName); 795 } 796 } 797 798 /** 799 * Adds a new policy subject. 800 * The policy will apply to a user if he is a member of 801 * any normal (non exclusive) subject in the policy 802 * or not a member of any exclusive subject in the policy. 803 * 804 * @param name name of the Subject instance 805 * @param subject Subject object to be added to the policy 806 * 807 * @param exclusive boolean flag indicating whether the subject 808 * is to be exclusive subject. If subject is exclusive, 809 * policy applies to users who are not members of the 810 * subject. Otherwise, policy applies to members of the subject. 811 * 812 * @exception NameAlreadyExistsException if a Subject with the given name 813 * already exists 814 * @exception InvalidNameException if the subject name is invalid 815 * 816 * @supported.api 817 * 818 */ 819 public void addSubject(String name, Subject subject, boolean exclusive) 820 throws NameAlreadyExistsException, InvalidNameException { 821 users.addSubject(name, subject, exclusive); 822 } 823 824 /** 825 * Replaces an existing subject with the same name by the 826 * current one. If a subject with the same name does not exist, 827 * it will be added. 828 * The subject is replaced as a normal (non exclusive) subject. 829 * So, policy will apply to members of the subject. 830 * The policy will apply to a user if he is a member of 831 * any normal (non exclusive) subject subject in the policy 832 * or not a member of any exclusive subject subject in the policy. 833 * 834 * @param name name of the Subject instance 835 * @param subject Subject that will replace an existing Subject 836 * with the same name 837 * 838 * @exception NameNotFoundException if a Subject instance 839 * with the given name is not present 840 * 841 * @supported.api 842 * 843 */ 844 public void replaceSubject(String name, Subject subject) 845 throws NameNotFoundException { 846 users.replaceSubject(name, subject, false); 847 } 848 849 /** 850 * Replaces an existing subject with the same name by the 851 * current one. If a subject with the same name does not exist, 852 * it will be added. 853 * The policy will apply to a user if he is a member of 854 * any normal (non exclusive) subject in the policy 855 * or not a member of any exclusive subject in the policy. 856 * 857 * @param name name of the Subject instance 858 * @param subject Subject that will replace an existing Subject 859 * with the same name 860 * 861 * @param exclusive boolean flag indicating whether the subject 862 * is to be exclusive subject. If subject is exclusive, 863 * policy applies to users who are not members of the 864 * subject. Otherwise, policy applies to members of the subject. 865 * 866 * @exception NameNotFoundException if a Subject instance 867 * with the given name is not present 868 * 869 * @supported.api 870 * 871 */ 872 public void replaceSubject(String name, Subject subject, boolean exclusive) 873 throws NameNotFoundException { 874 users.replaceSubject(name, subject, exclusive); 875 } 876 877 /** 878 * Removes the subject with the given name. 879 * 880 * @param subjectName name of the Subject 881 * 882 * @return returns the Subject object being removed. 883 * if not present returns <code>null</code> 884 * 885 * @supported.api 886 * 887 */ 888 public Subject removeSubject(String subjectName) { 889 return users.removeSubject(subjectName); 890 } 891 892 /** 893 * Removes the <code>Subject</code> object identified by 894 * object's <code>equals</code> method. If a Subject instance 895 * does not exist, the method will return silently. 896 * 897 * @param subject Subject object that 898 * will be removed from the user collection 899 * 900 * @supported.api 901 * 902 */ 903 public void removeSubject(Subject subject) { 904 String subjectName = users.getSubjectName(subject); 905 if (subjectName != null) { 906 removeSubject(subjectName); 907 } 908 } 909 910 911 /** 912 * Checks if the subject is exclusive. 913 * If subject is exclusive, policy applies to users who are not members of 914 * the subject. Otherwise, policy applies to members of the subject. 915 * The policy will apply to a user if he is a member of 916 * any normal (non exclusive) subject in the policy 917 * or not a member of any exclusive subject in the policy. 918 * 919 * @param subjectName name of the subject 920 * @return <code>true</code> if the subject is exclusive, <code>false</code> 921 * otherwise. 922 * @exception NameNotFoundException if the subject with the given 923 * <code>subjectName</code> does not exist in the policy. 924 * 925 * @supported.api 926 * 927 */ 928 public boolean isSubjectExclusive(String subjectName) 929 throws NameNotFoundException { 930 return users.isSubjectExclusive(subjectName); 931 } 932 933 /** 934 * Checks if the subjectName is a reference to a Subject 935 * defined at the realm 936 * 937 * @param subjectName name of the subject 938 * @return <code>true</code> if the subject is a reference to a 939 * Subject defined at the realm, <code>false</code> 940 * otherwise. 941 * @exception NameNotFoundException if the subject with the given 942 * <code>subjectName</code> does not exist in the policy. 943 * 944 * @supported.api 945 * 946 */ 947 public boolean isRealmSubject(String subjectName) 948 throws NameNotFoundException { 949 return users.isRealmSubject(subjectName); 950 } 951 952 /** 953 * Returns a <code>Referrals</code> object that contains 954 * a set of <code>Referral</code> instances for whom the 955 * policy is applied. 956 * 957 * @return Referrals object of the policy 958 */ 959 Referrals getReferrals() { 960 return (referrals); 961 } 962 963 /** 964 * Get the <code>Set</code> of referral names associated with the policy. 965 * 966 * @return <code>Set</code> of referral names 967 * 968 * @supported.api 969 * 970 */ 971 public Set getReferralNames() { 972 return referrals.getReferralNames(); 973 } 974 975 /** 976 * Gets the Referral object identified by name. 977 * 978 * @param referralName name of referral. 979 * 980 * @return <code>Referral</code> object 981 * 982 * @exception NameNotFoundException if a Referral with the given name 983 * does not exist 984 * 985 * @supported.api 986 * 987 */ 988 public Referral getReferral(String referralName) throws 989 NameNotFoundException 990 { 991 return referrals.getReferral(referralName); 992 } 993 994 /** 995 * Adds a new policy referral. 996 * 997 * @param name name of the <code>Referral</code> instance 998 * @param referral <code>Referral</code> object to be added to the policy 999 * 1000 * @exception NameAlreadyExistsException if a Referral with the given name 1001 * already exists 1002 * @exception InvalidNameException if the referral name is invalid 1003 * 1004 * @supported.api 1005 * 1006 */ 1007 public void addReferral(String name, Referral referral) 1008 throws NameAlreadyExistsException, InvalidNameException { 1009 referrals.addReferral(name, referral); 1010 } 1011 1012 /** 1013 * Replaces an existing referral with the same name by the 1014 * current one. If a referral with the same name does not exist, 1015 * it will be added. 1016 * 1017 * @param name name of the <code>Referral</code> instance 1018 * @param referral <code>Referral</code> that will replace an existing 1019 * Referral with the same name 1020 * 1021 * @exception NameNotFoundException if a Referral instance 1022 * with the given name is not present 1023 * 1024 * @supported.api 1025 * 1026 */ 1027 public void replaceReferral(String name, Referral referral) 1028 throws NameNotFoundException { 1029 referrals.replaceReferral(name, referral); 1030 } 1031 1032 /** 1033 * Removes the referral with the given name. 1034 * 1035 * @param referralName name of the <code>Referral</code> 1036 * 1037 * @return returns the <code>Referral</code> object being removed; 1038 * if not present returns <code>null</code> 1039 * 1040 * @supported.api 1041 * 1042 */ 1043 public Referral removeReferral(String referralName) { 1044 return referrals.removeReferral(referralName); 1045 } 1046 /** 1047 * Removes the <code>Referral</code> object identified by 1048 * object's <code>equals</code> method. If a Referral instance 1049 * does not exist, the method will return silently. 1050 * 1051 * @param referral Referral object that will be removed 1052 * 1053 * @supported.api 1054 * 1055 */ 1056 public void removeReferral(Referral referral) { 1057 String referralName = referrals.getReferralName(referral); 1058 if (referralName != null) { 1059 removeReferral(referralName); 1060 } 1061 } 1062 1063 1064 /** 1065 * Returns a <code>Conditions</code> object that contains 1066 * a set of <code>Condition</code> objects that apply 1067 * to the policy 1068 * 1069 * @return <code>Conditions</code> object of the policy 1070 */ 1071 Conditions getConditions() { 1072 return (conditions); 1073 } 1074 1075 /** 1076 * Get the set of condition names associated with the policy. 1077 * 1078 * @return <code>Set</code> of condition names 1079 * 1080 * @supported.api 1081 * 1082 */ 1083 public Set getConditionNames() { 1084 return conditions.getConditionNames(); 1085 } 1086 1087 /** 1088 * Gets the condition object identified by name. 1089 * 1090 * @param condition name of condition. 1091 * 1092 * @return <code>Condition</code> object. 1093 * 1094 * @exception NameNotFoundException if a Condition with the given name 1095 * does not exist. 1096 * 1097 * @supported.api 1098 * 1099 */ 1100 public Condition getCondition(String condition) throws 1101 NameNotFoundException 1102 { 1103 return conditions.getCondition(condition); 1104 } 1105 1106 /** 1107 * Adds a new policy condition. 1108 * 1109 * @param name name of the Condition instance 1110 * @param condition Condition object to be added to the policy 1111 * 1112 * @exception NameAlreadyExistsException if a Condition with the given name 1113 * already exists 1114 * @exception InvalidNameException if the condition name is invalid 1115 * 1116 * @supported.api 1117 * 1118 */ 1119 public void addCondition(String name, Condition condition) 1120 throws NameAlreadyExistsException, InvalidNameException { 1121 conditions.addCondition(name, condition); 1122 } 1123 1124 /** 1125 * Replaces an existing condition with the same name by the 1126 * current one. If a condition with the same name does not exist, 1127 * it will be added. 1128 * 1129 * @param name name of the <code>Condition</code> instance 1130 * @param condition <code>Condition</code> that will replace an 1131 * existing Condition with the same name 1132 * 1133 * @exception NameNotFoundException if a Condition instance 1134 * with the given name is not present 1135 * 1136 * @supported.api 1137 * 1138 */ 1139 public void replaceCondition(String name, Condition condition) 1140 throws NameNotFoundException { 1141 conditions.replaceCondition(name, condition); 1142 } 1143 1144 /** 1145 * Removes the condition with the given name. 1146 * 1147 * @param condition name of the <code>Condition</code> 1148 * 1149 * @return returns the Condition object being removed; 1150 * if not present returns <code>null</code> 1151 * 1152 * @supported.api 1153 * 1154 */ 1155 public Condition removeCondition(String condition) { 1156 return conditions.removeCondition(condition); 1157 } 1158 1159 /** 1160 * Removes the <code>Condition</code> object identified by 1161 * object's <code>equals</code> method. If a condition instance 1162 * does not exist, the method will return silently. 1163 * 1164 * @param condition Condition object that will be removed 1165 * 1166 * @supported.api 1167 * 1168 */ 1169 public void removeCondition(Condition condition) { 1170 String conditionName = conditions.getConditionName(condition); 1171 if (conditionName != null) { 1172 removeCondition(conditionName); 1173 } 1174 } 1175 1176 1177 /** 1178 * Returns a <code>ResponseProviders</code> object that contains 1179 * a set of <code>ResponseProvider</code> objects that apply 1180 * to the policy 1181 * 1182 * @return <code>ResponseProviders</code> object found in the policy 1183 */ 1184 ResponseProviders getResponseProviders() { 1185 return (respProviders); 1186 } 1187 1188 /** 1189 * Get a <code>Set</code> of <code>String</code> objects representing 1190 * the responseProvider names associated with the policy. 1191 * 1192 * @return <code>Set</code> of responseProvider names 1193 * 1194 * 1195 */ 1196 public Set getResponseProviderNames() { 1197 return respProviders.getResponseProviderNames(); 1198 } 1199 1200 /** 1201 * Gets the <code>ResponseProvider</code> object identified by name. 1202 * 1203 * @param respProvider name of <code>ResponseProvider</code>. 1204 * 1205 * @return <code>ResponseProvider</code> object. 1206 * 1207 * @exception NameNotFoundException if a ResponseProvider with the given 1208 * name does not exist. 1209 * 1210 * 1211 */ 1212 public ResponseProvider getResponseProvider(String respProvider) 1213 throws NameNotFoundException { 1214 return respProviders.getResponseProvider(respProvider); 1215 } 1216 1217 /** 1218 * Adds a new <code>ResponseProvider</code> to the policy. 1219 * 1220 * @param name name of the <code>ResponseProvider</code> instance 1221 * @param respProvider <code>ResponseProvider</code> object to be added to 1222 * the policy 1223 * 1224 * @exception NameAlreadyExistsException if a ResponseProvider with the 1225 * given name already exists 1226 * @exception InvalidNameException if the <code>respProvider</code> 1227 * name is invalid 1228 * 1229 * 1230 */ 1231 public void addResponseProvider(String name, ResponseProvider respProvider) 1232 throws NameAlreadyExistsException { 1233 respProviders.addResponseProvider(name, respProvider); 1234 } 1235 1236 /** 1237 * Replaces an existing <code>ResponseProvider</code> with the same name 1238 * by the current one. If a respProvider with the same name does not exist, 1239 * it will be added. 1240 * 1241 * @param name name of the ResponseProvider instance 1242 * @param respProvider ResponseProvider that will replace an existing 1243 * ResponseProvider with the same name 1244 * 1245 * @exception NameNotFoundException if a ResponseProvider instance 1246 * with the given name is not present. 1247 * 1248 * 1249 */ 1250 public void replaceResponseProvider(String name, 1251 ResponseProvider respProvider) throws NameNotFoundException { 1252 respProviders.replaceResponseProvider(name, respProvider); 1253 } 1254 1255 /** 1256 * Removes the <code>ResponseProvider</code> with the given name. 1257 * 1258 * @param respProvider name of the ResponseProvider 1259 * 1260 * @return returns the ResponseProvider object being removed; 1261 * if not present returns null. 1262 * 1263 * 1264 */ 1265 public ResponseProvider removeResponseProvider(String respProvider) { 1266 return respProviders.removeResponseProvider(respProvider); 1267 } 1268 1269 /** 1270 * Removes the <code>ResponseProvider</code> object. 1271 * If a respProvider instance does not exist, the method will 1272 * return silently. 1273 * 1274 * @param respProvider ResponseProvider object that 1275 * will be removed 1276 * 1277 * 1278 */ 1279 public void removeResponseProvider(ResponseProvider respProvider) { 1280 String respProviderName = respProviders.getResponseProviderName( 1281 respProvider); 1282 if (respProviderName != null) { 1283 removeResponseProvider(respProviderName); 1284 } 1285 } 1286 1287 /** 1288 * Stores the policy object in a persistent data store 1289 * under the organization, sub-organization or a container 1290 * object, specified as a parameter. The organization, 1291 * sub-organization, or the container can be either 1292 * a LDAP distinguished name (<code>dn</code>) or slash "/" separated 1293 * as per SMS. This method 1294 * uses the <code>SSOToken</code> provided to perform the store 1295 * operation, and hence if the single sign token has expired 1296 * <code>SSOException</code> will be thrown, and if the 1297 * user does not have the required privileges 1298 * <code>NoPermissionException</code> exception will be thrown. 1299 * <p> 1300 * If a policy with the same name exists for the organization 1301 * the method will throw <code>NameAlreadyExistsException</code>. 1302 * And if the organization name does not exist, the method 1303 * will throw <code>NameNotFoundException</code>. 1304 * 1305 * @param token SSO token of the user managing policy 1306 * @param name name of the organization, sub-organization or 1307 * a container in which the policy will be stored. 1308 * 1309 * @exception SSOException invalid or expired single-sign-on token 1310 * @exception NoPermissionException user does not have sufficient 1311 * privileges to add policy 1312 * 1313 * @exception NameAlreadyExistsException a policy with the same 1314 * name already exists 1315 * 1316 * @exception NameNotFoundException the given organization name 1317 * does not exist 1318 * 1319 * @exception PolicyException for any other abnormal condition 1320 * 1321 * @supported.api 1322 * 1323 */ 1324 public void store(SSOToken token, String name) throws SSOException, 1325 NoPermissionException, NameAlreadyExistsException, 1326 NameNotFoundException, PolicyException { 1327 PolicyManager pm = new PolicyManager(token, name); 1328 pm.addPolicy(this); 1329 } 1330 1331 /** 1332 * Checks if two policy objects are equal. 1333 * This method does not check the policy name and description 1334 * for equality. 1335 * 1336 * @param obj object againt which the policy object 1337 * will be checked for equality 1338 * 1339 * @return <code>true</code> if policies are equal, 1340 * <code>false</code> otherwise. 1341 */ 1342 public boolean equals(Object obj) { 1343 if (obj instanceof Policy) { 1344 Policy p = (Policy) obj; 1345 if (rules.equals(p.rules) && users.equals(p.users) 1346 && referrals.equals(p.referrals) 1347 && respProviders.equals(p.respProviders) 1348 && conditions.equals(p.conditions) ) { 1349 return (true); 1350 } 1351 } 1352 return (false); 1353 } 1354 1355 /** 1356 * Creates and returns a copy of this object. The returned 1357 * <code>Policy</code> object will have the same policy 1358 * name, rules, subjects, referrals and conditions 1359 * such that <code>x.clone().equals(x)</code> will be 1360 * <code>true</code>. However <code>x.clone()</code> 1361 * will not be the same as <code>x</code>, i.e., 1362 * <code>x.clone() != x</code>. 1363 * 1364 * @return a copy of this object 1365 */ 1366 public Object clone() { 1367 Policy answer = null; 1368 try { 1369 answer = (Policy) super.clone(); 1370 } catch (CloneNotSupportedException se) { 1371 answer = new Policy(); 1372 } 1373 // Copy state variables 1374 answer.origPolicyName = origPolicyName; 1375 answer.policyName = policyName; 1376 answer.description = description; 1377 answer.active = active; 1378 1379 // Copy rules 1380 answer.rules = new HashMap(); 1381 Iterator items = rules.keySet().iterator(); 1382 while (items.hasNext()) { 1383 Object o = items.next(); 1384 Rule rule = (Rule) rules.get(o); 1385 answer.rules.put(o, rule.clone()); 1386 } 1387 1388 // Copy subjects 1389 answer.users = (Subjects) users.clone(); 1390 1391 // Copy referrals 1392 answer.referrals = (Referrals) referrals.clone(); 1393 1394 // Copy responseProviders 1395 answer.respProviders = (ResponseProviders) respProviders.clone(); 1396 1397 // Copy conditions 1398 answer.conditions = (Conditions) conditions.clone(); 1399 1400 return (answer); 1401 } 1402 1403 /** 1404 * Returns the serialized policy in XML 1405 * @return serialized policy in XML 1406 * 1407 * @supported.api 1408 * 1409 */ 1410 public String toXML() { 1411 return toXML(true); 1412 } 1413 1414 public String toXML(boolean withHeader) { 1415 StringBuilder answer = new StringBuilder(200); 1416 1417 if (withHeader) { 1418 answer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); 1419 } 1420 1421 answer.append("<Policy name=\""); 1422 answer.append(XMLUtils.escapeSpecialCharacters(policyName)); 1423 if ((description != null) && (description.length() > 0)) { 1424 answer.append("\" description=\""); 1425 answer.append(XMLUtils.escapeSpecialCharacters(description)); 1426 } 1427 1428 if ((createdBy != null) && (createdBy.length() > 0)) { 1429 answer.append("\" ") 1430 .append(PolicyManager.CREATED_BY_ATTRIBUTE) 1431 .append("=\"") 1432 .append(XMLUtils.escapeSpecialCharacters(createdBy)); 1433 } 1434 if ((lastModifiedBy != null) && (lastModifiedBy.length() > 0)) { 1435 answer.append("\" ") 1436 .append(PolicyManager.LAST_MODIFIED_BY_ATTRIBUTE) 1437 .append("=\"") 1438 .append(XMLUtils.escapeSpecialCharacters(lastModifiedBy)); 1439 } 1440 if (creationDate > 0) { 1441 answer.append("\" ") 1442 .append(PolicyManager.CREATION_DATE_ATTRIBUTE) 1443 .append("=\"") 1444 .append(XMLUtils.escapeSpecialCharacters( 1445 Long.toString(creationDate))); 1446 } 1447 if (lastModifiedDate > 0) { 1448 answer.append("\" ") 1449 .append(PolicyManager.LAST_MODIFIED_DATE_ATTRIBUTE) 1450 .append("=\"") 1451 .append(XMLUtils.escapeSpecialCharacters( 1452 Long.toString(lastModifiedDate))); 1453 } 1454 1455 answer.append("\" referralPolicy=\"").append(referralPolicy); 1456 answer.append("\" active=\"").append(active); 1457 answer.append("\" >"); 1458 for (Iterator i = getRuleNames().iterator(); i.hasNext(); ) { 1459 String ruleName = (String)i.next(); 1460 try { 1461 Rule rule = getRule(ruleName); 1462 answer.append(rule.toXML()); 1463 } catch (Exception e) { 1464 // Ignore the exception 1465 DEBUG.error("Error in policy.toXML():" + e.getMessage()); 1466 } 1467 } 1468 1469 if (!this.referralPolicy) { 1470 // Add the users 1471 if ( !(users.getSubjectNames().isEmpty()) ) { 1472 answer.append(users.toXML()); 1473 } 1474 1475 // Add the conditions 1476 if ( !(conditions.getConditionNames().isEmpty()) ) { 1477 answer.append(conditions.toXML()); 1478 } 1479 // Add the responseProviders 1480 if ( !(respProviders.getResponseProviderNames().isEmpty()) ) { 1481 answer.append(respProviders.toXML()); 1482 } 1483 } else { 1484 // Add the referrals 1485 if ( !(referrals.getReferralNames().isEmpty()) ) { 1486 answer.append(referrals.toXML()); 1487 } 1488 } 1489 1490 answer.append("\n").append("</Policy>"); 1491 return (answer.toString()); 1492 } 1493 1494 /** 1495 * Gets string representation of the policy object. 1496 * 1497 * @return XML string representation of the policy object 1498 * 1499 * @supported.api 1500 */ 1501 public String toString() { 1502 return (toXML()); 1503 } 1504 1505 /** 1506 * Checks for the char <code>c</code> in the String 1507 * @param name String in which the character needs to be checked for. 1508 * @param c <code>char</code> which needs to be checked. 1509 * @exception InvalidNameException if <code>c</code> does not occur 1510 * anywhere in <code>name</code>. 1511 */ 1512 static void checkForCharacter(String name, char c) 1513 throws InvalidNameException { 1514 if (name.indexOf(c) != -1) { 1515 Character objs[] = { new Character(c) }; 1516 throw (new InvalidNameException(ResBundleUtils.rbName, 1517 "invalid_char_in_name", objs, name, 1518 PolicyException.POLICY)); 1519 } 1520 } 1521 1522 /** 1523 * Gets policy decision 1524 * @param token sso token identifying the user for who the policy has to 1525 * be evaluated. 1526 * @param resourceTypeName resourceType name 1527 * @param resourceName resourceName 1528 * @param actionNames a set of action names for which policy results 1529 * are to be evaluated. Each element of the set should be a 1530 * String 1531 * @param envParameters a <code>Map</code> of environment parameters 1532 * Each key of the <code>Map</code> is a String valued parameter name 1533 * Each value of the map is a <code>Set</code> of String values 1534 * @return a <code>PolicyDecision</code> 1535 * @exception NameNotFoundException if the action name or resource name 1536 * is not found 1537 * @exception SSOException if token is invalid 1538 * @exception PolicyException for any other exception condition 1539 */ 1540 public PolicyDecision getPolicyDecision(SSOToken token, 1541 String resourceTypeName,String resourceName, Set actionNames, 1542 Map envParameters) throws SSOException, NameNotFoundException, 1543 PolicyException 1544 { 1545 1546 PolicyDecision policyDecision = new PolicyDecision(); 1547 1548 ServiceTypeManager stm = ServiceTypeManager.getServiceTypeManager(); 1549 ServiceType resourceType 1550 = stm.getServiceType(resourceTypeName); 1551 1552 /** 1553 * get the evaluation order that is likely to be least expensive 1554 * in terms of cpu. 1555 */ 1556 if (token != null) { 1557 evaluationOrder = getEvaluationOrder(token); 1558 } else { 1559 evaluationOrder = SUBJECTS_RULES_CONDITIONS; 1560 } 1561 if (DEBUG.messageEnabled()) { 1562 DEBUG.message("Policy " + getName() 1563 + " is Using Policy evaluation order :" + evaluationOrder); 1564 } 1565 if (isReferralPolicy() && !referrals.isEmpty()) { 1566 1567 //process referrals irrespective subjects and conditions 1568 PolicyDecision referralDecision 1569 = referrals.getPolicyDecision(token, 1570 resourceTypeName, resourceName, actionNames, 1571 envParameters); 1572 if (referralDecision != null) { 1573 PolicyEvaluator.mergePolicyDecisions( 1574 resourceType, referralDecision, policyDecision); 1575 } 1576 if (DEBUG.messageEnabled()) { 1577 String tokenPrincipal = 1578 (token != null) ? token.getPrincipal().getName() 1579 : PolicyUtils.EMPTY_STRING; 1580 DEBUG.message( 1581 new StringBuffer("at Policy.getPolicyDecision()") 1582 .append(" after processing referrals only:") 1583 .append(" principal, resource name, action names,") 1584 .append(" policyName, referralResults = ") 1585 .append(tokenPrincipal) .append(", ") 1586 .append(resourceName) .append(", ") 1587 .append(actionNames) .append(", ") 1588 .append(this.getName()).append(", ") 1589 .append(referralDecision).toString()); 1590 } 1591 } else if (evaluationOrder == SUBJECTS_CONDITIONS_RULES) { 1592 if (DEBUG.messageEnabled()) { 1593 DEBUG.message("Using policy evaluation order:" 1594 + "SUBJECTS_CONDITIONS_RULES"); 1595 } 1596 getPolicyDecisionSCR(token, resourceType, resourceName, 1597 actionNames, envParameters, policyDecision); 1598 } else if (evaluationOrder == CONDITIONS_SUBJECTS_RULES) { 1599 if (DEBUG.messageEnabled()) { 1600 DEBUG.message("Using policy evaluation order:" 1601 + "CONDITIONS_SUBJECTS_RULES"); 1602 } 1603 getPolicyDecisionCSR(token, resourceType, resourceName, 1604 actionNames, envParameters, policyDecision); 1605 } else if (evaluationOrder == RULES_SUBJECTS_CONDITIONS) { 1606 if (DEBUG.messageEnabled()) { 1607 DEBUG.message("Using policy evaluation order:" 1608 + "RULES_SUBJECTS_CONDITIONS"); 1609 } 1610 getPolicyDecisionRSC(token, resourceType, resourceName, 1611 actionNames, envParameters, policyDecision); 1612 } else if (evaluationOrder == RULES_CONDITIONS_SUBJECTS) { 1613 if (DEBUG.messageEnabled()) { 1614 DEBUG.message("Using policy evaluation order:" 1615 + "RULES_CONDITIONS_SUBJECTS"); 1616 } 1617 getPolicyDecisionRCS(token, resourceType, resourceName, 1618 actionNames, envParameters, policyDecision); 1619 } else if (evaluationOrder == SUBJECTS_RULES_CONDITIONS) { 1620 if (DEBUG.messageEnabled()) { 1621 DEBUG.message("Using policy evaluation order:" 1622 + "SUBJECTS_RULES_CONDITIONS"); 1623 } 1624 getPolicyDecisionSRC(token, resourceType, resourceName, 1625 actionNames, envParameters, policyDecision); 1626 } else if (evaluationOrder == CONDITIONS_RULES_SUBJECTS) { 1627 if (DEBUG.messageEnabled()) { 1628 DEBUG.message("Using policy evaluation order:" 1629 + "CONDITIONS_RULES_SUBJECTS"); 1630 } 1631 getPolicyDecisionCRS(token, resourceType, resourceName, 1632 actionNames, envParameters, policyDecision); 1633 } else { //default:RULES_CONDITIONS_SUBJECTS 1634 if (DEBUG.messageEnabled()) { 1635 DEBUG.message("Using default policy evaluation order:" 1636 + "RULES_CONDITIONS_SUBJECTS"); 1637 } 1638 getPolicyDecisionRCS(token, resourceType, resourceName, 1639 actionNames, envParameters, policyDecision); 1640 } 1641 1642 if (DEBUG.messageEnabled()) { 1643 String tokenPrincipal = 1644 (token != null) ? token.getPrincipal().getName() 1645 : PolicyUtils.EMPTY_STRING; 1646 DEBUG.message( 1647 new StringBuffer("at Policy.getPolicyDecision()") 1648 .append(" principal, resource name, action names,") 1649 .append(" policyName, policyDecision = ") 1650 .append(tokenPrincipal) .append(", ") 1651 .append(resourceName) .append(", ") 1652 .append(actionNames) .append(", ") 1653 .append(this.getName()).append(", ") 1654 .append(policyDecision).toString()); 1655 } 1656 Map actionDecisionMap = policyDecision.getActionDecisions(); 1657 if (actionDecisionMap != null && !actionDecisionMap.isEmpty()) 1658 { 1659 Collection actionDecisions = null; 1660 if ((actionDecisions = actionDecisionMap.values()) != null && 1661 !actionDecisions.isEmpty()) { 1662 Iterator it = actionDecisions.iterator(); 1663 while (it.hasNext()) { 1664 Set actionValues = ((ActionDecision)it.next()).getValues(); 1665 if (actionValues != null && !actionValues.isEmpty()) 1666 { // put the response Attrs in the PolicyDecision 1667 Map responseAttributes = 1668 respProviders.getResponseProviderDecision(token, 1669 envParameters); 1670 policyDecision.setResponseAttributes( 1671 responseAttributes); 1672 break;/** 1673 * even if one action Value found, set the 1674 * resp attributes 1675 */ 1676 } 1677 } 1678 } 1679 } 1680 return policyDecision; 1681 } 1682 1683 /** Gets matched rule results given resource type, resource name and 1684 * action names 1685 * @param resourceType resource type(<code>ServiceType</code> of resource 1686 * @param resourceName resource name for which to get action values 1687 * @param actionNames action names for which to get values 1688 * @return <code>Map</code> of action values keyed by action names 1689 * @exception NameNotFoundException 1690 */ 1691 private Map getMatchedRuleResults(ServiceType resourceType, 1692 String resourceName, Set actionNames) throws NameNotFoundException { 1693 String resourceTypeName = resourceType.getName(); 1694 Map answer = null; 1695 StringBuilder cacheKeyBuffer = new StringBuilder(100); 1696 String cacheKey = cacheKeyBuffer.append(resourceTypeName) 1697 .append(resourceName).append(actionNames).toString(); 1698 answer = (Map) matchRulesResultsCache.get(cacheKey); 1699 if ( answer == null ) { 1700 answer = new HashMap(); 1701 1702 //Process rules 1703 Iterator ruleIterator = rules.values().iterator(); 1704 while (ruleIterator.hasNext()) { 1705 Rule rule = (Rule) ruleIterator.next(); 1706 Map actionResults = rule.getActionValues(resourceTypeName, 1707 resourceName, actionNames); 1708 PolicyUtils.appendMapToMap(actionResults, answer); 1709 } 1710 1711 Iterator actions = answer.keySet().iterator(); 1712 while ( actions.hasNext() ) { 1713 String action = (String) actions.next(); 1714 Set actionValues = (Set) answer.get(action); 1715 if ( actionValues.size() == 2 ) { 1716 ActionSchema actionSchema = null; 1717 AttributeSchema.Syntax actionSyntax = null; 1718 try { 1719 actionSchema = resourceType.getActionSchema(action); 1720 actionSyntax = actionSchema.getSyntax(); 1721 } catch(InvalidNameException e) { 1722 PolicyManager.debug.error( 1723 "can not find action schmea for action = " 1724 + action, e ); 1725 } 1726 if (AttributeSchema.Syntax.BOOLEAN.equals( 1727 actionSyntax)) { 1728 String trueValue = actionSchema.getTrueValue(); 1729 actionValues.remove(trueValue); 1730 } 1731 } 1732 } 1733 1734 // Add to cache 1735 matchRulesResultsCache.put(cacheKey, answer); 1736 } 1737 return cloneRuleResults(answer); 1738 } 1739 1740 /**Gets resource names that are exact matches, sub resources or 1741 * wild card matches of argument resource name. 1742 * To determine whether to include a 1743 * resource name of a resource, we compare argument resource name and 1744 * policy resource name, treating wild characters in the policy 1745 * resource name as wild. If the comparsion resulted in EXACT_MATCH, 1746 * WILD_CARD_MATCH or SUB_RESOURCE_MATCH, the resource result would be 1747 * included. 1748 * 1749 * @param token sso token 1750 * @param serviceTypeName service type name 1751 * @param resourceName resource name 1752 * @param followReferrals indicates whether to follow the referrals to 1753 * compute the resources 1754 * @return resource names that match to be exact match, sub 1755 * resource match or wild card match of the argument 1756 * resourceName 1757 * 1758 * @exception PolicyException 1759 * @exception SSOException 1760 * 1761 * @see ResourceMatch#EXACT_MATCH 1762 * @see ResourceMatch#SUB_RESOURCE_MATCH 1763 * @see ResourceMatch#WILDCARD_MATCH 1764 * 1765 */ 1766 Set getResourceNames(SSOToken token, String serviceTypeName, 1767 String resourceName, boolean followReferrals) 1768 throws PolicyException, SSOException { 1769 Set resourceNames = new HashSet(); 1770 ServiceType st = ServiceTypeManager.getServiceTypeManager() 1771 .getServiceType( serviceTypeName); 1772 Iterator ruleIterator = rules.values().iterator(); 1773 while (ruleIterator.hasNext()) { 1774 Rule rule = (Rule) ruleIterator.next(); 1775 if (rule.getServiceType().getName().equals(serviceTypeName)) { 1776 String ruleResource = rule.getResourceName(); 1777 ResourceMatch resourceMatch = st.compare(resourceName, 1778 ruleResource, true); // interpret wild char 1779 if (resourceMatch.equals(ResourceMatch.SUB_RESOURCE_MATCH) 1780 || resourceMatch.equals(ResourceMatch.EXACT_MATCH) 1781 || resourceMatch.equals(ResourceMatch.WILDCARD_MATCH)) { 1782 resourceNames.add(ruleResource); 1783 } 1784 if ( DEBUG.messageEnabled() ) { 1785 StringBuilder sb = new StringBuilder(200); 1786 sb.append("at Policy.getResourceNames : "); 1787 sb.append(" for policyName, serviceType, resourceName, "); 1788 sb.append(" ruleResource, resourceMatch :"); 1789 sb.append(getName()).append( ",").append( serviceTypeName); 1790 sb.append(",").append(resourceName).append(","); 1791 sb.append(ruleResource).append(",").append(resourceMatch); 1792 DEBUG.message(sb.toString()); 1793 } 1794 } 1795 } 1796 if (!resourceNames.isEmpty() && followReferrals) { 1797 Set rResourceNames = referrals.getResourceNames(token, 1798 serviceTypeName, resourceName); 1799 resourceNames.addAll(rResourceNames); 1800 } 1801 if ( DEBUG.messageEnabled() ) { 1802 StringBuilder sb = new StringBuilder(200); 1803 sb.append("at Policy.getResourceNames : "); 1804 sb.append(" for policyName, serviceType, resourceName, "); 1805 sb.append(" followReferral, resourceNames :"); 1806 sb.append(getName()).append( ",").append( serviceTypeName); 1807 sb.append(",").append(resourceName).append(","); 1808 sb.append(followReferrals).append(",").append(resourceNames); 1809 DEBUG.message(sb.toString()); 1810 } 1811 return resourceNames; 1812 } 1813 1814 /** Gets the resource names of a given serviceType managed by this 1815 * policy. 1816 * @param serviceTypeName name of service type for which to 1817 * find resource names 1818 * @return a set of resource names of serviceTypeName managed 1819 * by this policy 1820 * @exception SSOException 1821 * @exception NameNotFoundException 1822 */ 1823 Set getResourceNames(String serviceTypeName) throws SSOException, 1824 NameNotFoundException { 1825 Set resourceNames = new HashSet(); 1826 Iterator ruleIterator = rules.values().iterator(); 1827 while (ruleIterator.hasNext()) { 1828 Rule rule = (Rule) ruleIterator.next(); 1829 String rSvcTypeName = (rule.getServiceType() == null) ? 1830 rule.getServiceTypeName() : rule.getServiceType().getName(); 1831 if (rSvcTypeName.equals(serviceTypeName)) { 1832 String ruleResource = rule.getResourceName(); 1833 resourceNames.add(ruleResource); 1834 } 1835 } 1836 return resourceNames; 1837 } 1838 1839// public String getServiceTypeName() { 1840 /* com.iplanet.am.admin.cli uses this method. 1841 * Need to clean up cli not to use this 1842 * method. Without this method build breaks - 03/05/02 */ 1843 // return null; 1844 // } 1845 1846 /** 1847 * Gets organizations referred to in this policy by OrgReferral(s) 1848 * defined in this policy. 1849 * 1850 * @return names of organization (DNs) of organizations referred 1851 * to in this policy via <code>OrgReferral</code>(s) defined in 1852 * this policy. 1853 * Please note that <code>PeerOrgReferral</code> and 1854 * <code>SubOrgReferral</code> extend <code>OrgReferral</code> 1855 * and hence qualify as OrgReferral. 1856 * @exception PolicyException 1857 */ 1858 Set getReferredToOrganizations() throws PolicyException { 1859 Set referredToOrgs = new HashSet(); 1860 Iterator referralNames = referrals.getReferralNames().iterator(); 1861 while ( referralNames.hasNext() ) { 1862 String referralName = (String) referralNames.next(); 1863 Referral referral = (Referral) referrals.getReferral(referralName); 1864 if ( referral instanceof OrgReferral ) { 1865 Set values = referral.getValues(); 1866 if ( (values != null) && (!values.isEmpty()) ) { 1867 String orgName = (String) values.iterator().next(); 1868 referredToOrgs.add(orgName.toLowerCase()); 1869 } 1870 } 1871 } 1872 return referredToOrgs; 1873 } 1874 1875 /** Sets time to live for Subjects result. 1876 * @param ttl time to live for Subjects result 1877 */ 1878 void setSubjectsResultTtl(long ttl) { 1879 users.setResultTtl(ttl); 1880 } 1881 1882 1883 /** 1884 * validates the String <code>name</code>. 1885 * @param name String to be validated. 1886 * @exception throws InvalidNameException is name is null or 1887 * does contain invalid character "/". 1888 */ 1889 1890 private void validateName(String name) throws InvalidNameException { 1891 if ( (name == null) || (name.length() == 0) ) { 1892 DEBUG.message("Invalid policy name:" + name); 1893 throw (new InvalidNameException(ResBundleUtils.rbName, 1894 "null_name", null, "", PolicyException.POLICY)); 1895 } 1896 } 1897 1898 /** Gets policy decision computing Subjects, Conditions and Rules 1899 * in this order. Referrals in the policy are ignored. 1900 * 1901 * @param token sso token identifying the user for who the policy has to 1902 * be evaluated. 1903 * @param resourceType service type 1904 * @param resourceName resource name 1905 * @param actionNames a set of action names for which policy results 1906 * are to be evaluated. Each element of the set should be a 1907 * String 1908 * @param envParameters a map of environment parameters 1909 * Each key of the map is a String valued parameter name 1910 * Each value of the map is a set of String values 1911 * @param policyDecision a collecting argument. Computed policy decisions 1912 * in this method are merged to this policy decision 1913 * @return computed and merged policy decision 1914 * @exception NameNotFoundException if the action name or resource name 1915 * is not found 1916 * @exception SSOException if token is invalid 1917 * @exception PolicyException for any other exception condition 1918 */ 1919 private PolicyDecision getPolicyDecisionSCR(SSOToken token, 1920 ServiceType resourceType, 1921 String resourceName, Set actionNames, Map envParameters, 1922 PolicyDecision policyDecision) 1923 throws SSOException, NameNotFoundException, PolicyException { 1924 boolean resourceMatched = false; 1925 ConditionDecision conditionDecision = null; 1926 boolean allowedByConditions = false; 1927 boolean allowedBySubjects = false; 1928 Map advicesFromConditions = null; 1929 long conditionsTtl = Long.MIN_VALUE; 1930 long timeToLive = Long.MIN_VALUE; 1931 Map actionResults = null; 1932 1933 if (token != null) { 1934 allowedBySubjects = users.isMember(token); 1935 timeToLive = users.getResultTtl(token); 1936 } else { 1937 allowedBySubjects = true; 1938 timeToLive = Long.MAX_VALUE; 1939 } 1940 1941 if (allowedBySubjects) { //subjects+ 1942 conditionDecision = conditions.getConditionDecision( 1943 token, envParameters); 1944 allowedByConditions = conditionDecision.isAllowed(); 1945 advicesFromConditions = conditionDecision.getAdvices(); 1946 conditionsTtl = conditionDecision.getTimeToLive(); 1947 if ( conditionsTtl < timeToLive ) { 1948 timeToLive = conditionsTtl; 1949 } 1950 if (allowedByConditions) { //subjects+, conditions+ 1951 actionResults = getMatchedRuleResults(resourceType, 1952 resourceName, actionNames); 1953 resourceMatched = !actionResults.isEmpty(); 1954 if (resourceMatched) { //subjects+,conditions+,resourceMatch+ 1955 Iterator resultActionNames 1956 = actionResults.keySet().iterator(); 1957 while ( resultActionNames.hasNext() ) { 1958 String resultActionName 1959 = (String) resultActionNames.next(); 1960 Set resultActionValues 1961 = (Set)actionResults.get(resultActionName); 1962 1963 /* ActionDecision to include values, no advices 1964 */ 1965 ActionDecision actionDecision 1966 = new ActionDecision(resultActionName, 1967 resultActionValues, 1968 advicesFromConditions, timeToLive); 1969 policyDecision.addActionDecision( 1970 actionDecision, resourceType); 1971 } 1972 } else { // subjects+,conditions+,resourceMatch- 1973 policyDecision.setTimeToLive(Long.MAX_VALUE); 1974 } 1975 } else { //subjects+,conditions- 1976 //ActionDecision to include advices only 1977 1978 if (!advicesFromConditions.isEmpty()) { 1979 actionResults = getMatchedRuleResults(resourceType, 1980 resourceName, actionNames); 1981 Iterator resultActionNames 1982 = actionResults.keySet().iterator(); 1983 while ( resultActionNames.hasNext() ) { 1984 String resultActionName 1985 = (String) resultActionNames.next(); 1986 1987 /* ActionDecision to include advices, no values 1988 */ 1989 ActionDecision actionDecision 1990 = new ActionDecision(resultActionName, 1991 Collections.EMPTY_SET, 1992 advicesFromConditions, timeToLive); 1993 policyDecision.addActionDecision( 1994 actionDecision, resourceType); 1995 } 1996 } else { 1997 policyDecision.setTimeToLive(timeToLive); 1998 } 1999 } 2000 } else { //subjects- 2001 policyDecision.setTimeToLive(timeToLive); 2002 } 2003 return policyDecision; 2004 } 2005 2006 /** Gets policy decision computing Subjects, Rules and Conditions 2007 * in this order. Referrals in the policy are ignored. 2008 * 2009 * @param token sso token identifying the user for who the policy has to 2010 * be evaluated. 2011 * @param resourceType service type 2012 * @param resourceName resourceName 2013 * @param actionNames a set of action names for which policy results 2014 * are to be evaluated. Each element of the set should be a 2015 * String 2016 * @param envParameters a map of environment parameters 2017 * Each key of the map is a String valued parameter name 2018 * Each value of the map is a set of String values 2019 * @param policyDecision a collecting argument. Computed policy decisions 2020 * in this method are merged to this policy decision 2021 * @return computed and merged policy decision 2022 * @exception NameNotFoundException if the action name or resource name 2023 * is not found 2024 * @exception SSOException if token is invalid 2025 * @exception PolicyException for any other exception condition 2026 */ 2027 private PolicyDecision getPolicyDecisionSRC(SSOToken token, 2028 ServiceType resourceType, 2029 String resourceName, Set actionNames, Map envParameters, 2030 PolicyDecision policyDecision) 2031 throws SSOException, NameNotFoundException, PolicyException { 2032 boolean resourceMatched = false; 2033 ConditionDecision conditionDecision = null; 2034 boolean allowedByConditions = false; 2035 boolean allowedBySubjects = false; 2036 Map advicesFromConditions = null; 2037 long conditionsTtl = Long.MIN_VALUE; 2038 long timeToLive = Long.MIN_VALUE; 2039 Map actionResults = null; 2040 2041 if (token != null) { 2042 allowedBySubjects = users.isMember(token); 2043 timeToLive = users.getResultTtl(token); 2044 } else { 2045 allowedBySubjects = true; 2046 timeToLive = Long.MAX_VALUE; 2047 } 2048 if (allowedBySubjects) { //subjects+ 2049 actionResults = getMatchedRuleResults(resourceType, 2050 resourceName, actionNames); 2051 resourceMatched = !actionResults.isEmpty(); 2052 if (resourceMatched) { //subjects+, resourceMatch+ 2053 conditionDecision = conditions.getConditionDecision( 2054 token, envParameters); 2055 allowedByConditions = conditionDecision.isAllowed(); 2056 advicesFromConditions = conditionDecision.getAdvices(); 2057 conditionsTtl = conditionDecision.getTimeToLive(); 2058 if ( conditionsTtl < timeToLive ) { 2059 timeToLive = conditionsTtl; 2060 } 2061 if (allowedByConditions) { 2062 //subjects+, resourceMatch+,conditions+ 2063 Iterator resultActionNames 2064 = actionResults.keySet().iterator(); 2065 while ( resultActionNames.hasNext() ) { 2066 String resultActionName 2067 = (String) resultActionNames.next(); 2068 Set resultActionValues 2069 = (Set)actionResults.get(resultActionName); 2070 2071 /* ActionDecision to include values, no advices 2072 */ 2073 ActionDecision actionDecision 2074 = new ActionDecision(resultActionName, 2075 resultActionValues, 2076 advicesFromConditions, timeToLive); 2077 policyDecision.addActionDecision( 2078 actionDecision, resourceType); 2079 } 2080 } else { //subjects+, resourceMatch+,conditions- 2081 if (!advicesFromConditions.isEmpty()) { 2082 Iterator resultActionNames 2083 = actionResults.keySet().iterator(); 2084 while ( resultActionNames.hasNext() ) { 2085 String resultActionName 2086 = (String) resultActionNames.next(); 2087 2088 /* ActionDecision to include advices, no values 2089 */ 2090 ActionDecision actionDecision 2091 = new ActionDecision(resultActionName, 2092 Collections.EMPTY_SET, 2093 advicesFromConditions, timeToLive); 2094 policyDecision.addActionDecision( 2095 actionDecision, resourceType); 2096 } 2097 } else { 2098 policyDecision.setTimeToLive(timeToLive); 2099 } 2100 } 2101 } else { //subjects+,resourceMatch- 2102 policyDecision.setTimeToLive(Long.MAX_VALUE); 2103 } 2104 } else { //subjects- 2105 policyDecision.setTimeToLive(timeToLive); 2106 } 2107 return policyDecision; 2108 } 2109 2110 /** Gets policy decision computing Conditions, Subject and Rules 2111 * in this order. Referrals in the policy are ignored. 2112 * 2113 * @param token sso token identifying the user for who the policy has to 2114 * be evaluated. 2115 * @param resourceType service type 2116 * @param resourceName resourceName 2117 * @param actionNames a set of action names for which policy results 2118 * are to be evaluated. Each element of the set should be a 2119 * String 2120 * @param envParameters a map of environment parameters 2121 * Each key of the map is a String valued parameter name 2122 * Each value of the map is a set of String values 2123 * @param policyDecision a collecting arugment. Computed policy decisions 2124 * in this method are merged to this policy decision 2125 * @return computed and merged policy decision 2126 * @exception NameNotFoundException if the action name or resource name 2127 * is not found 2128 * @exception SSOException if token is invalid 2129 * @exception PolicyException for any other exception condition 2130 */ 2131 private PolicyDecision getPolicyDecisionCSR(SSOToken token, 2132 ServiceType resourceType, 2133 String resourceName, Set actionNames, Map envParameters, 2134 PolicyDecision policyDecision) 2135 throws SSOException, NameNotFoundException, PolicyException { 2136 boolean resourceMatched = false; 2137 ConditionDecision conditionDecision = null; 2138 boolean allowedByConditions = false; 2139 boolean allowedBySubjects = false; 2140 Map advicesFromConditions = null; 2141 long timeToLive = Long.MIN_VALUE; 2142 long subjectsTtl = Long.MIN_VALUE; 2143 Map actionResults = null; 2144 2145 conditionDecision = conditions.getConditionDecision( 2146 token, envParameters); 2147 allowedByConditions = conditionDecision.isAllowed(); 2148 advicesFromConditions = conditionDecision.getAdvices(); 2149 timeToLive = conditionDecision.getTimeToLive(); 2150 if (allowedByConditions) { //conditions+ 2151 allowedBySubjects = users.isMember(token); 2152 subjectsTtl = users.getResultTtl(token); 2153 if (subjectsTtl < timeToLive) { 2154 timeToLive = subjectsTtl; 2155 } 2156 if (allowedBySubjects) { //conditions+, subjects+ 2157 actionResults = getMatchedRuleResults(resourceType, 2158 resourceName, actionNames); 2159 resourceMatched = !actionResults.isEmpty(); 2160 if (resourceMatched) { 2161 //conditions+, subjects+, resourceMatched+ 2162 Iterator resultActionNames 2163 = actionResults.keySet().iterator(); 2164 while ( resultActionNames.hasNext() ) { 2165 String resultActionName 2166 = (String) resultActionNames.next(); 2167 Set resultActionValues 2168 = (Set)actionResults.get(resultActionName); 2169 2170 /* ActionDecision to include values, no advices 2171 */ 2172 ActionDecision actionDecision 2173 = new ActionDecision(resultActionName, 2174 resultActionValues, 2175 advicesFromConditions, timeToLive); 2176 policyDecision.addActionDecision( 2177 actionDecision, resourceType); 2178 } 2179 } else { //conditions+, subjects+, resourceMatched- 2180 policyDecision.setTimeToLive(Long.MAX_VALUE); 2181 } 2182 } else { //conditions+,subjects- 2183 policyDecision.setTimeToLive(timeToLive); 2184 } 2185 } else { //conditions- 2186 boolean reportAdvices = false; 2187 if (!advicesFromConditions.isEmpty()) { 2188 reportAdvices = users.isMember(token); 2189 subjectsTtl = users.getResultTtl(token); 2190 if (subjectsTtl < timeToLive) { 2191 timeToLive = subjectsTtl; 2192 } 2193 } 2194 if (reportAdvices) { 2195 actionResults = getMatchedRuleResults(resourceType, 2196 resourceName, actionNames); 2197 Iterator resultActionNames 2198 = actionResults.keySet().iterator(); 2199 while ( resultActionNames.hasNext() ) { 2200 String resultActionName 2201 = (String) resultActionNames.next(); 2202 2203 /* ActionDecision to include advices, no values 2204 */ 2205 ActionDecision actionDecision 2206 = new ActionDecision(resultActionName, 2207 Collections.EMPTY_SET, 2208 advicesFromConditions, timeToLive); 2209 policyDecision.addActionDecision( 2210 actionDecision, resourceType); 2211 } 2212 } else { //no advices to report 2213 policyDecision.setTimeToLive(timeToLive); 2214 } 2215 } 2216 return policyDecision; 2217 } 2218 2219 /** Gets policy decision computing Conditions, Rules and Subjects 2220 * in this order. Referrals in the policy are ignored. 2221 * 2222 * @param token sso token identifying the user for who the policy has to 2223 * be evaluated. 2224 * @param resourceType service type 2225 * @param resourceName resourceName 2226 * @param actionNames a set of action names for which policy results 2227 * are to be evaluated. Each element of the set should be a 2228 * String 2229 * @param envParameters a map of environment parameters 2230 * Each key of the map is a String valued parameter name 2231 * Each value of the map is a set of String values 2232 * @param policyDecision a collecting arugment. Computed policy decisions 2233 * in this method are merged to this policy decision 2234 * @return computed and merged policy decision 2235 * @exception NameNotFoundException if the action name or resource name 2236 * is not found 2237 * @exception SSOException if token is invalid 2238 * @exception PolicyException for any other exception condition 2239 */ 2240 private PolicyDecision getPolicyDecisionCRS(SSOToken token, 2241 ServiceType resourceType, 2242 String resourceName, Set actionNames, Map envParameters, 2243 PolicyDecision policyDecision) 2244 throws SSOException, NameNotFoundException, PolicyException { 2245 boolean resourceMatched = false; 2246 ConditionDecision conditionDecision = null; 2247 boolean allowedByConditions = false; 2248 boolean allowedBySubjects = false; 2249 Map advicesFromConditions = null; 2250 long subjectsTtl = Long.MIN_VALUE; 2251 long timeToLive = Long.MIN_VALUE; 2252 Map actionResults = null; 2253 2254 conditionDecision = conditions.getConditionDecision( 2255 token, envParameters); 2256 allowedByConditions = conditionDecision.isAllowed(); 2257 advicesFromConditions = conditionDecision.getAdvices(); 2258 timeToLive = conditionDecision.getTimeToLive(); 2259 actionResults = getMatchedRuleResults(resourceType, 2260 resourceName, actionNames); 2261 if (allowedByConditions) { //conditions+ 2262 resourceMatched = !actionResults.isEmpty(); 2263 if (resourceMatched) { ///conditions+, resourceMatched+ 2264 allowedBySubjects = users.isMember(token); 2265 subjectsTtl = users.getResultTtl(token); 2266 if (subjectsTtl < timeToLive) { 2267 timeToLive = subjectsTtl; 2268 } 2269 if (allowedBySubjects) { 2270 2271 //conditions+, resourceMatched+, subjects+ 2272 Iterator resultActionNames 2273 = actionResults.keySet().iterator(); 2274 while ( resultActionNames.hasNext() ) { 2275 String resultActionName 2276 = (String) resultActionNames.next(); 2277 Set resultActionValues 2278 = (Set)actionResults.get(resultActionName); 2279 2280 /* ActionDecision to include values, no advices 2281 */ 2282 ActionDecision actionDecision 2283 = new ActionDecision(resultActionName, 2284 resultActionValues, 2285 advicesFromConditions, timeToLive); 2286 policyDecision.addActionDecision( 2287 actionDecision, resourceType); 2288 } 2289 } else { //conditions+, resourceMatched+, subjects- 2290 policyDecision.setTimeToLive(timeToLive); 2291 } 2292 } else { //conditions+, resourceMatched- 2293 policyDecision.setTimeToLive(Long.MAX_VALUE); 2294 } 2295 } else { //conditions- 2296 boolean reportAdvices = false; 2297 if (!advicesFromConditions.isEmpty()) { 2298 reportAdvices = users.isMember(token); 2299 subjectsTtl = users.getResultTtl(token); 2300 if (subjectsTtl < timeToLive) { 2301 timeToLive = subjectsTtl; 2302 } 2303 } 2304 if (reportAdvices) { 2305 actionResults = getMatchedRuleResults(resourceType, 2306 resourceName, actionNames); 2307 Iterator resultActionNames 2308 = actionResults.keySet().iterator(); 2309 while ( resultActionNames.hasNext() ) { 2310 String resultActionName 2311 = (String) resultActionNames.next(); 2312 2313 /* ActionDecision to include advices, no values 2314 */ 2315 ActionDecision actionDecision 2316 = new ActionDecision(resultActionName, 2317 Collections.EMPTY_SET, 2318 advicesFromConditions, timeToLive); 2319 policyDecision.addActionDecision( 2320 actionDecision, resourceType); 2321 } 2322 } else { //no advices to report 2323 policyDecision.setTimeToLive(timeToLive); 2324 } 2325 } 2326 return policyDecision; 2327 } 2328 2329 /** Gets policy decision computing Rules, Subjects and Conditions 2330 * in this order. Referrals in the policy are ignored. 2331 * 2332 * @param token sso token identifying the user for who the policy has to 2333 * be evaluated. 2334 * @param resourceType service type 2335 * @param resourceName resourceName 2336 * @param actionNames a set of action names for which policy results 2337 * are to be evaluated. Each element of the set should be a 2338 * String 2339 * @param envParameters a map of environment parameters 2340 * Each key of the map is a String valued parameter name 2341 * Each value of the map is a set of String values 2342 * @param policyDecision a collecting arugment. Computed policy decisions 2343 * in this method are merged to this policy decision 2344 * @return computed and merged policy decision 2345 * @exception NameNotFoundException if the action name or resource name 2346 * is not found 2347 * @exception SSOException if token is invalid 2348 * @exception PolicyException for any other exception condition 2349 */ 2350 private PolicyDecision getPolicyDecisionRSC(SSOToken token, 2351 ServiceType resourceType, 2352 String resourceName, Set actionNames, Map envParameters, 2353 PolicyDecision policyDecision) 2354 throws SSOException, NameNotFoundException, PolicyException { 2355 boolean resourceMatched = false; 2356 ConditionDecision conditionDecision = null; 2357 boolean allowedByConditions = false; 2358 boolean allowedBySubjects = false; 2359 Map advicesFromConditions = null; 2360 long conditionsTtl = Long.MIN_VALUE; 2361 long timeToLive = Long.MIN_VALUE; 2362 2363 Map actionResults = getMatchedRuleResults(resourceType, 2364 resourceName, actionNames); 2365 resourceMatched = !actionResults.isEmpty(); 2366 if (resourceMatched) { //resourceMatched+ 2367 allowedBySubjects = users.isMember(token); 2368 timeToLive = users.getResultTtl(token); 2369 if (allowedBySubjects) { //resourceMatched+, subjects+ 2370 conditionDecision = conditions.getConditionDecision( 2371 token, envParameters); 2372 allowedByConditions = conditionDecision.isAllowed(); 2373 advicesFromConditions = conditionDecision.getAdvices(); 2374 conditionsTtl = conditionDecision.getTimeToLive(); 2375 if (conditionsTtl < timeToLive) { 2376 timeToLive = conditionsTtl; 2377 } 2378 if (allowedByConditions) { 2379 2380 //resourceMatched+, subjects+, conditions+ 2381 Iterator resultActionNames 2382 = actionResults.keySet().iterator(); 2383 while ( resultActionNames.hasNext() ) { 2384 String resultActionName 2385 = (String) resultActionNames.next(); 2386 Set resultActionValues 2387 = (Set)actionResults.get(resultActionName); 2388 2389 /* ActionDecision to include values, no advices 2390 */ 2391 ActionDecision actionDecision 2392 = new ActionDecision(resultActionName, 2393 resultActionValues, 2394 advicesFromConditions, timeToLive); 2395 policyDecision.addActionDecision( 2396 actionDecision, resourceType); 2397 } 2398 } else { //resourceMatched+, subjects+, conditions- 2399 Iterator resultActionNames 2400 = actionResults.keySet().iterator(); 2401 if (!advicesFromConditions.isEmpty()) { 2402 while ( resultActionNames.hasNext() ) { 2403 String resultActionName 2404 = (String) resultActionNames.next(); 2405 2406 /* ActionDecision to include advices, no values 2407 */ 2408 ActionDecision actionDecision 2409 = new ActionDecision(resultActionName, 2410 Collections.EMPTY_SET, 2411 advicesFromConditions, timeToLive); 2412 policyDecision.addActionDecision( 2413 actionDecision, resourceType); 2414 } 2415 } else { 2416 policyDecision.setTimeToLive(timeToLive); 2417 } 2418 } 2419 } else { //resourceMatched+, subjects- 2420 policyDecision.setTimeToLive(timeToLive); 2421 } 2422 } else { //resourceMached- 2423 policyDecision.setTimeToLive(Long.MAX_VALUE); 2424 } 2425 return policyDecision; 2426 } 2427 2428 /** Gets policy decision computing Rules, Conditions and Subjects 2429 * in this order. Referrals in the policy are ignored. 2430 * 2431 * @param token sso token identifying the user for who the policy has to 2432 * be evaluated. 2433 * @param resourceType service type 2434 * @param resourceName resourceName 2435 * @param actionNames a set of action names for which policy results 2436 * are to be evaluated. Each element of the set should be a 2437 * String 2438 * @param envParameters a map of environment parameters 2439 * Each key of the map is a String valued parameter name 2440 * Each value of the map is a set of String values 2441 * @param policyDecision a collecting argument. Computed policy decisions 2442 * in this method are merged to this policy decision 2443 * @return computed and merged policy decision 2444 * @exception NameNotFoundException if the action name or resource name 2445 * is not found 2446 * @exception SSOException if token is invalid 2447 * @exception PolicyException for any other exception condition 2448 */ 2449 private PolicyDecision getPolicyDecisionRCS(SSOToken token, 2450 ServiceType resourceType, 2451 String resourceName, Set actionNames, Map envParameters, 2452 PolicyDecision policyDecision) 2453 throws SSOException, NameNotFoundException, PolicyException { 2454 boolean resourceMatched = false; 2455 ConditionDecision conditionDecision = null; 2456 boolean allowedByConditions = false; 2457 boolean allowedBySubjects = false; 2458 Map advicesFromConditions = null; 2459 long conditionsTtl = Long.MIN_VALUE; 2460 long subjectsTtl = Long.MIN_VALUE; 2461 long timeToLive = Long.MIN_VALUE; 2462 2463 Map actionResults = getMatchedRuleResults(resourceType, 2464 resourceName, actionNames); 2465 resourceMatched = !actionResults.isEmpty(); 2466 if (resourceMatched) { //resourceMatch+ 2467 conditionDecision = conditions.getConditionDecision( 2468 token, envParameters); 2469 allowedByConditions = conditionDecision.isAllowed(); 2470 advicesFromConditions = conditionDecision.getAdvices(); 2471 conditionsTtl = conditionDecision.getTimeToLive(); 2472 timeToLive = conditionsTtl; 2473 if (allowedByConditions) { //resourceMatch+, conditions+ 2474 allowedBySubjects = users.isMember(token); 2475 subjectsTtl = users.getResultTtl(token); 2476 if (subjectsTtl < timeToLive) { 2477 timeToLive = subjectsTtl; 2478 } 2479 if (allowedBySubjects) { 2480 //resourceMatch+, conditions+, subjects+ 2481 Iterator resultActionNames 2482 = actionResults.keySet().iterator(); 2483 while ( resultActionNames.hasNext() ) { 2484 String resultActionName 2485 = (String) resultActionNames.next(); 2486 Set resultActionValues 2487 = (Set)actionResults.get(resultActionName); 2488 2489 /* ActionDecision to include values, no advices 2490 */ 2491 ActionDecision actionDecision 2492 = new ActionDecision(resultActionName, 2493 resultActionValues, 2494 advicesFromConditions, timeToLive); 2495 policyDecision.addActionDecision( 2496 actionDecision, resourceType); 2497 } 2498 } else { //resourceMatch+, conditions+, subjects- 2499 policyDecision.setTimeToLive(timeToLive); 2500 } 2501 } else { //resourceMatch+, conditions- 2502 boolean reportAdvices = false; 2503 if (!advicesFromConditions.isEmpty()) { 2504 reportAdvices = users.isMember(token); 2505 subjectsTtl = users.getResultTtl(token); 2506 if (subjectsTtl < timeToLive) { 2507 timeToLive = subjectsTtl; 2508 } 2509 } 2510 if (reportAdvices) { 2511 Iterator resultActionNames 2512 = actionResults.keySet().iterator(); 2513 while ( resultActionNames.hasNext() ) { 2514 String resultActionName 2515 = (String) resultActionNames.next(); 2516 2517 /* ActionDecision to include advices, no values 2518 */ 2519 ActionDecision actionDecision 2520 = new ActionDecision(resultActionName, 2521 Collections.EMPTY_SET, 2522 advicesFromConditions, timeToLive); 2523 policyDecision.addActionDecision( 2524 actionDecision, resourceType); 2525 } 2526 } else { //no advices to report 2527 policyDecision.setTimeToLive(timeToLive); 2528 } 2529 } 2530 } else { //resourceMatch- 2531 policyDecision.setTimeToLive(Long.MAX_VALUE); 2532 } 2533 return policyDecision; 2534 } 2535 2536 2537 /** Gets evaluation order of Subjects, Rules and Conditions for this policy 2538 * that is likely to be least expensive in terms of cpu. 2539 * 2540 * @return int representing preferred evaluation order for this policy 2541 */ 2542 private int getEvaluationOrder(SSOToken token) throws SSOException { 2543 2544 int evaluationOrder = RULES_CONDITIONS_SUBJECTS; 2545 2546 //treat subject weight as 0, if sub result is in cache 2547 int mpsWeight = users.isSubjectResultCached(token) ? 0 : psWeight; 2548 if (( mpsWeight <= pcWeight) && (pcWeight <= prWeight)) { 2549 evaluationOrder = SUBJECTS_CONDITIONS_RULES; 2550 } else if (( pcWeight <= mpsWeight) && (mpsWeight <= prWeight)) { 2551 evaluationOrder = CONDITIONS_SUBJECTS_RULES; 2552 } else if (( prWeight <= pcWeight) && (pcWeight <= mpsWeight)) { 2553 evaluationOrder = RULES_CONDITIONS_SUBJECTS; 2554 } else if (( prWeight <= mpsWeight) && (mpsWeight <= pcWeight)) { 2555 evaluationOrder = RULES_SUBJECTS_CONDITIONS; 2556 } else if (( mpsWeight <= prWeight) && (prWeight <= pcWeight)) { 2557 evaluationOrder = SUBJECTS_RULES_CONDITIONS; 2558 } else if (( pcWeight <= prWeight) && (prWeight <= mpsWeight)) { 2559 evaluationOrder = CONDITIONS_RULES_SUBJECTS; 2560 } 2561 return evaluationOrder; 2562 } 2563 2564 /** Initializes global values of evaluation weight 2565 * per Subject, per Condition and per Rule element 2566 * of the policies by reading value of property 2567 * <code>EVALUATION_WEIGHTS_KEY</code> from AMConfig.properties. 2568 * If the value is not defined in AMConfig.properties, the value defaults 2569 * to <code>DEFAULT_EVALUATION_WEIGHTS</code>. 2570 * @see #DEFAULT_EVALUATION_WEIGHTS 2571 */ 2572 private static void initializeStaticEvaluationWeights() { 2573 EVALUATION_WEIGHTS = com.iplanet.am.util.SystemProperties.get( 2574 EVALUATION_WEIGHTS_KEY, DEFAULT_EVALUATION_WEIGHTS); 2575 StringTokenizer st = new StringTokenizer(EVALUATION_WEIGHTS, ":"); 2576 int tokenCount = st.countTokens(); 2577 if ( tokenCount != 3) { 2578 if (PolicyManager.debug.warningEnabled()) { 2579 PolicyManager.debug.warning( 2580 "Policy.initializeStaticEvaluationWeights:" 2581 + " invalid evaulationWeights defined, " 2582 + " defaulting to " + DEFAULT_EVALUATION_WEIGHTS); 2583 } 2584 EVALUATION_WEIGHTS = DEFAULT_EVALUATION_WEIGHTS; 2585 } else { 2586 String weight = st.nextToken(); 2587 try { 2588 subjectWeight = Integer.parseInt(weight); 2589 } catch (NumberFormatException nfe) { 2590 if (PolicyManager.debug.warningEnabled()) { 2591 PolicyManager.debug.warning( 2592 "Policy.initializeStaticEvaluationWeights:" 2593 + " invalid subjectWeight defined, defaulting to 0"); 2594 } 2595 subjectWeight = 0; 2596 } 2597 weight = st.nextToken(); 2598 try { 2599 ruleWeight = Integer.parseInt(weight); 2600 } catch (NumberFormatException nfe) { 2601 if (PolicyManager.debug.warningEnabled()) { 2602 PolicyManager.debug.warning( 2603 "Policy.initializeStaticEvaluationWeights:" 2604 + " invalid ruleWeight defined, defaulting to 0"); 2605 } 2606 ruleWeight = 0; 2607 } 2608 weight = st.nextToken(); 2609 try { 2610 conditionWeight = Integer.parseInt(weight); 2611 } catch (NumberFormatException nfe) { 2612 if (PolicyManager.debug.warningEnabled()) { 2613 PolicyManager.debug.warning( 2614 "Policy.initializeStaticEvaluationWeights:" 2615 + " invalid conditionWeight defined, defaulting to 0"); 2616 } 2617 conditionWeight = 0; 2618 } 2619 } 2620 } 2621 2622 2623 /** Initializes evaluation weights for 2624 * Subjects, Conditions and rules of this policy object. 2625 */ 2626 void initializeEvaluationWeights() { 2627 psWeight = users.size() * subjectWeight; 2628 prWeight = rules.size() * ruleWeight; 2629 pcWeight = conditions.size() * conditionWeight; 2630 } 2631 2632 /** 2633 * Checks whether the policy is applicable to user identified by sso token 2634 * @return <code>true</code> if the policy is applicable to the user 2635 * identified by sso token, else <code>false</code> 2636 */ 2637 boolean isApplicableToUser(SSOToken token) 2638 throws PolicyException, SSOException 2639 { 2640 return users.isMember(token); 2641 } 2642 2643 static Map cloneRuleResults(Map ruleResults) { 2644 Map clonedResults = new HashMap(); 2645 if ( (ruleResults != null) && !ruleResults.isEmpty()) { 2646 Iterator keys = ruleResults.keySet().iterator(); 2647 while (keys.hasNext()) { 2648 String key = (String)keys.next(); 2649 Set values = (Set)ruleResults.get(key); 2650 Set clonedValues = new HashSet(); 2651 clonedValues.addAll(values); 2652 clonedResults.put(key, clonedValues); 2653 } 2654 } 2655 return clonedResults; 2656 } 2657 2658 /* 2659 * We track the subject realm when a realm subject is added to the policy. 2660 * We use this information to enforce that a policy has 2661 * realm subjects only from one realm. We also use this information 2662 * to enforce that policy is not saved into a different realm. 2663 */ 2664 String getSubjectRealm() { 2665 return subjectRealm; 2666 } 2667 2668 /** 2669 * Clears the cached membership evaluation results corresponding 2670 * to the <code>tokenIdString</code>. This is triggered through 2671 * <code>PolicySSOTokenListener</code> and <code>PolicyCache</code> 2672 * when session property 2673 * of a logged in user is changed 2674 * 2675 * @param tokenIdString sessionId of the user whose session property changed 2676 */ 2677 void clearSubjectResultCache(String tokenIdString) throws PolicyException { 2678 if (DEBUG.messageEnabled()) { 2679 DEBUG.message("Policy.clearSubjectResultCache(tokenIdString): " 2680 + " clearing cached subject evaluation result for " 2681 + " tokenId XXXXX"); 2682 } 2683 users.clearSubjectResultCache(tokenIdString); 2684 } 2685 2686 /** 2687 * Returns creation date. 2688 * 2689 * @return creation date. 2690 */ 2691 public long getCreationDate() { 2692 return creationDate; 2693 } 2694 2695 /** 2696 * Sets the creation date. 2697 * 2698 * @param creationDate creation date. 2699 */ 2700 public void setCreationDate(long creationDate) { 2701 this.creationDate = creationDate; 2702 } 2703 2704 /** 2705 * Returns last modified date. 2706 * 2707 * @return last modified date. 2708 */ 2709 public long getLastModifiedDate() { 2710 return lastModifiedDate; 2711 } 2712 2713 /** 2714 * Sets the last modified date. 2715 * 2716 * @param lastModifiedDate last modified date. 2717 */ 2718 public void setLastModifiedDate(long lastModifiedDate) { 2719 this.lastModifiedDate = lastModifiedDate; 2720 } 2721 2722 /** 2723 * Returns the user ID who last modified the policy. 2724 * 2725 * @return user ID who last modified the policy. 2726 */ 2727 public String getLastModifiedBy() { 2728 return lastModifiedBy; 2729 } 2730 2731 /** 2732 * Sets the user ID who last modified the policy. 2733 * 2734 * @param lastModifiedBy user ID who last modified the policy. 2735 */ 2736 public void setLastModifiedBy(String lastModifiedBy) { 2737 this.lastModifiedBy = lastModifiedBy; 2738 } 2739 2740 /** 2741 * Returns the user ID who created the policy. 2742 * 2743 * @return user ID who created the policy. 2744 */ 2745 public String getCreatedBy() { 2746 return createdBy; 2747 } 2748 2749 /** 2750 * Sets the user ID who created the policy. 2751 * 2752 * @param createdBy user ID who created the policy. 2753 */ 2754 public void setCreatedBy(String createdBy) { 2755 this.createdBy = createdBy; 2756 } 2757}