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 2006-2008 Sun Microsystems, Inc.
026 */
027 package org.opends.server.tools;
028 import org.opends.messages.Message;
029
030
031
032 import java.security.GeneralSecurityException;
033 import java.util.Collection;
034 import java.util.HashSet;
035 import java.util.LinkedList;
036 import java.util.Set;
037 import java.io.File;
038
039 import javax.crypto.Cipher;
040
041 import org.opends.server.admin.DefaultBehaviorProvider;
042 import org.opends.server.admin.DefinedDefaultBehaviorProvider;
043 import org.opends.server.admin.StringPropertyDefinition;
044 import org.opends.server.admin.std.meta.CryptoManagerCfgDefn;
045 import org.opends.server.api.ConfigHandler;
046 import org.opends.server.config.BooleanConfigAttribute;
047 import org.opends.server.config.ConfigEntry;
048 import org.opends.server.config.DNConfigAttribute;
049 import org.opends.server.config.IntegerConfigAttribute;
050 import org.opends.server.config.StringConfigAttribute;
051 import org.opends.server.core.DirectoryServer;
052 import org.opends.server.core.LockFileManager;
053 import org.opends.server.extensions.ConfigFileHandler;
054 import org.opends.server.extensions.SaltedSHA512PasswordStorageScheme;
055 import org.opends.server.protocols.ldap.LDAPResultCode;
056 import org.opends.server.types.DirectoryException;
057 import org.opends.server.types.DN;
058 import org.opends.server.types.DirectoryEnvironmentConfig;
059 import org.opends.server.types.InitializationException;
060 import org.opends.server.util.SetupUtils;
061 import org.opends.server.util.args.ArgumentException;
062 import org.opends.server.util.args.ArgumentParser;
063 import org.opends.server.util.args.BooleanArgument;
064 import org.opends.server.util.args.FileBasedArgument;
065 import org.opends.server.util.args.IntegerArgument;
066 import org.opends.server.util.args.StringArgument;
067
068 import static org.opends.server.config.ConfigConstants.*;
069 import static org.opends.messages.ConfigMessages.*;
070 import static org.opends.messages.ExtensionMessages.*;
071 import static org.opends.messages.ProtocolMessages.*;
072 import static org.opends.messages.ToolMessages.*;
073 import static org.opends.server.util.ServerConstants.*;
074 import static org.opends.server.util.StaticUtils.*;
075 import static org.opends.server.tools.ToolConstants.*;
076
077
078
079 /**
080 * This class provides a very basic tool that can be used to configure some of
081 * the most important settings in the Directory Server. This configuration is
082 * performed by editing the server's configuration files and therefore the
083 * Directory Server must be offline. This utility will be used during the
084 * Directory Server installation process.
085 * <BR><BR>
086 * The options that this tool can currently set include:
087 * <BR>
088 * <UL>
089 * <LI>The port on which the server will listen for LDAP communication</LI>
090 * <LI>The DN and password for the initial root user.
091 * <LI>The set of base DNs for user data</LI>
092 * </UL>
093 */
094 public class ConfigureDS
095 {
096 /**
097 * The fully-qualified name of this class.
098 */
099 private static final String CLASS_NAME =
100 "org.opends.server.tools.ConfigureDS";
101
102
103
104 /**
105 * The DN of the configuration entry defining the JE database backend.
106 */
107 private static final String DN_JE_BACKEND =
108 ATTR_BACKEND_ID + "=userRoot," + DN_BACKEND_BASE;
109
110
111
112 /**
113 * The DN of the configuration entry defining the LDAP connection handler.
114 */
115 private static final String DN_LDAP_CONNECTION_HANDLER =
116 "cn=LDAP Connection Handler," + DN_CONNHANDLER_BASE;
117
118
119 /**
120 * The DN of the configuration entry defining the LDAPS connection handler.
121 */
122 private static final String DN_LDAPS_CONNECTION_HANDLER =
123 "cn=LDAPS Connection Handler," + DN_CONNHANDLER_BASE;
124
125 /**
126 * The DN of the configuration entry defining the JMX connection handler.
127 */
128 private static final String DN_JMX_CONNECTION_HANDLER =
129 "cn=JMX Connection Handler," + DN_CONNHANDLER_BASE;
130
131
132 /**
133 * The DN of the configuration entry defining the initial root user.
134 */
135 private static final String DN_ROOT_USER =
136 "cn=Directory Manager," + DN_ROOT_DN_CONFIG_BASE;
137
138 /**
139 * The DN of the Crypto Manager.
140 */
141 private static final String DN_CRYPTO_MANAGER = "cn=Crypto Manager,cn=config";
142
143
144
145 /**
146 * Provides the command-line arguments to the <CODE>configMain</CODE> method
147 * for processing.
148 *
149 * @param args The set of command-line arguments provided to this program.
150 */
151 public static void main(String[] args)
152 {
153 int exitCode = configMain(args);
154 if (exitCode != 0)
155 {
156 System.exit(filterExitCode(exitCode));
157 }
158 }
159
160
161
162 /**
163 * Parses the provided command-line arguments and makes the appropriate
164 * changes to the Directory Server configuration.
165 *
166 * @param args The command-line arguments provided to this program.
167 *
168 * @return The exit code from the configuration processing. A nonzero value
169 * indicates that there was some kind of problem during the
170 * configuration processing.
171 */
172 public static int configMain(String[] args)
173 {
174 BooleanArgument showUsage;
175 BooleanArgument enableStartTLS;
176 FileBasedArgument rootPasswordFile;
177 IntegerArgument ldapPort;
178 IntegerArgument ldapsPort;
179 IntegerArgument jmxPort;
180 StringArgument baseDNString;
181 StringArgument configClass;
182 StringArgument configFile;
183 StringArgument rootDNString;
184 StringArgument rootPassword;
185 StringArgument keyManagerProviderDN;
186 StringArgument trustManagerProviderDN;
187 StringArgument certNickName;
188 StringArgument keyManagerPath;
189 StringArgument serverRoot;
190
191 Message toolDescription = INFO_CONFIGDS_TOOL_DESCRIPTION.get();
192 ArgumentParser argParser = new ArgumentParser(CLASS_NAME, toolDescription,
193 false);
194 try
195 {
196 configFile = new StringArgument("configfile", 'c', "configFile", true,
197 false, true,
198 INFO_CONFIGFILE_PLACEHOLDER.get(), null,
199 null,
200 INFO_DESCRIPTION_CONFIG_FILE.get());
201 configFile.setHidden(true);
202 argParser.addArgument(configFile);
203
204 configClass = new StringArgument("configclass", OPTION_SHORT_CONFIG_CLASS,
205 OPTION_LONG_CONFIG_CLASS, false,
206 false, true, INFO_CONFIGCLASS_PLACEHOLDER.get(),
207 ConfigFileHandler.class.getName(), null,
208 INFO_DESCRIPTION_CONFIG_CLASS.get());
209 configClass.setHidden(true);
210 argParser.addArgument(configClass);
211
212 ldapPort = new IntegerArgument("ldapport", OPTION_SHORT_PORT,
213 "ldapPort", false, false,
214 true, INFO_LDAPPORT_PLACEHOLDER.get(), 389,
215 null, true, 1,
216 true, 65535,
217 INFO_CONFIGDS_DESCRIPTION_LDAP_PORT.get());
218 argParser.addArgument(ldapPort);
219
220 ldapsPort = new IntegerArgument("ldapsPort", 'P', "ldapsPort", false,
221 false, true, INFO_LDAPPORT_PLACEHOLDER.get(), 636, null, true, 1,
222 true, 65535,
223 INFO_CONFIGDS_DESCRIPTION_LDAPS_PORT.get());
224 argParser.addArgument(ldapsPort);
225
226 enableStartTLS = new BooleanArgument("enableStartTLS",
227 OPTION_SHORT_START_TLS, "enableStartTLS",
228 INFO_CONFIGDS_DESCRIPTION_ENABLE_START_TLS.get());
229 argParser.addArgument(enableStartTLS);
230
231 jmxPort = new IntegerArgument("jmxport", 'x', "jmxPort", false, false,
232 true, INFO_JMXPORT_PLACEHOLDER.get(), SetupUtils.getDefaultJMXPort(),
233 null, true, 1,
234 true, 65535,
235 INFO_CONFIGDS_DESCRIPTION_JMX_PORT.get());
236 argParser.addArgument(jmxPort);
237
238 keyManagerProviderDN = new StringArgument("keymanagerproviderdn",
239 'k',
240 "keyManagerProviderDN",
241 false, false,
242 true, INFO_KEY_MANAGER_PROVIDER_DN_PLACEHOLDER.get(),
243 null,
244 null,
245 INFO_CONFIGDS_DESCRIPTION_KEYMANAGER_PROVIDER_DN.get());
246 argParser.addArgument(keyManagerProviderDN);
247
248 trustManagerProviderDN = new StringArgument("trustmanagerproviderdn",
249 't',
250 "trustManagerProviderDN",
251 false, false,
252 true, INFO_TRUST_MANAGER_PROVIDER_DN_PLACEHOLDER.get(),
253 null,
254 null,
255 INFO_CONFIGDS_DESCRIPTION_TRUSTMANAGER_PROVIDER_DN.get());
256 argParser.addArgument(trustManagerProviderDN);
257
258 keyManagerPath = new StringArgument("keymanagerpath",
259 'm',
260 "keyManagerPath",
261 false, false, true,
262 INFO_KEY_MANAGER_PATH_PLACEHOLDER.get(),
263 null,
264 null,
265 INFO_CONFIGDS_DESCRIPTION_KEYMANAGER_PATH.get());
266 argParser.addArgument(keyManagerPath);
267
268 certNickName = new StringArgument("certnickname",
269 'a',
270 "certNickName",
271 false, false,
272 true, INFO_NICKNAME_PLACEHOLDER.get(),
273 null,
274 null,
275 INFO_CONFIGDS_DESCRIPTION_CERTNICKNAME.get());
276 argParser.addArgument(certNickName);
277
278 baseDNString = new StringArgument(
279 "basedn", OPTION_SHORT_BASEDN,
280 OPTION_LONG_BASEDN, false, true,
281 true, INFO_BASEDN_PLACEHOLDER.get(),
282 "dc=example,dc=com",
283 null,
284 INFO_CONFIGDS_DESCRIPTION_BASE_DN.get());
285 argParser.addArgument(baseDNString);
286
287 rootDNString = new StringArgument(
288 "rootdn", OPTION_SHORT_ROOT_USER_DN,
289 OPTION_LONG_ROOT_USER_DN, false, false,
290 true, INFO_ROOT_USER_DN_PLACEHOLDER.get(),
291 "cn=Directory Manager", null,
292 INFO_CONFIGDS_DESCRIPTION_ROOT_DN.get());
293 argParser.addArgument(rootDNString);
294
295 rootPassword = new StringArgument(
296 "rootpw", OPTION_SHORT_BINDPWD,
297 "rootPassword", false,
298 false, true, INFO_ROOT_USER_PWD_PLACEHOLDER.get(), null, null,
299 INFO_CONFIGDS_DESCRIPTION_ROOT_PW.get());
300 argParser.addArgument(rootPassword);
301
302 rootPasswordFile = new FileBasedArgument(
303 "rootpwfile",
304 OPTION_SHORT_BINDPWD_FILE,
305 "rootPasswordFile", false, false,
306 INFO_FILE_PLACEHOLDER.get(), null, null,
307 INFO_CONFIGDS_DESCRIPTION_ROOT_PW_FILE.get());
308 argParser.addArgument(rootPasswordFile);
309
310 showUsage = new BooleanArgument("showusage", OPTION_SHORT_HELP,
311 OPTION_LONG_HELP,
312 INFO_DESCRIPTION_USAGE.get());
313 argParser.addArgument(showUsage);
314 argParser.setUsageArgument(showUsage);
315
316 serverRoot = new StringArgument("serverRoot",
317 ToolConstants.OPTION_SHORT_SERVER_ROOT,
318 ToolConstants.OPTION_LONG_SERVER_ROOT,
319 false, false, true, INFO_SERVER_ROOT_DIR_PLACEHOLDER.get(), null,
320 null, null);
321 serverRoot.setHidden(true);
322 argParser.addArgument(serverRoot);
323 }
324 catch (ArgumentException ae)
325 {
326 Message message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage());
327 System.err.println(wrapText(message, MAX_LINE_WIDTH));
328 return 1;
329 }
330
331
332 // Parse the command-line arguments provided to the program.
333 try
334 {
335 argParser.parseArguments(args);
336 }
337 catch (ArgumentException ae)
338 {
339 Message message = ERR_ERROR_PARSING_ARGS.get(ae.getMessage());
340
341 System.err.println(wrapText(message, MAX_LINE_WIDTH));
342 System.err.println(argParser.getUsage());
343 return LDAPResultCode.CLIENT_SIDE_PARAM_ERROR;
344 }
345
346
347 // If we should just display usage or version information,
348 // then print it and exit.
349 if (argParser.usageOrVersionDisplayed())
350 {
351 return 0;
352 }
353
354
355 // Make sure that the user actually tried to configure something.
356 if (! (baseDNString.isPresent() || ldapPort.isPresent() ||
357 jmxPort.isPresent() || rootDNString.isPresent()))
358 {
359 Message message = ERR_CONFIGDS_NO_CONFIG_CHANGES.get();
360 System.err.println(wrapText(message, MAX_LINE_WIDTH));
361 System.err.println(argParser.getUsage());
362 return 1;
363 }
364
365 try
366 {
367 Set<Integer> ports = new HashSet<Integer>();
368 if (ldapPort.isPresent())
369 {
370 ports.add(ldapPort.getIntValue());
371 }
372 if (ldapsPort.isPresent())
373 {
374 if (ports.contains(ldapsPort.getIntValue()))
375 {
376 Message message = ERR_CONFIGDS_PORT_ALREADY_SPECIFIED.get(
377 String.valueOf(ldapsPort.getIntValue()));
378 System.err.println(wrapText(message, MAX_LINE_WIDTH));
379 System.err.println(argParser.getUsage());
380 return 1;
381 }
382 else
383 {
384 ports.add(ldapsPort.getIntValue());
385 }
386 }
387 if (jmxPort.isPresent())
388 {
389 if (ports.contains(jmxPort.getIntValue()))
390 {
391 Message message = ERR_CONFIGDS_PORT_ALREADY_SPECIFIED.get(
392 String.valueOf(jmxPort.getIntValue()));
393 System.err.println(wrapText(message, MAX_LINE_WIDTH));
394 System.err.println(argParser.getUsage());
395 return 1;
396 }
397 else
398 {
399 ports.add(jmxPort.getIntValue());
400 }
401 }
402 }
403 catch (ArgumentException ae)
404 {
405 Message message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage());
406 System.err.println(wrapText(message, MAX_LINE_WIDTH));
407 return 1;
408 }
409
410 if (serverRoot.isPresent()) {
411 DirectoryEnvironmentConfig env = DirectoryServer.getEnvironmentConfig();
412 String root = serverRoot.getValue();
413 try {
414 env.setServerRoot(new File(serverRoot.getValue()));
415 } catch (InitializationException e) {
416 ERR_INITIALIZE_SERVER_ROOT.get(root, e.getMessageObject());
417 }
418 }
419
420 // Initialize the Directory Server configuration handler using the
421 // information that was provided.
422 DirectoryServer directoryServer = DirectoryServer.getInstance();
423 directoryServer.bootstrapClient();
424
425 try
426 {
427 directoryServer.initializeJMX();
428 }
429 catch (Exception e)
430 {
431 Message message = ERR_CONFIGDS_CANNOT_INITIALIZE_JMX.get(
432 String.valueOf(configFile.getValue()),
433 e.getMessage());
434 System.err.println(wrapText(message, MAX_LINE_WIDTH));
435 return 1;
436 }
437
438 try
439 {
440 directoryServer.initializeConfiguration(configClass.getValue(),
441 configFile.getValue());
442 }
443 catch (Exception e)
444 {
445 Message message = ERR_CONFIGDS_CANNOT_INITIALIZE_CONFIG.get(
446 String.valueOf(configFile.getValue()),
447 e.getMessage());
448 System.err.println(wrapText(message, MAX_LINE_WIDTH));
449 return 1;
450 }
451
452 try
453 {
454 directoryServer.initializeSchema();
455 }
456 catch (Exception e)
457 {
458 Message message = ERR_CONFIGDS_CANNOT_INITIALIZE_SCHEMA.get(
459 String.valueOf(configFile.getValue()),
460 e.getMessage());
461 System.err.println(wrapText(message, MAX_LINE_WIDTH));
462 return 1;
463 }
464
465
466 // Make sure that we can get an exclusive lock for the Directory Server, so
467 // that no other operation will be allowed while this is in progress.
468 String serverLockFileName = LockFileManager.getServerLockFileName();
469 StringBuilder failureReason = new StringBuilder();
470 if (! LockFileManager.acquireExclusiveLock(serverLockFileName,
471 failureReason))
472 {
473 Message message = ERR_CONFIGDS_CANNOT_ACQUIRE_SERVER_LOCK.get(
474 String.valueOf(serverLockFileName),
475 String.valueOf(failureReason));
476 System.err.println(wrapText(message, MAX_LINE_WIDTH));
477 return 1;
478 }
479
480
481 try
482 {
483 // If one or more base DNs were provided, then make sure that they can be
484 // parsed as valid DNs.
485 LinkedList<DN> baseDNs = null;
486 if (baseDNString.isPresent())
487 {
488 baseDNs = new LinkedList<DN>();
489 for (String dnString : baseDNString.getValues())
490 {
491 try
492 {
493 baseDNs.add(DN.decode(dnString));
494 }
495 catch (DirectoryException de)
496 {
497 Message message = ERR_CONFIGDS_CANNOT_PARSE_BASE_DN.get(
498 String.valueOf(dnString),
499 de.getMessageObject());
500 System.err.println(wrapText(message, MAX_LINE_WIDTH));
501 return 1;
502 }
503 }
504 }
505
506
507 // If a root user DN was provided, then make sure it can be parsed. Also,
508 // make sure that either a password or password file was specified.
509 DN rootDN = null;
510 String rootPW = null;
511 if (rootDNString.isPresent())
512 {
513 try
514 {
515 rootDN = DN.decode(rootDNString.getValue());
516 }
517 catch (DirectoryException de)
518 {
519 Message message = ERR_CONFIGDS_CANNOT_PARSE_ROOT_DN.get(
520 String.valueOf(rootDNString.getValue()),
521 de.getMessageObject());
522 System.err.println(wrapText(message, MAX_LINE_WIDTH));
523 return 1;
524 }
525
526 if (rootPassword.isPresent())
527 {
528 rootPW = rootPassword.getValue();
529 }
530 else if (rootPasswordFile.isPresent())
531 {
532 rootPW = rootPasswordFile.getValue();
533 }
534 else
535 {
536 Message message = ERR_CONFIGDS_NO_ROOT_PW.get();
537 System.err.println(wrapText(message, MAX_LINE_WIDTH));
538 return 1;
539 }
540 }
541
542
543 // Get the Directory Server configuration handler and use it to make the
544 // appropriate configuration changes.
545 ConfigHandler configHandler = directoryServer.getConfigHandler();
546
547
548 // Check that the key manager provided is valid.
549 if (keyManagerProviderDN.isPresent())
550 {
551 DN dn = null;
552 try
553 {
554 dn = DN.decode(keyManagerProviderDN.getValue());
555 }
556 catch (DirectoryException de)
557 {
558 Message message =
559 ERR_CONFIGDS_CANNOT_PARSE_KEYMANAGER_PROVIDER_DN.get(
560 keyManagerProviderDN.getValue(),
561 de.getMessageObject());
562 System.err.println(wrapText(message, MAX_LINE_WIDTH));
563 return 1;
564 }
565
566 try
567 {
568 configHandler.getConfigEntry(dn);
569 }
570 catch (Exception e)
571 {
572 Message message = ERR_CONFIG_KEYMANAGER_CANNOT_GET_BASE.get(
573 String.valueOf(e));
574 System.err.println(wrapText(message, MAX_LINE_WIDTH));
575 return 1;
576 }
577 }
578
579 // Check that the trust manager provided is valid.
580 if (trustManagerProviderDN.isPresent())
581 {
582 DN dn = null;
583 try
584 {
585 dn = DN.decode(trustManagerProviderDN.getValue());
586 }
587 catch (DirectoryException de)
588 {
589 Message message = ERR_CONFIGDS_CANNOT_PARSE_TRUSTMANAGER_PROVIDER_DN.
590 get(trustManagerProviderDN.getValue(), de.getMessageObject());
591 System.err.println(wrapText(message, MAX_LINE_WIDTH));
592 return 1;
593 }
594
595 try
596 {
597 configHandler.getConfigEntry(dn);
598 }
599 catch (Exception e)
600 {
601 Message message = ERR_CONFIG_TRUSTMANAGER_CANNOT_GET_BASE.get(
602 String.valueOf(e));
603 System.err.println(wrapText(message, MAX_LINE_WIDTH));
604 return 1;
605 }
606 }
607
608 // Check that the keystore path values are valid.
609 if (keyManagerPath.isPresent())
610 {
611 if (!keyManagerProviderDN.isPresent())
612 {
613 Message message = ERR_CONFIGDS_KEYMANAGER_PROVIDER_DN_REQUIRED.get(
614 keyManagerProviderDN.getLongIdentifier(),
615 keyManagerPath.getLongIdentifier());
616 System.err.println(wrapText(message, MAX_LINE_WIDTH));
617 return 1;
618 }
619 }
620
621 // If one or more base DNs were specified, then update the config
622 // accordingly.
623 if (baseDNs != null)
624 {
625 try
626 {
627 DN jeBackendDN = DN.decode(DN_JE_BACKEND);
628 ConfigEntry configEntry = configHandler.getConfigEntry(jeBackendDN);
629
630 DNConfigAttribute baseDNAttr =
631 new DNConfigAttribute(
632 ATTR_BACKEND_BASE_DN,
633 INFO_CONFIG_BACKEND_ATTR_DESCRIPTION_BASE_DNS.get(),
634 true, true, false, baseDNs);
635 configEntry.putConfigAttribute(baseDNAttr);
636 }
637 catch (Exception e)
638 {
639 Message message = ERR_CONFIGDS_CANNOT_UPDATE_BASE_DN.get(
640 String.valueOf(e));
641 System.err.println(wrapText(message, MAX_LINE_WIDTH));
642 return 1;
643 }
644 }
645
646
647 // If an LDAP port was specified, then update the config accordingly.
648 if (ldapPort.isPresent())
649 {
650 try
651 {
652 DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
653 ConfigEntry configEntry =
654 configHandler.getConfigEntry(ldapListenerDN);
655
656
657 IntegerConfigAttribute portAttr =
658 new IntegerConfigAttribute(ATTR_LISTEN_PORT,
659 INFO_LDAP_CONNHANDLER_DESCRIPTION_LISTEN_PORT.get(),
660 true, false, true, true, 1, true,
661 65535, ldapPort.getIntValue());
662 configEntry.putConfigAttribute(portAttr);
663 }
664 catch (Exception e)
665 {
666 Message message = ERR_CONFIGDS_CANNOT_UPDATE_LDAP_PORT.get(
667 String.valueOf(e));
668 System.err.println(wrapText(message, MAX_LINE_WIDTH));
669 return 1;
670 }
671 }
672
673 // If an LDAPS port was specified, then update the config accordingly.
674 if (ldapsPort.isPresent())
675 {
676 try
677 {
678 DN ldapListenerDN = DN.decode(DN_LDAPS_CONNECTION_HANDLER);
679 ConfigEntry configEntry =
680 configHandler.getConfigEntry(ldapListenerDN);
681
682
683 IntegerConfigAttribute portAttr =
684 new IntegerConfigAttribute(ATTR_LISTEN_PORT,
685 INFO_LDAP_CONNHANDLER_DESCRIPTION_LISTEN_PORT.get(),
686 true, false, true, true, 1, true,
687 65535, ldapsPort.getIntValue());
688 configEntry.putConfigAttribute(portAttr);
689
690 BooleanConfigAttribute enablePortAttr =
691 new BooleanConfigAttribute(ATTR_CONNECTION_HANDLER_ENABLED,
692 INFO_LDAPS_CONNHANDLER_DESCRIPTION_ENABLE.get(),
693 true, true);
694 configEntry.putConfigAttribute(enablePortAttr);
695 }
696 catch (Exception e)
697 {
698 Message message = ERR_CONFIGDS_CANNOT_UPDATE_LDAPS_PORT.get(
699 String.valueOf(e));
700 System.err.println(wrapText(message, MAX_LINE_WIDTH));
701 return 1;
702 }
703 }
704
705 // If an JMX port was specified, then update the config accordingly.
706 if (jmxPort.isPresent())
707 {
708 try
709 {
710 DN jmxListenerDN = DN.decode(DN_JMX_CONNECTION_HANDLER);
711 ConfigEntry configEntry =
712 configHandler.getConfigEntry(jmxListenerDN);
713
714 IntegerConfigAttribute portAttr =
715 new IntegerConfigAttribute(
716 ATTR_LISTEN_PORT,
717 INFO_JMX_CONNHANDLER_DESCRIPTION_LISTEN_PORT.get(),
718 true, false, true, true, 1, true,
719 65535, jmxPort.getIntValue());
720 configEntry.putConfigAttribute(portAttr);
721
722 BooleanConfigAttribute enablePortAttr =
723 new BooleanConfigAttribute(ATTR_CONNECTION_HANDLER_ENABLED,
724 INFO_JMX_CONNHANDLER_DESCRIPTION_ENABLE.get(),
725 true, true);
726 configEntry.putConfigAttribute(enablePortAttr);
727 }
728 catch (Exception e)
729 {
730 Message message = ERR_CONFIGDS_CANNOT_UPDATE_JMX_PORT.get(
731 String.valueOf(e));
732 System.err.println(wrapText(message, MAX_LINE_WIDTH));
733 return 1;
734 }
735 }
736
737 // Start TLS configuration
738 if (enableStartTLS.isPresent())
739 {
740 try
741 {
742 DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
743 ConfigEntry configEntry =
744 configHandler.getConfigEntry(ldapListenerDN);
745
746
747 BooleanConfigAttribute startTLS =
748 new BooleanConfigAttribute(ATTR_ALLOW_STARTTLS,
749 INFO_LDAP_CONNHANDLER_DESCRIPTION_ALLOW_STARTTLS.get(),
750 true, true);
751 configEntry.putConfigAttribute(startTLS);
752 }
753 catch (Exception e)
754 {
755 Message message = ERR_CONFIGDS_CANNOT_ENABLE_STARTTLS.get(
756 String.valueOf(e));
757 System.err.println(wrapText(message, MAX_LINE_WIDTH));
758 return 1;
759 }
760 }
761
762 // Key manager provider
763 if (keyManagerProviderDN.isPresent())
764 {
765 if (enableStartTLS.isPresent() || ldapsPort.isPresent())
766 {
767 try
768 {
769 // Enable the key manager
770 DN dn = DN.decode(keyManagerProviderDN.getValue());
771 ConfigEntry configEntry = configHandler.getConfigEntry(dn);
772
773 BooleanConfigAttribute enableAttr =
774 new BooleanConfigAttribute(ATTR_KEYMANAGER_ENABLED,
775 INFO_CONFIG_KEYMANAGER_DESCRIPTION_ENABLED.get(),
776 true, true);
777 configEntry.putConfigAttribute(enableAttr);
778 }
779 catch (Exception e)
780 {
781 Message message = ERR_CONFIGDS_CANNOT_ENABLE_KEYMANAGER.get(
782 String.valueOf(e));
783 System.err.println(wrapText(message, MAX_LINE_WIDTH));
784 return 1;
785 }
786 }
787
788 try
789 {
790 if (enableStartTLS.isPresent())
791 {
792 // Use the key manager specified for the LDAP connection handler.
793 DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
794 ConfigEntry configEntry =
795 configHandler.getConfigEntry(ldapListenerDN);
796
797 StringConfigAttribute keyManagerProviderAttr =
798 new StringConfigAttribute(ATTR_KEYMANAGER_DN,
799 INFO_LDAP_CONNHANDLER_DESCRIPTION_KEYMANAGER_DN.get(),
800 false, false, true, keyManagerProviderDN.getValue());
801 configEntry.putConfigAttribute(keyManagerProviderAttr);
802 }
803
804 if (ldapsPort.isPresent())
805 {
806 // Use the key manager specified for the LDAPS connection handler.
807 DN ldapsListenerDN = DN.decode(DN_LDAPS_CONNECTION_HANDLER);
808 ConfigEntry configEntry =
809 configHandler.getConfigEntry(ldapsListenerDN);
810
811 StringConfigAttribute keyManagerProviderAttr =
812 new StringConfigAttribute(ATTR_KEYMANAGER_DN,
813 INFO_LDAP_CONNHANDLER_DESCRIPTION_KEYMANAGER_DN.get(),
814 false, false,
815 true, keyManagerProviderDN.getValue());
816 configEntry.putConfigAttribute(keyManagerProviderAttr);
817 }
818 }
819 catch (Exception e)
820 {
821 Message message = ERR_CONFIGDS_CANNOT_UPDATE_KEYMANAGER_REFERENCE.get(
822 String.valueOf(e));
823 System.err.println(wrapText(message, MAX_LINE_WIDTH));
824 return 1;
825 }
826
827 if (keyManagerPath.isPresent())
828 {
829 try
830 {
831 // Enable the key manager
832 DN dn = DN.decode(keyManagerProviderDN.getValue());
833 ConfigEntry configEntry = configHandler.getConfigEntry(dn);
834
835 StringConfigAttribute pathAttr =
836 new StringConfigAttribute(ATTR_KEYSTORE_FILE,
837 INFO_FILE_KEYMANAGER_DESCRIPTION_FILE.get(), true, true, true,
838 keyManagerPath.getValue());
839 configEntry.putConfigAttribute(pathAttr);
840 }
841 catch (Exception e)
842 {
843 String message = String.valueOf(e);
844 System.err.println(wrapText(message, MAX_LINE_WIDTH));
845 return 1;
846 }
847 }
848 }
849 if (trustManagerProviderDN.isPresent())
850 {
851 if (enableStartTLS.isPresent() || ldapsPort.isPresent())
852 {
853 // Enable the trust manager
854 try
855 {
856 DN dn = DN.decode(trustManagerProviderDN.getValue());
857 ConfigEntry configEntry = configHandler.getConfigEntry(dn);
858
859 BooleanConfigAttribute enableAttr =
860 new BooleanConfigAttribute(ATTR_TRUSTMANAGER_ENABLED,
861 ERR_CONFIG_TRUSTMANAGER_DESCRIPTION_ENABLED.get(),
862 true, true);
863 configEntry.putConfigAttribute(enableAttr);
864 }
865 catch (Exception e)
866 {
867 Message message = ERR_CONFIGDS_CANNOT_ENABLE_TRUSTMANAGER.get(
868 String.valueOf(e));
869 System.err.println(wrapText(message, MAX_LINE_WIDTH));
870 return 1;
871 }
872 }
873
874 try
875 {
876 if (enableStartTLS.isPresent())
877 {
878 // Use the trust manager specified for the LDAP connection handler.
879 DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
880 ConfigEntry configEntry =
881 configHandler.getConfigEntry(ldapListenerDN);
882
883 StringConfigAttribute trustManagerProviderAttr =
884 new StringConfigAttribute(ATTR_TRUSTMANAGER_DN,
885 INFO_LDAP_CONNHANDLER_DESCRIPTION_TRUSTMANAGER_DN.get(),
886 false, false,
887 true, trustManagerProviderDN.getValue());
888 configEntry.putConfigAttribute(trustManagerProviderAttr);
889 }
890
891 if (ldapsPort.isPresent())
892 {
893 // Use the trust manager specified for the LDAPS connection handler.
894 DN ldapsListenerDN = DN.decode(DN_LDAPS_CONNECTION_HANDLER);
895 ConfigEntry configEntry =
896 configHandler.getConfigEntry(ldapsListenerDN);
897
898 StringConfigAttribute trustManagerProviderAttr =
899 new StringConfigAttribute(ATTR_TRUSTMANAGER_DN,
900 INFO_LDAP_CONNHANDLER_DESCRIPTION_TRUSTMANAGER_DN.get(),
901 false, false,
902 true, trustManagerProviderDN.getValue());
903 configEntry.putConfigAttribute(trustManagerProviderAttr);
904 }
905 }
906 catch (Exception e)
907 {
908 Message message =
909 ERR_CONFIGDS_CANNOT_UPDATE_TRUSTMANAGER_REFERENCE.get(
910 String.valueOf(e));
911 System.err.println(wrapText(message, MAX_LINE_WIDTH));
912 return 1;
913 }
914 }
915
916 if (certNickName.isPresent())
917 {
918 try
919 {
920 StringConfigAttribute certNickNameAttr =
921 new StringConfigAttribute(
922 ATTR_SSL_CERT_NICKNAME,
923 INFO_LDAP_CONNHANDLER_DESCRIPTION_SSL_CERT_NICKNAME.get(),
924 false, false, true, certNickName.getValue());
925
926 if (ldapPort.isPresent())
927 {
928 // Use the key manager specified for the LDAP connection handler.
929 DN ldapListenerDN = DN.decode(DN_LDAP_CONNECTION_HANDLER);
930 ConfigEntry configEntry =
931 configHandler.getConfigEntry(ldapListenerDN);
932
933 configEntry.putConfigAttribute(certNickNameAttr);
934 }
935
936 if (ldapsPort.isPresent())
937 {
938 // Use the key manager specified for the LDAPS connection handler.
939 DN ldapsListenerDN = DN.decode(DN_LDAPS_CONNECTION_HANDLER);
940 ConfigEntry configEntry =
941 configHandler.getConfigEntry(ldapsListenerDN);
942
943 configEntry.putConfigAttribute(certNickNameAttr);
944 }
945
946 if (jmxPort.isPresent())
947 {
948 certNickNameAttr = new StringConfigAttribute(ATTR_SSL_CERT_NICKNAME,
949 INFO_JMX_CONNHANDLER_DESCRIPTION_SSL_CERT_NICKNAME.get(),
950 false, false, true, certNickName.getValue());
951
952 // Use the key manager specified for the JMX connection handler.
953 DN jmxListenerDN = DN.decode(DN_JMX_CONNECTION_HANDLER);
954 ConfigEntry configEntry =
955 configHandler.getConfigEntry(jmxListenerDN);
956
957 configEntry.putConfigAttribute(certNickNameAttr);
958 }
959 }
960 catch (Exception e)
961 {
962 Message message = ERR_CONFIGDS_CANNOT_UPDATE_CERT_NICKNAME.get(
963 String.valueOf(e));
964 System.err.println(wrapText(message, MAX_LINE_WIDTH));
965 return 1;
966 }
967 }
968
969 // If a root user DN and password were specified, then update the config
970 // accordingly.
971 if (rootDN != null)
972 {
973 try
974 {
975 DN rootUserDN = DN.decode(DN_ROOT_USER);
976 ConfigEntry configEntry = configHandler.getConfigEntry(rootUserDN);
977
978 DNConfigAttribute bindDNAttr =
979 new DNConfigAttribute(
980 ATTR_ROOTDN_ALTERNATE_BIND_DN,
981 INFO_CONFIG_ROOTDN_DESCRIPTION_ALTERNATE_BIND_DN.get(),
982 false, true, false,
983 rootDN);
984 configEntry.putConfigAttribute(bindDNAttr);
985
986 byte[] rootPWBytes = getBytes(rootPW);
987 String encodedPassword =
988 SaltedSHA512PasswordStorageScheme.encodeOffline(rootPWBytes);
989 StringConfigAttribute bindPWAttr =
990 new StringConfigAttribute(ATTR_USER_PASSWORD, Message.EMPTY,
991 false, false, false, encodedPassword);
992 configEntry.putConfigAttribute(bindPWAttr);
993 }
994 catch (Exception e)
995 {
996 Message message = ERR_CONFIGDS_CANNOT_UPDATE_ROOT_USER.get(
997 String.valueOf(e));
998 System.err.println(wrapText(message, MAX_LINE_WIDTH));
999 return 1;
1000 }
1001 }
1002
1003
1004 // Check that the cipher specified is supported. This is intended to
1005 // fix issues with JVM that do not support the default cipher (see
1006 // issue 3075 for instance).
1007 CryptoManagerCfgDefn cryptoManager = CryptoManagerCfgDefn.getInstance();
1008 StringPropertyDefinition prop =
1009 cryptoManager.getKeyWrappingTransformationPropertyDefinition();
1010 String defaultCipher = null;
1011 DefaultBehaviorProvider p = prop.getDefaultBehaviorProvider();
1012 if (p instanceof DefinedDefaultBehaviorProvider)
1013 {
1014 Collection<?> defaultValues =
1015 ((DefinedDefaultBehaviorProvider)p).getDefaultValues();
1016 if (!defaultValues.isEmpty())
1017 {
1018 defaultCipher = defaultValues.iterator().next().toString();
1019 }
1020 }
1021 if (defaultCipher != null)
1022 {
1023 // Check that the default cipher is supported by the JVM.
1024 try
1025 {
1026 Cipher.getInstance(defaultCipher);
1027 }
1028 catch (GeneralSecurityException ex)
1029 {
1030 // The cipher is not supported: try to find an alternative one.
1031 String alternativeCipher = getAlternativeCipher();
1032 if (alternativeCipher != null)
1033 {
1034 try
1035 {
1036 DN cipherDN = DN.decode(DN_CRYPTO_MANAGER);
1037 ConfigEntry configEntry = configHandler.getConfigEntry(cipherDN);
1038
1039 // Set the alternative cipher
1040 StringConfigAttribute keyWrappingTransformation =
1041 new StringConfigAttribute(
1042 ATTR_CRYPTO_CIPHER_KEY_WRAPPING_TRANSFORMATION,
1043 Message.EMPTY, false, false, true, alternativeCipher);
1044 configEntry.putConfigAttribute(keyWrappingTransformation);
1045 }
1046 catch (Exception e)
1047 {
1048 Message message = ERR_CONFIGDS_CANNOT_UPDATE_CRYPTO_MANAGER.get(
1049 String.valueOf(e));
1050 System.err.println(wrapText(message, MAX_LINE_WIDTH));
1051 return 1;
1052 }
1053 }
1054 }
1055 }
1056
1057 // Write the updated configuration.
1058 try
1059 {
1060 configHandler.writeUpdatedConfig();
1061
1062 Message message = INFO_CONFIGDS_WROTE_UPDATED_CONFIG.get();
1063 System.out.println(wrapText(message, MAX_LINE_WIDTH));
1064 }
1065 catch (DirectoryException de)
1066 {
1067 Message message = ERR_CONFIGDS_CANNOT_WRITE_UPDATED_CONFIG.get(
1068 de.getMessageObject());
1069 System.err.println(wrapText(message, MAX_LINE_WIDTH));
1070 return 1;
1071 }
1072 }
1073 finally
1074 {
1075 LockFileManager.releaseLock(serverLockFileName, failureReason);
1076 }
1077
1078
1079 // If we've gotten here, then everything was successful.
1080 return 0;
1081 }
1082
1083 /**
1084 * Returns a cipher that is supported by the JVM we are running at.
1085 * Returns <CODE>null</CODE> if no alternative cipher could be found.
1086 * @return a cipher that is supported by the JVM we are running at.
1087 */
1088 private static String getAlternativeCipher()
1089 {
1090 final String[] preferredAlternativeCiphers =
1091 {
1092 "RSA/ECB/OAEPWITHSHA1ANDMGF1PADDING",
1093 "RSA/ECB/PKCS1Padding"
1094 };
1095 String alternativeCipher = null;
1096 for (String cipher : preferredAlternativeCiphers)
1097 {
1098 try
1099 {
1100 Cipher.getInstance(cipher);
1101 alternativeCipher = cipher;
1102 break;
1103 }
1104 catch (Throwable t)
1105 {
1106 }
1107 }
1108 return alternativeCipher;
1109 }
1110 }
1111