001/** 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2005 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: ServiceManager.java,v 1.27 2009/10/28 04:24:26 hengming Exp $ 026 * 027 */ 028 029/* 030 * Portions Copyrighted 2012-2013 ForgeRock AS 031 */ 032 033package com.sun.identity.sm; 034 035import com.iplanet.services.util.AMEncryption; 036import com.iplanet.sso.SSOException; 037import com.iplanet.sso.SSOToken; 038import com.iplanet.sso.SSOTokenManager; 039import com.iplanet.ums.IUMSConstants; 040import com.sun.identity.authentication.util.ISAuthConstants; 041import com.sun.identity.common.CaseInsensitiveHashMap; 042import com.sun.identity.common.configuration.ServerConfiguration; 043import com.sun.identity.idm.IdConstants; 044import com.sun.identity.shared.debug.Debug; 045import com.sun.identity.shared.xml.XMLUtils; 046import com.sun.identity.security.AdminTokenAction; 047import com.sun.identity.security.DecodeAction; 048import com.sun.identity.security.EncodeAction; 049import java.io.InputStream; 050import java.io.UnsupportedEncodingException; 051import java.security.AccessController; 052import java.text.MessageFormat; 053import java.util.ArrayList; 054import java.util.Collections; 055import java.util.HashMap; 056import java.util.HashSet; 057import java.util.Iterator; 058import java.util.List; 059import java.util.Map; 060import java.util.Set; 061import org.w3c.dom.Document; 062import org.w3c.dom.DocumentType; 063import org.w3c.dom.Node; 064import org.w3c.dom.NodeList; 065 066/** 067 * The <code>ServiceManager</code> class provides methods to register/remove 068 * services and to list currently registered services. It also provides methods 069 * to obtain an instance of <code>ServiceSchemaManager</code> and an instance 070 * of <code>ServiceConfigManager</code>. 071 * 072 * @supported.api 073 */ 074public class ServiceManager { 075 076 // Initialization parameters 077 private static boolean initialized; 078 079 private static boolean loadedAuthServices; 080 081 protected static final String serviceDN = SMSEntry.SERVICES_RDN 082 + "," + SMSEntry.baseDN; 083 084 // For realms and co-existance support 085 protected static final String COEXISTENCE_ATTR_NAME = "coexistenceMode"; 086 087 protected static HashMap serviceNameDefaultVersion = 088 new CaseInsensitiveHashMap(); 089 090 protected static final String REALM_ATTR_NAME = "realmMode"; 091 092 public static final String REALM_SERVICE = 093 "sunidentityrepositoryservice"; 094 095 protected static final String DEFAULT_SERVICES_FOR_REALMS = 096 "serviceNamesForAutoAssignment"; 097 098 protected static final String SERVICE_VERSION = "1.0"; 099 100 protected static final String REALM_ENTRY = "ou=" + SERVICE_VERSION 101 + ",ou=" + REALM_SERVICE + "," + serviceDN; 102 103 protected static final String PLATFORM_SERVICE = "iPlanetAMPlatformService"; 104 105 protected static final String ATTR_SERVER_LIST = 106 "iplanet-am-platform-server-list"; 107 108 private static boolean realmCache; 109 110 private static boolean coexistenceCache = true; 111 112 private static boolean ditUpgradedCache; 113 114 protected static Set requiredServices; 115 116 protected static Set defaultServicesToLoad; 117 118 // constants for IdRepo management 119 private static final String SERVICE_OC_ATTR_NAME = "serviceObjectClasses"; 120 121 private static final String ALL_SERVICES = "null"; 122 123 private static Map serviceNameAndOCs = new CaseInsensitiveHashMap(); 124 125 // List of sub-services 126 protected static SMSEntry smsEntry; 127 128 protected static CachedSubEntries serviceNames; 129 130 protected static HashMap serviceVersions = new CaseInsensitiveHashMap(); 131 132 protected static Set accessManagerServers; 133 134 // SSOToken of the caller 135 private SSOToken token; 136 137 private CachedSubEntries subEntries = null; 138 139 // Debug & I18n 140 private static Debug debug = SMSEntry.debug; 141 142 private static boolean amsdkChecked; 143 144 private static boolean isAMSDKEnabled; 145 146 /** 147 * Creates an instance of <code>ServiceManager</code>. 148 * The <code>SSOToken</code> is used to identify the user performing 149 * service operations. 150 * 151 * @param token 152 * the authenticated single sign on token. 153 * @throws SSOException 154 * if the user's single sign on token is invalid or expired 155 * @throws SMSException 156 * if an error occurred while performing the operation 157 * 158 * @supported.api 159 */ 160 public ServiceManager(SSOToken token) throws SSOException, SMSException { 161 // Initilaize the static variables and caches 162 initialize(token); 163 164 // Validate SSOToken 165 SSOTokenManager.getInstance().validateToken(token); 166 this.token = token; 167 } 168 169 /** 170 * Returns the <code>ServiceSchemaManager</code> for 171 * the given service name and version. 172 * 173 * @param serviceName 174 * the name of the service 175 * @param version 176 * the version of the service 177 * @return the <code>ServiceSchemaManager</code> for the given service 178 * name and version 179 * @throws SSOException 180 * if the user's single sign on token is invalid or expired 181 * @throws SMSException 182 * if an error occurred while performing the operation 183 * 184 * @supported.api 185 */ 186 public ServiceSchemaManager getSchemaManager(String serviceName, 187 String version) throws SMSException, SSOException { 188 return (new ServiceSchemaManager(token, serviceName, version)); 189 } 190 191 /** 192 * Returns the <code>ServiceConfigManager</code> for 193 * the given service name and version. 194 * 195 * @param serviceName 196 * the name of the service 197 * @param version 198 * the version of the service 199 * @return the <code>ServiceConfigManager</code> for the given service 200 * name and version. 201 * @throws SSOException 202 * if the user's single sign on token is invalid or expired 203 * @throws SMSException 204 * if an error occurred while performing the operation 205 * 206 * @supported.api 207 */ 208 public ServiceConfigManager getConfigManager(String serviceName, 209 String version) throws SMSException, SSOException { 210 return (new ServiceConfigManager(token, serviceName, version)); 211 } 212 213 /** 214 * Returns the <code>OrganizationConfigManager</code> for the given 215 * organization name. If the <code>orgName</code> either <code> 216 * null</code> 217 * or empty or "/", the organization configuration for the root organization 218 * will be returned. 219 * 220 * @param orgName 221 * the name of the organization 222 * @return the <code>OrganizationConfigManager</code> for the given 223 * organization name 224 * 225 * @throws SSOException 226 * if the user's single sign on token is invalid or expired 227 * @throws SMSException 228 * if an error occurred while performing the operation 229 */ 230 public OrganizationConfigManager getOrganizationConfigManager( 231 String orgName) throws SMSException, SSOException { 232 return (new OrganizationConfigManager(token, orgName)); 233 } 234 235 /** 236 * Returns all the service names that have been 237 * registered. 238 * 239 * @return the set of names of services that have been registered 240 * @throws SMSException 241 * if an error occurred while performing the operation 242 * 243 * @supported.api 244 */ 245 public Set getServiceNames() throws SMSException { 246 try { 247 if (serviceNames == null) { 248 serviceNames = CachedSubEntries.getInstance(token, serviceDN); 249 } 250 return (serviceNames.getSubEntries(token)); 251 } catch (SSOException s) { 252 debug.error("ServiceManager: Unable to get service names", s); 253 throw (new SMSException(s, "sms-service-not-found")); 254 } 255 } 256 257 /** 258 * Returns a map of service names and the related object classes for the 259 * given <code>schemaType</code>. 260 * 261 * @param schemaType 262 * name of the schema 263 * @return Map of service names and objectclasses 264 */ 265 public Map getServiceNamesAndOCs(String schemaType) { 266 if (schemaType == null) { 267 schemaType = ALL_SERVICES; 268 } else if (schemaType.equalsIgnoreCase("realm")) { 269 schemaType = "filteredrole"; 270 } 271 Map answer = (Map) serviceNameAndOCs.get(schemaType); 272 if (answer == null) { 273 try { 274 answer = new HashMap(); 275 Set sNames = getServiceNames(); 276 if (sNames != null && !sNames.isEmpty()) { 277 Iterator it = sNames.iterator(); 278 while (it.hasNext()) { 279 try { 280 String service = (String) it.next(); 281 ServiceSchemaManagerImpl ssm; 282 if (isCoexistenceMode()) { 283 // For backward compatibility, get the 284 // version from the service. 285 // no hardcoding to '1.0', even if it 286 // improves performance in OpenSSO. 287 // Otherwise, it breaks for services like 288 // iplanetAMProviderConfigService with 289 // '1.1' as version. 290 ssm = ServiceSchemaManagerImpl.getInstance( 291 token, service, serviceDefaultVersion( 292 token, service)); 293 } else { 294 ssm = ServiceSchemaManagerImpl.getInstance( 295 token, service, 296 ServiceManager.getVersion(service)); 297 } 298 if (ssm != null) { 299 // Check if service has schemaType 300 if (schemaType != null && 301 ssm.getSchema(new SchemaType( 302 schemaType)) == null) { 303 // If the schema type is "User" 304 // check for "Dynamic" also 305 if (schemaType.equalsIgnoreCase( 306 SMSUtils.USER_SCHEMA) 307 && ssm.getSchema(SchemaType.DYNAMIC) 308 == null) 309 { 310 continue; 311 } 312 // If the schema type is "Role: 313 // check for "Dynamic" also 314 if (schemaType.toLowerCase() 315 .indexOf("role") != -1 316 && ssm.getSchema(SchemaType.DYNAMIC) 317 == null) 318 { 319 continue; 320 } 321 } 322 ServiceSchemaImpl ss = ssm 323 .getSchema(SchemaType.GLOBAL); 324 if (ss != null) { 325 Map attrs = ss.getAttributeDefaults(); 326 if (attrs.containsKey(SERVICE_OC_ATTR_NAME)) 327 { 328 answer.put(service, attrs 329 .get(SERVICE_OC_ATTR_NAME)); 330 } 331 } 332 } 333 } catch (SMSException smse) { 334 // continue with next service. Best effort to get 335 // all service names. 336 if (debug.messageEnabled()) { 337 debug.message( 338 "ServiceManager.getServiceNamesandOCs" 339 + " caught SMSException ", smse); 340 } 341 } 342 } 343 } 344 serviceNameAndOCs.put(schemaType, answer); 345 } catch (SMSException smse) { 346 // ignore 347 if (debug.messageEnabled()) { 348 debug.message("ServiceManager.getServiceNamesandOCs" 349 + " caught SMSException ", smse); 350 } 351 } catch (SSOException ssoe) { 352 // ignore 353 if (debug.messageEnabled()) { 354 debug.message("ServiceManager.getServiceNamesandOCs" 355 + " caught SSOException ", ssoe); 356 } 357 } 358 } 359 return (SMSUtils.copyAttributes(answer)); 360 } 361 362 /** 363 * Returns all versions supported by the service. 364 * 365 * @param serviceName 366 * service name. 367 * @return the set of versions supported by the service 368 * @throws SMSException 369 * if an error occurred while performing the operation 370 * 371 * @supported.api 372 */ 373 public Set getServiceVersions(String serviceName) throws SMSException { 374 try { 375 return (getVersions(token, serviceName)); 376 } catch (SSOException s) { 377 debug.error("ServiceManager: Unable to get service versions", s); 378 throw (new SMSException(s, "sms-version-not-found")); 379 } 380 } 381 382 /** 383 * Registers one or more services, defined by the XML 384 * input stream that follows the SMS DTD. 385 * 386 * @param xmlServiceSchema 387 * the input stream of service metadata in XML conforming to SMS 388 * DTD. 389 * @return set of registered service names. 390 * @throws SMSException if an error occurred while performing the operation. 391 * @throws SSOException if the user's single sign on token is invalid or 392 * expired. 393 * 394 * @supported.api 395 */ 396 public Set registerServices(InputStream xmlServiceSchema) 397 throws SMSException, SSOException { 398 return registerServices(xmlServiceSchema, null); 399 } 400 401 /** 402 * Registers one or more services, defined by the XML 403 * input stream that follows the SMS DTD. 404 * 405 * @param xmlServiceSchema 406 * the input stream of service metadata in XML conforming to SMS 407 * DTD. 408 * @param decryptObj Object to decrypt the password in the XML. 409 * @return set of registered service names. 410 * @throws SMSException if an error occurred while performing the operation 411 * @throws SSOException if the user's single sign on token is invalid or 412 * expired. 413 */ 414 public Set registerServices( 415 InputStream xmlServiceSchema, 416 AMEncryption decryptObj 417 ) throws SMSException, SSOException { 418 // Validate SSO Token 419 SMSEntry.validateToken(token); 420 Set sNames = new HashSet(); 421 List serviceNodes = new ArrayList(); 422 // Get the XML document and get the list of service nodes 423 Document doc = SMSSchema.getXMLDocument(xmlServiceSchema); 424 425 if (!validSMSDtdDocType(doc)) { 426 throw new SMSException(IUMSConstants.UMS_BUNDLE_NAME, 427 IUMSConstants.SMS_xml_invalid_doc_type, null); 428 } 429 430 // Before validating service schema, we need to check 431 // for AttributeSchema having the syntax of "password" 432 // and if present, encrypt the DefaultValues if any 433 checkAndEncryptPasswordSyntax(doc, true, decryptObj); 434 435 // Create service schema 436 NodeList nodes = doc.getElementsByTagName(SMSUtils.SERVICE); 437 for (int i = 0; (nodes != null) && (i < nodes.getLength()); i++) { 438 Node serviceNode = nodes.item(i); 439 String name = XMLUtils.getNodeAttributeValue(serviceNode, 440 SMSUtils.NAME); 441 String version = XMLUtils.getNodeAttributeValue(serviceNode, 442 SMSUtils.VERSION); 443 444 // Obtain the SMSSchema for Schema and PluginSchema 445 SMSSchema smsSchema = new SMSSchema(name, version, doc); 446 447 // Check if the schema element exists 448 if (XMLUtils.getChildNode(serviceNode, SMSUtils.SCHEMA) != null) { 449 validateServiceSchema(serviceNode); 450 ServiceSchemaManager.createService(token, smsSchema); 451 452 // Update the service name and version cached SMSEntry 453 if (serviceNames == null) { 454 serviceNames = CachedSubEntries.getInstance(token, 455 serviceDN); 456 } 457 serviceNames.add(name); 458 CachedSubEntries sVersions = (CachedSubEntries) serviceVersions 459 .get(name); 460 if (sVersions == null) { 461 // Not present, hence create it and add it 462 sVersions = CachedSubEntries.getInstance(token, 463 getServiceNameDN(name)); 464 serviceVersions.put(name, sVersions); 465 } 466 sVersions.add(version); 467 sNames.add(name); 468 } 469 470 // Check if PluginSchema nodes exists 471 for (Iterator pluginNodes = XMLUtils.getChildNodes(serviceNode, 472 SMSUtils.PLUGIN_SCHEMA).iterator(); pluginNodes.hasNext();) 473 { 474 Node pluginNode = (Node) pluginNodes.next(); 475 PluginSchema.createPluginSchema(token, pluginNode, smsSchema); 476 } 477 478 if (XMLUtils.getChildNode(serviceNode, SMSUtils.CONFIGURATION) 479 != null) { 480 serviceNodes.add(serviceNode); 481 } 482 } 483 484 if (serviceNodes.size() > 0) { 485 clearCache(); 486 } 487 /* 488 * Need to do this after all the schema has been loaded 489 */ 490 for (Iterator i = serviceNodes.iterator(); i.hasNext(); ) { 491 Node svcNode = (Node)i.next(); 492 String name = XMLUtils.getNodeAttributeValue(svcNode, 493 SMSUtils.NAME); 494 String version = XMLUtils.getNodeAttributeValue(svcNode, 495 SMSUtils.VERSION); 496 Node configNode = XMLUtils.getChildNode(svcNode, 497 SMSUtils.CONFIGURATION); 498 /* 499 * Store the configuration, will throw exception if 500 * the service configuration already exists 501 */ 502 CreateServiceConfig.createService(this, name, version, 503 configNode, true, decryptObj); 504 } 505 return sNames; 506 } 507 508 public Document parseServicesFile(InputStream xmlServiceSchema) 509 throws SMSException, SSOException { 510 return parseServicesFile(xmlServiceSchema, null); 511 } 512 513 public Document parseServicesFile( 514 InputStream xmlServiceSchema, 515 AMEncryption decryptObj 516 ) throws SMSException, SSOException { 517 // Validate SSO Token 518 SMSEntry.validateToken(token); 519 //Set<SMSSchema> smsSchemas = new HashSet<SMSSchema>(); 520 Map<String, SMSSchema> smsSchemas = new HashMap<String, SMSSchema>(); 521 List serviceNodes = new ArrayList(); 522 // Get the XML document and get the list of service nodes 523 Document doc = SMSSchema.getXMLDocument(xmlServiceSchema); 524 525 return doc; 526 } 527 528 /* 529 if (!validSMSDtdDocType(doc)) { 530 throw new SMSException(IUMSConstants.UMS_BUNDLE_NAME, 531 IUMSConstants.SMS_xml_invalid_doc_type, null); 532 } 533 534 // Before validating service schema, we need to check 535 // for AttributeSchema having the syntax of "password" 536 // and if present, encrypt the DefaultValues if any 537 checkAndEncryptPasswordSyntax(doc, true, decryptObj); 538 539 // Create service schema 540 NodeList nodes = doc.getElementsByTagName(SMSUtils.SERVICE); 541 for (int i = 0; (nodes != null) && (i < nodes.getLength()); i++) { 542 Node serviceNode = nodes.item(i); 543 String name = XMLUtils.getNodeAttributeValue(serviceNode, 544 SMSUtils.NAME); 545 String version = XMLUtils.getNodeAttributeValue(serviceNode, 546 SMSUtils.VERSION); 547 548 // Obtain the SMSSchema for Schema and PluginSchema 549 SMSSchema smsSchema = new SMSSchema(name, version, doc); 550 smsSchemas.put(name, smsSchema); 551 552 } 553 554 // Check if the schema element exists 555 /*if (XMLUtils.getChildNode(serviceNode, SMSUtils.SCHEMA) != null) { 556 validateServiceSchema(serviceNode); 557 ServiceSchemaManager.createService(token, smsSchema); 558 559 // Update the service name and version cached SMSEntry 560 if (serviceNames == null) { 561 serviceNames = CachedSubEntries.getInstance(token, 562 serviceDN); 563 } 564 serviceNames.add(name); 565 CachedSubEntries sVersions = (CachedSubEntries) serviceVersions 566 .get(name); 567 if (sVersions == null) { 568 // Not present, hence create it and add it 569 sVersions = CachedSubEntries.getInstance(token, 570 getServiceNameDN(name)); 571 serviceVersions.put(name, sVersions); 572 } 573 sVersions.add(version); 574 sNames.add(name); 575 } 576 577 // Check if PluginSchema nodes exists 578 for (Iterator pluginNodes = XMLUtils.getChildNodes(serviceNode, 579 SMSUtils.PLUGIN_SCHEMA).iterator(); pluginNodes.hasNext();) 580 { 581 Node pluginNode = (Node) pluginNodes.next(); 582 PluginSchema.createPluginSchema(token, pluginNode, smsSchema); 583 } 584 585 if (XMLUtils.getChildNode(serviceNode, SMSUtils.CONFIGURATION) 586 != null) { 587 serviceNodes.add(serviceNode); 588 } 589 590 } 591 592 if (serviceNodes.size() > 0) { 593 clearCache(); 594 } 595 /* 596 * Need to do this after all the schema has been loaded 597 */ 598 /* 599 for (Iterator i = serviceNodes.iterator(); i.hasNext(); ) { 600 Node svcNode = (Node)i.next(); 601 String name = XMLUtils.getNodeAttributeValue(svcNode, 602 SMSUtils.NAME); 603 String version = XMLUtils.getNodeAttributeValue(svcNode, 604 SMSUtils.VERSION); 605 Node configNode = XMLUtils.getChildNode(svcNode, 606 SMSUtils.CONFIGURATION); 607 /* 608 * Store the configuration, will throw exception if 609 * the service configuration already exists 610 */ 611 /* 612 CreateServiceConfig.createService(this, name, version, 613 configNode, true, decryptObj); 614 } 615 return sNames; 616 return smsSchemas; 617 }*/ 618 619 private boolean validSMSDtdDocType(Document doc) { 620 boolean valid = false; 621 DocumentType docType = doc.getDoctype(); 622 623 if (docType != null) { 624 String dtdPath = docType.getSystemId(); 625 if (dtdPath != null) { 626 int idx = dtdPath.lastIndexOf('/'); 627 if (idx != -1) { 628 dtdPath = dtdPath.substring(idx + 1); 629 } 630 valid = dtdPath.equals("sms.dtd"); 631 } 632 } 633 634 return valid; 635 } 636 637 /** 638 * Adds a new plugin schema to an existing service 639 * 640 * @param pluginDoc 641 * @throws SMSException if an error occurred while performing the operation 642 * @throws SSOException if the user's single sign on token is invalid or 643 * expired. 644 */ 645 public void addPluginSchema(Document pluginDoc) 646 throws SMSException, SSOException { 647 // Validate SSO Token 648 SMSEntry.validateToken(token); 649 650 Node serviceNode = XMLUtils.getRootNode(pluginDoc, SMSUtils.SERVICE); 651 String serviceName = XMLUtils.getNodeAttributeValue(serviceNode, 652 SMSUtils.NAME); 653 ServiceSchemaManager ssm = new ServiceSchemaManager(serviceName, token); 654 Document schemaDoc = ssm.getDocumentCopy(); 655 656 Node pluginSchemaDoc = XMLUtils.getRootNode(pluginDoc, SMSUtils.PLUGIN_SCHEMA); 657 658 // Obtain the SMSSchema for Schema and PluginSchema 659 SMSSchema smsSchema = new SMSSchema(schemaDoc); 660 PluginSchema.createPluginSchema(token, pluginSchemaDoc, smsSchema); 661 } 662 663 /** 664 * Removes a plugin schema from a service 665 * 666 * @param serviceName The name of the service 667 * @param interfaceName The name of the plugin interface 668 * @param pluginName The name of the plugin schema 669 * @throws SMSException if an error occurred while performing the operation 670 * @throws SSOException if the user's single sign on token is invalid or 671 * expired. 672 */ 673 public void removePluginSchema(String serviceName, 674 String interfaceName, 675 String pluginName) 676 throws SMSException, SSOException { 677 ServiceSchemaManager ssm = new ServiceSchemaManager(serviceName, token); 678 String version = ssm.getVersion(); 679 680 // Check if PluginSchema nodes exists 681 Set pluginSchemaNames = ssm.getPluginSchemaNames(interfaceName, null); 682 683 // if they match, delete 684 if (pluginSchemaNames.contains(pluginName)) { 685 StringBuilder sb = new StringBuilder(100); 686 687 // Construct the DN and get CachedSMSEntry 688 sb.append("ou=").append(pluginName).append(",").append("ou=").append( 689 interfaceName).append(",").append( 690 CreateServiceConfig.PLUGIN_CONFIG_NODE).append("ou=").append( 691 version).append(",").append("ou=").append(serviceName).append( 692 ",").append(SMSEntry.SERVICES_RDN).append(","); 693 694 CachedSMSEntry ce; 695 696 try { 697 ce = CachedSMSEntry.getInstance(token, sb.toString() 698 + SMSEntry.baseDN); 699 SMSEntry smsEntry = ce.getClonedSMSEntry(); 700 smsEntry.forceDelete(token); 701 ce.refresh(smsEntry); 702 } catch (SSOException ssoe) { 703 throw (new SMSException(ssoe, "sms-INVALID_SSO_TOKEN")); 704 } 705 } else { 706 throw new SMSException("Condition does not exist"); 707 } 708 709 if (debug.messageEnabled()) { 710 debug.message("removePluginSchema: remove plugin " + pluginName + 711 "from service " + serviceName); 712 } 713 } 714 715 /** 716 * Removes the service schema and configuration for 717 * the given service name. 718 * 719 * @param serviceName 720 * the name of the service 721 * @param version 722 * the version of the service 723 * @throws SMSException 724 * if an error occurred while performing the operation 725 * @throws SSOException 726 * if the user's single sign on token is invalid or expired 727 * 728 * @supported.api 729 */ 730 public void removeService(String serviceName, String version) 731 throws SMSException, SSOException { 732 // Find all service entries that have the DN 733 // Search for (&(ou=<serviceName>)(objectclass=top)) 734 // construct the rdn with the given version, look for the entry 735 // in iDS and if entry exists(service with that version), delete. 736 if (serviceName.equalsIgnoreCase(IdConstants.REPO_SERVICE) || 737 serviceName.equalsIgnoreCase(ISAuthConstants.AUTH_SERVICE_NAME)) { 738 Object args[] = { serviceName }; 739 throw (new SMSException(IUMSConstants.UMS_BUNDLE_NAME, 740 "sms-SERVICE_CORE_CANNOT_DELETE", args)); 741 } 742 SMSEntry.validateToken(token); 743 String[] objs = { serviceName }; 744 Iterator results = SMSEntry.search(token, SMSEntry.baseDN, 745 MessageFormat.format(SMSEntry.FILTER_PATTERN, (Object[])objs), 746 0, 0, false, false).iterator(); 747 while (results.hasNext()) { 748 String dn = (String) results.next(); 749 String configdn = SMSEntry.PLACEHOLDER_RDN + SMSEntry.EQUALS 750 + version + SMSEntry.COMMA + dn; 751 CachedSMSEntry configsmse = CachedSMSEntry.getInstance(token, 752 configdn); 753 if (configsmse.isDirty()) { 754 configsmse.refresh(); 755 } 756 SMSEntry confige = configsmse.getClonedSMSEntry(); 757 if (!confige.isNewEntry()) { 758 confige.delete(token); 759 configsmse.refresh(confige); 760 } 761 // If there are no other service version nodes for that service, 762 // delete that node(schema). 763 CachedSMSEntry smse = CachedSMSEntry.getInstance(token, dn); 764 if (smse.isDirty()) { 765 smse.refresh(); 766 } 767 SMSEntry e = smse.getSMSEntry(); 768 Iterator versions = 769 e.subEntries(token, "*", 0, false, false).iterator(); 770 if (!versions.hasNext()) { 771 e.delete(token); 772 smse.refresh(e); 773 } 774 } 775 } 776 777 /** 778 * Deletes only the schema for the given service name. This is provided only 779 * for backward compatibility for DSAME 5.0 and will be deprecated in the 780 * future release. Alternative is to use 781 * <code>ServiceSchemaManager.replaceSchema()</code>. 782 * 783 * @param serviceName 784 * Name of service to be deleted. 785 * @throws SMSException 786 * if an error occurred while performing the operation 787 * @throws SSOException 788 * if the user's single sign on token is invalid or expired 789 */ 790 public void deleteService(String serviceName) throws SMSException, 791 SSOException { 792 if (serviceName.equalsIgnoreCase(IdConstants.REPO_SERVICE) || 793 serviceName.equalsIgnoreCase(ISAuthConstants.AUTH_SERVICE_NAME)) { 794 Object args[] = { serviceName }; 795 throw (new SMSException(IUMSConstants.UMS_BUNDLE_NAME, 796 "sms-SERVICE_CORE_CANNOT_DELETE", args)); 797 } 798 799 Iterator versions = getServiceVersions(serviceName).iterator(); 800 while (versions.hasNext()) { 801 String version = (String) versions.next(); 802 CachedSMSEntry ce = CachedSMSEntry.getInstance(token, 803 getServiceNameDN(serviceName, version)); 804 if (ce.isDirty()) { 805 ce.refresh(); 806 } 807 SMSEntry e = ce.getClonedSMSEntry(); 808 String[] values = { SMSSchema.getDummyXML(serviceName, version) }; 809 e.setAttribute(SMSEntry.ATTR_SCHEMA, values); 810 e.save(token); 811 ce.refresh(e); 812 } 813 } 814 815 /** 816 * Returns the base DN (or root DN) that was set in 817 * <code>serverconfig.xml</code> at install time. 818 */ 819 public static String getBaseDN() { 820 return (SMSEntry.baseDN); 821 } 822 823 /** 824 * Returns all AM Server instance. Read the configured servers from platform 825 * service's <code>iplanet-am-platform-server-list</code> 826 */ 827 public static Set getAMServerInstances() { 828 // Check cache 829 if (accessManagerServers == null) { 830 // Get AdminToken 831 try { 832 SSOToken token = (SSOToken) AccessController 833 .doPrivileged(AdminTokenAction.getInstance()); 834 accessManagerServers = ServerConfiguration.getServers(token); 835 if (debug.messageEnabled()) { 836 debug.message("ServiceManager.getAMServerInstances: " 837 + "server list: " + accessManagerServers); 838 } 839 } catch (SMSException e) { 840 if (debug.warningEnabled()) { 841 debug.warning("ServiceManager.getAMServerInstances: " + 842 "Unable to get server list", e); 843 } 844 } catch (SSOException e) { 845 if (debug.warningEnabled()) { 846 debug.warning("ServiceManager.getAMServerInstances: " + 847 "Unable to get server list", e); 848 } 849 } 850 } 851 return (accessManagerServers == null ? new HashSet() : new HashSet( 852 accessManagerServers)); 853 } 854 855 /** 856 * Returns organization names that match the given attribute name and 857 * values. Only exact matching is supported, and if more than one value is 858 * provided the organization must have all these values for the attribute. 859 * Basically an AND is performed for attribute values for searching. 860 * 861 * @param serviceName 862 * service name under which the attribute is to be sought. 863 * @param attrName 864 * name of the attribute to search. 865 * @param values 866 * set of attribute values to search. 867 * @return organizations that match the attribute name and values. 868 * @throws SMSException 869 * if an error occurred while performing the operation. 870 * @throws SSOException 871 * if the user's single sign on token is invalid or expired. 872 */ 873 public Set searchOrganizationNames(String serviceName, String attrName, 874 Set values) throws SMSException, SSOException { 875 876 try { 877 if (subEntries == null) { 878 subEntries = CachedSubEntries.getInstance(token, 879 SMSEntry.SERVICES_RDN + SMSEntry.COMMA 880 + SMSEntry.baseDN); 881 } 882 return (subEntries.searchOrgNames(token, serviceName.toLowerCase(), 883 attrName, values)); 884 } catch (SSOException ssoe) { 885 debug.error("OrganizationConfigManagerImpl: Unable to " 886 + "get sub organization names", ssoe); 887 throw (new SMSException(SMSEntry.bundle 888 .getString("sms-INVALID_SSO_TOKEN"), 889 "sms-INVALID_SSO_TOKEN")); 890 } 891 } 892 893 /** 894 * Removes all the SMS cached entries. This method 895 * should be called to clear the cache for example, if ACIs for the SMS 896 * entries are changed in the directory. Also, this clears the SMS entries 897 * only in this JVM instance. If multiple instances (of JVM) are running 898 * this method must be called within each instance. 899 * 900 * @supported.api 901 */ 902 public synchronized void clearCache() { 903 // Clear the local caches 904 serviceNameAndOCs = new CaseInsensitiveHashMap(); 905 serviceVersions = new CaseInsensitiveHashMap(); 906 serviceNameDefaultVersion = new CaseInsensitiveHashMap(); 907 accessManagerServers = null; 908 amsdkChecked = false; 909 910 // Call respective Impl classes 911 CachedSMSEntry.clearCache(); 912 CachedSubEntries.clearCache(); 913 // ServiceSchemaManagerImpl.clearCache(); 914 PluginSchemaImpl.clearCache(); 915 ServiceInstanceImpl.clearCache(); 916 ServiceConfigImpl.clearCache(); 917 ServiceConfigManagerImpl.clearCache(); 918 OrganizationConfigManagerImpl.clearCache(); 919 OrgConfigViaAMSDK.clearCache(); 920 921 // Re-initialize the flags 922 try { 923 checkFlags(token); 924 OrganizationConfigManager.initializeFlags(); 925 DNMapper.clearCache(); 926 } catch (Exception e) { 927 debug.error("ServiceManager::clearCache unable to " + 928 "re-initialize global flags", e); 929 } 930 } 931 932 /** 933 * Returns the flag which lets IdRepo and SM know that we are running in the 934 * co-existence mode. 935 * 936 * @return true or false depending on if the coexistence flag is enabled or 937 * not. 938 */ 939 public static boolean isCoexistenceMode() { 940 isRealmEnabled(); 941 return (coexistenceCache); 942 } 943 944 /** 945 * Returns the version for a service. This is to handle the co-existence 946 * of OpenSSO and AM 7.1 in realm mode. The co-existence of OpenSSO and 947 * AM 7.1 in legacy mode is handled by the call to isCoexistenceMode() 948 * method. There is a special service named "iPlanetAMProviderConfigService" 949 * used in AM 7.x code for ID-FF metadata, the version for the service 950 * is "1.1", all the rest of service is "1.0" right now. This method can 951 * be removed if no need to support Co-existence of OpenSSO and AM 7.x 952 * any more. 953 * @param serviceName Name of the service. 954 * @return version of the service, the value will be 1.0 or 1.1. 955 */ 956 protected static String getVersion(String serviceName) { 957 if ("iPlanetAMProviderConfigService".equals(serviceName)) { 958 return "1.1"; 959 } else { 960 return "1.0"; 961 } 962 } 963 964 /** 965 * Returns <code>true</code> if current service 966 * configuration uses the realm model to store the configuration data. 967 * 968 * @return <code>true</code> is realm model is used for storing 969 * configuration data; <code>false</code> otherwise. 970 * 971 * @supported.api 972 */ 973 public static boolean isRealmEnabled() { 974 if (!initialized) { 975 try { 976 initialize((SSOToken) AccessController 977 .doPrivileged(AdminTokenAction.getInstance())); 978 } catch (Exception ssme) { 979 debug.error("ServiceManager::isRealmEnabled unable to " 980 + "initialize", ssme); 981 } 982 } 983 return (realmCache); 984 } 985 986 987 /** 988 * Returns <code>true</code> if AMSDK IdRepo plugin is 989 * configured in any of the realms 990 */ 991 public static boolean isAMSDKConfigured() throws SMSException { 992 if (!isRealmEnabled() || OrgConfigViaAMSDK.isAMSDKConfigured("/")) { 993 // Legacy mode, AMSDK is configured by default 994 return (true); 995 } 996 997 // Iterate through all the realms to check if AMSDK is configured 998 SSOToken token = (SSOToken) AccessController 999 .doPrivileged(AdminTokenAction.getInstance()); 1000 Set realms = (new OrganizationConfigManager(token, "/")) 1001 .getSubOrganizationNames("*", true); 1002 for (Iterator items = realms.iterator(); items.hasNext();) { 1003 String realm = items.next().toString(); 1004 if (OrgConfigViaAMSDK.isAMSDKConfigured(realm)) { 1005 return (true); 1006 } 1007 } 1008 return (false); 1009 } 1010 1011 /** 1012 * Returns <code>true</code> if configuration data has been migrated to 1013 * Access Manager 7.0. Else <code>false</code> otherwise. 1014 * 1015 * @return <code>true</code> if configuration data has been migrated to AM 1016 * 7.0; <code>false</code> otherwise 1017 */ 1018 public static boolean isConfigMigratedTo70() { 1019 isRealmEnabled(); 1020 return (ditUpgradedCache); 1021 } 1022 1023 // ------------------------------------------------------------ 1024 // Protected methods 1025 // ------------------------------------------------------------ 1026 1027 // Called by CreateServiceConfig.java to create LDAP entries 1028 SSOToken getSSOToken() { 1029 return (token); 1030 } 1031 1032 protected static String getCacheIndex(String serviceName, String version) { 1033 StringBuilder sb = new StringBuilder(20); 1034 return ( 1035 sb.append(serviceName).append(version).toString().toLowerCase()); 1036 } 1037 1038 protected static String getServiceNameDN(String serviceName) { 1039 StringBuilder sb = new StringBuilder(100); 1040 sb.append(SMSEntry.PLACEHOLDER_RDN).append(SMSEntry.EQUALS).append( 1041 serviceName).append(SMSEntry.COMMA).append(serviceDN); 1042 return (sb.toString()); 1043 } 1044 1045 protected static String getServiceNameDN(String serviceName, String version) 1046 { 1047 StringBuilder sb = new StringBuilder(100); 1048 sb.append(SMSEntry.PLACEHOLDER_RDN).append(SMSEntry.EQUALS).append( 1049 version).append(SMSEntry.COMMA).append( 1050 getServiceNameDN(serviceName)); 1051 return (sb.toString()); 1052 } 1053 1054 protected static Set getVersions(SSOToken token, String serviceName) 1055 throws SMSException, SSOException { 1056 CachedSubEntries sVersions = (CachedSubEntries) serviceVersions 1057 .get(serviceName); 1058 if (sVersions == null) { 1059 sVersions = CachedSubEntries.getInstance(token, 1060 getServiceNameDN(serviceName)); 1061 if (sVersions == null || sVersions.getSMSEntry().isNewEntry() 1062 || sVersions.getSubEntries(token).isEmpty()) { 1063 String[] msgs = { serviceName }; 1064 throw (new ServiceNotFoundException( 1065 IUMSConstants.UMS_BUNDLE_NAME, 1066 IUMSConstants.SMS_service_does_not_exist, msgs)); 1067 } 1068 serviceVersions.put(serviceName, sVersions); 1069 } 1070 return (sVersions.getSubEntries(token)); 1071 } 1072 1073 protected static void checkAndEncryptPasswordSyntax(Document doc, 1074 boolean encrypt 1075 ) throws SMSException { 1076 checkAndEncryptPasswordSyntax(doc, encrypt, null); 1077 } 1078 1079 protected static void checkAndEncryptPasswordSyntax( 1080 Document doc, 1081 boolean encrypt, 1082 AMEncryption encryptObj 1083 ) throws SMSException { 1084 // Get the node list of all AttributeSchema 1085 NodeList nl = doc.getElementsByTagName(SMSUtils.SCHEMA_ATTRIBUTE); 1086 for (int i = 0; i < nl.getLength(); i++) { 1087 Node node = nl.item(i); 1088 // Check if the "syntax" attribute is "password" 1089 String syntax = XMLUtils.getNodeAttributeValue(node, 1090 SMSUtils.ATTRIBUTE_SYNTAX); 1091 if (syntax.equals(AttributeSchema.Syntax.PASSWORD.toString())) { 1092 if (debug.messageEnabled()) { 1093 debug.message("ServiceManager: encrypting password syntax"); 1094 } 1095 // Get the DefaultValues and encrypt then 1096 Node defaultNode; 1097 if ((defaultNode = XMLUtils.getChildNode(node, 1098 SMSUtils.ATTRIBUTE_DEFAULT_ELEMENT)) != null) { 1099 // Get NodeList of "Value" nodes and encrypt them 1100 for (Iterator items = XMLUtils.getChildNodes(defaultNode, 1101 SMSUtils.ATTRIBUTE_VALUE).iterator(); items 1102 .hasNext();) { 1103 Node valueNode = (Node) items.next(); 1104 String value = XMLUtils.getValueOfValueNode(valueNode); 1105 String encValue; 1106 1107 // skip empty passwords 1108 if (value.equals("null")) { 1109 continue; 1110 } 1111 1112 if (encrypt) { 1113 if (encryptObj != null) { 1114 value = (String)AccessController 1115 .doPrivileged(new DecodeAction( 1116 value, encryptObj)); 1117 if (value.equals("&#160;")) { 1118 try { 1119 byte[] b = new byte[1]; 1120 b[0] = -96; 1121 value = new String(b, "ISO-8859-1"); 1122 } catch (UnsupportedEncodingException e) { 1123 //ignore 1124 } 1125 } 1126 } 1127 encValue = (String)AccessController.doPrivileged( 1128 new EncodeAction(value)); 1129 } else { 1130 encValue = AccessController.doPrivileged(new DecodeAction(value)); 1131 1132 if (encValue == null) { 1133 encValue = "&#160;"; 1134 } else { 1135 try { 1136 //this is catch the whitespace for password 1137 byte[] b = encValue.getBytes("ISO-8859-1"); 1138 if ((b.length == 1) && (b[0] == -96)) { 1139 encValue = "&#160;"; 1140 } 1141 } catch (UnsupportedEncodingException e) { 1142 //ignore 1143 } 1144 } 1145 if (encryptObj != null) { 1146 encValue = (String)AccessController 1147 .doPrivileged(new EncodeAction( 1148 encValue, encryptObj)); 1149 } 1150 } 1151 1152 // Construct the encrypted "Value" node 1153 StringBuilder sb = new StringBuilder(100); 1154 sb.append(AttributeSchema.VALUE_BEGIN).append(encValue) 1155 .append(AttributeSchema.VALUE_END); 1156 Document newDoc = SMSSchema.getXMLDocument( 1157 sb.toString(), false); 1158 Node newValueNode = XMLUtils.getRootNode(newDoc, 1159 SMSUtils.ATTRIBUTE_VALUE); 1160 // Replace the node 1161 Node nValueNode = doc.importNode(newValueNode, true); 1162 defaultNode.replaceChild(nValueNode, valueNode); 1163 } 1164 } 1165 } 1166 } 1167 } 1168 1169 protected static boolean validateServiceSchema(Node serviceNode) 1170 throws SMSException { 1171 Node schemaRoot = XMLUtils.getChildNode(serviceNode, SMSUtils.SCHEMA); 1172 String[] schemaNames = { SMSUtils.GLOBAL_SCHEMA, SMSUtils.ORG_SCHEMA, 1173 SMSUtils.DYNAMIC_SCHEMA, SMSUtils.USER_SCHEMA, 1174 SMSUtils.POLICY_SCHEMA, SMSUtils.GROUP_SCHEMA, 1175 SMSUtils.DOMAIN_SCHEMA }; 1176 for (int i = 0; i < schemaNames.length; i++) { 1177 Node childNode = XMLUtils.getChildNode(schemaRoot, schemaNames[i]); 1178 if (childNode != null) { 1179 ServiceSchemaImpl ssi = new ServiceSchemaImpl(null, childNode); 1180 Map attrs = ssi.getAttributeDefaults(); 1181 ssi.validateAttributes(attrs, false); 1182 } 1183 } 1184 return (true); 1185 } 1186 1187 // Gets called by OrganizationConfigManager when service schema has changed 1188 protected static void schemaChanged() { 1189 // Reset the service names and OCs used by IdRepo 1190 serviceNameAndOCs = new CaseInsensitiveHashMap(); 1191 // Reset the schema types and service names 1192 // Reset the service names 1193 serviceNames = null; 1194 } 1195 1196 protected static String serviceDefaultVersion(SSOToken token, 1197 String serviceName) throws SMSException, SSOException { 1198 String version = (String) serviceNameDefaultVersion.get(serviceName); 1199 if (version == null) { 1200 Iterator iter = getVersions(token, serviceName).iterator(); 1201 if (iter.hasNext()) { 1202 version = (String) iter.next(); 1203 } else { 1204 String msgs[] = { serviceName }; 1205 throw (new ServiceNotFoundException( 1206 IUMSConstants.UMS_BUNDLE_NAME, 1207 IUMSConstants.SMS_service_does_not_exist, 1208 msgs)); 1209 } 1210 serviceNameDefaultVersion.put(serviceName, version); 1211 } 1212 return (version); 1213 } 1214 1215 /** 1216 * Returns service names that will be assigned to a realm during creation. 1217 */ 1218 public static Set servicesAssignedByDefault() { 1219 if (!loadedAuthServices) { 1220 AuthenticationServiceNameProvider provider = 1221 AuthenticationServiceNameProviderFactory.getProvider(); 1222 defaultServicesToLoad.addAll(provider 1223 .getAuthenticationServiceNames()); 1224 if (debug.messageEnabled()) { 1225 debug.message("ServiceManager::servicesAssignedByDefault:" 1226 + "defaultServicesToLoad = " + defaultServicesToLoad); 1227 } 1228 loadedAuthServices = true; 1229 defaultServicesToLoad = Collections 1230 .unmodifiableSet(defaultServicesToLoad); 1231 } 1232 return (defaultServicesToLoad); 1233 } 1234 1235 /** 1236 * Returns service names configured via IdRepo service to be 1237 * added as required services 1238 */ 1239 static Set requiredServices() { 1240 return (requiredServices); 1241 } 1242 1243 static void initialize(SSOToken token) throws SMSException, SSOException { 1244 // Validate SSOToken 1245 SMSEntry.validateToken(token); 1246 1247 // Check if already initialized 1248 if (initialized) 1249 return; 1250 // Initilaize the parameters 1251 try { 1252 // Get the service names and cache it 1253 serviceNames = CachedSubEntries.getInstance(token, serviceDN); 1254 if (serviceNames.getSMSEntry().isNewEntry()) { 1255 if (debug.warningEnabled()) { 1256 debug.warning("SeviceManager:: Root service node " 1257 + "does not exists: " + serviceDN); 1258 } 1259 String[] msgs = new String[1]; 1260 msgs[0] = serviceDN; 1261 throw (new SMSException(IUMSConstants.UMS_BUNDLE_NAME, 1262 IUMSConstants.SMS_services_node_does_not_exist, msgs)); 1263 } 1264 } catch (SMSException e) { 1265 debug.error("ServiceManager::unable to get " + "services node: " 1266 + serviceDN, e); 1267 throw (e); 1268 } 1269 // Check if realm is enabled and set appropriate flags 1270 checkFlags(token); 1271 initialized = true; 1272 } 1273 1274 static void checkFlags(SSOToken token) throws SMSException, SSOException { 1275 try { 1276 CachedSMSEntry entry = CachedSMSEntry.getInstance(token, 1277 REALM_ENTRY); 1278 if (entry.isDirty()) { 1279 entry.refresh(); 1280 } 1281 if (!entry.isNewEntry()) { 1282 ditUpgradedCache = true; 1283 ServiceConfigManagerImpl ssm = ServiceConfigManagerImpl 1284 .getInstance(token, REALM_SERVICE, SERVICE_VERSION); 1285 ServiceConfigImpl sc = null; 1286 Map map = null; 1287 if (ssm == null 1288 || (sc = ssm.getGlobalConfig(token, null)) == null 1289 || (map = sc.getAttributes()) == null) { 1290 return; 1291 } 1292 Set coexistEntry = (Set) map.get(COEXISTENCE_ATTR_NAME); 1293 if (coexistEntry != null && coexistEntry.contains("false")) { 1294 coexistenceCache = false; 1295 } 1296 Set realmEntry = (Set) map.get(REALM_ATTR_NAME); 1297 if (realmEntry != null && realmEntry.contains("true")) { 1298 realmCache = true; 1299 } 1300 // Get the default services to be loaded 1301 requiredServices = (Set) map 1302 .get(DEFAULT_SERVICES_FOR_REALMS); 1303 defaultServicesToLoad = new HashSet(); 1304 defaultServicesToLoad.addAll(requiredServices); 1305 1306 // Make this flag false, for always the union of 1307 // auto assignment services from idRepoService.xml and 1308 // auth services from AMAuthenticationManager code 1309 // should be returned for deep copy for a newly created 1310 // sub realm. 1311 loadedAuthServices = false; 1312 } 1313 if (debug.messageEnabled()) { 1314 debug.message("ServiceManager::checkFlags:realmEnabled=" 1315 + realmCache); 1316 debug.message("ServiceManager::checkFlags:coexistenceMode=" 1317 + coexistenceCache); 1318 } 1319 } catch (SMSException e) { 1320 debug.error("ServiceManager::unable to check " 1321 + "if Realm is enabled: ", e); 1322 throw (e); 1323 } 1324 } 1325 1326 public String toXML(AMEncryption encryptObj) 1327 throws SMSException, SSOException 1328 { 1329 StringBuilder buff = new StringBuilder(); 1330 buff.append(SMSSchema.XML_ENC) 1331 .append("\n") 1332 .append("<!DOCTYPE ServicesConfiguration\n") 1333 .append( 1334 "PUBLIC \"=//iPlanet//Service Management Services (SMS) 1.0 DTD//EN\"\n") 1335 .append("\"jar://com/sun/identity/sm/sms.dtd\">\n\n"); 1336 buff.append("<ServicesConfiguration>\n"); 1337 1338 Set serviceNames = getServiceNames(); 1339 1340 for (Iterator i = serviceNames.iterator(); i.hasNext(); ) { 1341 String serviceName = (String)i.next(); 1342 Set versions = getServiceVersions(serviceName); 1343 1344 for (Iterator j = versions.iterator(); j.hasNext(); ) { 1345 String version = (String)j.next(); 1346 ServiceSchemaManager ssm = new 1347 ServiceSchemaManager(token, serviceName, version); 1348 String xml = ssm.toXML(encryptObj); 1349 ServiceConfigManager scm = new ServiceConfigManager( 1350 serviceName, token); 1351 int idx = xml.lastIndexOf("</" + SMSUtils.SERVICE + ">"); 1352 xml = xml.substring(0, idx) + scm.toXML(encryptObj) + "</" + 1353 SMSUtils.SERVICE + ">"; 1354 buff.append(xml).append("\n"); 1355 } 1356 } 1357 1358 buff.append("</ServicesConfiguration>\n"); 1359 return buff.toString().replaceAll("&#160;", " "); 1360 } 1361 1362 /** 1363 * Returns <code>true</code> if AMSDK IdRepo plugin is enabled/present 1364 * in IdRepo Service Configuration schema 1365 */ 1366 public static boolean isAMSDKEnabled() { 1367 if (amsdkChecked) { 1368 return (isAMSDKEnabled); 1369 } 1370 SSOToken adminToken = (SSOToken) AccessController 1371 .doPrivileged(AdminTokenAction.getInstance()); 1372 try { 1373 if (!ServiceManager.isRealmEnabled()) { 1374 amsdkChecked = true; 1375 // If in legacy mode, then amSDK plugin would always be there. 1376 isAMSDKEnabled = true; 1377 } else { 1378 ServiceSchemaManager ssm = new ServiceSchemaManager( 1379 IdConstants.REPO_SERVICE, adminToken); 1380 ServiceSchema idRepoSubSchema = ssm.getOrganizationSchema(); 1381 Set idRepoPlugins = idRepoSubSchema.getSubSchemaNames(); 1382 if (idRepoPlugins.contains("amSDK")) { 1383 isAMSDKEnabled = true; 1384 } 1385 amsdkChecked = true; 1386 } 1387 } catch (Exception e) { 1388 debug.error("IdUtils.isAMSDKEnabled() " + 1389 "Error in checking AM.SDK being configured", e); 1390 } 1391 amsdkChecked = true; 1392 return (isAMSDKEnabled); 1393 } 1394}
Copyright © 2010-2017, ForgeRock All Rights Reserved.