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 }