001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2007-2008 Sun Microsystems, Inc. 026 */ 027 028 package org.opends.admin.ads; 029 030 import java.io.File; 031 import java.util.LinkedHashSet; 032 import java.util.LinkedList; 033 import java.util.Set; 034 import java.util.HashSet; 035 import java.util.Map; 036 import java.util.HashMap; 037 import java.util.logging.Level; 038 import java.util.logging.Logger; 039 040 import javax.naming.CompositeName; 041 import javax.naming.InvalidNameException; 042 import javax.naming.NameAlreadyBoundException; 043 import javax.naming.NameNotFoundException; 044 import javax.naming.NamingEnumeration; 045 import javax.naming.NamingException; 046 import javax.naming.NoPermissionException; 047 import javax.naming.NotContextException; 048 import javax.naming.directory.DirContext; 049 import javax.naming.directory.SearchResult; 050 import javax.naming.directory.Attribute; 051 import javax.naming.directory.Attributes; 052 import javax.naming.directory.BasicAttribute; 053 import javax.naming.directory.BasicAttributes; 054 import javax.naming.directory.SearchControls; 055 import javax.naming.ldap.InitialLdapContext; 056 import javax.naming.ldap.LdapName; 057 import javax.naming.ldap.Rdn; 058 import javax.naming.ldap.Control; 059 import javax.naming.ldap.LdapContext; 060 061 062 /** 063 * Class used to update and read the contents of the Administration Data. 064 */ 065 public class ADSContext 066 { 067 private static final Logger LOG = 068 Logger.getLogger(ADSContext.class.getName()); 069 070 /** 071 * Enumeration containing the different server properties syntaxes 072 * that could be stored in the ADS. 073 */ 074 public enum ADSPropertySyntax 075 { 076 /** 077 * String syntax. 078 */ 079 STRING, 080 081 /** 082 * Integer syntax. 083 */ 084 INTEGER, 085 086 /** 087 * Boolean syntax. 088 */ 089 BOOLEAN, 090 091 /** 092 * Certificate;binary syntax. 093 */ 094 CERTIFICATE_BINARY 095 } 096 097 /** 098 * Enumeration containing the different server properties that are stored in 099 * the ADS. 100 */ 101 public enum ServerProperty 102 { 103 /** 104 * The ID used to identify the server. 105 */ 106 ID("id",ADSPropertySyntax.STRING), 107 /** 108 * The host name of the server. 109 */ 110 HOST_NAME("hostname",ADSPropertySyntax.STRING), 111 /** 112 * The LDAP port of the server. 113 */ 114 LDAP_PORT("ldapport",ADSPropertySyntax.INTEGER), 115 /** 116 * The JMX port of the server. 117 */ 118 JMX_PORT("jmxport",ADSPropertySyntax.INTEGER), 119 /** 120 * The JMX secure port of the server. 121 */ 122 JMXS_PORT("jmxsport",ADSPropertySyntax.INTEGER), 123 /** 124 * The LDAPS port of the server. 125 */ 126 LDAPS_PORT("ldapsport",ADSPropertySyntax.INTEGER), 127 /** 128 * The certificate used by the server. 129 */ 130 CERTIFICATE("certificate",ADSPropertySyntax.STRING), 131 /** 132 * The path where the server is installed. 133 */ 134 INSTANCE_PATH("instancepath",ADSPropertySyntax.STRING), 135 /** 136 * The description of the server. 137 */ 138 DESCRIPTION("description",ADSPropertySyntax.STRING), 139 /** 140 * The OS of the machine where the server is installed. 141 */ 142 HOST_OS("os",ADSPropertySyntax.STRING), 143 /** 144 * Whether LDAP is enabled or not. 145 */ 146 LDAP_ENABLED("ldapEnabled",ADSPropertySyntax.BOOLEAN), 147 /** 148 * Whether LDAPS is enabled or not. 149 */ 150 LDAPS_ENABLED("ldapsEnabled",ADSPropertySyntax.BOOLEAN), 151 /** 152 * Whether StartTLS is enabled or not. 153 */ 154 STARTTLS_ENABLED("startTLSEnabled",ADSPropertySyntax.BOOLEAN), 155 /** 156 * Whether JMX is enabled or not. 157 */ 158 JMX_ENABLED("jmxEnabled",ADSPropertySyntax.BOOLEAN), 159 /** 160 * Whether JMX is enabled or not. 161 */ 162 JMXS_ENABLED("jmxsEnabled",ADSPropertySyntax.BOOLEAN), 163 /** 164 * The location of the server. 165 */ 166 LOCATION("location",ADSPropertySyntax.STRING), 167 /** 168 * The groups to which this server belongs. 169 */ 170 GROUPS("memberofgroups",ADSPropertySyntax.STRING), 171 /** 172 * The unique name of the instance key public-key certificate. 173 */ 174 INSTANCE_KEY_ID("ds-cfg-key-id",ADSPropertySyntax.STRING), 175 /** 176 * The instance key-pair public-key certificate. Note: This attribute 177 * belongs to an instance key entry, separate from the server entry and 178 * named by the ds-cfg-key-id attribute from the server entry. 179 */ 180 INSTANCE_PUBLIC_KEY_CERTIFICATE( 181 "ds-cfg-public-key-certificate", 182 ADSPropertySyntax.CERTIFICATE_BINARY); 183 184 private String attrName; 185 private ADSPropertySyntax attSyntax; 186 187 /** 188 * Private constructor. 189 * @param n the name of the attribute. 190 * @param s the name of the syntax. 191 */ 192 private ServerProperty(String n, ADSPropertySyntax s) 193 { 194 attrName = n; 195 attSyntax = s ; 196 } 197 198 /** 199 * Returns the attribute name. 200 * @return the attribute name. 201 */ 202 public String getAttributeName() 203 { 204 return attrName; 205 } 206 207 /** 208 * Returns the attribute syntax. 209 * @return the attribute syntax. 210 */ 211 public ADSPropertySyntax getAttributeSyntax() 212 { 213 return attSyntax; 214 } 215 } 216 217 /** Default global admin UID. */ 218 public static final String GLOBAL_ADMIN_UID = "admin"; 219 220 private static HashMap<String, ServerProperty> nameToServerProperty = null; 221 222 /** 223 * Get a ServerProperty associated to a name. 224 * @param name The name of the property to retrieve. 225 * 226 * @return The corresponding ServerProperty or null if name 227 * doesn't match with an existing property. 228 */ 229 public static ServerProperty getServerPropFromName(String name) 230 { 231 if (nameToServerProperty == null) 232 { 233 nameToServerProperty = new HashMap<String, ServerProperty>(); 234 for (ServerProperty s : ServerProperty.values()) 235 { 236 nameToServerProperty.put(s.getAttributeName(), s); 237 } 238 } 239 return nameToServerProperty.get(name); 240 } 241 242 /** 243 * The list of server properties that are multivalued. 244 */ 245 private final static Set<ServerProperty> MULTIVALUED_SERVER_PROPERTIES = 246 new HashSet<ServerProperty>(); 247 static 248 { 249 MULTIVALUED_SERVER_PROPERTIES.add(ServerProperty.GROUPS); 250 } 251 252 /** 253 * The default server group which will contain all registered servers. 254 */ 255 public static final String ALL_SERVERGROUP_NAME = "all-servers"; 256 257 /** 258 * Enumeration containing the different server group properties that are 259 * stored in the ADS. 260 */ 261 public enum ServerGroupProperty 262 { 263 /** 264 * The UID of the server group. 265 */ 266 UID("cn"), 267 /** 268 * The description of the server group. 269 */ 270 DESCRIPTION("description"), 271 /** 272 * The members of the server group. 273 */ 274 MEMBERS("uniqueMember"); 275 276 private String attrName; 277 278 /** 279 * Private constructor. 280 * @param n the attribute name. 281 */ 282 private ServerGroupProperty(String n) 283 { 284 attrName = n; 285 } 286 287 /** 288 * Returns the attribute name. 289 * @return the attribute name. 290 */ 291 public String getAttributeName() 292 { 293 return attrName; 294 } 295 } 296 297 /** 298 * The list of server group properties that are multivalued. 299 */ 300 private final static 301 Set<ServerGroupProperty> MULTIVALUED_SERVER_GROUP_PROPERTIES = 302 new HashSet<ServerGroupProperty>(); 303 static 304 { 305 MULTIVALUED_SERVER_GROUP_PROPERTIES.add(ServerGroupProperty.MEMBERS); 306 } 307 308 /** 309 * The enumeration containing the different Administrator properties. 310 */ 311 public enum AdministratorProperty 312 { 313 /** 314 * The UID of the administrator. 315 */ 316 UID("id",ADSPropertySyntax.STRING), 317 /** 318 * The password of the administrator. 319 */ 320 PASSWORD("password",ADSPropertySyntax.STRING), 321 /** 322 * The description of the administrator. 323 */ 324 DESCRIPTION("description",ADSPropertySyntax.STRING), 325 /** 326 * The DN of the administrator. 327 */ 328 ADMINISTRATOR_DN("administrator dn",ADSPropertySyntax.STRING), 329 /** 330 * The administrator privilege. 331 */ 332 PRIVILEGE("privilege",ADSPropertySyntax.STRING); 333 334 private String attrName; 335 private ADSPropertySyntax attrSyntax; 336 337 /** 338 * Private constructor. 339 * @param n the name of the attribute. 340 * @param s the name of the syntax. 341 */ 342 private AdministratorProperty(String n, ADSPropertySyntax s) 343 { 344 attrName = n; 345 attrSyntax = s ; 346 } 347 348 /** 349 * Returns the attribute name. 350 * @return the attribute name. 351 */ 352 public String getAttributeName() 353 { 354 return attrName; 355 } 356 357 /** 358 * Returns the attribute syntax. 359 * @return the attribute syntax. 360 */ 361 public ADSPropertySyntax getAttributeSyntax() 362 { 363 return attrSyntax; 364 } 365 } 366 367 private static HashMap<String, AdministratorProperty> 368 nameToAdminUserProperty = null; 369 370 /** 371 * Get a AdministratorProperty associated to a name. 372 * @param name The name of the property to retrieve. 373 * 374 * @return The corresponding AdministratorProperty or null if name 375 * doesn't match with an existing property. 376 */ 377 public static AdministratorProperty getAdminUserPropFromName(String name) 378 { 379 if (nameToAdminUserProperty == null) 380 { 381 nameToAdminUserProperty = new HashMap<String, AdministratorProperty>(); 382 for (AdministratorProperty u : AdministratorProperty.values()) 383 { 384 nameToAdminUserProperty.put(u.getAttributeName(), u); 385 } 386 } 387 return nameToAdminUserProperty.get(name); 388 } 389 390 // The context used to retrieve information 391 private final InitialLdapContext dirContext; 392 393 394 /** 395 * Constructor of the ADSContext. 396 * @param dirContext the DirContext that must be used to retrieve information. 397 */ 398 public ADSContext(InitialLdapContext dirContext) 399 { 400 this.dirContext = dirContext; 401 } 402 403 404 /** 405 * Returns the DirContext used to retrieve information by this ADSContext. 406 * @return the DirContext used to retrieve information by this ADSContext. 407 */ 408 public InitialLdapContext getDirContext() 409 { 410 return dirContext; 411 } 412 413 /** 414 * Method called to register a server in the ADS. 415 * @param serverProperties the properties of the server. 416 * @throws ADSContextException if the server could not be registered. 417 */ 418 public void registerServer(Map<ServerProperty, Object> serverProperties) 419 throws ADSContextException 420 { 421 LdapName dn = makeDNFromServerProperties(serverProperties); 422 BasicAttributes attrs = makeAttrsFromServerProperties(serverProperties); 423 try 424 { 425 // This check is required because by default the server container entry 426 // does not exist. 427 if (!isExistingEntry(nameFromDN(getServerContainerDN()))) 428 { 429 createContainerEntry(getServerContainerDN()); 430 } 431 dirContext.createSubcontext(dn, attrs).close(); 432 if (serverProperties.containsKey( 433 ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE)) 434 { 435 registerInstanceKeyCertificate(serverProperties, dn); 436 } 437 438 // register this server into "all" groups 439 HashMap<ServerGroupProperty, Object> serverGroupProperties = 440 new HashMap<ServerGroupProperty, Object>(); 441 Set<String> memberList = getServerGroupMemberList(ALL_SERVERGROUP_NAME); 442 if (memberList == null) { 443 memberList = new HashSet<String>(); 444 } 445 String newMember = "cn=" 446 + Rdn.escapeValue(serverProperties.get(ServerProperty.ID)); 447 448 memberList.add(newMember); 449 serverGroupProperties.put(ServerGroupProperty.MEMBERS, memberList); 450 451 updateServerGroup(ALL_SERVERGROUP_NAME, serverGroupProperties); 452 453 // Update the server property "GROUPS" 454 Set rawGroupList = (Set) serverProperties.get(ServerProperty.GROUPS); 455 Set<String> groupList = new HashSet<String>(); 456 if (rawGroupList != null) { 457 for (Object elm : rawGroupList.toArray()) { 458 groupList.add(elm.toString()); 459 } 460 } 461 groupList.add(ALL_SERVERGROUP_NAME); 462 serverProperties.put(ServerProperty.GROUPS, groupList); 463 updateServer(serverProperties, null); 464 465 } 466 catch (ADSContextException ace) 467 { 468 throw ace; 469 } 470 catch (NameAlreadyBoundException x) 471 { 472 throw new ADSContextException( 473 ADSContextException.ErrorType.ALREADY_REGISTERED); 474 } 475 catch (Exception x) 476 { 477 throw new ADSContextException( 478 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 479 } 480 } 481 482 483 /** 484 * Method called to udpate the properties of a server in the ADS. 485 * @param serverProperties the new properties of the server. 486 * @param newServerId The new server Identifier, or null. 487 * @throws ADSContextException if the server could not be registered. 488 */ 489 public void updateServer(Map<ServerProperty, Object> serverProperties, 490 String newServerId) throws ADSContextException 491 { 492 LdapName dn = makeDNFromServerProperties(serverProperties); 493 494 try 495 { 496 if (newServerId != null) 497 { 498 HashMap<ServerProperty, Object> newServerProps = 499 new HashMap<ServerProperty, Object>(serverProperties); 500 newServerProps.put(ServerProperty.ID,newServerId); 501 LdapName newDn = makeDNFromServerProperties(newServerProps); 502 dirContext.rename(dn, newDn); 503 dn = newDn ; 504 serverProperties.put(ServerProperty.ID,newServerId); 505 } 506 BasicAttributes attrs = makeAttrsFromServerProperties(serverProperties); 507 dirContext.modifyAttributes(dn, DirContext.REPLACE_ATTRIBUTE, 508 attrs); 509 if (serverProperties.containsKey( 510 ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE)) 511 { 512 registerInstanceKeyCertificate(serverProperties, dn); 513 } 514 } 515 catch (ADSContextException ace) 516 { 517 throw ace; 518 } 519 catch (NameNotFoundException x) 520 { 521 throw new ADSContextException( 522 ADSContextException.ErrorType.NOT_YET_REGISTERED); 523 } 524 catch (Exception x) 525 { 526 throw new ADSContextException( 527 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 528 } 529 } 530 531 /** 532 * Method called to unregister a server in the ADS. Note that the server's 533 * instance key-pair public-key certificate entry (created in 534 * <tt>registerServer()</tt>) 535 * is left untouched. 536 * @param serverProperties the properties of the server. 537 * @throws ADSContextException if the server could not be unregistered. 538 */ 539 public void unregisterServer(Map<ServerProperty, Object> serverProperties) 540 throws ADSContextException 541 { 542 LdapName dn = makeDNFromServerProperties(serverProperties); 543 try 544 { 545 if (serverProperties.containsKey( 546 ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE)) 547 { 548 unregisterInstanceKeyCertificate(serverProperties, dn); 549 } 550 dirContext.destroySubcontext(dn); 551 } 552 catch (NameNotFoundException x) 553 { 554 throw new ADSContextException( 555 ADSContextException.ErrorType.NOT_YET_REGISTERED); 556 } 557 catch (NamingException x) 558 { 559 throw new ADSContextException( 560 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 561 } 562 563 // Unregister the server in server groups 564 try 565 { 566 NamingEnumeration ne; 567 SearchControls sc = new SearchControls(); 568 569 String serverID = getServerID(serverProperties); 570 if (serverID != null) 571 { 572 String memberAttrName = ServerGroupProperty.MEMBERS.getAttributeName(); 573 String filter = "("+memberAttrName+"=cn="+serverID+")"; 574 sc.setSearchScope(SearchControls.ONELEVEL_SCOPE); 575 ne = dirContext.search(getServerGroupContainerDN(), filter, sc); 576 while (ne.hasMore()) 577 { 578 SearchResult sr = (SearchResult)ne.next(); 579 String groupDn = sr.getNameInNamespace(); 580 BasicAttribute newAttr = new BasicAttribute(memberAttrName); 581 NamingEnumeration attrs = sr.getAttributes().getAll(); 582 while (attrs.hasMore()) 583 { 584 Attribute attr = (Attribute)attrs.next(); 585 String attrID = attr.getID(); 586 587 if (attrID.equalsIgnoreCase(memberAttrName)) 588 { 589 NamingEnumeration ae = attr.getAll(); 590 while (ae.hasMore()) 591 { 592 String value = (String)ae.next(); 593 if (!value.equalsIgnoreCase("cn="+serverID)) 594 { 595 newAttr.add(value); 596 } 597 } 598 } 599 } 600 BasicAttributes newAttrs = new BasicAttributes(); 601 newAttrs.put(newAttr); 602 if (newAttr.size() > 0) 603 { 604 dirContext.modifyAttributes(groupDn, DirContext.REPLACE_ATTRIBUTE, 605 newAttrs); 606 } 607 else 608 { 609 dirContext.modifyAttributes(groupDn, DirContext.REMOVE_ATTRIBUTE, 610 newAttrs); 611 } 612 } 613 } 614 } 615 catch (NameNotFoundException x) 616 { 617 throw new ADSContextException( 618 ADSContextException.ErrorType.BROKEN_INSTALL); 619 } 620 catch (NoPermissionException x) 621 { 622 throw new ADSContextException( 623 ADSContextException.ErrorType.ACCESS_PERMISSION); 624 } 625 catch (NamingException x) 626 { 627 throw new ADSContextException( 628 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 629 } 630 } 631 632 /** 633 * Returns whether a given server is already registered or not. 634 * @param serverProperties the server properties. 635 * @return <CODE>true</CODE> if the server was registered and 636 * <CODE>false</CODE> otherwise. 637 * @throws ADSContextException if something went wrong. 638 */ 639 public boolean isServerAlreadyRegistered( 640 Map<ServerProperty, Object> serverProperties) 641 throws ADSContextException 642 { 643 LdapName dn = makeDNFromServerProperties(serverProperties); 644 return isExistingEntry(dn); 645 } 646 647 /** 648 * Returns whether a given administrator is already registered or not. 649 * @param adminProperties the administrator properties. 650 * @return <CODE>true</CODE> if the administrator was registered and 651 * <CODE>false</CODE> otherwise. 652 * @throws ADSContextException if something went wrong. 653 */ 654 public boolean isAdministratorAlreadyRegistered( 655 Map<AdministratorProperty, Object> adminProperties) 656 throws ADSContextException 657 { 658 LdapName dn = makeDNFromAdministratorProperties(adminProperties); 659 return isExistingEntry(dn); 660 } 661 662 /** 663 * A convenience method that takes some server properties as parameter and 664 * if there is no server registered associated with those properties, 665 * registers it and if it is already registered, updates it. 666 * @param serverProperties the server properties. 667 * @return 0 if the server was registered; 1 if udpated (i.e., the server 668 * entry was already in ADS). 669 * @throws ADSContextException if something goes wrong. 670 */ 671 public int registerOrUpdateServer( 672 Map<ServerProperty, Object> serverProperties) throws ADSContextException 673 { 674 int result = 0; 675 try 676 { 677 registerServer(serverProperties); 678 } 679 catch(ADSContextException x) 680 { 681 if (x.getError() == ADSContextException.ErrorType.ALREADY_REGISTERED) 682 { 683 updateServer(serverProperties, null); 684 result = 1; 685 } 686 else 687 { 688 throw x; 689 } 690 } 691 return result; 692 } 693 694 /** 695 * Returns the member list of a group of server. 696 * 697 * @param serverGroupId 698 * The group name. 699 * @return the member list of a group of server. 700 * @throws ADSContextException 701 * if something goes wrong. 702 */ 703 public Set<String> getServerGroupMemberList( 704 String serverGroupId) throws ADSContextException 705 { 706 LdapName dn = nameFromDN("cn=" + Rdn.escapeValue(serverGroupId) + "," 707 + getServerGroupContainerDN()); 708 709 Set<String> result = new HashSet<String>() ; 710 try 711 { 712 SearchControls sc = new SearchControls(); 713 sc.setSearchScope(SearchControls.OBJECT_SCOPE); 714 NamingEnumeration<SearchResult> srs = getDirContext().search(dn, 715 "(objectclass=*)", sc); 716 717 if (!srs.hasMore()) 718 { 719 return result; 720 } 721 Attributes attrs = srs.next().getAttributes(); 722 NamingEnumeration ne = attrs.getAll(); 723 while (ne.hasMore()) 724 { 725 Attribute attr = (Attribute)ne.next(); 726 String attrID = attr.getID(); 727 728 if (!attrID.toLowerCase().equals( 729 ServerGroupProperty.MEMBERS.getAttributeName().toLowerCase())) 730 { 731 continue; 732 } 733 734 // We have the members list 735 NamingEnumeration ae = attr.getAll(); 736 while (ae.hasMore()) 737 { 738 result.add((String)ae.next()); 739 } 740 break; 741 } 742 } 743 catch (NameNotFoundException x) 744 { 745 result = new HashSet<String>(); 746 } 747 catch (NoPermissionException x) 748 { 749 throw new ADSContextException( 750 ADSContextException.ErrorType.ACCESS_PERMISSION); 751 } 752 catch (NamingException x) 753 { 754 throw new ADSContextException( 755 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 756 } 757 return result; 758 } 759 760 /** 761 * Returns a set containing the servers that are registered in the 762 * ADS. 763 * 764 * @return a set containing the servers that are registered in the 765 * ADS. 766 * @throws ADSContextException 767 * if something goes wrong. 768 */ 769 public Set<Map<ServerProperty,Object>> readServerRegistry() 770 throws ADSContextException 771 { 772 Set<Map<ServerProperty,Object>> result = 773 new HashSet<Map<ServerProperty,Object>>(); 774 try 775 { 776 NamingEnumeration ne; 777 SearchControls sc = new SearchControls(); 778 779 sc.setSearchScope(SearchControls.ONELEVEL_SCOPE); 780 ne = dirContext.search(getServerContainerDN(), "(objectclass=*)", sc); 781 while (ne.hasMore()) 782 { 783 SearchResult sr = (SearchResult)ne.next(); 784 Map<ServerProperty,Object> properties = 785 makePropertiesFromServerAttrs(sr.getAttributes()); 786 Object keyId = properties.get(ServerProperty.INSTANCE_KEY_ID); 787 if (keyId != null) 788 { 789 try 790 { 791 SearchControls sc1 = new SearchControls(); 792 793 sc1.setSearchScope(SearchControls.ONELEVEL_SCOPE); 794 final String attrIDs[] = { "ds-cfg-public-key-certificate;binary" }; 795 sc1.setReturningAttributes(attrIDs); 796 SearchResult certEntry = 797 dirContext.search(getInstanceKeysContainerDN(), 798 "(ds-cfg-key-id="+keyId+")", sc).next(); 799 Attribute certAttr = certEntry.getAttributes().get(attrIDs[0]); 800 properties.put(ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE, 801 certAttr.get()); 802 } 803 catch (NameNotFoundException x) 804 { 805 LOG.log(Level.WARNING, "Could not find public key for "+properties); 806 } 807 } 808 result.add(properties); 809 } 810 } 811 catch (NameNotFoundException x) 812 { 813 throw new ADSContextException( 814 ADSContextException.ErrorType.BROKEN_INSTALL); 815 } 816 catch (NoPermissionException x) 817 { 818 throw new ADSContextException( 819 ADSContextException.ErrorType.ACCESS_PERMISSION); 820 } 821 catch(NamingException x) 822 { 823 throw new ADSContextException( 824 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 825 } 826 827 return result; 828 } 829 830 831 /** 832 * Creates a Server Group in the ADS. 833 * @param serverGroupProperties the properties of the server group to be 834 * created. 835 * @throws ADSContextException if somethings goes wrong. 836 */ 837 public void createServerGroup( 838 Map<ServerGroupProperty, Object> serverGroupProperties) 839 throws ADSContextException 840 { 841 LdapName dn = makeDNFromServerGroupProperties(serverGroupProperties); 842 BasicAttributes attrs = makeAttrsFromServerGroupProperties( 843 serverGroupProperties); 844 // Add the objectclass attribute value 845 Attribute oc = new BasicAttribute("objectclass"); 846 oc.add("top"); 847 oc.add("groupOfUniqueNames"); 848 attrs.put(oc); 849 try 850 { 851 DirContext ctx = dirContext.createSubcontext(dn, attrs); 852 ctx.close(); 853 } 854 catch (NameAlreadyBoundException x) 855 { 856 throw new ADSContextException( 857 ADSContextException.ErrorType.ALREADY_REGISTERED); 858 } 859 catch (NamingException x) 860 { 861 throw new ADSContextException( 862 ADSContextException.ErrorType.BROKEN_INSTALL, x); 863 } 864 } 865 866 /** 867 * Updates the properties of a Server Group in the ADS. 868 * @param serverGroupProperties the new properties of the server group to be 869 * updated. 870 * @param groupID The group name. 871 * @throws ADSContextException if somethings goes wrong. 872 */ 873 public void updateServerGroup(String groupID, 874 Map<ServerGroupProperty, Object> serverGroupProperties) 875 throws ADSContextException 876 { 877 LdapName dn = nameFromDN("cn=" + Rdn.escapeValue(groupID) + "," + 878 getServerGroupContainerDN()); 879 try 880 { 881 // Entry renaming ? 882 if (serverGroupProperties.containsKey(ServerGroupProperty.UID)) 883 { 884 String newGroupId = serverGroupProperties 885 .get(ServerGroupProperty.UID).toString(); 886 if (!newGroupId.equals(groupID)) 887 { 888 // Rename to entry 889 LdapName newDN = nameFromDN("cn=" + Rdn.escapeValue(newGroupId) 890 + "," + getServerGroupContainerDN()); 891 dirContext.rename(dn, newDN); 892 dn = newDN ; 893 } 894 895 // In any case, we remove the "cn" attribute. 896 serverGroupProperties.remove(ServerGroupProperty.UID); 897 } 898 if (serverGroupProperties.isEmpty()) 899 { 900 return ; 901 } 902 903 BasicAttributes attrs = 904 makeAttrsFromServerGroupProperties(serverGroupProperties); 905 // attribute modification 906 dirContext.modifyAttributes(dn, DirContext.REPLACE_ATTRIBUTE, attrs); 907 } 908 catch (NameNotFoundException x) 909 { 910 throw new ADSContextException( 911 ADSContextException.ErrorType.NOT_YET_REGISTERED); 912 } 913 catch (NameAlreadyBoundException x) 914 { 915 throw new ADSContextException( 916 ADSContextException.ErrorType.ALREADY_REGISTERED); 917 } 918 catch (NamingException x) 919 { 920 throw new ADSContextException( 921 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 922 } 923 } 924 925 /** 926 * Updates the properties of a Server Group in the ADS. 927 * @param serverGroupProperties the new properties of the server group to be 928 * updated. 929 * @param groupID The group name. 930 * @throws ADSContextException if somethings goes wrong. 931 */ 932 public void removeServerGroupProp(String groupID, 933 Set<ServerGroupProperty> serverGroupProperties) 934 throws ADSContextException 935 { 936 937 LdapName dn = nameFromDN("cn=" + Rdn.escapeValue(groupID) + "," + 938 getServerGroupContainerDN()); 939 BasicAttributes attrs = 940 makeAttrsFromServerGroupProperties(serverGroupProperties); 941 try 942 { 943 dirContext.modifyAttributes(dn, DirContext.REMOVE_ATTRIBUTE, attrs); 944 } 945 catch (NameAlreadyBoundException x) 946 { 947 throw new ADSContextException( 948 ADSContextException.ErrorType.ALREADY_REGISTERED); 949 } 950 catch (NamingException x) 951 { 952 throw new ADSContextException( 953 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 954 } 955 } 956 957 /** 958 * Deletes a Server Group in the ADS. 959 * @param serverGroupProperties the properties of the server group to be 960 * deleted. 961 * @throws ADSContextException if somethings goes wrong. 962 */ 963 public void deleteServerGroup( 964 Map<ServerGroupProperty, Object> serverGroupProperties) 965 throws ADSContextException 966 { 967 LdapName dn = makeDNFromServerGroupProperties(serverGroupProperties); 968 try 969 { 970 dirContext.destroySubcontext(dn); 971 } 972 catch(NamingException x) 973 { 974 throw new ADSContextException( 975 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 976 } 977 } 978 979 /** 980 * Returns a set containing the server groups that are defined in the ADS. 981 * @return a set containing the server groups that are defined in the ADS. 982 * @throws ADSContextException if something goes wrong. 983 */ 984 public Set<Map<ServerGroupProperty, Object>> readServerGroupRegistry() 985 throws ADSContextException 986 { 987 Set<Map<ServerGroupProperty, Object>> result = 988 new HashSet<Map<ServerGroupProperty, Object>>(); 989 try 990 { 991 NamingEnumeration ne; 992 SearchControls sc = new SearchControls(); 993 994 sc.setSearchScope(SearchControls.ONELEVEL_SCOPE); 995 ne = dirContext.search(getServerGroupContainerDN(), "(objectclass=*)", 996 sc); 997 while (ne.hasMore()) 998 { 999 SearchResult sr = (SearchResult)ne.next(); 1000 Map<ServerGroupProperty, Object> properties = 1001 makePropertiesFromServerGroupAttrs(sr.getAttributes()); 1002 result.add(properties); 1003 } 1004 } 1005 catch (NameNotFoundException x) 1006 { 1007 throw new ADSContextException( 1008 ADSContextException.ErrorType.BROKEN_INSTALL); 1009 } 1010 catch (NoPermissionException x) 1011 { 1012 throw new ADSContextException( 1013 ADSContextException.ErrorType.ACCESS_PERMISSION); 1014 } 1015 catch (NamingException x) 1016 { 1017 throw new ADSContextException( 1018 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 1019 } 1020 return result; 1021 } 1022 1023 1024 /** 1025 * Returns a set containing the administrators that are defined in the ADS. 1026 * @return a set containing the administrators that are defined in the ADS. 1027 * @throws ADSContextException if something goes wrong. 1028 */ 1029 public Set<Map<AdministratorProperty, Object>> readAdministratorRegistry() 1030 throws ADSContextException 1031 { 1032 Set<Map<AdministratorProperty, Object>> result = 1033 new HashSet<Map<AdministratorProperty, Object>>(); 1034 try { 1035 NamingEnumeration ne; 1036 SearchControls sc = new SearchControls(); 1037 1038 sc.setSearchScope(SearchControls.ONELEVEL_SCOPE); 1039 String[] attList = { "cn", "userpassword", "ds-privilege-name", 1040 "description" }; 1041 sc.setReturningAttributes(attList); 1042 ne = dirContext.search(getAdministratorContainerDN(), "(objectclass=*)", 1043 sc); 1044 while (ne.hasMore()) 1045 { 1046 SearchResult sr = (SearchResult)ne.next(); 1047 1048 Map<AdministratorProperty, Object> properties = 1049 makePropertiesFromAdministratorAttrs( 1050 getRdn(sr.getName()), sr.getAttributes()); 1051 1052 result.add(properties); 1053 } 1054 } 1055 catch (NameNotFoundException x) 1056 { 1057 throw new ADSContextException( 1058 ADSContextException.ErrorType.BROKEN_INSTALL); 1059 } 1060 catch (NoPermissionException x) 1061 { 1062 throw new ADSContextException( 1063 ADSContextException.ErrorType.ACCESS_PERMISSION); 1064 } 1065 catch (NamingException x) 1066 { 1067 throw new ADSContextException( 1068 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 1069 } 1070 1071 return result; 1072 } 1073 1074 /** 1075 * Creates the Administration Data in the server. 1076 * The call to this method assumes that OpenDS.jar has already been loaded. 1077 * So this should not be called by the Java Web Start before being sure that 1078 * this jar is loaded. 1079 * @param backendName the backend name which will handle admin information. 1080 * <CODE>null</CODE> to use the default backend name for the admin 1081 * information. 1082 * @throws ADSContextException if something goes wrong. 1083 */ 1084 public void createAdminData(String backendName) throws ADSContextException 1085 { 1086 // Add the administration suffix 1087 createAdministrationSuffix(backendName); 1088 1089 // Create the DIT below the administration suffix 1090 if (!isExistingEntry(nameFromDN(getAdministrationSuffixDN()))) 1091 { 1092 createTopContainerEntry(); 1093 } 1094 if (!isExistingEntry(nameFromDN(getAdministratorContainerDN()))) 1095 { 1096 createAdministratorContainerEntry(); 1097 } 1098 if (!isExistingEntry(nameFromDN(getServerContainerDN()))) 1099 { 1100 createContainerEntry(getServerContainerDN()); 1101 } 1102 if (!isExistingEntry(nameFromDN(getServerGroupContainerDN()))) 1103 { 1104 createContainerEntry(getServerGroupContainerDN()); 1105 } 1106 1107 // Add the default "all-servers" group 1108 if (!isExistingEntry(nameFromDN(getAllServerGroupDN()))) 1109 { 1110 Map<ServerGroupProperty, Object> allServersGroupsMap = 1111 new HashMap<ServerGroupProperty, Object>(); 1112 allServersGroupsMap.put(ServerGroupProperty.UID, ALL_SERVERGROUP_NAME); 1113 createServerGroup(allServersGroupsMap); 1114 } 1115 1116 // Create the CryptoManager instance key DIT below the administration suffix 1117 if (!isExistingEntry(nameFromDN(getInstanceKeysContainerDN()))) 1118 { 1119 createContainerEntry(getInstanceKeysContainerDN()); 1120 } 1121 1122 // Create the CryptoManager secret key DIT below the administration suffix 1123 if (!isExistingEntry(nameFromDN(getSecretKeysContainerDN()))) 1124 { 1125 createContainerEntry(getSecretKeysContainerDN()); 1126 } 1127 } 1128 1129 /** 1130 * Removes the administration data. 1131 * @throws ADSContextException if something goes wrong. 1132 */ 1133 public void removeAdminData() throws ADSContextException 1134 { 1135 LdapName dn = nameFromDN(getServerContainerDN()); 1136 try 1137 { 1138 Control[] controls = new Control[] { new SubtreeDeleteControl() }; 1139 LdapContext tmpContext = dirContext.newInstance(controls); 1140 try 1141 { 1142 tmpContext.destroySubcontext(dn); 1143 } 1144 finally 1145 { 1146 tmpContext.close(); 1147 } 1148 } 1149 catch(NamingException x) 1150 { 1151 throw new ADSContextException( 1152 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 1153 } 1154 } 1155 1156 1157 /** 1158 * Returns <CODE>true</CODE> if the server contains Administration Data and 1159 * <CODE>false</CODE> otherwise. 1160 * @return <CODE>true</CODE> if the server contains Administration Data and 1161 * <CODE>false</CODE> otherwise. 1162 * @throws ADSContextException if something goes wrong. 1163 */ 1164 public boolean hasAdminData() throws ADSContextException 1165 { 1166 String[] dns = {getAdministratorContainerDN(), getAllServerGroupDN(), 1167 getServerContainerDN(), getInstanceKeysContainerDN(), 1168 getSecretKeysContainerDN()}; 1169 boolean hasAdminData = true; 1170 for (int i=0; i<dns.length && hasAdminData; i++) 1171 { 1172 hasAdminData = isExistingEntry(nameFromDN(dns[i])); 1173 } 1174 return hasAdminData; 1175 } 1176 1177 /** 1178 * Returns the DN of the administrator for a given UID. 1179 * @param uid the UID to be used to generate the DN. 1180 * @return the DN of the administrator for the given UID: 1181 */ 1182 public static String getAdministratorDN(String uid) 1183 { 1184 return "cn=" + Rdn.escapeValue(uid) + "," + getAdministratorContainerDN(); 1185 } 1186 1187 /** 1188 * Creates an Administrator in the ADS. 1189 * @param adminProperties the properties of the administrator to be created. 1190 * @throws ADSContextException if something goes wrong. 1191 */ 1192 public void createAdministrator( 1193 Map<AdministratorProperty, Object> adminProperties) 1194 throws ADSContextException { 1195 LdapName dnCentralAdmin = 1196 makeDNFromAdministratorProperties(adminProperties); 1197 BasicAttributes attrs = makeAttrsFromAdministratorProperties( 1198 adminProperties, true, null); 1199 1200 try 1201 { 1202 DirContext ctx = dirContext.createSubcontext(dnCentralAdmin, attrs); 1203 ctx.close(); 1204 } 1205 catch (NameAlreadyBoundException x) 1206 { 1207 throw new ADSContextException( 1208 ADSContextException.ErrorType.ALREADY_REGISTERED); 1209 } 1210 catch (NoPermissionException x) 1211 { 1212 throw new ADSContextException( 1213 ADSContextException.ErrorType.ACCESS_PERMISSION); 1214 } 1215 catch (NamingException x) 1216 { 1217 throw new ADSContextException( 1218 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 1219 } 1220 } 1221 1222 /** 1223 * Deletes the administrator in the ADS. 1224 * @param adminProperties the properties of the administrator to be deleted. 1225 * @throws ADSContextException if something goes wrong. 1226 */ 1227 public void deleteAdministrator( 1228 Map<AdministratorProperty, Object> adminProperties) 1229 throws ADSContextException { 1230 1231 LdapName dnCentralAdmin = 1232 makeDNFromAdministratorProperties(adminProperties); 1233 1234 try 1235 { 1236 dirContext.destroySubcontext(dnCentralAdmin); 1237 } 1238 catch (NameNotFoundException x) 1239 { 1240 throw new ADSContextException( 1241 ADSContextException.ErrorType.NOT_YET_REGISTERED); 1242 } 1243 catch (NotContextException x) 1244 { 1245 throw new ADSContextException( 1246 ADSContextException.ErrorType.NOT_YET_REGISTERED); 1247 } 1248 catch (NoPermissionException x) 1249 { 1250 throw new ADSContextException( 1251 ADSContextException.ErrorType.ACCESS_PERMISSION); 1252 } 1253 catch (NamingException x) 1254 { 1255 throw new ADSContextException( 1256 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 1257 } 1258 } 1259 1260 /** 1261 * Updates and administrator registered in the ADS. 1262 * @param adminProperties the new properties of the administrator. 1263 * @param newAdminUserId The new admin user Identifier, or null. 1264 * @throws ADSContextException if something goes wrong. 1265 */ 1266 public void updateAdministrator( 1267 Map<AdministratorProperty, Object> adminProperties, String newAdminUserId) 1268 throws ADSContextException 1269 { 1270 1271 LdapName dnCentralAdmin = 1272 makeDNFromAdministratorProperties(adminProperties); 1273 1274 boolean updatePassword = adminProperties 1275 .containsKey(AdministratorProperty.PASSWORD); 1276 try 1277 { 1278 // Entry renaming 1279 if (newAdminUserId != null) 1280 { 1281 HashMap<AdministratorProperty, Object> newAdminUserProps = 1282 new HashMap<AdministratorProperty, Object>(adminProperties); 1283 newAdminUserProps.put(AdministratorProperty.UID,newAdminUserId); 1284 LdapName newDn = makeDNFromAdministratorProperties(newAdminUserProps); 1285 dirContext.rename(dnCentralAdmin, newDn); 1286 dnCentralAdmin = newDn ; 1287 adminProperties.put(AdministratorProperty.UID,newAdminUserId); 1288 } 1289 1290 // if modification includes 'privilege', we have to get first the 1291 // current privileges list. 1292 NamingEnumeration currentPrivileges = null; 1293 if (adminProperties.containsKey(AdministratorProperty.PRIVILEGE)) 1294 { 1295 SearchControls sc = new SearchControls(); 1296 sc.setSearchScope(SearchControls.OBJECT_SCOPE); 1297 String[] attList = {"ds-privilege-name"}; 1298 sc.setReturningAttributes(attList); 1299 NamingEnumeration ne = dirContext.search( 1300 dnCentralAdmin, "(objectclass=*)", sc); 1301 SearchResult sr = (SearchResult)ne.next(); 1302 1303 currentPrivileges = sr.getAttributes().get("ds-privilege-name") 1304 .getAll(); 1305 } 1306 1307 // Replace properties, if needed. 1308 if (adminProperties.size() > 1) 1309 { 1310 BasicAttributes attrs = 1311 makeAttrsFromAdministratorProperties( 1312 adminProperties, updatePassword, currentPrivileges); 1313 dirContext.modifyAttributes(dnCentralAdmin, 1314 DirContext.REPLACE_ATTRIBUTE, attrs); 1315 } 1316 } 1317 catch (NameNotFoundException x) 1318 { 1319 throw new ADSContextException( 1320 ADSContextException.ErrorType.NOT_YET_REGISTERED); 1321 } 1322 catch (NoPermissionException x) 1323 { 1324 throw new ADSContextException( 1325 ADSContextException.ErrorType.ACCESS_PERMISSION); 1326 } 1327 catch (NamingException x) 1328 { 1329 throw new ADSContextException( 1330 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 1331 } 1332 } 1333 1334 /** 1335 * Returns the DN of the suffix that contains the administration data. 1336 * @return the DN of the suffix that contains the administration data. 1337 */ 1338 public static String getAdministrationSuffixDN() 1339 { 1340 return "cn=admin data"; 1341 } 1342 1343 /** 1344 * This method returns the DN of the entry that corresponds to the given host 1345 * name and installation path. 1346 * @param hostname the host name. 1347 * @param ipath the installation path. 1348 * @return the DN of the entry that corresponds to the given host name and 1349 * installation path. 1350 * @throws ADSContextException if something goes wrong. 1351 */ 1352 private static LdapName makeDNFromHostnameAndPath(String hostname, 1353 String ipath) throws ADSContextException 1354 { 1355 String cnValue = Rdn.escapeValue(hostname + "@" + ipath); 1356 return nameFromDN("cn=" + cnValue + "," + getServerContainerDN()); 1357 } 1358 1359 /** 1360 * This method returns the DN of the entry that corresponds to the given host 1361 * name port representation. 1362 * @param serverUniqueId the host name and port. 1363 * @return the DN of the entry that corresponds to the given host name and 1364 * port. 1365 * @throws ADSContextException if something goes wrong. 1366 */ 1367 private static LdapName makeDNFromServerUniqueId(String serverUniqueId) 1368 throws ADSContextException 1369 { 1370 String cnValue = Rdn.escapeValue(serverUniqueId); 1371 return nameFromDN("cn=" + cnValue + "," + getServerContainerDN()); 1372 } 1373 1374 1375 /** 1376 * This method returns the DN of the entry that corresponds to the given 1377 * server group properties. 1378 * @param serverGroupProperties the server group properties 1379 * @return the DN of the entry that corresponds to the given server group 1380 * properties. 1381 * @throws ADSContextException if something goes wrong. 1382 */ 1383 private static LdapName makeDNFromServerGroupProperties( 1384 Map<ServerGroupProperty, Object> serverGroupProperties) 1385 throws ADSContextException 1386 { 1387 String serverGroupId = (String)serverGroupProperties.get( 1388 ServerGroupProperty.UID); 1389 if (serverGroupId == null) 1390 { 1391 throw new ADSContextException(ADSContextException.ErrorType.MISSING_NAME); 1392 } 1393 return nameFromDN("cn=" + Rdn.escapeValue(serverGroupId) + "," + 1394 getServerGroupContainerDN()); 1395 } 1396 1397 /** 1398 * This method returns the DN of the entry that corresponds to the given 1399 * server properties. 1400 * @param serverProperties the server properties. 1401 * @return the DN of the entry that corresponds to the given server 1402 * properties. 1403 * @throws ADSContextException if something goes wrong. 1404 */ 1405 private static LdapName makeDNFromServerProperties( 1406 Map<ServerProperty, Object> serverProperties) throws ADSContextException 1407 { 1408 String serverID ; 1409 if ( (serverID = getServerID(serverProperties)) != null ) 1410 { 1411 return makeDNFromServerUniqueId(serverID); 1412 } 1413 1414 String hostname = getHostname(serverProperties); 1415 try 1416 { 1417 String ipath = getInstallPath(serverProperties); 1418 return makeDNFromHostnameAndPath(hostname, ipath); 1419 } 1420 catch (ADSContextException ace) 1421 { 1422 ServerDescriptor s = ServerDescriptor.createStandalone(serverProperties); 1423 return makeDNFromServerUniqueId(s.getHostPort(true)); 1424 } 1425 } 1426 1427 /** 1428 * This method returns the DN of the entry that corresponds to the given 1429 * server properties. 1430 * @param serverProperties the server properties. 1431 * @return the DN of the entry that corresponds to the given server 1432 * properties. 1433 * @throws ADSContextException if something goes wrong. 1434 */ 1435 public static String getServerIdFromServerProperties( 1436 Map<ServerProperty, Object> serverProperties) throws ADSContextException 1437 { 1438 LdapName ldapName = makeDNFromServerProperties(serverProperties); 1439 String rdn = ldapName.get(ldapName.size() -1); 1440 int pos = rdn.indexOf("="); 1441 return rdn.substring(pos+1); 1442 } 1443 1444 /** 1445 * This method returns the DN of the entry that corresponds to the given 1446 * administrator properties. 1447 * @param adminProperties the administrator properties. 1448 * @return the DN of the entry that corresponds to the given administrator 1449 * properties. 1450 * @throws ADSContextException if something goes wrong. 1451 */ 1452 private static LdapName makeDNFromAdministratorProperties( 1453 Map<AdministratorProperty, Object> adminProperties) 1454 throws ADSContextException 1455 { 1456 String adminUid = getAdministratorUID(adminProperties); 1457 1458 String dnCentralAdmin = getAdministratorDN(adminUid); 1459 1460 return nameFromDN(dnCentralAdmin); 1461 } 1462 1463 /** 1464 * Returns the attributes for some administrator properties. 1465 * @param adminProperties the administrator properties. 1466 * @param passwordRequired Indicates if the properties should include 1467 * the password. 1468 * @param currentPrivileges The current privilege list or null. 1469 * @return the attributes for the given administrator properties. 1470 * @throws ADSContextException if something goes wrong. 1471 */ 1472 private static BasicAttributes makeAttrsFromAdministratorProperties( 1473 Map<AdministratorProperty, Object> adminProperties, 1474 boolean passwordRequired, NamingEnumeration currentPrivileges) 1475 throws ADSContextException 1476 { 1477 BasicAttributes attrs = new BasicAttributes(); 1478 Attribute oc = new BasicAttribute("objectclass"); 1479 if (passwordRequired) 1480 { 1481 attrs.put("userPassword", getAdministratorPassword(adminProperties)); 1482 } 1483 oc.add("top"); 1484 oc.add("person"); 1485 attrs.put(oc); 1486 attrs.put("sn", GLOBAL_ADMIN_UID); 1487 if (adminProperties.containsKey(AdministratorProperty.DESCRIPTION)) 1488 { 1489 attrs.put("description", adminProperties 1490 .get(AdministratorProperty.DESCRIPTION)); 1491 } 1492 Attribute privilegeAtt; 1493 if (adminProperties.containsKey(AdministratorProperty.PRIVILEGE)) 1494 { 1495 // We assume that privilege strings provided in 1496 // AdministratorProperty.PRIVILEGE 1497 // are valid privileges represented as a LinkedList of string. 1498 privilegeAtt = new BasicAttribute("ds-privilege-name"); 1499 if (currentPrivileges != null) 1500 { 1501 while (currentPrivileges.hasMoreElements()) 1502 { 1503 privilegeAtt.add(currentPrivileges.nextElement().toString()); 1504 } 1505 } 1506 1507 LinkedList privileges = (LinkedList) 1508 adminProperties.get(AdministratorProperty.PRIVILEGE); 1509 for( Object o : privileges) 1510 { 1511 String p = o.toString() ; 1512 if (p.startsWith("-")) 1513 { 1514 privilegeAtt.remove(p.substring(1)); 1515 } 1516 else 1517 { 1518 privilegeAtt.add(p); 1519 } 1520 } 1521 } 1522 else 1523 { 1524 privilegeAtt = addRootPrivileges(); 1525 } 1526 attrs.put(privilegeAtt); 1527 return attrs; 1528 } 1529 1530 1531 /** 1532 * Builds an attribute which contains 'root' privileges. 1533 * @return The attribute which contains 'root' privileges. 1534 */ 1535 private static Attribute addRootPrivileges() 1536 { 1537 Attribute privilege = new BasicAttribute("ds-privilege-name"); 1538 privilege.add("bypass-acl"); 1539 privilege.add("modify-acl"); 1540 privilege.add("config-read"); 1541 privilege.add("config-write"); 1542 privilege.add("ldif-import"); 1543 privilege.add("ldif-export"); 1544 privilege.add("backend-backup"); 1545 privilege.add("backend-restore"); 1546 privilege.add("server-shutdown"); 1547 privilege.add("server-restart"); 1548 privilege.add("disconnect-client"); 1549 privilege.add("cancel-request"); 1550 privilege.add("password-reset"); 1551 privilege.add("update-schema"); 1552 privilege.add("privilege-change"); 1553 privilege.add("unindexed-search"); 1554 return privilege; 1555 } 1556 1557 /** 1558 * Returns the attributes for some server properties. 1559 * @param serverProperties the server properties. 1560 * @return the attributes for the given server properties. 1561 */ 1562 private static BasicAttributes makeAttrsFromServerProperties( 1563 Map<ServerProperty, Object> serverProperties) 1564 { 1565 BasicAttributes result = new BasicAttributes(); 1566 1567 // Transform 'properties' into 'attributes' 1568 for (ServerProperty prop: serverProperties.keySet()) 1569 { 1570 Attribute attr = makeAttrFromServerProperty(prop, 1571 serverProperties.get(prop)); 1572 if (attr != null) 1573 { 1574 result.put(attr); 1575 } 1576 } 1577 // Add the objectclass attribute value 1578 // TODO: use another structural objectclass 1579 Attribute oc = new BasicAttribute("objectclass"); 1580 oc.add("top"); 1581 oc.add("ds-cfg-branch"); 1582 oc.add("extensibleobject"); 1583 result.put(oc); 1584 return result; 1585 } 1586 1587 /** 1588 * Returns the attribute for a given server property. 1589 * @param property the server property. 1590 * @param value the value. 1591 * @return the attribute for a given server property. 1592 */ 1593 private static Attribute makeAttrFromServerProperty(ServerProperty property, 1594 Object value) 1595 { 1596 Attribute result; 1597 1598 switch(property) 1599 { 1600 case INSTANCE_PUBLIC_KEY_CERTIFICATE: 1601 result = null; // used in separate instance key entry 1602 break; 1603 case GROUPS: 1604 result = new BasicAttribute(ServerProperty.GROUPS.getAttributeName()); 1605 for (Object o : ((Set) value)) { 1606 result.add(o); 1607 } 1608 break; 1609 default: 1610 result = new BasicAttribute(property.getAttributeName(), value); 1611 } 1612 return result; 1613 } 1614 1615 /** 1616 * Returns the attributes for some server group properties. 1617 * @param serverGroupProperties the server group properties. 1618 * @return the attributes for the given server group properties. 1619 */ 1620 private static BasicAttributes makeAttrsFromServerGroupProperties( 1621 Map<ServerGroupProperty, Object> serverGroupProperties) 1622 { 1623 BasicAttributes result = new BasicAttributes(); 1624 1625 // Transform 'properties' into 'attributes' 1626 for (ServerGroupProperty prop: serverGroupProperties.keySet()) 1627 { 1628 Attribute attr = makeAttrFromServerGroupProperty(prop, 1629 serverGroupProperties.get(prop)); 1630 if (attr != null) 1631 { 1632 result.put(attr); 1633 } 1634 } 1635 return result; 1636 } 1637 1638 /** 1639 * Returns the attributes for some server group properties. 1640 * @param serverGroupProperties the server group properties. 1641 * @return the attributes for the given server group properties. 1642 */ 1643 private static BasicAttributes makeAttrsFromServerGroupProperties( 1644 Set<ServerGroupProperty> serverGroupProperties) 1645 { 1646 BasicAttributes result = new BasicAttributes(); 1647 1648 // Transform 'properties' into 'attributes' 1649 for (ServerGroupProperty prop: serverGroupProperties) 1650 { 1651 Attribute attr = makeAttrFromServerGroupProperty(prop,null); 1652 if (attr != null) 1653 { 1654 result.put(attr); 1655 } 1656 } 1657 return result; 1658 } 1659 1660 /** 1661 * Returns the attribute for a given server group property. 1662 * @param property the server group property. 1663 * @param value the value. 1664 * @return the attribute for a given server group property. 1665 */ 1666 private static Attribute makeAttrFromServerGroupProperty( 1667 ServerGroupProperty property, Object value) 1668 { 1669 Attribute result; 1670 1671 switch(property) 1672 { 1673 case MEMBERS: 1674 result = new BasicAttribute( 1675 ServerGroupProperty.MEMBERS.getAttributeName()); 1676 for (Object o : ((Set) value)) { 1677 result.add(o); 1678 } 1679 break; 1680 default: 1681 result = new BasicAttribute(property.getAttributeName(), value); 1682 } 1683 1684 return result; 1685 } 1686 1687 /** 1688 * Returns the properties of a server group for some LDAP attributes. 1689 * @param attrs the LDAP attributes. 1690 * @return the properties of a server group for some LDAP attributes. 1691 * @throws ADSContextException if something goes wrong. 1692 */ 1693 private Map<ServerGroupProperty, Object> makePropertiesFromServerGroupAttrs( 1694 Attributes attrs) throws ADSContextException 1695 { 1696 HashMap<ServerGroupProperty, Object> result = 1697 new HashMap<ServerGroupProperty, Object>(); 1698 try 1699 { 1700 for (ServerGroupProperty prop : ServerGroupProperty.values()) 1701 { 1702 Attribute attr = attrs.get(prop.getAttributeName()); 1703 if (attr == null) 1704 { 1705 continue ; 1706 } 1707 Object value; 1708 1709 if (attr.size() >= 1 && 1710 MULTIVALUED_SERVER_GROUP_PROPERTIES.contains(prop)) 1711 { 1712 1713 Set<String> set = new HashSet<String>(); 1714 NamingEnumeration ae = attr.getAll(); 1715 while (ae.hasMore()) 1716 { 1717 set.add((String)ae.next()); 1718 } 1719 value = set; 1720 } 1721 else 1722 { 1723 value = attr.get(0); 1724 } 1725 1726 result.put(prop, value); 1727 } 1728 } 1729 catch(NamingException x) 1730 { 1731 throw new ADSContextException( 1732 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 1733 } 1734 return result; 1735 } 1736 1737 /** 1738 * Returns the properties of a server for some LDAP attributes. 1739 * @param attrs the LDAP attributes. 1740 * @return the properties of a server for some LDAP attributes. 1741 * @throws ADSContextException if something goes wrong. 1742 */ 1743 private Map<ServerProperty, Object> makePropertiesFromServerAttrs( 1744 Attributes attrs) throws ADSContextException 1745 { 1746 HashMap<ServerProperty, Object> result = 1747 new HashMap<ServerProperty, Object>(); 1748 try 1749 { 1750 NamingEnumeration ne = attrs.getAll(); 1751 while (ne.hasMore()) 1752 { 1753 Attribute attr = (Attribute)ne.next(); 1754 String attrID = attr.getID(); 1755 Object value; 1756 1757 if (attrID.endsWith(";binary")) 1758 { 1759 attrID = attrID.substring(0, attrID.lastIndexOf(";binary")); 1760 } 1761 1762 ServerProperty prop = null; 1763 ServerProperty[] props = ServerProperty.values(); 1764 for (int i=0; i<props.length && (prop == null); i++) 1765 { 1766 String v = props[i].getAttributeName(); 1767 if (attrID.equalsIgnoreCase(v)) 1768 { 1769 prop = props[i]; 1770 } 1771 } 1772 if (prop == null) 1773 { 1774 // Do not handle it 1775 } 1776 else 1777 { 1778 1779 if (attr.size() >= 1 && MULTIVALUED_SERVER_PROPERTIES.contains(prop)) 1780 { 1781 Set<String> set = new HashSet<String>(); 1782 NamingEnumeration ae = attr.getAll(); 1783 while (ae.hasMore()) 1784 { 1785 set.add((String)ae.next()); 1786 } 1787 value = set; 1788 } 1789 else 1790 { 1791 value = attr.get(0); 1792 } 1793 1794 result.put(prop, value); 1795 } 1796 } 1797 } 1798 catch(NamingException x) 1799 { 1800 throw new ADSContextException( 1801 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 1802 } 1803 return result; 1804 } 1805 1806 1807 /** 1808 * Returns the properties of an administrator for some rdn and LDAP 1809 * attributes. 1810 * @param rdn the RDN. 1811 * @param attrs the LDAP attributes. 1812 * @return the properties of an administrator for the given rdn and LDAP 1813 * attributes. 1814 * @throws ADSContextException if something goes wrong. 1815 */ 1816 private Map<AdministratorProperty, Object> 1817 makePropertiesFromAdministratorAttrs(String rdn, Attributes attrs) 1818 throws ADSContextException 1819 { 1820 Map<AdministratorProperty, Object> result = 1821 new HashMap<AdministratorProperty, Object>(); 1822 LdapName nameObj; 1823 nameObj = nameFromDN(rdn); 1824 String dn = nameObj + "," + getAdministratorContainerDN(); 1825 result.put(AdministratorProperty.ADMINISTRATOR_DN, dn); 1826 1827 try 1828 { 1829 NamingEnumeration<? extends Attribute> ne = attrs.getAll(); 1830 while (ne.hasMore()) { 1831 Attribute attr = ne.next(); 1832 String attrID = attr.getID(); 1833 Object value; 1834 1835 if (attrID.equalsIgnoreCase("cn")) 1836 { 1837 value = attr.get(0); 1838 result.put(AdministratorProperty.UID, value); 1839 } 1840 else if (attrID.equalsIgnoreCase("userpassword")) 1841 { 1842 value = new String((byte[]) attr.get()); 1843 result.put(AdministratorProperty.PASSWORD, value); 1844 } 1845 else if (attrID.equalsIgnoreCase("description")) 1846 { 1847 value = attr.get(0); 1848 result.put(AdministratorProperty.DESCRIPTION, value); 1849 } 1850 else if (attrID.equalsIgnoreCase("ds-privilege-name")) 1851 { 1852 LinkedHashSet<String> privileges = new LinkedHashSet<String>(); 1853 NamingEnumeration attValueList = attr.getAll(); 1854 while (attValueList.hasMoreElements()) 1855 { 1856 privileges.add(attValueList.next().toString()); 1857 } 1858 result.put(AdministratorProperty.PRIVILEGE, privileges); 1859 } 1860 } 1861 } 1862 catch(NamingException x) 1863 { 1864 throw new ADSContextException( 1865 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 1866 } 1867 1868 return result; 1869 } 1870 1871 /** 1872 * Returns the parent entry of the server entries. 1873 * @return the parent entry of the server entries. 1874 */ 1875 private static String getServerContainerDN() 1876 { 1877 return "cn=Servers," + getAdministrationSuffixDN(); 1878 } 1879 1880 /** 1881 * Returns the parent entry of the administrator entries. 1882 * @return the parent entry of the administrator entries. 1883 */ 1884 public static String getAdministratorContainerDN() 1885 { 1886 return "cn=Administrators," + getAdministrationSuffixDN(); 1887 } 1888 1889 /** 1890 * Returns the parent entry of the server group entries. 1891 * @return the parent entry of the server group entries. 1892 */ 1893 private static String getServerGroupContainerDN() 1894 { 1895 return "cn=Server Groups," + getAdministrationSuffixDN(); 1896 } 1897 1898 /** 1899 * Returns the all server group entry DN. 1900 * @return the all server group entry DN. 1901 */ 1902 private static String getAllServerGroupDN() 1903 { 1904 return "cn=" + Rdn.escapeValue(ALL_SERVERGROUP_NAME) + 1905 "," + getServerGroupContainerDN(); 1906 } 1907 1908 /** 1909 * Returns the host name for the given properties. 1910 * @param serverProperties the server properties. 1911 * @return the host name for the given properties. 1912 * @throws ADSContextException if the host name could not be found or its 1913 * value is not valid. 1914 */ 1915 private static String getHostname( 1916 Map<ServerProperty, Object> serverProperties) throws ADSContextException 1917 { 1918 String result = (String)serverProperties.get(ServerProperty.HOST_NAME); 1919 if (result == null) 1920 { 1921 throw new ADSContextException( 1922 ADSContextException.ErrorType.MISSING_HOSTNAME); 1923 } 1924 else if (result.length() == 0) 1925 { 1926 throw new ADSContextException( 1927 ADSContextException.ErrorType.NOVALID_HOSTNAME); 1928 } 1929 return result; 1930 } 1931 1932 /** 1933 * Returns the Server ID for the given properties. 1934 * @param serverProperties the server properties. 1935 * @return the server ID for the given properties or null. 1936 */ 1937 private static String getServerID( 1938 Map<ServerProperty, Object> serverProperties) 1939 { 1940 String result = (String) serverProperties.get(ServerProperty.ID); 1941 if (result != null) 1942 { 1943 if (result.length() == 0) 1944 { 1945 result = null; 1946 } 1947 } 1948 return result; 1949 } 1950 1951 /** 1952 * Returns the install path for the given properties. 1953 * @param serverProperties the server properties. 1954 * @return the install path for the given properties. 1955 * @throws ADSContextException if the install path could not be found or its 1956 * value is not valid. 1957 */ 1958 private static String getInstallPath( 1959 Map<ServerProperty, Object> serverProperties) throws ADSContextException 1960 { 1961 String result = (String)serverProperties.get(ServerProperty.INSTANCE_PATH); 1962 if (result == null) 1963 { 1964 throw new ADSContextException( 1965 ADSContextException.ErrorType.MISSING_IPATH); 1966 } 1967 else if (result.length() == 0) 1968 { 1969 throw new ADSContextException( 1970 ADSContextException.ErrorType.NOVALID_IPATH); 1971 } 1972 return result; 1973 } 1974 1975 1976 /** 1977 * Returns the Administrator UID for the given properties. 1978 * @param adminProperties the server properties. 1979 * @return the Administrator UID for the given properties. 1980 * @throws ADSContextException if the administrator UID could not be found. 1981 */ 1982 private static String getAdministratorUID( 1983 Map<AdministratorProperty, Object> adminProperties) 1984 throws ADSContextException { 1985 String result = (String)adminProperties.get( 1986 AdministratorProperty.UID); 1987 if (result == null) 1988 { 1989 throw new ADSContextException( 1990 ADSContextException.ErrorType.MISSING_ADMIN_UID); 1991 } 1992 return result; 1993 } 1994 1995 /** 1996 * Returns the Administrator password for the given properties. 1997 * @param adminProperties the server properties. 1998 * @return the Administrator password for the given properties. 1999 * @throws ADSContextException if the administrator password could not be 2000 * found. 2001 */ 2002 private static String getAdministratorPassword( 2003 Map<AdministratorProperty, Object> adminProperties) 2004 throws ADSContextException { 2005 String result = (String)adminProperties.get( 2006 AdministratorProperty.PASSWORD); 2007 if (result == null) 2008 { 2009 throw new ADSContextException( 2010 ADSContextException.ErrorType.MISSING_ADMIN_PASSWORD); 2011 } 2012 return result; 2013 } 2014 2015 2016 // 2017 // LDAP utilities 2018 // 2019 /** 2020 * Returns the LdapName object for the given dn. 2021 * @param dn the DN. 2022 * @return the LdapName object for the given dn. 2023 * @throws ADSContextException if a valid LdapName could not be retrieved 2024 * for the given dn. 2025 */ 2026 private static LdapName nameFromDN(String dn) throws ADSContextException 2027 { 2028 LdapName result; 2029 try 2030 { 2031 result = new LdapName(dn); 2032 } 2033 catch (InvalidNameException x) 2034 { 2035 LOG.log(Level.SEVERE, "Error parsing dn "+dn, x); 2036 throw new ADSContextException( 2037 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 2038 } 2039 return result; 2040 } 2041 2042 /** 2043 * Returns the String rdn for the given search result name. 2044 * @param rdnName the search result name. 2045 * @return the String rdn for the given search result name. 2046 * @throws ADSContextException if a valid String rdn could not be retrieved 2047 * for the given result name. 2048 */ 2049 private static String getRdn(String rdnName) throws ADSContextException 2050 { 2051 CompositeName nameObj; 2052 String rdn; 2053 // 2054 // Transform the JNDI name into a RDN string 2055 // 2056 try { 2057 nameObj = new CompositeName(rdnName); 2058 rdn = nameObj.get(0); 2059 } 2060 catch (InvalidNameException x) 2061 { 2062 LOG.log(Level.SEVERE, "Error parsing rdn "+rdnName, x); 2063 throw new ADSContextException( 2064 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 2065 } 2066 return rdn; 2067 } 2068 2069 /** 2070 * Tells whether an entry with the provided DN exists. 2071 * @param dn the DN to check. 2072 * @return <CODE>true</CODE> if the entry exists and <CODE>false</CODE> if 2073 * it does not. 2074 * @throws ADSContextException if an error occurred while checking if the 2075 * entry exists or not. 2076 */ 2077 private boolean isExistingEntry(LdapName dn) throws ADSContextException 2078 { 2079 boolean result; 2080 2081 try 2082 { 2083 SearchControls sc = new SearchControls(); 2084 2085 sc.setSearchScope(SearchControls.OBJECT_SCOPE); 2086 result = getDirContext().search(dn, "(objectclass=*)", sc).hasMore(); 2087 } 2088 catch (NameNotFoundException x) 2089 { 2090 result = false; 2091 } 2092 catch (NoPermissionException x) 2093 { 2094 throw new ADSContextException( 2095 ADSContextException.ErrorType.ACCESS_PERMISSION); 2096 } 2097 catch(javax.naming.NamingException x) 2098 { 2099 throw new ADSContextException( 2100 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 2101 } 2102 2103 return result; 2104 } 2105 2106 /** 2107 * Creates a container entry with the given dn. 2108 * @param dn the entry of the new entry to be created. 2109 * @throws ADSContextException if the entry could not be created. 2110 */ 2111 private void createContainerEntry(String dn) throws ADSContextException 2112 { 2113 BasicAttributes attrs = new BasicAttributes(); 2114 Attribute oc = new BasicAttribute("objectclass"); 2115 oc.add("top"); 2116 oc.add("ds-cfg-branch"); 2117 attrs.put(oc); 2118 createEntry(dn, attrs); 2119 } 2120 2121 /** 2122 * Creates the administrator container entry. 2123 * @throws ADSContextException if the entry could not be created. 2124 */ 2125 private void createAdministratorContainerEntry() throws ADSContextException 2126 { 2127 BasicAttributes attrs = new BasicAttributes(); 2128 2129 Attribute oc = new BasicAttribute("objectclass"); 2130 oc.add("groupofurls"); 2131 attrs.put(oc); 2132 attrs.put("memberURL", "ldap:///" + getAdministratorContainerDN() + 2133 "??one?(objectclass=*)"); 2134 attrs.put("description", "Group of identities which have full access."); 2135 createEntry(getAdministratorContainerDN(), attrs); 2136 } 2137 2138 2139 /** 2140 * Creates the top container entry. 2141 * @throws ADSContextException if the entry could not be created. 2142 */ 2143 private void createTopContainerEntry() throws ADSContextException 2144 { 2145 BasicAttributes attrs = new BasicAttributes(); 2146 2147 Attribute oc = new BasicAttribute("objectclass"); 2148 oc.add("top"); 2149 oc.add("ds-cfg-branch"); 2150 attrs.put(oc); 2151 createEntry(getAdministrationSuffixDN(), attrs); 2152 } 2153 2154 2155 /** 2156 * Creates an entry with the provided dn and attributes. 2157 * @param dn the dn of the entry. 2158 * @param attrs the attributes of the entry. 2159 * @throws ADSContextException if the entry could not be created. 2160 */ 2161 private void createEntry(String dn, Attributes attrs) 2162 throws ADSContextException { 2163 try 2164 { 2165 DirContext ctx = getDirContext().createSubcontext(nameFromDN(dn), attrs); 2166 ctx.close(); 2167 } 2168 catch(NamingException x) 2169 { 2170 throw new ADSContextException( 2171 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 2172 } 2173 } 2174 2175 /** 2176 * Creates the Administration Suffix. 2177 * @param backendName the backend name to be used for the Administration 2178 * Suffix. If this value is null the default backendName for the 2179 * Administration Suffix will be used. 2180 * @throws ADSContextException if something goes wrong. 2181 */ 2182 public void createAdministrationSuffix(String backendName) 2183 throws ADSContextException 2184 { 2185 ADSContextHelper helper = new ADSContextHelper(); 2186 String ben = backendName ; 2187 if (backendName == null) 2188 { 2189 ben = getDefaultBackendName() ; 2190 } 2191 helper.createAdministrationSuffix(getDirContext(), ben); 2192 } 2193 2194 /** 2195 * Removes the administration suffix. 2196 * @throws ADSContextException if something goes wrong. 2197 */ 2198 // private void removeAdministrationSuffix() throws ADSContextException 2199 // { 2200 // ADSContextHelper helper = new ADSContextHelper(); 2201 // helper.removeAdministrationSuffix(getDirContext(), 2202 // getDefaultBackendName()); 2203 // } 2204 2205 /** 2206 * Returns the default backend name of the administration data. 2207 * @return the default backend name of the administration data. 2208 */ 2209 public static String getDefaultBackendName() 2210 { 2211 return "adminRoot"; 2212 } 2213 2214 /** 2215 * Returns the LDIF file of the administration data. 2216 * @return the LDIF file of the administration data. 2217 */ 2218 public static String getAdminLDIFFile() 2219 { 2220 return "config"+File.separator+"admin-backend.ldif"; 2221 } 2222 2223 2224 2225 /* 2226 *** CryptoManager related types, fields, and methods. *** 2227 */ 2228 2229 /** 2230 Returns the parent entry of the server key entries in ADS. 2231 @return the parent entry of the server key entries in ADS. 2232 */ 2233 public static String getInstanceKeysContainerDN() 2234 { 2235 return "cn=instance keys," + getAdministrationSuffixDN(); 2236 } 2237 2238 /** 2239 Returns the parent entry of the secret key entries in ADS. 2240 @return the parent entry of the secret key entries in ADS. 2241 */ 2242 public static String getSecretKeysContainerDN() 2243 { 2244 return "cn=secret keys," + getAdministrationSuffixDN(); 2245 } 2246 2247 2248 /** 2249 Register instance key-pair public-key certificate provided in 2250 serverProperties: generate a key-id attribute if one is not provided (as 2251 expected); add an instance key public-key certificate entry for the key 2252 certificate; and associate the certificate entry with the server entry via 2253 the key ID attribute. 2254 @param serverProperties Properties of the server being registered to which 2255 the instance key entry belongs. 2256 @param serverEntryDn The server's ADS entry DN. 2257 @throws NamingException In case some JNDI operation fails. 2258 @throws CryptoManager.CryptoManagerException In case there is a problem 2259 getting the instance public key certificate ID. 2260 */ 2261 private void registerInstanceKeyCertificate( 2262 Map<ServerProperty, Object> serverProperties, 2263 LdapName serverEntryDn) 2264 throws ADSContextException { 2265 ADSContextHelper helper = new ADSContextHelper(); 2266 helper.registerInstanceKeyCertificate(dirContext, serverProperties, 2267 serverEntryDn); 2268 } 2269 2270 /** 2271 Unregister instance key-pair public-key certificate provided in 2272 serverProperties.. 2273 @param serverProperties Properties of the server being unregistered to which 2274 the instance key entry belongs. 2275 @param serverEntryDn The server's ADS entry DN. 2276 @throws NamingException In case some JNDI operation fails. 2277 */ 2278 private void unregisterInstanceKeyCertificate( 2279 Map<ServerProperty, Object> serverProperties, 2280 LdapName serverEntryDn) 2281 throws ADSContextException { 2282 ADSContextHelper helper = new ADSContextHelper(); 2283 helper.unregisterInstanceKeyCertificate(dirContext, serverProperties, 2284 serverEntryDn); 2285 } 2286 2287 /** 2288 Return the set of valid (i.e., not tagged as compromised) instance key-pair 2289 public-key certificate entries in ADS. 2290 NOTE: calling this method assumes that all the jar files are present in the 2291 classpath. 2292 @return The set of valid (i.e., not tagged as compromised) instance key-pair 2293 public-key certificate entries in ADS represented as a Map from ds-cfg-key-id 2294 value to ds-cfg-public-key-certificate;binary value. Note that the collection 2295 might be empty. 2296 @throws ADSContextException in case of problems with the entry search. 2297 @see org.opends.server.crypto.CryptoManagerImpl#getTrustedCertificates 2298 */ 2299 public Map<String,byte[]> getTrustedCertificates() 2300 throws ADSContextException 2301 { 2302 final Map<String, byte[]> certificateMap = new HashMap<String, byte[]>(); 2303 final String baseDNStr = getInstanceKeysContainerDN(); 2304 try { 2305 ADSContextHelper helper = new ADSContextHelper(); 2306 final LdapName baseDN = new LdapName(baseDNStr); 2307 final String FILTER_OC_INSTANCE_KEY 2308 = new StringBuilder("(objectclass=") 2309 .append(helper.getOcCryptoInstanceKey()) 2310 .append(")").toString(); 2311 final String FILTER_NOT_COMPROMISED = new StringBuilder("(!(") 2312 .append(helper.getAttrCryptoKeyCompromisedTime()) 2313 .append("=*))").toString(); 2314 final String searchFilter = new StringBuilder("(&") 2315 .append(FILTER_OC_INSTANCE_KEY) 2316 .append(FILTER_NOT_COMPROMISED) 2317 .append(")").toString(); 2318 final SearchControls searchControls = new SearchControls(); 2319 searchControls.setSearchScope(SearchControls.ONELEVEL_SCOPE); 2320 final String attrIDs[]= { 2321 ADSContext.ServerProperty.INSTANCE_KEY_ID.getAttributeName(), 2322 ADSContext.ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE 2323 .getAttributeName() + ";binary"}; 2324 searchControls.setReturningAttributes(attrIDs); 2325 NamingEnumeration<SearchResult> keyEntries 2326 = dirContext.search(baseDN, searchFilter, searchControls); 2327 while (keyEntries.hasMore()) { 2328 final SearchResult entry = keyEntries.next(); 2329 final Attributes attrs = entry.getAttributes(); 2330 final Attribute keyIDAttr = attrs.get(attrIDs[0]); 2331 final Attribute keyCertAttr = attrs.get(attrIDs[1]); 2332 if (null == keyIDAttr || null == keyCertAttr) continue; // schema viol. 2333 certificateMap.put((String)keyIDAttr.get(), (byte[])keyCertAttr.get()); 2334 } 2335 } 2336 catch (NamingException x) { 2337 throw new ADSContextException( 2338 ADSContextException.ErrorType.ERROR_UNEXPECTED, x); 2339 } 2340 return certificateMap; 2341 } 2342 }