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: PolicyEvaluator.java,v 1.19 2010/01/14 23:18:35 dillidorai Exp $ 026 * 027 * Portions Copyrighted 2011-2014 ForgeRock AS. 028 */ 029package com.sun.identity.policy; 030 031import java.util.Set; 032import java.util.Enumeration; 033import java.util.HashSet; 034import java.util.Map; 035import java.util.HashMap; 036import java.util.Iterator; 037import java.util.Collections; 038import com.iplanet.am.sdk.AMStoreConnection; 039import com.iplanet.am.sdk.AMUser; 040import com.iplanet.am.sdk.AMException; 041import com.iplanet.am.util.Cache; 042import com.iplanet.am.util.SystemProperties; 043import com.sun.identity.shared.debug.Debug; 044import com.sun.identity.shared.stats.Stats; 045import com.iplanet.sso.SSOToken; 046import com.iplanet.sso.SSOTokenListener; 047import com.iplanet.sso.SSOException; 048import com.sun.identity.monitoring.Agent; 049import com.sun.identity.monitoring.SsoServerPolicySvcImpl; 050import com.sun.identity.entitlement.Application; 051import com.sun.identity.entitlement.ApplicationManager; 052import com.sun.identity.entitlement.Entitlement; 053import com.sun.identity.entitlement.EntitlementException; 054import com.sun.identity.entitlement.Evaluator; 055import com.sun.identity.entitlement.PrivilegeManager; 056import com.sun.identity.entitlement.opensso.SubjectUtils; 057import com.sun.identity.monitoring.MonitoringUtil; 058import com.sun.identity.policy.interfaces.Condition; 059import com.sun.identity.policy.interfaces.PolicyListener; 060import com.sun.identity.security.AdminTokenAction; 061import com.sun.identity.sm.AttributeSchema; 062import com.sun.identity.sm.ServiceManager; 063import com.sun.identity.shared.ldap.util.DN; 064import com.sun.identity.sm.DNMapper; 065import java.security.AccessController; 066import java.security.Principal; 067import java.util.List; 068import javax.security.auth.Subject; 069 070import static org.forgerock.openam.utils.CollectionUtils.asSet; 071 072/** 073 * The class <code>PolicyEvaluator</code> evaluates policies 074 * and provides policy decisions. 075 * @supported.api 076 * @deprecated since 12.0.0 077 */ 078@Deprecated 079public class PolicyEvaluator { 080 081 /** 082 * Constant used to identity all the resources of a service type. 083 * The resources include the sub resources of all resource prefixes of 084 * resource type 085 * 086 * @supported.api 087 */ 088 public static final String ALL_RESOURCES 089 = "---ALL_RESOURCES---"; 090 091 public static final String ADVICING_ORGANIZATION 092 = "AdvicingOrganization"; 093 094 /** 095 * Constant used to identity empty resource 096 * 097 * @supported.api 098 */ 099 public static final String EMPTY_RESOURCE_NAME = ""; 100 101 /** 102 * Constant used for key to pass the requested resource name canonicalized 103 * in the env map, so that Condition(s)/ResponseProvider(s) could use 104 * the requested resource name, if necessary 105 */ 106 public static final String SUN_AM_REQUESTED_RESOURCE 107 = "sun.am.requestedResource"; 108 109 /** 110 * Constant used for key to pass the requested resource name uncanonicalized 111 * in the env map, so that Condition(s)/ResponseProvider(s) could use 112 * the requested resource name, if necessary 113 */ 114 public static final String SUN_AM_ORIGINAL_REQUESTED_RESOURCE 115 = "sun.am.requestedOriginalResource"; 116 117 /** 118 * Constant used for key to pass the requested actions names 119 * in the env map, so that Condition(s)/ResponseProvider(s) could use 120 * the requested actions names, if necessary 121 */ 122 public static final String SUN_AM_REQUESTED_ACTIONS 123 = "sun.am.requestedActions"; 124 125 /** 126 * Constant used for key to pass the realm DN in the env map, so that Condition(s) 127 * can look up the relevant <code>PolicyConfig</code> config map, if necessary. 128 * <code>LDAPFilterCondition</code> needs to use PolicyConfig config map. 129 */ 130 public static final String REALM_DN = "am.policy.realmDN"; 131 132 public static final String RESULTS_CACHE_SESSION_CAP 133 = "com.sun.identity.policy.resultsCacheSessionCap"; 134 135 public static int DEFAULT_RESULTS_CACHE_SESSION_CAP = 1000; 136 137 public static int resultsCacheSessionCap = DEFAULT_RESULTS_CACHE_SESSION_CAP; 138 139 public static final String RESULTS_CACHE_RESOURCE_CAP 140 = "com.sun.identity.policy.resultsCacheResourceCap"; 141 142 public static int DEFAULT_RESULTS_CACHE_RESOURCE_CAP = 100; 143 144 public static int resultsCacheResourceCap = DEFAULT_RESULTS_CACHE_RESOURCE_CAP; 145 146 private static final Debug DEBUG = PolicyManager.debug; 147 private static final boolean USE_POLICY_CACHE = true; 148 private static final boolean INCLUDE_SUPER_RESOURCE_POLCIES = true; 149 private static final long DEFAULT_USER_NSROLE_CACHE_TTL = 600000; 150 151 private String orgName; 152 private String realm; 153 private String serviceTypeName; 154 private String applicationName; 155 private ServiceType serviceType; 156 private PolicyCache policyCache; 157 private PolicyManager policyManager; 158 private ResourceIndexManager resourceIndexManager; 159 160 private HashMap booleanActionNameTrueValues; //cache 161 private HashMap booleanActionNameFalseValues; //cache 162 private Set actionNames; //all action names valid for the serviceType 163 private Set orgNames = new HashSet(); // to pass org name in envParameters 164 // used to pass service type name in envParameters 165 private Set serviceTypeNames = new HashSet(); 166 // listener for policy decision cache 167 private PolicyDecisionCacheListener listener = null; 168 169 /* 170 * Cache to keep the policy evaluation results 171 * Cache structure layout: 172 * 173 * cache ----> Servicename1 174 * ----> servicename2 175 * ... 176 * ----> servicenameN 177 * 178 * servicenameI ----> Resourcename1 179 * ----> Resourcename2 180 * ... 181 * ----> ResourcenameN 182 * 183 * resourcenameI ----> userssotokenidstring1 184 * ----> userssotokenidstring2 185 * ... 186 * ----> userssotokenidstringN 187 * 188 * userssotokenidstringI ----> requestscope1 189 * ----> requestscope2 190 * 191 * requestscope1 ----> resourceresult1 192 * requestscope2 ----> resourceresult2 193 */ 194 static Map policyResultsCache = new HashMap(); 195 196 /* 197 * The sso token listener registry for policy decision cache. 198 * To avoid adding multiple sso token listeners for the same 199 * token, we use this registry to make sure the listener is 200 * registered only once for each token. It will be unregistered 201 * if token is expired. 202 * 203 * Key is tokenId and value is policySSOTokenListener 204 * ssoTokenIDString : PolicySSOTokenListener 205 * 206 * Used to clean up cache on ssoToken notifications 207 */ 208 public static Map ssoListenerRegistry = 209 Collections.synchronizedMap(new HashMap()); 210 211 /* 212 * The policy change listener registry for policy decision cache. 213 * To avoid adding multiple listeners for the same service, we 214 * use this registry to make sure the listener is registered only 215 * once for each service. 216 * 217 * Key is serviceTypeName and value is <code>PolicyDecisionCacheListener 218 * </code> 219 * serviceTypeName : PolicyDecisionCacheListener for service type 220 * 221 * Used to clean up the decision cache on policy change notification 222 */ 223 private static Map<String, PolicyDecisionCacheListener> policyListenerRegistry = 224 Collections.synchronizedMap(new HashMap<String, PolicyDecisionCacheListener>()); 225 226 /** 227 * The user <code>nsRole</code> attribute cache. 228 * AMSDK cache stops caching a user's nsRole attribute in 6.2 229 * due to notification issue. Adding this cache in policy to 230 * avoid performance impact caused by the AMSDK change. This 231 * cache uses a user's token as the key to map to the user's 232 * <code>nsRole</code> attribute values. 233 * 234 * Key is tokenId and value is set of role DN(s) 235 * ssoTokenIDString : set of role DN(s) 236 */ 237 static Map userNSRoleCache = 238 Collections.synchronizedMap(new HashMap()); 239 240 // TTL value for entries in the user's nsRole attribute values. 241 private static long userNSRoleCacheTTL = 0; 242 243 /** 244 * listener object to be used in cleaning up the 245 * userNSRoleCache, subjectEvaluationCache , user role 246 * cache in LDAPRoles and policyResultsCache 247 * upon user token expiration. 248 */ 249 public static SSOTokenListener ssoListener = 250 new PolicySSOTokenListener(); 251 252 /* 253 * Cache for sub resources keyed by resource name 254 * The structure is a Map of 255 * serviceType(String) : resourceNamesCache(Cache) 256 * Key for resourceNamesCache is a root resource name and value is 257 * a <code>Set</code> of sub resource names for the root resource name 258 * 259 * serviceType: resourceName : resourceNames 260 */ 261 private static Map resourceNamesMap = new HashMap(); 262 263 /** 264 * Constant key for passing organization name in the environment map during 265 * policy evaluation. The value for the key would be a <code>Set</code> 266 * with one element of type String. The string is the name of the 267 * organization the policy evaluator has been instantiated for. 268 */ 269 static final String ORGANIZATION_NAME = "organizationName"; 270 271 /** 272 * Constant key for passing service type name in the environment map during 273 * policy evaluation. The value for the key would be a <code>Set</code> 274 * with one element of type String. The string is the name of the 275 * <code>ServiceType</code> the policy evaluator has been instantiated for. 276 */ 277 static final String SERVICE_TYPE_NAME = "serviceTypeName"; 278 279 static final Object lock = new Object(); 280 281 /** 282 * Constructor to create a <code>PolicyEvaluator</code> given the <code> 283 * ServiceType</code> name. 284 * 285 * @param serviceTypeName the name of the <code>ServiceType</code> for 286 * which this evaluator can be used. 287 * @throws SSOException if <code>SSOToken</code> used by 288 * <code>PolicyEvaluator</code> is invalid 289 * @throws NameNotFoundException if the service with name 290 * <code>serviceTypeName</code> is not found 291 * @throws PolicyException for any other abnormal condition 292 * 293 * @supported.api 294 */ 295 public PolicyEvaluator(String serviceTypeName) 296 throws SSOException, NameNotFoundException, PolicyException { 297 298 this("", serviceTypeName); 299 300 registerListener(); 301 } 302 303 /** 304 * Constructor to create a <code>PolicyEvaluator</code> given organization 305 * name and the <code>ServiceType</code> name. 306 * 307 * @param orgName the name of the organization under which the evaluation 308 * is being done 309 * @param serviceTypeName the name of the <code>ServiceType</code> for 310 * which this evaluator can be used. 311 */ 312 public PolicyEvaluator(String orgName, String serviceTypeName) 313 throws SSOException, PolicyException, NameNotFoundException { 314 315 if ( (orgName == null) || (orgName.equals("/")) 316 || (orgName.length() == 0) ) { 317 orgName = ServiceManager.getBaseDN(); 318 } else { 319 orgName = com.sun.identity.sm.DNMapper.orgNameToDN(orgName); 320 } 321 this.orgName = orgName; 322 323 this.realm = com.sun.identity.sm.DNMapper.orgNameToRealmName(orgName); 324 this.serviceTypeName = serviceTypeName; 325 // Default application to be the service type, this maintains legacy behaviour. 326 this.applicationName = serviceTypeName; 327 328 this.policyCache = PolicyCache.getInstance(); 329 330 ServiceTypeManager stm = ServiceTypeManager.getServiceTypeManager(); 331 serviceType = stm.getServiceType(serviceTypeName); 332 policyManager = policyCache.getPolicyManager(orgName); 333 this.orgNames.add(policyManager.getOrganizationDN()); 334 this.serviceTypeNames.add(serviceTypeName); 335 resourceIndexManager = policyManager.getResourceIndexManager(); 336 337 String resultsCacheSessionCapString 338 = SystemProperties.get(RESULTS_CACHE_SESSION_CAP); 339 if (resultsCacheSessionCapString != null) { 340 try { 341 resultsCacheSessionCap 342 = Integer.parseInt(resultsCacheSessionCapString); 343 } catch (NumberFormatException nfe) { 344 if (PolicyManager.debug.warningEnabled()) { 345 PolicyManager.debug.warning("PolicyEvaluator:" 346 + "number format exception: " 347 + "defaulting resultsCacheSessionCap to " 348 + DEFAULT_RESULTS_CACHE_SESSION_CAP); 349 } 350 resultsCacheSessionCap = DEFAULT_RESULTS_CACHE_SESSION_CAP; 351 } 352 } else { 353 if (PolicyManager.debug.warningEnabled()) { 354 PolicyManager.debug.warning("PolicyEvaluator:" 355 + "resultsCacheSessionCap not specified, " 356 + "defaulting resultsCacheSessionCap to " 357 + DEFAULT_RESULTS_CACHE_SESSION_CAP); 358 } 359 resultsCacheSessionCap = DEFAULT_RESULTS_CACHE_SESSION_CAP; 360 } 361 if (PolicyManager.debug.messageEnabled()) { 362 PolicyManager.debug.message("PolicyEvaluator:" 363 + "resultsCacheSessionCap=" + resultsCacheSessionCap); 364 } 365 366 String resultsCacheResourceCapString 367 = SystemProperties.get(RESULTS_CACHE_RESOURCE_CAP); 368 if (resultsCacheResourceCapString != null) { 369 try { 370 resultsCacheResourceCap 371 = Integer.parseInt(resultsCacheResourceCapString); 372 } catch (NumberFormatException nfe) { 373 if (PolicyManager.debug.warningEnabled()) { 374 PolicyManager.debug.warning("PolicyEvaluator:" 375 + "number format exception: " 376 + "defaulting resultsCacheResourceCap to " 377 + DEFAULT_RESULTS_CACHE_RESOURCE_CAP); 378 } 379 resultsCacheResourceCap = DEFAULT_RESULTS_CACHE_RESOURCE_CAP; 380 } 381 } else { 382 if (PolicyManager.debug.warningEnabled()) { 383 PolicyManager.debug.warning("PolicyEvaluator:" 384 + "resultsCacheResourceCap not specified, " 385 + "defaulting resultsCacheResourceCap to " 386 + DEFAULT_RESULTS_CACHE_RESOURCE_CAP); 387 } 388 resultsCacheResourceCap = DEFAULT_RESULTS_CACHE_RESOURCE_CAP; 389 } 390 if (PolicyManager.debug.messageEnabled()) { 391 PolicyManager.debug.message("PolicyEvaluator:" 392 + "resultsCacheResourceCap=" + resultsCacheResourceCap); 393 } 394 395 } 396 397 /** 398 * Creates a new policy evaluator instance. 399 * 400 * @param orgName 401 * the name of the organization under which the evaluation is being done 402 * @param serviceTypeName 403 * the name of the <code>ServiceType</code> for which this evaluator can be used 404 * @param applicationName 405 * the application name containing the policies in question 406 * 407 * @throws PolicyException 408 * should some error occur constructor the evaluator 409 * @throws SSOException 410 * should some error occur with regards to any SSO token 411 */ 412 public PolicyEvaluator(String orgName, String serviceTypeName, String applicationName) 413 throws PolicyException, SSOException { 414 this(orgName, serviceTypeName); 415 this.applicationName = applicationName; 416 417 registerListener(); 418 } 419 420 /** 421 * Register a policy listener for updating policy decision cache if there is none already registered. 422 */ 423 private void registerListener() { 424 synchronized (lock) { 425 if (!policyListenerRegistry.containsKey(serviceTypeName)) { 426 listener = new PolicyDecisionCacheListener(serviceTypeName); 427 428 try { 429 PolicyCache.getInstance().addPolicyListener(listener); 430 } catch (PolicyException pe) { 431 DEBUG.error("PolicyEvaluator: registering policy decision cache listener failed"); 432 } 433 434 policyListenerRegistry.put(serviceTypeName, listener); 435 436 if (DEBUG.messageEnabled()) { 437 DEBUG.message("PolicyEvaluator:policy listener for service " + serviceTypeName + " added"); 438 } 439 440 } else { 441 listener = policyListenerRegistry.get(serviceTypeName); 442 } 443 } 444 } 445 446 /** 447 * Evaluates a simple privilege of boolean type. The privilege indicate 448 * if the user can perform specified action on the specified resource. 449 * Invoking this method would result in <code>PolicyException</code>, 450 * if the syntax for the <code>actionName</code> is not declared to be 451 * boolean, in the service schema. 452 * 453 * @param token single sign on token of the user evaluating policies 454 * @param resourceName name of the resource the user is trying to access 455 * @param actionName name of the action the user is trying to perform on 456 * the resource 457 * 458 * @return the result of the evaluation as a boolean value 459 * 460 * @exception SSOException single-sign-on token invalid or expired 461 * 462 */ 463 public boolean isAllowed(SSOToken token, String resourceName, 464 String actionName) throws PolicyException, SSOException { 465 return (isAllowed(token, resourceName, actionName, 466 new HashMap())); 467 } 468 469 /** 470 * Evaluates simple privileges of boolean type. The privilege indicate 471 * if the user can perform specified action on the specified resource. 472 * The evaluation depends on user's application environment parameters. 473 * Invoking this method would result in <code>PolicyException</code>, 474 * if the syntax for the <code>actionName</code> is not declared to be 475 * boolean, in the service schema. 476 * 477 * @param token single sign on token of the user evaluating policies 478 * @param resourceName name of the resource the user is trying to access 479 * @param actionName name of the action the user is trying to perform on 480 * the resource 481 * @param envParameters run-time environment parameters 482 * 483 * @return the result of the evaluation as a boolean value 484 * 485 * @throws SSOException single-sign-on token invalid or expired 486 * @throws PolicyException for any other abnormal condition 487 * 488 * @supported.api 489 */ 490 public boolean isAllowed(SSOToken token, String resourceName, 491 String actionName, Map envParameters) throws SSOException, 492 PolicyException { 493 if (PolicyManager.isMigratedToEntitlementService()) { 494 return isAllowedE(token, resourceName, actionName, envParameters); 495 } 496 return isAllowedO(token, resourceName, actionName, envParameters); 497 } 498 499 public boolean isAllowedO(SSOToken token, String resourceName, 500 String actionName, Map envParameters) throws SSOException, 501 PolicyException { 502 503 ActionSchema schema = serviceType.getActionSchema(actionName); 504 505 // Cache the false values for the action names 506 if (booleanActionNameFalseValues == null) { 507 booleanActionNameFalseValues = new HashMap(10); 508 } 509 String falseValue = null; 510 if ((falseValue = (String) 511 booleanActionNameFalseValues.get(actionName)) == null) { 512 falseValue = schema.getFalseValue(); 513 // Add it to the cache 514 booleanActionNameFalseValues.put(actionName, falseValue); 515 } 516 517 518 // Cache the true values for the action names 519 if (booleanActionNameTrueValues == null) { 520 booleanActionNameTrueValues = new HashMap(10); 521 } 522 523 String trueValue = null; 524 if ((trueValue = (String) 525 booleanActionNameTrueValues.get(actionName)) == null) { 526 trueValue = schema.getTrueValue(); 527 // Add it to the cache 528 booleanActionNameTrueValues.put(actionName, trueValue); 529 } 530 531 if (!AttributeSchema.Syntax.BOOLEAN.equals(schema.getSyntax())) { 532 String objs[] = {actionName}; 533 throw new PolicyException( 534 ResBundleUtils.rbName, 535 "action_does_not_have_boolean_syntax", objs, null); 536 } 537 538 boolean actionAllowed = false; 539 HashSet actionNames = new HashSet(2); 540 actionNames.add(actionName); 541 PolicyDecision policyDecision = getPolicyDecision(token, resourceName, 542 actionNames, envParameters); 543 ActionDecision actionDecision = 544 (ActionDecision) policyDecision.getActionDecisions() 545 .get(actionName); 546 547 if ( actionDecision != null ) { 548 Set set = (Set) actionDecision.getValues(); 549 if ( (set != null) ) { 550 if ( set.contains(falseValue) ) { 551 actionAllowed = false; 552 } else if ( set.contains(trueValue) ) { 553 actionAllowed = true; 554 } 555 } 556 } 557 558 return actionAllowed; 559 } 560 561 private void padEnvParameters(SSOToken token, String resourceName, 562 String actionName, Map envParameters) throws PolicyException, SSOException { 563 if ((resourceName == null) || (resourceName.trim().length() == 0)) { 564 resourceName = Rule.EMPTY_RESOURCE_NAME; 565 } 566 567 Set originalResourceNames = new HashSet(2); 568 originalResourceNames.add(resourceName); 569 570 String realmName = (DN.isDN(realm)) ? 571 DNMapper.orgNameToRealmName(realm) : realm; 572 try { 573 Application appl = ApplicationManager.getApplication( 574 PrivilegeManager.superAdminSubject, 575 realmName, applicationName); 576 resourceName = appl.getResourceComparator().canonicalize( 577 resourceName); 578 } catch (EntitlementException e) { 579 throw new PolicyException(e); 580 } 581 //Add request resourceName and request actionNames to the envParameters 582 //so that Condition(s)/ResponseProvider(s) can use them if necessary 583 Set resourceNames = new HashSet(2); 584 resourceNames.add(resourceName); 585 586 Set actions = new HashSet(); 587 if (actionName != null) { 588 actions.add(actionName); 589 } else { 590 Set actionNames = serviceType.getActionNames(); 591 if (actionNames != null) { 592 actions.addAll(actionNames); 593 } 594 } 595 596 envParameters.put(SUN_AM_REQUESTED_RESOURCE, resourceNames); 597 envParameters.put(SUN_AM_ORIGINAL_REQUESTED_RESOURCE, 598 originalResourceNames); 599 envParameters.put(SUN_AM_REQUESTED_ACTIONS, actions); 600 envParameters.put(REALM_DN, asSet(policyManager.getOrganizationDN())); 601 602 // Fix for OPENAM-811 603 String userid = null; 604 Principal principal = token.getPrincipal(); 605 if (principal != null) { 606 userid = principal.getName(); 607 } 608 if ((userid != null) && (userid.length() != 0)) { 609 HashSet<String> set = new HashSet<String>(); 610 set.add(userid); 611 // Required by the AMIdentityMembershipCondition 612 envParameters.put(Condition.INVOCATOR_PRINCIPAL_UUID, set); 613 } else { 614 if (DEBUG.messageEnabled()) { 615 DEBUG.message("PolicyEvaluator.padEnvParameters() unable to get userid from token."); 616 } 617 } 618 } 619 620 private boolean isAllowedE(SSOToken token, String resourceName, 621 String actionName, Map envParameters) throws SSOException, 622 PolicyException { 623 624 if ((envParameters == null) || envParameters.isEmpty()) { 625 envParameters = new HashMap(); 626 } 627 628 padEnvParameters(token, resourceName, actionName, envParameters); 629 630 ActionSchema schema = serviceType.getActionSchema(actionName); 631 632 if (!AttributeSchema.Syntax.BOOLEAN.equals(schema.getSyntax())) { 633 String objs[] = {actionName}; 634 throw new PolicyException( 635 ResBundleUtils.rbName, 636 "action_does_not_have_boolean_syntax", objs, null); 637 } 638 639 HashSet actions = new HashSet(2); 640 actions.add(actionName); 641 SSOToken adminSSOToken = (SSOToken) AccessController.doPrivileged( 642 AdminTokenAction.getInstance()); 643 644 try { 645 Subject adminSubject = SubjectUtils.createSubject(token); 646 647 Entitlement entitlement = new Entitlement(serviceTypeName, resourceName, actions); 648 entitlement.canonicalizeResources(adminSubject, realm); 649 650 Evaluator eval = new Evaluator(adminSubject, applicationName); 651 return eval.hasEntitlement(realm, SubjectUtils.createSubject(token), entitlement, envParameters); 652 653 } catch (EntitlementException e) { 654 throw new PolicyException(e); 655 } 656 } 657 658 private String getActionFalseBooleanValue(String actionName) 659 throws InvalidNameException { 660 661 if (serviceType == null) { 662 return Boolean.FALSE.toString(); 663 } 664 665 ActionSchema schema = serviceType.getActionSchema(actionName); 666 667 // Cache the false values for the action names 668 if (booleanActionNameFalseValues == null) { 669 booleanActionNameFalseValues = new HashMap(10); 670 } 671 String falseValue = null; 672 if ((falseValue = (String) 673 booleanActionNameFalseValues.get(actionName)) == null) { 674 falseValue = schema.getFalseValue(); 675 // Add it to the cache 676 booleanActionNameFalseValues.put(actionName, falseValue); 677 } 678 return falseValue; 679 } 680 681 private String getActionTrueBooleanValue(String actionName) 682 throws InvalidNameException { 683 684 if (serviceType == null) { 685 return Boolean.TRUE.toString(); 686 } 687 688 ActionSchema schema = serviceType.getActionSchema(actionName); 689 690 // Cache the true values for the action names 691 if (booleanActionNameTrueValues == null) { 692 booleanActionNameTrueValues = new HashMap(10); 693 } 694 695 String trueValue = null; 696 if ((trueValue = (String) 697 booleanActionNameTrueValues.get(actionName)) == null) { 698 trueValue = schema.getTrueValue(); 699 booleanActionNameTrueValues.put(actionName, trueValue); 700 } 701 702 return trueValue; 703 } 704 705 /** 706 * Evaluates privileges of the user to perform the specified actions 707 * on the specified resource. 708 * 709 * @param token single sign on token of the user evaluating policies 710 * @param resourceName name of the resource the user is trying to access 711 * @param actionNames a <code>Set</code> of <code>Sting</code> objects 712 * representing names of the actions the user is trying to perform on 713 * the resource 714 * 715 * @return policy decision 716 * 717 * @exception SSOException single-sign-on token invalid or expired 718 * @exception PolicyException for any other abnormal condition. 719 */ 720 public PolicyDecision getPolicyDecision(SSOToken token, String resourceName, 721 Set actionNames) throws PolicyException, SSOException { 722 return getPolicyDecision(token, resourceName, actionNames, null); 723 } 724 725 726 /** 727 * Evaluates privileges of the user to perform the specified actions 728 * on the specified resource. The evaluation depends on user's 729 * application environment parameters. 730 * 731 * @param token single sign on token of the user evaluating policies 732 * @param resourceName name of the resource the user is trying to access 733 * @param actionNames <code>Set</code> of names(<code>String</code>) of 734 * the action the user is trying to perform on the resource 735 * @param envParameters <code>Map</code> of run-time environment parameters 736 * 737 * @return policy decision 738 * 739 * @throws SSOException single-sign-on token invalid or expired 740 * @throws PolicyException for any other abnormal condition 741 * 742 * @supported.api 743 */ 744 public PolicyDecision getPolicyDecision( 745 SSOToken token, String resourceName, Set actionNames, 746 Map envParameters) throws SSOException, PolicyException { 747 if ( (resourceName == null) || (resourceName.length() == 0) ) { 748 resourceName = Rule.EMPTY_RESOURCE_NAME; 749 } 750 751 Set originalResourceNames = new HashSet(2); 752 originalResourceNames.add(resourceName); 753 754 resourceName = serviceType.canonicalize(resourceName); 755 756 //Add request resourceName and request actionNames to the envParameters 757 //so that Condition(s)/ResponseProvider(s) can use them if necessary 758 Set resourceNames = new HashSet(2); 759 resourceNames.add(resourceName); 760 761 /* compute for all action names if passed in actionNames is 762 null or empty */ 763 if ( (actionNames == null) || (actionNames.isEmpty()) ) { 764 actionNames = serviceType.getActionNames(); 765 } 766 767 Set actions = new HashSet(); 768 if (actionNames != null) { 769 actions.addAll(actionNames); 770 } 771 772 /* 773 * We create new HashMap in place of empty map since 774 * Collections.EMPTY_MAP can not be modified 775 */ 776 if ((envParameters == null) || envParameters.isEmpty()) { 777 envParameters = new HashMap(); 778 } 779 780 envParameters.put(SUN_AM_REQUESTED_RESOURCE, resourceNames); 781 envParameters.put(SUN_AM_ORIGINAL_REQUESTED_RESOURCE, 782 originalResourceNames); 783 envParameters.put(SUN_AM_REQUESTED_ACTIONS, actions); 784 envParameters.put(REALM_DN, asSet(policyManager.getOrganizationDN())); 785 786 return getPolicyDecision(token, resourceName, actionNames, 787 envParameters, new HashSet()); 788 } 789 790 /** 791 * Evaluates privileges of the user to perform the specified actions 792 * on the specified resource. The evaluation depends on user's 793 * application environment parameters. 794 * 795 * @param token single sign on token of the user evaluating policies 796 * @param resourceName name of the resource the user is trying to access 797 * @param actionNames <code>Set</code> of names(<code>String</code>) of the 798 * action the user is trying to perform on the resource. 799 * @param envParameters run-time environment parameters 800 * @param visitedOrgs names of organizations that have been already visited 801 * during policy evaluation for this request 802 * 803 * @return policy decision 804 * 805 * @exception SSOException single-sign-on token invalid or expired 806 * @exception PolicyException if any policy evaluation error. 807 */ 808 private PolicyDecision getPolicyDecision( 809 SSOToken token, String resourceName, Set actionNames, 810 Map envParameters, Set visitedOrgs) 811 throws PolicyException, SSOException { 812 if (MonitoringUtil.isRunning()) { 813 SsoServerPolicySvcImpl sspsi = 814 Agent.getPolicySvcMBean(); 815 sspsi.incPolicyEvalsIn(); 816 } 817 818 try { 819 return (PolicyManager.isMigratedToEntitlementService()) ? 820 getPolicyDecisionE(token, resourceName, actionNames, 821 envParameters) : getPolicyDecisionO(token, resourceName, 822 actionNames, 823 envParameters, visitedOrgs); 824 } finally { 825 if (MonitoringUtil.isRunning()) { 826 SsoServerPolicySvcImpl sspsi = 827 Agent.getPolicySvcMBean(); 828 sspsi.incPolicyEvalsOut(); 829 } 830 } 831 } 832 833 834 /** 835 * Evaluates privileges of the user to perform the specified actions 836 * on the specified resource. The evaluation depends on user's 837 * application environment parameters. 838 * 839 * @param token single sign on token of the user evaluating policies 840 * @param resourceName name of the resource the user is trying to access 841 * @param actionNames <code>Set</code> of names(<code>String</code>) of the 842 * action the user is trying to perform on the resource. 843 * @param envParameters run-time environment parameters 844 * @return policy decision 845 * 846 * @exception SSOException single-sign-on token invalid or expired 847 * @exception PolicyException if any policy evaluation error. 848 */ 849 private PolicyDecision getPolicyDecisionE( 850 SSOToken token, String resourceName, Set actionNames, 851 Map envParameters) 852 throws PolicyException, SSOException { 853 854 if ( DEBUG.messageEnabled() ) { 855 DEBUG.message("Evaluating policies at org " + orgName); 856 } 857 858 /* compute for all action names if passed in actionNames is 859 null or empty */ 860 if ( (actionNames == null) || (actionNames.isEmpty()) ) { 861 actionNames = serviceType.getActionNames(); 862 } 863 864 SSOToken adminSSOToken = (SSOToken) AccessController.doPrivileged( 865 AdminTokenAction.getInstance()); 866 867 try { 868 Evaluator eval = new Evaluator( 869 SubjectUtils.createSubject(adminSSOToken), applicationName); 870 Subject sbj = (token != null) ? SubjectUtils.createSubject(token) : 871 null; 872 List<Entitlement> entitlements = eval.evaluate( 873 orgName, sbj, resourceName, envParameters, false); 874 if ((entitlements != null) && !entitlements.isEmpty()) { 875 Entitlement e = entitlements.iterator().next(); 876 return (entitlementToPolicyDecision(e, actionNames)); 877 } 878 } catch (EntitlementException e) { 879 throw new PolicyException(e); 880 } 881 return (new PolicyDecision()); 882 } 883 884 private PolicyDecision getPolicyDecisionO( 885 SSOToken token, String resourceName, Set actionNames, 886 Map envParameters, Set visitedOrgs) 887 throws PolicyException, SSOException { 888 889 if ( DEBUG.messageEnabled() ) { 890 DEBUG.message("Evaluating policies at org " + orgName); 891 } 892 893 /* compute for all action names if passed in actionNames is 894 null or empty */ 895 if ( (actionNames == null) || (actionNames.isEmpty()) ) { 896 actionNames = serviceType.getActionNames(); 897 } 898 899 Set actions = new HashSet(); 900 actions.addAll(actionNames); 901 902 PolicyDecision mergedPolicyDecision = null; 903 Set policyNameSet = null; 904 Set toRemovePolicyNameSet = null; 905 policyNameSet = resourceIndexManager.getPolicyNames( 906 serviceType, resourceName, INCLUDE_SUPER_RESOURCE_POLCIES); 907 if ( DEBUG.messageEnabled() ) { 908 String tokenPrincipal = 909 (token != null) ? token.getPrincipal().getName() 910 : PolicyUtils.EMPTY_STRING; 911 DEBUG.message(new StringBuffer("at PolicyEvaluator") 912 .append(".getPolicyDecision()") 913 .append(" principal, resource name, ") 914 .append("action names, policy names,") 915 .append(" orgName =") 916 .append(tokenPrincipal) .append(", ") 917 .append(resourceName) .append(", ") 918 .append(actionNames) .append(", ") 919 .append(policyNameSet).append(", ") 920 .append(orgName).toString()); 921 } 922 Iterator policyIter = policyNameSet.iterator(); 923 while ( policyIter.hasNext() ) { 924 String policyName = (String) policyIter.next(); 925 Policy policy = policyManager.getPolicy(policyName, 926 USE_POLICY_CACHE); 927 if ( policy != null && policy.isActive()) { 928 //policy might have been removed or inactivated 929 PolicyDecision policyDecision = policy.getPolicyDecision(token, 930 serviceTypeName, resourceName, actions, envParameters); 931 if (!policy.isReferralPolicy() && policyDecision.hasAdvices()) { 932 addAdvice(policyDecision, ADVICING_ORGANIZATION, orgName); 933 } 934 935 // Let us log all policy evaluation results 936 if (PolicyUtils.logStatus && (token != null)) { 937 String decision = policyDecision.toString(); 938 if (decision != null && decision.length() != 0) { 939 String[] objs = { policyName, orgName, serviceTypeName, 940 resourceName, actionNames.toString(), 941 decision }; 942 PolicyUtils.logAccessMessage("POLICY_EVALUATION", 943 objs, token, serviceTypeName); 944 } 945 } 946 if ( mergedPolicyDecision == null ) { 947 mergedPolicyDecision = policyDecision; 948 } else { 949 mergePolicyDecisions(serviceType, policyDecision, 950 mergedPolicyDecision); 951 } 952 953 if (!PolicyConfig.continueEvaluationOnDenyDecision()) { 954 actions.removeAll(getFinalizedActions(serviceType, 955 mergedPolicyDecision)); 956 } 957 958 if ( actions.isEmpty() ) { 959 break; 960 } 961 } else { // add policy names to toRemovePolicyNameSet 962 if (toRemovePolicyNameSet == null) { 963 toRemovePolicyNameSet = new HashSet(); 964 } 965 toRemovePolicyNameSet.add(policyName); 966 if ( DEBUG.messageEnabled() ) { 967 DEBUG.message("PolicyEvaluator.getPolicyDecision():" 968 +policyName+ " is inactive or non-existent"); 969 } 970 } 971 } 972 973 // remove inactive/missing policies from policyNameSet 974 if (toRemovePolicyNameSet != null) { 975 policyNameSet.removeAll(toRemovePolicyNameSet); 976 } 977 978 Set orgsToVisit = getOrgsToVisit(policyNameSet); 979 980 if (PolicyConfig.orgAliasMappedResourcesEnabled() 981 && PolicyManager.WEB_AGENT_SERVICE.equalsIgnoreCase( 982 serviceTypeName)) { 983 String orgAlias = policyManager.getOrgAliasWithResource( 984 resourceName); 985 if (orgAlias != null) { 986 String orgWithAlias = policyManager.getOrgNameWithAlias( 987 orgAlias); 988 if (orgWithAlias != null) { 989 if ( DEBUG.messageEnabled() ) { 990 DEBUG.message("PolicyEvaluator.getPolicyDecision():" 991 + "adding orgWithAlias to orgsToVisit=" 992 + orgWithAlias); 993 } 994 orgsToVisit.add(orgWithAlias); 995 } 996 } 997 } 998 999 if ( DEBUG.messageEnabled() ) { 1000 DEBUG.message(new StringBuffer("at PolicyEvaluator") 1001 .append(".getPolicyDecision()") 1002 .append(" orgsToVist=").append(orgsToVisit.toString()) 1003 .toString()); 1004 } 1005 orgsToVisit.removeAll(visitedOrgs); 1006 if ( DEBUG.messageEnabled() ) { 1007 DEBUG.message(new StringBuffer("at PolicyEvaluator") 1008 .append(".getPolicyDecision()") 1009 .append(" orgsToVist(after removing already visited orgs=") 1010 .append(orgsToVisit.toString()) 1011 .toString() ); 1012 } 1013 while ( !orgsToVisit.isEmpty() && !actions.isEmpty() ) { 1014 String orgToVisit = (String) orgsToVisit.iterator().next(); 1015 orgsToVisit.remove(orgToVisit); 1016 visitedOrgs.add(orgToVisit); 1017 try { 1018 // need to use admin sso token here. Need all privileges to 1019 // check for the organzation 1020 policyManager.verifyOrgName(orgToVisit); 1021 } catch (NameNotFoundException nnfe) { 1022 if( DEBUG.warningEnabled()) { 1023 DEBUG.warning("Organization does not exist - " 1024 + "skipping referral to " + orgToVisit); 1025 } 1026 continue; 1027 } 1028 PolicyEvaluator pe = new PolicyEvaluator(orgToVisit, 1029 serviceTypeName); 1030 /** 1031 * save current realm DN before passing control down to sub-realm 1032 */ 1033 Set<String> savedRealmDn = (Set<String>) envParameters.get(REALM_DN); 1034 // Update env to point to the realm policy config data. 1035 envParameters.put(REALM_DN, asSet(DNMapper.orgNameToDN(orgToVisit))); 1036 PolicyDecision policyDecision 1037 = pe.getPolicyDecision(token, resourceName, actionNames, 1038 envParameters,visitedOrgs); 1039 // restore back the policy config data for the parent realm 1040 envParameters.put(REALM_DN, savedRealmDn); 1041 if ( mergedPolicyDecision == null ) { 1042 mergedPolicyDecision = policyDecision; 1043 } else { 1044 mergePolicyDecisions(serviceType, policyDecision, 1045 mergedPolicyDecision); 1046 } 1047 if (!PolicyConfig.continueEvaluationOnDenyDecision()) { 1048 actions.removeAll(getFinalizedActions(serviceType, 1049 mergedPolicyDecision)); 1050 } 1051 } 1052 1053 if ( mergedPolicyDecision == null ) { 1054 mergedPolicyDecision = new PolicyDecision(); 1055 } 1056 1057 return mergedPolicyDecision; 1058 } 1059 1060 /** 1061 * Gets protected resources for a user identified by single sign on token 1062 * Conditions defined in the policies are ignored while 1063 * computing protected resources. 1064 * Only resources that are sub resources of the given 1065 * <code>rootResource</code> or equal to the given <code>rootResource</code> 1066 * would be returned. 1067 * If all policies applicable to a resource are 1068 * only referral policies, no <code>ProtectedResource</code> would be 1069 * returned for such a resource. 1070 * 1071 * @param token single sign on token of the user 1072 * @param rootResource only resources that are sub resources of the 1073 * given <code>rootResource</code> or equal to the 1074 * given <code>rootResource</code> would be returned 1075 * <code>rootResource</code> would be returned. 1076 * If <code>PolicyEvaluator.ALL_RESOURCES</code> is 1077 * passed as <code>rootResource</code>, resources under 1078 * all root resources of the service 1079 * type are considered while computing protected 1080 * resources. 1081 * @return <code>Set</code> of protected resources. The set 1082 * contains <code>ProtectedResource</code> objects. 1083 * 1084 * @throws SSOException if single sign on token is invalid 1085 * @throws PolicyException for any other abnormal condition 1086 * @see ProtectedResource 1087 * 1088 * @supported.api 1089 * 1090 */ 1091 public Set getProtectedResourcesIgnoreConditions( 1092 SSOToken token, String rootResource) 1093 throws SSOException, PolicyException 1094 { 1095 if ( (rootResource == null) || (rootResource.equals("")) ) { 1096 rootResource = EMPTY_RESOURCE_NAME; 1097 } 1098 Set protectedResources = new HashSet(); 1099 Set topLevelResources = null; 1100 if (rootResource.equals(ALL_RESOURCES)) { 1101 topLevelResources 1102 = resourceIndexManager.getTopLevelResourceNames( 1103 serviceType); 1104 } else { 1105 topLevelResources = new HashSet(); 1106 topLevelResources.add(rootResource); 1107 } 1108 Iterator iter = topLevelResources.iterator(); 1109 while (iter.hasNext()) { 1110 String topLevelResource = (String)iter.next(); 1111 Set resourceNames 1112 = getResourceNames(token, topLevelResource, true); 1113 Iterator resourceIter = resourceNames.iterator(); 1114 while (resourceIter.hasNext()) { 1115 String resourceName = (String)resourceIter.next(); 1116 Set protectingPolicies 1117 = getProtectingPolicies(token, resourceName); 1118 if ((protectingPolicies != null) 1119 && (!protectingPolicies.isEmpty())) { 1120 boolean allReferralPolicies = true; 1121 Iterator iter1 = protectingPolicies.iterator(); 1122 while (iter1.hasNext()){ 1123 Policy policy = (Policy)iter1.next(); 1124 if (!policy.isReferralPolicy()) { 1125 allReferralPolicies = false; 1126 break; 1127 } 1128 } 1129 if (!allReferralPolicies) { 1130 protectedResources.add( 1131 new ProtectedResource(resourceName, 1132 protectingPolicies)); 1133 } 1134 } 1135 } 1136 } 1137 return protectedResources; 1138 } 1139 1140 /** 1141 * Gets policies applicable to user that are protecting 1142 * the specified resource. 1143 * 1144 * @param token single sign on token of the user evaluating policies 1145 * @param resourceName name of the resource the user is trying to access 1146 * 1147 * @return set of policies applicable to user that are protecting the 1148 * specified resource 1149 * 1150 * @throws PolicyException policy exception coming from policy framework 1151 * @throws SSOException single-sign-on token invalid or expired 1152 * 1153 */ 1154 Set getProtectingPolicies( 1155 SSOToken token, String resourceName) 1156 throws PolicyException, SSOException 1157 { 1158 return getProtectingPolicies(token, resourceName, new HashSet()); 1159 } 1160 1161 /** 1162 * Gets policies applicable to user that are protecting 1163 * the specified resource. 1164 * 1165 * @param token single sign on token of the user evaluating policies 1166 * @param resourceName name of the resource the user is trying to access 1167 * 1168 * @param visitedOrgs names of organizations that have been 1169 * already visited during evaluation for this request 1170 * @return set of policies applicable to user that are protecting the 1171 * specified resource 1172 * 1173 * @throws PolicyException policy exception coming from policy framework 1174 * @throws SSOException single-sign-on token invalid or expired 1175 * 1176 */ 1177 private Set getProtectingPolicies( 1178 SSOToken token, String resourceName, Set visitedOrgs) 1179 throws PolicyException, SSOException 1180 { 1181 1182 Set protectingPolicies = new HashSet(); 1183 1184 1185 // false - do not include super resource policies 1186 // includes EXACT_MATCH and WILD_CARD_MATCH 1187 Set policyNameSet = resourceIndexManager.getPolicyNames( 1188 serviceType, resourceName, false); 1189 Set toRemovePolicyNameSet = null; 1190 if ( DEBUG.messageEnabled() ) { 1191 String tokenPrincipal = 1192 (token != null) ? token.getPrincipal().getName() 1193 : PolicyUtils.EMPTY_STRING; 1194 DEBUG.message(new StringBuffer( 1195 "at PolicyEvaluator.getProtectingPolicies()") 1196 .append(" principal, resource name, policy names,") 1197 .append(" orgName =") 1198 .append(tokenPrincipal) .append(", ") 1199 .append(resourceName) .append(", ") 1200 .append(policyNameSet).append(", ") 1201 .append(orgName).toString()); 1202 } 1203 Iterator policyIter = policyNameSet.iterator(); 1204 while ( policyIter.hasNext() ) { 1205 String policyName = (String) policyIter.next(); 1206 Policy policy = policyManager.getPolicy(policyName); 1207 if ( policy != null && policy.isActive()) { 1208 //policy might have been removed or inactivated 1209 if (!policy.isReferralPolicy()) { 1210 if (policy.isApplicableToUser(token)) { 1211 policy.setOrganizationName(orgName); 1212 protectingPolicies.add(policy); 1213 } 1214 } else { 1215 policy.setOrganizationName(orgName); 1216 protectingPolicies.add(policy); 1217 } 1218 } else { // add policy names to toRemovePolicyNameSet 1219 if (toRemovePolicyNameSet == null) { 1220 toRemovePolicyNameSet = new HashSet(); 1221 } 1222 toRemovePolicyNameSet.add(policyName); 1223 if ( DEBUG.messageEnabled() ) { 1224 DEBUG.message("PolicyEvaluator.getProtectingPolicies():" 1225 +policyName+ " is inactive or non-existent"); 1226 } 1227 } 1228 } 1229 1230 // remove inactive/missing policies from policyNameSet 1231 if (toRemovePolicyNameSet != null) { 1232 policyNameSet.removeAll(toRemovePolicyNameSet); 1233 } 1234 1235 //include super resource policies provided they are referral policies 1236 policyNameSet = resourceIndexManager.getSuperResourcePolicyNames( 1237 serviceType, resourceName); 1238 if (toRemovePolicyNameSet != null) { 1239 toRemovePolicyNameSet.clear(); 1240 } 1241 policyIter = policyNameSet.iterator(); 1242 while ( policyIter.hasNext() ) { 1243 String policyName = (String) policyIter.next(); 1244 Policy policy = policyManager.getPolicy(policyName); 1245 if ( policy != null && policy.isActive()) { 1246 //policy might have been removed or inactivated 1247 if (policy.isReferralPolicy()) { 1248 policy.setOrganizationName(orgName); 1249 protectingPolicies.add(policy); 1250 } 1251 } else { // add policy names to toRemovePolicyNameSet 1252 if (toRemovePolicyNameSet == null) { 1253 toRemovePolicyNameSet = new HashSet(); 1254 } 1255 toRemovePolicyNameSet.add(policyName); 1256 if ( DEBUG.messageEnabled() ) { 1257 DEBUG.message("PolicyEvaluator.getProtectingPolicies():" 1258 +policyName+ " is inactive or non-existent"); 1259 } 1260 } 1261 } 1262 // remove inactive/missing policies from policyNameSet 1263 if (toRemovePolicyNameSet != null) { 1264 policyNameSet.removeAll(toRemovePolicyNameSet); 1265 } 1266 1267 Set orgsToVisit = getOrgsToVisit(policyNameSet); 1268 if ( DEBUG.messageEnabled() ) { 1269 DEBUG.message(new StringBuffer( 1270 "at PolicyEvaluator.getProtectingPolicies()") 1271 .append(" orgsToVist=").append(orgsToVisit.toString()) 1272 .toString()); 1273 } 1274 1275 if (PolicyConfig.orgAliasMappedResourcesEnabled() 1276 && PolicyManager.WEB_AGENT_SERVICE.equalsIgnoreCase( 1277 serviceTypeName)) { 1278 String orgAlias = policyManager.getOrgAliasWithResource( 1279 resourceName); 1280 if (orgAlias != null) { 1281 String orgWithAlias = policyManager.getOrgNameWithAlias( 1282 orgAlias); 1283 if (orgWithAlias != null) { 1284 if ( DEBUG.messageEnabled() ) { 1285 DEBUG.message("PolicyEvaluator.getProtectingPolicies():" 1286 + "adding orgWithAlias to orgsToVisit=" 1287 + orgWithAlias); 1288 } 1289 orgsToVisit.add(orgWithAlias); 1290 } 1291 } 1292 } 1293 1294 orgsToVisit.removeAll(visitedOrgs); 1295 if ( DEBUG.messageEnabled() ) { 1296 DEBUG.message(new StringBuffer( 1297 "at PolicyEvaluator.getProtectingPolicies()") 1298 .append(" orgsToVist(after removing already visited orgs=") 1299 .append(orgsToVisit.toString()) 1300 .toString() ); 1301 } 1302 while (!orgsToVisit.isEmpty() ) { 1303 String orgToVisit = (String) orgsToVisit.iterator().next(); 1304 orgsToVisit.remove(orgToVisit); 1305 visitedOrgs.add(orgToVisit); 1306 try { 1307 // need to use admin sso token here. Need all privileges to 1308 // check for the organzation 1309 policyManager.verifyOrgName(orgToVisit); 1310 } catch (NameNotFoundException nnfe) { 1311 if( DEBUG.warningEnabled()) { 1312 DEBUG.warning("Organization does not exist - " 1313 + "skipping referral to " + orgToVisit); 1314 } 1315 continue; 1316 } 1317 PolicyEvaluator pe 1318 = new PolicyEvaluator(orgToVisit, serviceTypeName); 1319 Set pp = pe.getProtectingPolicies(token, resourceName, 1320 visitedOrgs); 1321 protectingPolicies.addAll(pp); 1322 } 1323 1324 String principalName = (token != null) 1325 ? token.getPrincipal().getName() 1326 : PolicyUtils.EMPTY_STRING; 1327 1328 StringBuffer sb = null; 1329 String pp = null; 1330 if (PolicyManager.debug.messageEnabled() || PolicyUtils.logStatus) { 1331 sb = new StringBuffer(); 1332 Iterator pIter = protectingPolicies.iterator(); 1333 while (pIter.hasNext()) { 1334 Policy policy = (Policy)pIter.next(); 1335 sb.append(policy.getOrganizationName()).append(":") 1336 .append(policy.getName()) .append(","); 1337 } 1338 pp = sb.toString(); 1339 } 1340 1341 1342 if (PolicyManager.debug.messageEnabled()) { 1343 PolicyManager.debug.message("Computed policies " 1344 + " protecting resource " 1345 + resourceName 1346 + "for principal:" + principalName + " " + pp); 1347 } 1348 1349 if (PolicyUtils.logStatus && (token != null)) { 1350 String[] objs = { principalName, 1351 resourceName, pp }; 1352 PolicyUtils.logAccessMessage("PROTECTED_RESOURCES", objs, token, 1353 serviceTypeName); 1354 } 1355 return protectingPolicies; 1356 } 1357 1358 /** 1359 * Gets resource result objects given a resource name. The set 1360 * contains <code>ResourceResult</code> objects for all resources 1361 * that would affect policy decisions for any resource associated with the 1362 * argument resource name. To determine whether to include the 1363 * <code>ResourceResult</code> of a resource, we compare argument resource 1364 * name and policy resource name, treating wild characters in the policy 1365 * resource name as wild. If the comparison resulted in 1366 * <code>EXACT_MATCH</code>, <code>WILD_CARD_MACTH</code> or 1367 * <code>SUB_RESOURCE_MACTH</code>, the resource result would be 1368 * included. 1369 * 1370 * @param token single sign on token of the user evaluating policies 1371 * @param resourceName name of the resource 1372 * @param scope indicates whether to compute the resource result based on 1373 * the policy decision for only the <code>resourceName</code> 1374 * or all the resources associated with the resource name. 1375 * The valid scope values are: 1376 * <ul> 1377 * <li><code>ResourceResult.SUBTREE_SCOPE</code> 1378 * <li><code>ResourceResult.STRICT_SUBTREE_SCOPE</code> 1379 * <li><code>ResourceResult.SELF_SCOPE</code> 1380 * <ul> 1381 * If the scope is <code>ResourceResult.SUBTREE_SCOPE</code>, 1382 * the method will return a set of <code>ResourceResult</code> 1383 * objects, one of them for the <code>resourceName</code> and 1384 * its sub resources; the others are for resources that match 1385 * the <code>resourceName</code> by wildcard. If the scope is 1386 * <code>ResourceResult.STRICT_SUBTREE_SCOPE</code>, the 1387 * method will return a set object that contains one 1388 * <code>ResourceResult</code> object. The 1389 * <code>ResourceResult</code> contains the policy decisions 1390 * regarding the <code>resourceName</code> and its sub 1391 * resources. If the scope is 1392 * <code>ResourceResult.SELF_SCOPE</code>, the method will 1393 * return a set object that contains one 1394 * <code>ResourceResult</code> object. 1395 * The <code>ResourceResult</code> contains the policy decision 1396 * regarding the <code>resourceName</code> only. 1397 * 1398 * @param envParameters run-time environment parameters 1399 * 1400 * @return set of <code>ResourceResult</code> objects 1401 * 1402 * @throws SSOException if <code>token</code> is invalid 1403 * @throws PolicyException for any other abnormal condition 1404 * 1405 * @see ResourceMatch#EXACT_MATCH 1406 * @see ResourceMatch#SUB_RESOURCE_MATCH 1407 * @see ResourceMatch#WILDCARD_MATCH 1408 * @see ResourceResult#SUBTREE_SCOPE 1409 * @see ResourceResult#STRICT_SUBTREE_SCOPE 1410 * @see ResourceResult#SELF_SCOPE 1411 * 1412 * 1413 * @supported.api 1414 */ 1415 public Set getResourceResults(SSOToken token, 1416 String resourceName, String scope, Map envParameters) 1417 throws SSOException, PolicyException { 1418 return (PolicyManager.isMigratedToEntitlementService()) ? 1419 getResourceResultsE(token, resourceName, scope, envParameters) : 1420 getResourceResultsO(token, resourceName, scope, envParameters); 1421 } 1422 1423 private Set getResourceResultsO(SSOToken token, 1424 String resourceName, String scope, Map envParameters) 1425 throws SSOException, PolicyException { 1426 Set resultsSet; 1427 1428 if (ResourceResult.SUBTREE_SCOPE.equals(scope)) { 1429 resultsSet = getResourceResultTree(token, resourceName, scope, 1430 envParameters).getResourceResults(); 1431 } else if (ResourceResult.STRICT_SUBTREE_SCOPE.equals(scope) 1432 || ResourceResult.SELF_SCOPE.equals(scope)) { 1433 ResourceResult result = getResourceResultTree(token, resourceName, 1434 scope, envParameters); 1435 resultsSet = new HashSet(); 1436 resultsSet.add(result); 1437 } else { 1438 DEBUG.error("PolicyEvaluator: invalid request scope: " + scope); 1439 String objs[] = {scope}; 1440 throw new PolicyException(ResBundleUtils.rbName, 1441 "invalid_request_scope", objs, null); 1442 } 1443 1444 return resultsSet; 1445 } 1446 1447 private Set getResourceResultsE(SSOToken token, 1448 String resourceName, String scope, Map envParameters) 1449 throws SSOException, PolicyException { 1450 1451 if ((envParameters == null) || envParameters.isEmpty()) { 1452 envParameters = new HashMap(); 1453 } 1454 padEnvParameters(token, resourceName, null, envParameters); 1455 1456 Set resultsSet; 1457 boolean subTreeSearch = false; 1458 1459 if (ResourceResult.SUBTREE_SCOPE.equals(scope)) { 1460 subTreeSearch = true; 1461 //resultsSet = getResourceResultTree(token, resourceName, scope, 1462 // envParameters).getResourceResults(); 1463 } else if (ResourceResult.STRICT_SUBTREE_SCOPE.equals(scope) 1464 || ResourceResult.SELF_SCOPE.equals(scope)) { 1465 /* 1466 ResourceResult result = getResourceResultTree(token, resourceName, 1467 scope, envParameters); 1468 resultsSet = new HashSet(); 1469 resultsSet.add(result);*/ 1470 } else { 1471 DEBUG.error("PolicyEvaluator: invalid request scope: " + scope); 1472 String objs[] = {scope}; 1473 throw new PolicyException(ResBundleUtils.rbName, 1474 "invalid_request_scope", objs, null); 1475 } 1476 1477 SSOToken adminSSOToken = (SSOToken)AccessController.doPrivileged( 1478 AdminTokenAction.getInstance()); 1479 1480 try { 1481 // Parse the resource name before proceeding. 1482 resourceName = serviceType.canonicalize(resourceName); 1483 1484 Subject userSubject = SubjectUtils.createSubject(token); 1485 Evaluator eval = new Evaluator( 1486 SubjectUtils.createSubject(adminSSOToken), applicationName); 1487 1488 List<Entitlement> entitlements = eval.evaluate( 1489 realm, userSubject, resourceName, 1490 envParameters, subTreeSearch); 1491 resultsSet = new HashSet(); 1492 1493 if (!entitlements.isEmpty()) { 1494 if (!subTreeSearch) { 1495 resultsSet.add(entitlementToResourceResult( 1496 (Entitlement)entitlements.iterator().next())); 1497 } else { 1498 ResourceResult virtualResourceResult = 1499 new ResourceResult(ResourceResult.VIRTUAL_ROOT, 1500 new PolicyDecision()); 1501 for (Entitlement ent : entitlements ) { 1502 ResourceResult r = entitlementToResourceResult(ent); 1503 virtualResourceResult.addResourceResult(r, serviceType); 1504 } 1505 1506 resultsSet.addAll( 1507 virtualResourceResult.getResourceResults()); 1508 } 1509 } 1510 } catch (Exception e) { 1511 DEBUG.error("Error in getResourceResults", e); 1512 throw new PolicyException(e.getMessage()); //TOFIX 1513 } 1514 1515 return resultsSet; 1516 } 1517 1518 1519 private ResourceResult entitlementToResourceResult( 1520 Entitlement entitlement 1521 ) throws PolicyException { 1522 return new ResourceResult(entitlement.getRequestedResourceName(), 1523 entitlementToPolicyDecision(entitlement, Collections.EMPTY_SET)); 1524 } 1525 1526 private PolicyDecision entitlementToPolicyDecision( 1527 Entitlement entitlement, 1528 Set<String> actionNames 1529 ) throws PolicyException { 1530 PolicyDecision pd = new PolicyDecision(); 1531 Map actionValues = entitlement.getActionValues(); 1532 1533 if ((actionValues != null) && !actionValues.isEmpty()) { 1534 for (Iterator i = actionValues.keySet().iterator(); i.hasNext();) { 1535 String actionName = (String) i.next(); 1536 Set set = new HashSet(); 1537 boolean isBooleanAction = true; 1538 if (serviceType != null) { 1539 ActionSchema as = null; 1540 try { 1541 as = serviceType.getActionSchema(actionName); 1542 } catch (InvalidNameException inex) { 1543 if (DEBUG.warningEnabled()) { 1544 DEBUG.warning("PolicyEvaluator." + 1545 "entitlementToPolicyDecision:", inex); 1546 } 1547 } 1548 isBooleanAction = (as != null) && 1549 as.getSyntax().equals(AttributeSchema.Syntax.BOOLEAN); 1550 } 1551 1552 if (isBooleanAction) { 1553 1554 Boolean values = (Boolean) actionValues.get(actionName); 1555 1556 if (values.booleanValue()) { 1557 set.add(getActionTrueBooleanValue(actionName)); 1558 } else { 1559 set.add(getActionFalseBooleanValue(actionName)); 1560 } 1561 } else { 1562 // Parse the action name to get the value 1563 int index = actionName.indexOf('_'); 1564 if (index != -1) { 1565 set.add(actionName.substring(index+1)); 1566 actionName = actionName.substring(0, index); 1567 } else { 1568 set.add(actionName); 1569 } 1570 } 1571 1572 ActionDecision ad = new ActionDecision(actionName, set); 1573 ad.setAdvices(entitlement.getAdvices()); 1574 ad.setTimeToLive(entitlement.getTTL()); 1575 pd.addActionDecision(ad, serviceType); 1576 } 1577 } else { 1578 Map advices = entitlement.getAdvices(); 1579 if ((advices != null) && (!advices.isEmpty()) && 1580 ((actionNames == null) || actionNames.isEmpty())) { 1581 actionNames = serviceType.getActionNames(); 1582 } 1583 for (String actionName : actionNames) { 1584 Set set = new HashSet(); 1585 // Determinte if the serviceType have boolean action values 1586 ActionSchema as = null; 1587 if (serviceType != null) { 1588 try { 1589 as = serviceType.getActionSchema(actionName); 1590 } catch (InvalidNameException inex) { 1591 if (DEBUG.warningEnabled()) { 1592 DEBUG.warning("PolicyEvaluator." + 1593 "entitlementToPolicyDecision:", inex); 1594 } 1595 } 1596 } 1597 if ((as == null) || 1598 as.getSyntax().equals(AttributeSchema.Syntax.BOOLEAN)) { 1599 set.add(getActionFalseBooleanValue(actionName)); 1600 } else { 1601 set.addAll(as.getDefaultValues()); 1602 } 1603 ActionDecision ad = new ActionDecision(actionName, set); 1604 ad.setAdvices(entitlement.getAdvices()); 1605 ad.setTimeToLive(entitlement.getTTL()); 1606 pd.addActionDecision(ad, serviceType); 1607 } 1608 } 1609 1610 pd.setTimeToLive(entitlement.getTTL()); 1611 pd.setResponseAttributes(entitlement.getAttributes()); 1612 return pd; 1613 } 1614 1615 /** 1616 * Gets resource result given a resource name. <code>ResourceResult</code> 1617 * is a tree representation of policy decisions for all resources rooted 1618 * at the resource name. 1619 * To determine whether a resource defined in the policy 1620 * is a sub resource of argument resource name, argument resource name 1621 * and policy resource name are compared, treating wild characters as 1622 * literals. If comparison resulted in <code>EXACT_MACTH</code> or 1623 * <code>SUB_RESOURCE_MACTH</code>, the resource would be included 1624 * 1625 * @param token single sign on token of the user evaluating policies 1626 * @param resourceName name of the resource 1627 * @param scope indicates whether to compute the resource result based on 1628 * the policy decision for only the <code>resourceName</code> 1629 * or all the resources associated with the resource name. 1630 * The valid scope values are: 1631 * <ul> 1632 * <li><code>ResourceResult.SUBTREE_SCOPE</code> 1633 * <li><code>ResourceResult.STRICT_SUBTREE_SCOPE</code> 1634 * <li><code>ResourceResult.SELF_SCOPE</code> 1635 * </ul> 1636 * If the scope is <code>ResourceResult.SUBTREE_SCOPE</code> or 1637 * <code>ResourceResult.STRICT_SUBTREE_SCOPE</code>, the method 1638 * will return a <code>ResourceResult</code> object that 1639 * contains the policy decisions regarding the 1640 * <code>resourceName</code> and its sub resources. 1641 * If the scope is <code>ResourceResult.SELF_SCOPE</code>, the 1642 * method will return a <code>ResourceResult</code> object that 1643 * contains the policy decision regarding the 1644 * <code>resourceName</code> only. Note, scope values 1645 * <code>ResourceResult.SUBTREE_SCOPE</code> and 1646 * <code>ResourceResult.STRICT_SUBTREE_SCOPE</code> are being 1647 * treated as the same for backword compatibility reasons. This 1648 * method is being deprecated. The method 1649 * <code>getResourceResults()</code> should be used instead. 1650 * 1651 * @param envParameters run-time environment parameters 1652 * 1653 * @return <code>ResourceResult</code>. 1654 * 1655 * @throws SSOException if <code>token</code> is invalid 1656 * @throws PolicyException for any other abnormal condition 1657 * 1658 * @see ResourceMatch#EXACT_MATCH 1659 * @see ResourceMatch#SUB_RESOURCE_MATCH 1660 * @see ResourceMatch#WILDCARD_MATCH 1661 * @see ResourceResult#SUBTREE_SCOPE 1662 * @see ResourceResult#STRICT_SUBTREE_SCOPE 1663 * @see ResourceResult#SELF_SCOPE 1664 * 1665 * @deprecated Use <code>getResourceResults()</code> 1666 * 1667 * @supported.api 1668 * 1669 */ 1670 public ResourceResult getResourceResult(SSOToken token, 1671 String resourceName, String scope, Map envParameters) 1672 throws SSOException, PolicyException { 1673 if (ResourceResult.SUBTREE_SCOPE.equals(scope) 1674 || ResourceResult.STRICT_SUBTREE_SCOPE.equals(scope) 1675 || ResourceResult.SELF_SCOPE.equals(scope)) { 1676 if (ResourceResult.SUBTREE_SCOPE.equals(scope)) { 1677 scope = ResourceResult.STRICT_SUBTREE_SCOPE; 1678 } 1679 return getResourceResultTree(token, resourceName, scope, 1680 envParameters); 1681 } else { 1682 DEBUG.error("PolicyEvaluator: invalid request scope: " + scope); 1683 String objs[] = {scope}; 1684 throw new PolicyException(ResBundleUtils.rbName, 1685 "invalid_request_scope", objs, null); 1686 } 1687 } 1688 1689 /** 1690 * Gets resource result given a resource name. <code>ResourceResult</code> 1691 * is a tree representation of policy decisions for all resources 1692 * that are sub resources of argument resource name. 1693 * 1694 * @param token single sign on token of the user evaluating policies 1695 * @param resourceName name of the resource 1696 * @param scope indicates whether to compute the resource result based on 1697 * the policy decision for only the <code>resourceName</code> 1698 * or all the resources associated with the resource name. 1699 * @param envParameters run-time environment parameters 1700 * 1701 * @return <code>ResourceResult</code>. 1702 * 1703 * @exception SSOException if <code>token</code> is invalid 1704 * @exception PolicyException for any other abnormal condition 1705 * 1706 * @see ResourceMatch#EXACT_MATCH 1707 * @see ResourceMatch#SUB_RESOURCE_MATCH 1708 * @see ResourceMatch#WILDCARD_MATCH 1709 * 1710 */ 1711 private ResourceResult getResourceResultTree(SSOToken token, 1712 String resourceName, String scope, Map envParameters) 1713 throws PolicyException, SSOException { 1714 1715 String userSSOTokenIDStr = (token != null) 1716 ? token.getTokenID().toString() 1717 : PolicyUtils.EMPTY_STRING; 1718 1719 if (token == null) { 1720 if (DEBUG.messageEnabled()) { 1721 DEBUG.message("user sso token is null, forcing ResourceResult" 1722 + " evaluation to self_scope"); 1723 } 1724 scope = ResourceResult.SELF_SCOPE; 1725 1726 } 1727 1728 ResourceResult resourceResult = null; 1729 1730 if ( (resourceName == null) || (resourceName.equals("")) ) { 1731 resourceName = Rule.EMPTY_RESOURCE_NAME; 1732 } 1733 resourceName = serviceType.canonicalize(resourceName); 1734 Map clientEnv = PolicyUtils.cloneMap(envParameters); 1735 1736 1737 // check if we already have the result in the cache 1738 // policyResultsCache: 1739 // serviceType -> resource -> sessionId -> scope -> result 1740 synchronized(policyResultsCache) { 1741 // rscCACHE: resource -> sessionId -> scope -> result 1742 Map rscCache = (Map)policyResultsCache.get(serviceTypeName); 1743 if (rscCache != null) { 1744 // resultCACHE: sessionId -> scope -> resourceResult 1745 Map resultsCache = (Map)rscCache.get(resourceName); 1746 if (resultsCache != null) { 1747 Map results = (Map)resultsCache.get(userSSOTokenIDStr); 1748 if (results != null) { 1749 resourceResult = (ResourceResult)results.get(scope); 1750 if (resourceResult != null) { 1751 long currentTime = System.currentTimeMillis(); 1752 long ttlMinimal = resourceResult.getTimeToLive(); 1753 if (ttlMinimal > currentTime) { 1754 1755 //check envMap equality of request and cache 1756 Map cachedEnv = resourceResult.getEnvMap(); 1757 if ( ((clientEnv == null) 1758 && (cachedEnv == null)) 1759 || ((clientEnv != null) 1760 && clientEnv.equals(cachedEnv)) ) { 1761 if (DEBUG.messageEnabled()) { 1762 DEBUG.message("PolicyEvaluator." 1763 + " getResourceResult(): we get the " 1764 + "result from the cache.\n" 1765 + resourceResult.toXML()); 1766 } 1767 return resourceResult; 1768 } else { 1769 if (PolicyManager.debug.messageEnabled()) { 1770 PolicyManager.debug.message( 1771 "PolicyEvaluator.getResourceesultTree()" 1772 + ":cached envMap does not equal " 1773 + "request envMap, request envMap = " 1774 + clientEnv 1775 + ", cachedEnv=" + cachedEnv 1776 ); 1777 } 1778 } 1779 } 1780 } 1781 } 1782 } 1783 } 1784 } 1785 1786 /* compute all action names if passed in actionNames is 1787 null or empty */ 1788 if ( (actionNames == null) || (actionNames.isEmpty()) ) { 1789 actionNames = serviceType.getActionNames(); 1790 } 1791 1792 if (DEBUG.messageEnabled()) { 1793 DEBUG.message("PolicyEvaluator:computing policy decisions " 1794 + " for resource : " + resourceName); 1795 } 1796 PolicyDecision policyDecision = getPolicyDecision(token, resourceName, 1797 actionNames, envParameters); 1798 resourceResult = new ResourceResult(resourceName, policyDecision); 1799 1800 if (ResourceResult.SUBTREE_SCOPE.equals(scope)) { 1801 ResourceResult virtualResourceResult 1802 = new ResourceResult(ResourceResult.VIRTUAL_ROOT, 1803 new PolicyDecision()); 1804 virtualResourceResult.addResourceResult(resourceResult, 1805 serviceType); 1806 resourceResult = virtualResourceResult; 1807 } 1808 1809 if (ResourceResult.SUBTREE_SCOPE.equals(scope) 1810 || ResourceResult.STRICT_SUBTREE_SCOPE.equals(scope)) { 1811 Map resourceNamesCache 1812 = (Map)resourceNamesMap.get(serviceTypeName); 1813 if (resourceNamesCache == null) { 1814 resourceNamesCache = new Cache(resultsCacheResourceCap); 1815 resourceNamesMap.put(serviceTypeName, resourceNamesCache); 1816 } 1817 Set resourceNames = (Set)resourceNamesCache.get(resourceName); 1818 if (resourceNames == null) { 1819 if (DEBUG.messageEnabled()) { 1820 DEBUG.message("Computing subresources for: " 1821 + resourceName); 1822 } 1823 // true indicates to follow referral 1824 resourceNames = getResourceNames(token, resourceName, true); 1825 resourceNames = removeDuplicateResourceNames(resourceNames, 1826 serviceType); 1827 resourceNames = removeResourceName(resourceNames, 1828 serviceType, resourceName); 1829 resourceNamesCache.put(resourceName, resourceNames); 1830 } 1831 if (DEBUG.messageEnabled()) { 1832 DEBUG.message("PolicyEvaluator:computing policy decisions " 1833 + " for subresources : " + resourceNames); 1834 } 1835 1836 Iterator resourceNameIter = resourceNames.iterator(); 1837 while (resourceNameIter.hasNext()) { 1838 String subResourceName = (String) resourceNameIter.next(); 1839 if (ResourceResult.SUBTREE_SCOPE.equals(scope) || 1840 (serviceType.compare(resourceName, 1841 subResourceName, false).equals( 1842 ResourceMatch.SUB_RESOURCE_MATCH))) { 1843 PolicyDecision pDecision = getPolicyDecision(token, 1844 subResourceName, actionNames, envParameters); 1845 resourceResult.addResourceResult( 1846 new ResourceResult(subResourceName, pDecision), 1847 serviceType); 1848 } 1849 } 1850 } 1851 1852 // Do not cache policy decision with advices 1853 if ( (resourceResult != null) 1854 && !resourceResult.hasAdvices()) { 1855 resourceResult.setEnvMap(clientEnv); 1856 // add the evaluation result to the result cache 1857 Map scopeElem = null; 1858 //cacheElem: sessionId -> scope -> resourceResult 1859 Map cacheElem = null; 1860 Map rscElem = null; 1861 // serviceType -> resourceName -> sessionId -> scope -> resourceResult 1862 synchronized(policyResultsCache) { 1863 // rscElemCACHE: resourceName -> sessionId -> scope -> resourceResult 1864 rscElem = (Map)policyResultsCache.get( 1865 serviceTypeName); 1866 if (rscElem != null) { // serviceType has been seen earlier 1867 //CACHEElem: sessionId -> scope -> resourceResult 1868 cacheElem = (Map)rscElem.get(resourceName); 1869 if (cacheElem != null) { // resource seen earlier 1870 scopeElem = (Map)cacheElem.get( 1871 userSSOTokenIDStr); 1872 if (scopeElem == null) { // seeing sessionId first time 1873 scopeElem = new HashMap(); 1874 } 1875 } else { // seeing the resource first time 1876 if (PolicyManager.debug.messageEnabled()) { 1877 PolicyManager.debug.message( 1878 "PolicyEvaluator.getResourceResultTree()" 1879 + " Create Cache for:" 1880 + ", resourceName=" + resourceName 1881 + ", sessionId=" + userSSOTokenIDStr 1882 + ", scope=" + scope); 1883 } 1884 cacheElem = new Cache(resultsCacheSessionCap); 1885 scopeElem = new HashMap(); 1886 } 1887 } else { // seeing service for first time 1888 // rscElemCACHE: resourceName -> sessionId -> scope -> resourceResult 1889 rscElem = new Cache(resultsCacheResourceCap); 1890 //CACHEElem: sessionId -> scope -> resourceResult 1891 if (PolicyManager.debug.messageEnabled()) { 1892 PolicyManager.debug.message( 1893 "PolicyEvaluator.getResourceResultTree()" 1894 + " Create Cache for:" 1895 + ", resourceName=" + resourceName 1896 + ", sessionId=" + userSSOTokenIDStr 1897 + ", scope=" + scope 1898 + ", serviceType=" + serviceTypeName); 1899 } 1900 cacheElem = new Cache(resultsCacheSessionCap); 1901 scopeElem = new HashMap(); 1902 } 1903 scopeElem.put(scope, resourceResult); 1904 cacheElem.put(userSSOTokenIDStr, scopeElem); 1905 if (PolicyManager.debug.messageEnabled()) { 1906 PolicyManager.debug.message( 1907 "PolicyEvaluator.getResourceResultTree()" 1908 + " Create Cache for:" 1909 + ", resourceName=" + resourceName 1910 + ", sessionId=" + userSSOTokenIDStr 1911 + ", scope=" + scope 1912 + ", cacheSize=" + cacheElem.size()); 1913 } 1914 rscElem.put(resourceName, cacheElem); 1915 policyResultsCache.put(serviceTypeName, rscElem); 1916 } 1917 1918 if ( (token != null) 1919 && !(ssoListenerRegistry.containsKey( 1920 userSSOTokenIDStr))) { 1921 try { 1922 token.addSSOTokenListener(ssoListener); 1923 } catch (SSOException se) { 1924 DEBUG.error("PolicyEvaluator:" 1925 + "failed to add sso token listener"); 1926 } 1927 ssoListenerRegistry.put(userSSOTokenIDStr, ssoListener); 1928 if (DEBUG.messageEnabled()) { 1929 DEBUG.message("PolicyEvaluator.getResourceResultTree():" 1930 + " sso listener added .\n"); 1931 } 1932 } 1933 if (DEBUG.messageEnabled()) { 1934 DEBUG.message("PolicyEvaluator: we added the evaluation " 1935 + " result to the cache"); 1936 } 1937 } 1938 1939 return resourceResult; 1940 } 1941 1942 1943 /** 1944 * Gets resource names that are exact matches, sub resources or 1945 * wild card matches of argument resource name. 1946 * To determine whether to include a 1947 * resource name of a resource, we compare argument resource name and 1948 * policy resource name, treating wild characters in the policy 1949 * resource name as wild. If the comparison resulted in 1950 * <code>EXACT_MATCH</code>, <code>WILD_CARD_MACTH</code> or 1951 * <code>SUB_RESOURCE_MACTH</code>, the resource result would be 1952 * included. 1953 * 1954 * @param token single sign on token 1955 * 1956 * @param resourceName resoure name 1957 * @param followReferral indicates whether to follow the referrals 1958 * defined in policies to compute resource names 1959 * @return names of sub resources for the given <code>resourceName</code>. 1960 * The return value would also include the 1961 * <code>resourceName</code>. 1962 * 1963 * @exception SSOException if <code>token</code> is invalid 1964 * @exception PolicyException for any other abnormal condition 1965 * 1966 * @see ResourceMatch#EXACT_MATCH 1967 * @see ResourceMatch#SUB_RESOURCE_MATCH 1968 * @see ResourceMatch#WILDCARD_MATCH 1969 * 1970 */ 1971 public Set getResourceNames(SSOToken token, String resourceName, 1972 boolean followReferral) throws PolicyException, SSOException { 1973 Set visitedOrgs = new HashSet(); 1974 visitedOrgs.add(policyManager.getOrganizationDN()); 1975 return getResourceNames(token, resourceName, followReferral, 1976 visitedOrgs); 1977 } 1978 1979 /**Gets resource names that are exact matches, sub resources or 1980 * wild card matches of argument resource name. 1981 * To determine whether to include a 1982 * resource name of a resource, we compare argument resource name and 1983 * policy resource name, treating wild characters in the policy 1984 * resource name as wild. If the comparsion resulted in 1985 * <code>EXACT_MATCH</code>, <code>WILD_CARD_MACTH</code> or 1986 * <code>SUB_RESOURCE_MACTH</code>, the resource result would be 1987 * included. 1988 * 1989 * @param token single sign on token 1990 * 1991 * @param resourceName resoure name 1992 * @param followReferral indicates whether to follow the referrals 1993 * defined in policies to compute resource names 1994 * @param visitedOrgs organizations that were already visited to 1995 * compute resource names 1996 * @return names of sub resources for the given <code>resourceName</code>. 1997 * The return value would also include the 1998 * <code>resourceName</code>. 1999 * 2000 * @exception SSOException if <code>token</code> is invalid 2001 * @exception PolicyException for any other abnormal condition 2002 * 2003 * @see ResourceMatch#EXACT_MATCH 2004 * @see ResourceMatch#SUB_RESOURCE_MATCH 2005 * @see ResourceMatch#WILDCARD_MATCH 2006 * 2007 */ 2008 public Set getResourceNames(SSOToken token, String resourceName, 2009 boolean followReferral, Set visitedOrgs) 2010 throws PolicyException, SSOException { 2011 DEBUG.message("PolicyEvaluator.getResourceNames():entering"); 2012 Set resourceNames = new HashSet(); 2013 Set policyNameSet = null; 2014 Set toRemovePolicyNameSet = null; 2015 Set orgsToVisit = new HashSet(); 2016 policyNameSet = resourceIndexManager.getSubResourcePolicyNames( 2017 serviceType, resourceName); 2018 policyNameSet.addAll( 2019 resourceIndexManager.getPolicyNames(serviceType, 2020 resourceName, true)); //include policies of super resources 2021 policyNameSet.addAll( 2022 resourceIndexManager.getWildSubResourcePolicyNames( 2023 serviceType, resourceName)); 2024 if ( (policyNameSet != null) && (!policyNameSet.isEmpty()) ) { 2025 Iterator policyIter = policyNameSet.iterator(); 2026 while (policyIter.hasNext()) { 2027 String policyName = (String) policyIter.next(); 2028 Policy policy = policyManager.getPolicy(policyName, 2029 USE_POLICY_CACHE); 2030 // policy could have been deleted 2031 if ( policy != null && policy.isActive()) { 2032 // true inidicates to follow referrals 2033 Set pResourceNames = policy.getResourceNames(token, 2034 serviceTypeName, resourceName, true); 2035 if (pResourceNames != null) { 2036 resourceNames.addAll(pResourceNames); 2037 } 2038 } else { // add policy names to toRemovePolicyNameSet 2039 if (toRemovePolicyNameSet == null) { 2040 toRemovePolicyNameSet = new HashSet(); 2041 } 2042 toRemovePolicyNameSet.add(policyName); 2043 if ( DEBUG.messageEnabled() ) { 2044 DEBUG.message("PolicyEvaluator.getResourceNames():" 2045 +policyName+ " is inactive or non-existent"); 2046 } 2047 } 2048 } 2049 // remove inactive/missing policies from policyNameSet 2050 if (toRemovePolicyNameSet != null) { 2051 policyNameSet.removeAll(toRemovePolicyNameSet); 2052 } 2053 2054 orgsToVisit.addAll(getOrgsToVisit(policyNameSet)); 2055 2056 if ( DEBUG.messageEnabled() ) { 2057 DEBUG.message("PolicyEvaluator.getResourceNames():" 2058 + "realmAliasEnabled=" 2059 + PolicyConfig.orgAliasMappedResourcesEnabled() 2060 + ", serviceTypeName=" + serviceTypeName); 2061 } 2062 } 2063 if (PolicyConfig.orgAliasMappedResourcesEnabled() 2064 && PolicyManager.WEB_AGENT_SERVICE.equalsIgnoreCase( 2065 serviceTypeName)) { 2066 String orgAlias = policyManager.getOrgAliasWithResource( 2067 resourceName); 2068 if (orgAlias != null) { 2069 String orgWithAlias = policyManager.getOrgNameWithAlias( 2070 orgAlias); 2071 if (orgWithAlias != null) { 2072 if ( DEBUG.messageEnabled() ) { 2073 DEBUG.message("PolicyEvaluator." 2074 + "getgetResourceNames():" 2075 + "adding orgWithAlias to orgsToVisit=" 2076 + orgWithAlias); 2077 } 2078 orgsToVisit.add(orgWithAlias); 2079 } else { 2080 if ( DEBUG.messageEnabled() ) { 2081 DEBUG.message("PolicyEvaluator." 2082 + "getgetResourceNames():" 2083 + "no realm matched orgAlias:" + orgAlias); 2084 } 2085 } 2086 } 2087 } 2088 2089 orgsToVisit.removeAll(visitedOrgs); 2090 while (!orgsToVisit.isEmpty() ) { 2091 String orgToVisit = (String) orgsToVisit.iterator().next(); 2092 orgsToVisit.remove(orgToVisit); 2093 visitedOrgs.add(orgToVisit); 2094 //resourceNames.add(resourceName); 2095 try { 2096 // need to use admin sso token here. Need all privileges to 2097 // check for the organzation 2098 policyManager.verifyOrgName(orgToVisit); 2099 } catch (NameNotFoundException nnfe) { 2100 if( DEBUG.warningEnabled()) { 2101 DEBUG.warning("PolicyEvaluator." 2102 + "getgetResourceNames():" 2103 + "Organization does not exist - " 2104 + "skipping referral to " + orgToVisit); 2105 } 2106 continue; 2107 } 2108 PolicyEvaluator pe = new PolicyEvaluator(orgToVisit, 2109 serviceTypeName); 2110 resourceNames.addAll(pe.getResourceNames(token, 2111 resourceName, true, 2112 visitedOrgs)); 2113 } 2114 return resourceNames; 2115 } 2116 2117 /** Adds a policy listener that would be notified whenever a policy 2118 * is added, removed or changed 2119 * 2120 * @param policyListener the listener to be added 2121 * 2122 * @supported.api 2123 */ 2124 public void addPolicyListener(PolicyListener policyListener) { 2125 policyCache.addPolicyListener(policyListener); 2126 } 2127 2128 /** Removes a policy listener that was previously registered 2129 * to receive notifications whenever a policy is added, removed 2130 * or changed. It is not an error to attempt to remove a listener 2131 * that was not registered. It would return silently. 2132 * 2133 * @param policyListener the listener to be removed 2134 * 2135 * @supported.api 2136 */ 2137 public void removePolicyListener(PolicyListener policyListener) { 2138 policyCache.removePolicyListener(policyListener); 2139 } 2140 2141 /** Merges two policy decisions. 2142 * Merging policy decisions merges each action decision of the 2143 * policy with the corresponding action decision of the other 2144 * policy. This method also merges ResponseProviderDecision of one 2145 * policy ( response attributes per policy) 2146 * with that of the other policy. 2147 * These are the rules followed to merge each action decision: 2148 * If the action schema has boolean syntax, boolean false value 2149 * overrides boolean true value. The time to live of boolean false 2150 * value overrides the time to live of boolean true value. 2151 * Otherwise, action values are simply aggregated. Time to live 2152 * is set to the minimum of time to live(s) of all values of the 2153 * action. 2154 * For response attributes, all response attributes are aggregated. 2155 * In case of mutiple values for the same attribute 2156 * they appear as multi valued data for the attribute. 2157 * @param serviceType service type that would be consulted to merge the 2158 * policy decisions 2159 * @param pd1 policy decision 1 2160 * @param pd2 policy decision 2 2161 * @return the merged policy decision. 2162 * Policy decisions pd1 and pd2 are merged into pd2 and 2163 * pd2 is returned. 2164 */ 2165 static PolicyDecision mergePolicyDecisions(ServiceType 2166 serviceType, PolicyDecision pd1, PolicyDecision pd2) { 2167 Map actionDecisions1 = pd1.getActionDecisions(); 2168 Set actions = new HashSet(); 2169 actions.addAll(actionDecisions1.keySet()); 2170 Iterator iter = actions.iterator(); 2171 while ( iter.hasNext() ) { 2172 String action = (String) iter.next(); 2173 ActionDecision ad1 = (ActionDecision) actionDecisions1.get( 2174 action); 2175 pd2.addActionDecision(ad1, serviceType); 2176 } 2177 Map mergedReponseAttrsMap = new HashMap(); 2178 PolicyUtils.appendMapToMap(pd1.getResponseAttributes(), 2179 mergedReponseAttrsMap); 2180 PolicyUtils.appendMapToMap(pd2.getResponseAttributes(), 2181 mergedReponseAttrsMap); 2182 pd2.setResponseAttributes(mergedReponseAttrsMap); 2183 return pd2; 2184 } 2185 2186 /** Gets a set of action names for which final values have been 2187 * determined. We assume the final values have been determined 2188 * for an action if the action schema syntax is boolean and 2189 * the value is boolean false value 2190 * 2191 * @param serviceType service type that would be consulted to decide 2192 * the final values for actions 2193 * @param pd policy decision 2194 */ 2195 static Set getFinalizedActions(ServiceType 2196 serviceType, PolicyDecision pd) { 2197 Set finalizedActions = new HashSet(); 2198 Map actionDecisions = pd.getActionDecisions(); 2199 Iterator actions = actionDecisions.keySet().iterator(); 2200 while ( actions.hasNext() ) { 2201 String action = (String) actions.next(); 2202 ActionDecision actionDecision 2203 = (ActionDecision) actionDecisions.get(action); 2204 Set values = actionDecision.getValues(); 2205 if ( (values != null) && !values.isEmpty() ) { 2206 try { 2207 ActionSchema schema 2208 = serviceType.getActionSchema(action); 2209 if ((AttributeSchema.Syntax.BOOLEAN.equals( 2210 schema.getSyntax())) 2211 && values.contains(schema.getFalseValue()) ) { 2212 finalizedActions.add(action); 2213 } 2214 } catch(InvalidNameException e) { 2215 DEBUG.error("can not find action schmea for action = " + 2216 action, e ); 2217 } 2218 2219 } 2220 2221 2222 } 2223 return finalizedActions; 2224 } 2225 2226 /** 2227 * Gets names of organizations to visit for policy evaluation 2228 * based on the give policy names. This is used to follow 2229 * OrgReferral(s) defined in the policies 2230 * 2231 * @return names of organization to visit 2232 * @exception SSOException if <code>token</code> is invalid 2233 * @exception PolicyException for any other abnormal condition 2234 */ 2235 private Set getOrgsToVisit(Set policyNameSet) 2236 throws PolicyException, SSOException { 2237 Set orgsToVisit = new HashSet(); 2238 Iterator policyNames = policyNameSet.iterator(); 2239 while ( policyNames.hasNext() ) { 2240 String policyName = (String) policyNames.next(); 2241 Policy policy = policyManager.getPolicy(policyName, 2242 USE_POLICY_CACHE); 2243 if (policy != null) { 2244 orgsToVisit.addAll(policy.getReferredToOrganizations()); 2245 } 2246 } 2247 return orgsToVisit; 2248 } 2249 2250 /** 2251 * This would be a costly operation. 2252 * Can be avoided if ResourceName has api for getting canonical name. 2253 * When the policies are stored, resource names would be converted to and 2254 * stored as canonical name. 2255 */ 2256 private static Set removeDuplicateResourceNames(Set resourceNames, 2257 ServiceType serviceType) { 2258 Set answer = resourceNames; 2259 if ( (resourceNames != null) && (serviceType != null) ) { 2260 answer = new HashSet(resourceNames.size()); 2261 Iterator iter = resourceNames.iterator(); 2262 while ( iter.hasNext() ) { 2263 String resourceName = (String) iter.next(); 2264 Iterator answerIter = answer.iterator(); 2265 boolean duplicate = false; 2266 while (answerIter.hasNext()) { 2267 String answerResourceName = (String) answerIter.next(); 2268 2269 if ( serviceType.compare(resourceName, 2270 answerResourceName, false) 2271 .equals(ResourceMatch.EXACT_MATCH) ) { 2272 duplicate = true; 2273 break; 2274 } 2275 } 2276 if (!duplicate) { 2277 answer.add(resourceName); 2278 } 2279 } 2280 2281 } 2282 return answer; 2283 } 2284 2285 /** 2286 * Removes the <code>resourceName</code> from the <code>Set</code> 2287 * of resource names matching on <code>serviceType</code> and 2288 * performing a <code>ResourceMatch.EXACT_MATCH</code> 2289 */ 2290 2291 private static Set removeResourceName(Set resourceNames, 2292 ServiceType serviceType, String resourceName) { 2293 Set answer = resourceNames; 2294 if ( (resourceNames != null) && (serviceType != null) 2295 && (resourceName != null) ) { 2296 answer = new HashSet(resourceNames.size()); 2297 answer.addAll(resourceNames); 2298 Iterator iter = resourceNames.iterator(); 2299 while ( iter.hasNext() ) { 2300 String rName = (String) iter.next(); 2301 if ( serviceType.compare(resourceName, 2302 rName, false).equals(ResourceMatch.EXACT_MATCH) ) { 2303 answer.remove(rName); 2304 } 2305 } 2306 2307 } 2308 return answer; 2309 } 2310 2311 2312 /** 2313 * Handles policyChanged notifications - clears the cached resource 2314 * names for the service type name 2315 * 2316 * @param serviceTypeName service type name 2317 * @param pe policy event 2318 */ 2319 static void policyChanged(String serviceTypeName, PolicyEvent pe) { 2320 2321 if (DEBUG.messageEnabled()) { 2322 DEBUG.message("PolicyEvaulator.policyChanged():serviceTypeName=" 2323 + serviceTypeName); 2324 } 2325 resourceNamesMap.remove(serviceTypeName); 2326 2327 Cache resourceNamesCache 2328 = (Cache)resourceNamesMap.get(serviceTypeName); 2329 if ((resourceNamesCache == null) || (resourceNamesCache.isEmpty())) { 2330 return; 2331 } 2332 try { 2333 DEBUG.error("PolicyEvaluator.policyChanged: enterred try block"); 2334 ServiceTypeManager stm = ServiceTypeManager.getServiceTypeManager(); 2335 ServiceType serviceType = stm.getServiceType(serviceTypeName); 2336 Set resourceNamesToRemove = new HashSet(); 2337 synchronized(resourceNamesCache) { 2338 Enumeration resourceNames = resourceNamesCache.keys(); 2339 while (resourceNames.hasMoreElements()) { 2340 String resourceName = (String)resourceNames.nextElement(); 2341 if (resourceNamesToRemove.contains(resourceName)) { 2342 continue; 2343 } 2344 Set affectedResourceNames = pe.getResourceNames(); 2345 Iterator iter = affectedResourceNames.iterator(); 2346 while (iter.hasNext()) { 2347 String affectedResourceName = (String)iter.next(); 2348 if (serviceType.compare(resourceName, 2349 affectedResourceName) 2350 != ResourceMatch.NO_MATCH) { 2351 resourceNamesToRemove.add(resourceName); 2352 } 2353 } 2354 } 2355 Iterator iter1 = resourceNamesToRemove.iterator(); 2356 while (iter1.hasNext()) { 2357 String resourceNameToRemove = (String) iter1.next(); 2358 resourceNamesCache.remove(resourceNameToRemove); 2359 } 2360 } 2361 } catch (SSOException e) { 2362 DEBUG.error("PolicyEvaluator.policyChanged:", e); 2363 } catch (PolicyException pex) { 2364 DEBUG.error("PolicyEvaluator.policyChanged:", pex); 2365 } 2366 if (DEBUG.messageEnabled()) { 2367 DEBUG.message("PolicyEvaulator.policyChanged():serviceTypeName=" 2368 + serviceTypeName 2369 + ", new cached resoruceNames=" 2370 + resourceNamesMap.get(serviceTypeName)); 2371 } 2372 } 2373 2374 /** 2375 * Add an advice to the policy decision. 2376 * @param pd <code>PolicyDecision</code> in which to add the advice. 2377 * @param adviceKey key to the condition generating the advice 2378 * like SessionCondition.SESSION_CONDITION_ADVICE, 2379 * AuthSchemeCondition.AUTH_SCHEME_CONDITION_ADVICE 2380 * @param adviceValue advice message to be added to the advice 2381 */ 2382 private static void addAdvice(PolicyDecision pd, String adviceKey, 2383 String adviceValue) { 2384 if ((pd != null) 2385 && (pd.hasAdvices())) { 2386 Map actionDecisions = pd.getActionDecisions(); 2387 Iterator actionDecisionIter = actionDecisions.keySet().iterator(); 2388 while (actionDecisionIter.hasNext()) { 2389 String key = (String) actionDecisionIter.next(); 2390 ActionDecision ad = (ActionDecision) actionDecisions.get(key); 2391 Map advices = ad.getAdvices(); 2392 if ((advices != null) && !advices.isEmpty()) { 2393 Set values = (Set)advices.get(adviceKey); 2394 if (values == null) { 2395 values = new HashSet(); 2396 } 2397 values.add(adviceValue); 2398 advices.put(adviceKey, values); 2399 } 2400 } 2401 } 2402 } 2403 2404 /** 2405 * Get the policy decision for a resource ignoring the subject 2406 */ 2407 2408 PolicyDecision getPolicyDecisionIgnoreSubjects(String resourceName, 2409 Set actionNames, Map env) throws PolicyException, SSOException { 2410 2411 Set originalResourceNames = new HashSet(2); 2412 originalResourceNames.add(resourceName); 2413 2414 /* 2415 * Add request resourceName and request actionNames to the envParameters 2416 * so that Condition(s)/ResponseProvider(s) can use them if necessary 2417 */ 2418 Set resourceNames = new HashSet(2); 2419 resourceNames.add(resourceName); 2420 2421 /* compute for all action names if passed in actionNames is 2422 null or empty */ 2423 if ( (actionNames == null) || (actionNames.isEmpty()) ) { 2424 actionNames = serviceType.getActionNames(); 2425 } 2426 2427 Set actions = new HashSet(); 2428 if (actionNames != null) { 2429 actions.addAll(actionNames); 2430 } 2431 2432 //We create new HashMap in place of empty map since 2433 //Collections.EMPTY_MAP can not be modified 2434 if ((env == null) || env.isEmpty()) { 2435 env = new HashMap(); 2436 } 2437 2438 env.put(SUN_AM_REQUESTED_RESOURCE, resourceNames); 2439 env.put(SUN_AM_ORIGINAL_REQUESTED_RESOURCE, 2440 originalResourceNames); 2441 env.put(SUN_AM_REQUESTED_ACTIONS, actions); 2442 env.put(REALM_DN, asSet(policyManager.getOrganizationDN())); 2443 2444 return getPolicyDecision(null, resourceName, actionNames, env, 2445 new HashSet()); 2446 } 2447 2448 2449 /** 2450 * Get the set of role DNs of a user. The role DNs are cached to 2451 * improve the performance of IdentityServerRole subject membership 2452 * validation. 2453 * 2454 * @param token single sign on token of the user evaluating policies 2455 * 2456 * @return The set of user <code>nsRole</code> attribute values 2457 * 2458 * @exception SSOException single-sign-on token invalid or expired 2459 * @exception PolicyException if an error occured while getting the 2460 * user's nsRole attribute value set 2461 */ 2462 public static Set getUserNSRoleValues(SSOToken token) 2463 throws SSOException, PolicyException { 2464 if (userNSRoleCacheTTL == 0) { 2465 synchronized(userNSRoleCache) { 2466 String orgName = ServiceManager.getBaseDN(); 2467 Map pConfigValues = PolicyConfig.getPolicyConfig(orgName); 2468 userNSRoleCacheTTL = 2469 PolicyConfig.getSubjectsResultTtl(pConfigValues); 2470 if (userNSRoleCacheTTL <= 0) { 2471 userNSRoleCacheTTL = DEFAULT_USER_NSROLE_CACHE_TTL; 2472 if (DEBUG.warningEnabled()) { 2473 DEBUG.warning("Invalid TTL got from configuration." 2474 + " Set TTL to default:" 2475 + userNSRoleCacheTTL); 2476 } 2477 } 2478 if (DEBUG.messageEnabled()) { 2479 DEBUG.message("userNSRoleCacheTTL=" 2480 + userNSRoleCacheTTL); 2481 } 2482 } 2483 } 2484 if (token == null) { 2485 return null; 2486 } 2487 String tokenIDStr = token.getTokenID().toString(); 2488 Object[] element = (Object[])userNSRoleCache.get(tokenIDStr); 2489 if (element != null) { 2490 Long timeStamp = (Long)element[0]; 2491 long timeToLive = 0; 2492 if (timeStamp != null) { 2493 timeToLive = timeStamp.longValue(); 2494 } 2495 long currentTime = System.currentTimeMillis(); 2496 if (timeToLive > currentTime) { 2497 if (DEBUG.messageEnabled()) { 2498 DEBUG.message("PolicyEvaluator.getUserNSRoleValues():" 2499 + " get the nsRole values from cache.\n"); 2500 } 2501 return (HashSet)element[1]; 2502 } 2503 } 2504 // add or update the cache entry. 2505 // we come here either the token is first registered with the 2506 // cache or the cache element is out of date. 2507 try { 2508 AMStoreConnection am = new AMStoreConnection(token); 2509 AMUser user = am.getUser(token.getPrincipal().getName()); 2510 if ((user == null) || !(user.isActivated())) { 2511 return null; 2512 } 2513 Set roleSet = new HashSet(); 2514 Set roles = new HashSet(); 2515 // get all the roles assigned to the user 2516 Set staticRoles = user.getRoleDNs(); 2517 Set filteredRoles = user.getFilteredRoleDNs(); 2518 if (staticRoles != null) { 2519 roles.addAll(staticRoles); 2520 } 2521 if (filteredRoles != null) { 2522 roles.addAll(filteredRoles); 2523 } 2524 if (!roles.isEmpty()) { 2525 Iterator iter = roles.iterator(); 2526 while (iter.hasNext()) { 2527 String role = (String) iter.next(); 2528 if (role != null) { 2529 roleSet.add((new DN(role)).toRFCString().toLowerCase()); 2530 } 2531 } 2532 } 2533 if (DEBUG.messageEnabled()) { 2534 DEBUG.message("PolicyEvaluator.getUserNSRoleValues():" 2535 + " added user nsRoles: " + roleSet); 2536 } 2537 Object[] elem = new Object[2]; 2538 elem[0] = new Long(System.currentTimeMillis() 2539 + userNSRoleCacheTTL); 2540 elem[1] = roleSet; 2541 userNSRoleCache.put(tokenIDStr, elem); 2542 if (!ssoListenerRegistry.containsKey(tokenIDStr)) { 2543 token.addSSOTokenListener(ssoListener); 2544 ssoListenerRegistry.put(tokenIDStr, ssoListener); 2545 if (DEBUG.messageEnabled()) { 2546 DEBUG.message("PolicyEvaluator.getUserNSRoleValues():" 2547 + " sso listener added .\n"); 2548 } 2549 } 2550 return roleSet; 2551 } catch (AMException e) { 2552 throw (new PolicyException(e)); 2553 } 2554 } 2555 2556 /** 2557 * record stats for policyResultsCache, ssoListenerRegistry, 2558 * policyListenerRegistry, userNSRoleCache, resouceNamesMap 2559 */ 2560 static void printStats(Stats policyStats) { 2561 2562 2563 int resultsCacheSize = 0; 2564 synchronized (policyResultsCache) { 2565 resultsCacheSize = policyResultsCache.size(); 2566 } 2567 policyStats.record("PolicyEvaluator: Number of services in " 2568 + " resultsCache: " + resultsCacheSize); 2569 2570 policyStats.record("PolicyEvaluator: Number of token IDs in " 2571 + " sessionListernerRgistry:" 2572 + ssoListenerRegistry.size()); 2573 2574 policyStats.record("PolicyEvaluator: Number of serviceNames " 2575 + " in policyListenerRegistry: " 2576 + policyListenerRegistry.size()); 2577 2578 policyStats.record("PolicyEvaluator: Number of token IDs " 2579 + " in role cahce: " + userNSRoleCache.size()); 2580 2581 policyStats.record("PolicyEvaluator:Number of serviceNames in " 2582 + " resourceNames cache: " 2583 + resourceNamesMap.size()); 2584 } 2585}
Copyright © 2010-2017, ForgeRock All Rights Reserved.