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