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