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