001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2008-2010 Sun Microsystems, Inc. 015 * Portions Copyright 2011-2016 ForgeRock AS. 016 */ 017package org.opends.server.tools; 018 019import static com.forgerock.opendj.cli.ArgumentConstants.*; 020import static com.forgerock.opendj.cli.CliMessages.INFO_JMXPORT_PLACEHOLDER; 021import static com.forgerock.opendj.cli.CliMessages.INFO_KEYSTORE_PWD_FILE_PLACEHOLDER; 022import static com.forgerock.opendj.cli.CliMessages.INFO_NUM_ENTRIES_PLACEHOLDER; 023import static com.forgerock.opendj.cli.CliMessages.INFO_PORT_PLACEHOLDER; 024import static com.forgerock.opendj.cli.CliMessages.INFO_ROOT_USER_PWD_FILE_PLACEHOLDER; 025import static com.forgerock.opendj.cli.CommonArguments.*; 026import static com.forgerock.opendj.cli.Utils.addErrorMessageIfArgumentsConflict; 027import static com.forgerock.opendj.util.OperatingSystem.*; 028 029import static org.opends.messages.ToolMessages.*; 030 031import java.util.Collection; 032import java.util.HashSet; 033import java.util.LinkedHashSet; 034import java.util.Set; 035 036import org.forgerock.i18n.LocalizableMessage; 037import org.forgerock.i18n.LocalizableMessageDescriptor.Arg1; 038import org.forgerock.i18n.slf4j.LocalizedLogger; 039import org.opends.quicksetup.Constants; 040import org.opends.quicksetup.Installation; 041import org.opends.quicksetup.UserData; 042import org.opends.quicksetup.util.Utils; 043import org.opends.server.config.AdministrationConnector; 044import org.opends.server.core.DirectoryServer.DirectoryServerVersionHandler; 045 046import com.forgerock.opendj.cli.Argument; 047import com.forgerock.opendj.cli.ArgumentException; 048import com.forgerock.opendj.cli.ArgumentParser; 049import com.forgerock.opendj.cli.BooleanArgument; 050import com.forgerock.opendj.cli.CliConstants; 051import com.forgerock.opendj.cli.FileBasedArgument; 052import com.forgerock.opendj.cli.IntegerArgument; 053import com.forgerock.opendj.cli.StringArgument; 054 055/** 056 * Class used to parse the arguments of the setup command-line and to check 057 * that there are not conflicting arguments (nor missing arguments in no prompt 058 * mode). 059 * Note that this class does not perform checks involving network (like if 060 * a given port is free) nor the validity of the certificate information 061 * provided. 062 */ 063public class InstallDSArgumentParser extends ArgumentParser 064{ 065 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 066 067 private BooleanArgument cliArg; 068 BooleanArgument addBaseEntryArg; 069 private BooleanArgument showUsageArg; 070 BooleanArgument quietArg; 071 BooleanArgument noPromptArg; 072 BooleanArgument verboseArg; 073 private StringArgument propertiesFileArgument; 074 private BooleanArgument noPropertiesFileArgument; 075 BooleanArgument skipPortCheckArg; 076 BooleanArgument enableWindowsServiceArg; 077 BooleanArgument doNotStartArg; 078 BooleanArgument enableStartTLSArg; 079 BooleanArgument generateSelfSignedCertificateArg; 080 StringArgument hostNameArg; 081 BooleanArgument usePkcs11Arg; 082 private FileBasedArgument directoryManagerPwdFileArg; 083 private FileBasedArgument keyStorePasswordFileArg; 084 IntegerArgument ldapPortArg; 085 IntegerArgument adminConnectorPortArg; 086 IntegerArgument ldapsPortArg; 087 IntegerArgument jmxPortArg; 088 IntegerArgument sampleDataArg; 089 StringArgument baseDNArg; 090 StringArgument importLDIFArg; 091 StringArgument rejectedImportFileArg; 092 StringArgument skippedImportFileArg; 093 StringArgument directoryManagerDNArg; 094 private StringArgument directoryManagerPwdStringArg; 095 StringArgument useJavaKeyStoreArg; 096 StringArgument useJCEKSArg; 097 StringArgument usePkcs12Arg; 098 private StringArgument keyStorePasswordArg; 099 StringArgument certNicknameArg; 100 private StringArgument progNameArg; 101 private IntegerArgument connectTimeoutArg; 102 BooleanArgument acceptLicense; 103 StringArgument backendTypeArg; 104 105 /** 106 * The default constructor for this class. 107 * @param mainClassName the class name of the main class for the command-line 108 * that is being used. 109 */ 110 public InstallDSArgumentParser(String mainClassName) 111 { 112 super(mainClassName, INFO_INSTALLDS_TOOL_DESCRIPTION.get(), false); 113 setShortToolDescription(REF_SHORT_DESC_SETUP.get()); 114 setVersionHandler(new DirectoryServerVersionHandler()); 115 } 116 117 /** 118 * Initializes the arguments without parsing them. 119 * @throws ArgumentException if there was an error creating or adding the 120 * arguments. If this occurs is likely to be a bug. 121 */ 122 public void initializeArguments() throws ArgumentException 123 { 124 cliArg = cliArgument(); 125 addArgument(cliArg); 126 127 progNameArg = StringArgument.builder("programName") 128 .shortIdentifier('P') 129 .description(INFO_INSTALLDS_DESCRIPTION_PROGNAME.get()) 130 .hidden() 131 .defaultValue(Installation.getSetupFileName()) 132 .valuePlaceholder(INFO_PROGRAM_NAME_PLACEHOLDER.get()) 133 .buildArgument(); 134 addArgument(progNameArg); 135 136 noPromptArg = noPromptArgument(); 137 addArgument(noPromptArg); 138 139 quietArg = quietArgument(); 140 addArgument(quietArg); 141 142 verboseArg = verboseArgument(); 143 addArgument(verboseArg); 144 145 propertiesFileArgument = 146 StringArgument.builder(OPTION_LONG_PROP_FILE_PATH) 147 .description(INFO_DESCRIPTION_PROP_FILE_PATH.get()) 148 .valuePlaceholder(INFO_PROP_FILE_PATH_PLACEHOLDER.get()) 149 .buildArgument(); 150 addArgument(propertiesFileArgument); 151 setFilePropertiesArgument(propertiesFileArgument); 152 153 noPropertiesFileArgument = 154 BooleanArgument.builder(OPTION_LONG_NO_PROP_FILE) 155 .description(INFO_DESCRIPTION_NO_PROP_FILE.get()) 156 .buildArgument(); 157 addArgument(noPropertiesFileArgument); 158 setNoPropertiesFileArgument(noPropertiesFileArgument); 159 160 baseDNArg = 161 StringArgument.builder(OPTION_LONG_BASEDN) 162 .shortIdentifier(OPTION_SHORT_BASEDN) 163 .description(INFO_INSTALLDS_DESCRIPTION_BASEDN.get()) 164 .multiValued() 165 .valuePlaceholder(INFO_BASEDN_PLACEHOLDER.get()) 166 .buildArgument(); 167 addArgument(baseDNArg); 168 169 addBaseEntryArg = 170 BooleanArgument.builder("addBaseEntry") 171 .shortIdentifier('a') 172 .description(INFO_INSTALLDS_DESCRIPTION_ADDBASE.get()) 173 .buildArgument(); 174 addArgument(addBaseEntryArg); 175 176 importLDIFArg = 177 StringArgument.builder(OPTION_LONG_LDIF_FILE) 178 .shortIdentifier(OPTION_SHORT_LDIF_FILE) 179 .description(INFO_INSTALLDS_DESCRIPTION_IMPORTLDIF.get()) 180 .multiValued() 181 .valuePlaceholder(INFO_LDIFFILE_PLACEHOLDER.get()) 182 .buildArgument(); 183 addArgument(importLDIFArg); 184 185 rejectedImportFileArg = 186 StringArgument.builder("rejectFile") 187 .shortIdentifier('R') 188 .description(INFO_INSTALLDS_DESCRIPTION_REJECTED_FILE.get()) 189 .valuePlaceholder(INFO_REJECT_FILE_PLACEHOLDER.get()) 190 .buildArgument(); 191 addArgument(rejectedImportFileArg); 192 193 skippedImportFileArg = 194 StringArgument.builder("skipFile") 195 .description(INFO_INSTALLDS_DESCRIPTION_SKIPPED_FILE.get()) 196 .valuePlaceholder(INFO_SKIP_FILE_PLACEHOLDER.get()) 197 .buildArgument(); 198 addArgument(skippedImportFileArg); 199 200 sampleDataArg = 201 IntegerArgument.builder("sampleData") 202 .shortIdentifier('d') 203 .description(INFO_INSTALLDS_DESCRIPTION_SAMPLE_DATA.get()) 204 .lowerBound(0) 205 .defaultValue(0) 206 .valuePlaceholder(INFO_NUM_ENTRIES_PLACEHOLDER.get()) 207 .buildArgument(); 208 addArgument(sampleDataArg); 209 210 int defaultLdapPort = UserData.getDefaultPort(); 211 if (defaultLdapPort == -1) 212 { 213 defaultLdapPort = 389; 214 } 215 216 ldapPortArg = 217 IntegerArgument.builder("ldapPort") 218 .shortIdentifier(OPTION_SHORT_PORT) 219 .description(INFO_INSTALLDS_DESCRIPTION_LDAPPORT.get()) 220 .range(1, 65535) 221 .defaultValue(defaultLdapPort) 222 .valuePlaceholder(INFO_PORT_PLACEHOLDER.get()) 223 .buildArgument(); 224 addArgument(ldapPortArg); 225 226 int defaultAdminPort = UserData.getDefaultAdminConnectorPort(); 227 if (defaultAdminPort == -1) 228 { 229 defaultAdminPort = 230 AdministrationConnector.DEFAULT_ADMINISTRATION_CONNECTOR_PORT; 231 } 232 233 adminConnectorPortArg = 234 IntegerArgument.builder("adminConnectorPort") 235 .description(INFO_INSTALLDS_DESCRIPTION_ADMINCONNECTORPORT.get()) 236 .range(1, 65535) 237 .defaultValue(defaultAdminPort) 238 .valuePlaceholder(INFO_PORT_PLACEHOLDER.get()) 239 .buildArgument(); 240 addArgument(adminConnectorPortArg); 241 242 jmxPortArg = 243 IntegerArgument.builder("jmxPort") 244 .shortIdentifier('x') 245 .description(INFO_INSTALLDS_DESCRIPTION_JMXPORT.get()) 246 .range(1, 65535) 247 .defaultValue(CliConstants.DEFAULT_JMX_PORT) 248 .valuePlaceholder(INFO_JMXPORT_PLACEHOLDER.get()) 249 .buildArgument(); 250 addArgument(jmxPortArg); 251 252 skipPortCheckArg = 253 BooleanArgument.builder("skipPortCheck") 254 .shortIdentifier('S') 255 .description(INFO_INSTALLDS_DESCRIPTION_SKIPPORT.get()) 256 .buildArgument(); 257 addArgument(skipPortCheckArg); 258 259 directoryManagerDNArg = 260 StringArgument.builder(OPTION_LONG_ROOT_USER_DN) 261 .shortIdentifier(OPTION_SHORT_ROOT_USER_DN) 262 .description(INFO_INSTALLDS_DESCRIPTION_ROOTDN.get()) 263 .defaultValue("cn=Directory Manager") 264 .valuePlaceholder(INFO_ROOT_USER_DN_PLACEHOLDER.get()) 265 .buildArgument(); 266 addArgument(directoryManagerDNArg); 267 268 directoryManagerPwdStringArg = 269 StringArgument.builder("rootUserPassword") 270 .shortIdentifier(OPTION_SHORT_BINDPWD) 271 .description(INFO_INSTALLDS_DESCRIPTION_ROOTPW.get()) 272 .valuePlaceholder(INFO_ROOT_USER_PWD_PLACEHOLDER.get()) 273 .buildArgument(); 274 addArgument(directoryManagerPwdStringArg); 275 276 directoryManagerPwdFileArg = 277 FileBasedArgument.builder("rootUserPasswordFile") 278 .shortIdentifier(OPTION_SHORT_BINDPWD_FILE) 279 .description(INFO_INSTALLDS_DESCRIPTION_ROOTPWFILE.get()) 280 .valuePlaceholder(INFO_ROOT_USER_PWD_FILE_PLACEHOLDER.get()) 281 .buildArgument(); 282 addArgument(directoryManagerPwdFileArg); 283 284 enableWindowsServiceArg = 285 BooleanArgument.builder("enableWindowsService") 286 .shortIdentifier('e') 287 .description(INFO_INSTALLDS_DESCRIPTION_ENABLE_WINDOWS_SERVICE.get()) 288 .buildArgument(); 289 if (isWindows()) 290 { 291 addArgument(enableWindowsServiceArg); 292 } 293 294 doNotStartArg = 295 BooleanArgument.builder("doNotStart") 296 .shortIdentifier('O') 297 .description(INFO_INSTALLDS_DESCRIPTION_DO_NOT_START.get()) 298 .buildArgument(); 299 addArgument(doNotStartArg); 300 301 enableStartTLSArg = 302 BooleanArgument.builder("enableStartTLS") 303 .shortIdentifier(OPTION_SHORT_START_TLS) 304 .description(INFO_INSTALLDS_DESCRIPTION_ENABLE_STARTTLS.get()) 305 .buildArgument(); 306 addArgument(enableStartTLSArg); 307 308 int defaultSecurePort = UserData.getDefaultSslPort(defaultLdapPort); 309 if (defaultSecurePort == -1) 310 { 311 defaultSecurePort = 636; 312 } 313 314 ldapsPortArg = 315 IntegerArgument.builder("ldapsPort") 316 .shortIdentifier(OPTION_SHORT_USE_SSL) 317 .description(INFO_INSTALLDS_DESCRIPTION_LDAPSPORT.get()) 318 .range(1, 65535) 319 .defaultValue(defaultSecurePort) 320 .valuePlaceholder(INFO_PORT_PLACEHOLDER.get()) 321 .buildArgument(); 322 addArgument(ldapsPortArg); 323 324 generateSelfSignedCertificateArg = 325 BooleanArgument.builder("generateSelfSignedCertificate") 326 .description(INFO_INSTALLDS_DESCRIPTION_USE_SELF_SIGNED.get()) 327 .buildArgument(); 328 addArgument(generateSelfSignedCertificateArg); 329 330 hostNameArg = 331 StringArgument.builder(OPTION_LONG_HOST) 332 .shortIdentifier(OPTION_SHORT_HOST) 333 .description(INFO_INSTALLDS_DESCRIPTION_HOST_NAME.get()) 334 .defaultValue(UserData.getDefaultHostName()) 335 .valuePlaceholder(INFO_HOST_PLACEHOLDER.get()) 336 .buildArgument(); 337 addDefaultArgument(hostNameArg); 338 339 usePkcs11Arg = 340 BooleanArgument.builder("usePkcs11Keystore") 341 .description(INFO_INSTALLDS_DESCRIPTION_USE_PKCS11.get()) 342 .buildArgument(); 343 addArgument(usePkcs11Arg); 344 345 useJavaKeyStoreArg = 346 StringArgument.builder("useJavaKeystore") 347 .description(INFO_INSTALLDS_DESCRIPTION_USE_JAVAKEYSTORE.get()) 348 .valuePlaceholder(INFO_KEYSTOREPATH_PLACEHOLDER.get()) 349 .buildArgument(); 350 addArgument(useJavaKeyStoreArg); 351 352 useJCEKSArg = 353 StringArgument.builder("useJCEKS") 354 .description(INFO_INSTALLDS_DESCRIPTION_USE_JCEKS.get()) 355 .valuePlaceholder(INFO_KEYSTOREPATH_PLACEHOLDER.get()) 356 .buildArgument(); 357 addArgument(useJCEKSArg); 358 359 usePkcs12Arg = 360 StringArgument.builder("usePkcs12keyStore") 361 .description(INFO_INSTALLDS_DESCRIPTION_USE_PKCS12.get()) 362 .valuePlaceholder(INFO_KEYSTOREPATH_PLACEHOLDER.get()) 363 .buildArgument(); 364 addArgument(usePkcs12Arg); 365 366 keyStorePasswordArg = 367 StringArgument.builder(OPTION_LONG_KEYSTORE_PWD) 368 .shortIdentifier(OPTION_SHORT_KEYSTORE_PWD) 369 .description(INFO_INSTALLDS_DESCRIPTION_KEYSTOREPASSWORD.get()) 370 .valuePlaceholder(INFO_KEYSTORE_PWD_PLACEHOLDER.get()) 371 .buildArgument(); 372 addDefaultArgument(keyStorePasswordArg); 373 374 keyStorePasswordFileArg = 375 FileBasedArgument.builder(OPTION_LONG_KEYSTORE_PWD_FILE) 376 .shortIdentifier(OPTION_SHORT_KEYSTORE_PWD_FILE) 377 .description(INFO_INSTALLDS_DESCRIPTION_KEYSTOREPASSWORD_FILE.get()) 378 .valuePlaceholder(INFO_KEYSTORE_PWD_FILE_PLACEHOLDER.get()) 379 .buildArgument(); 380 addDefaultArgument(keyStorePasswordFileArg); 381 382 certNicknameArg = 383 StringArgument.builder(OPTION_LONG_CERT_NICKNAME) 384 .shortIdentifier(OPTION_SHORT_CERT_NICKNAME) 385 .description(INFO_INSTALLDS_DESCRIPTION_CERT_NICKNAME.get()) 386 .multiValued() 387 .valuePlaceholder(INFO_NICKNAME_PLACEHOLDER.get()) 388 .buildArgument(); 389 addDefaultArgument(certNicknameArg); 390 391 connectTimeoutArg = connectTimeOutHiddenArgument(); 392 addArgument(connectTimeoutArg); 393 394 acceptLicense = acceptLicenseArgument(); 395 addArgument(acceptLicense); 396 397 showUsageArg = showUsageArgument(); 398 addArgument(showUsageArg); 399 setUsageArgument(showUsageArg); 400 401 backendTypeArg = 402 StringArgument.builder(OPTION_LONG_BACKEND_TYPE) 403 .shortIdentifier(OPTION_SHORT_BACKEND_TYPE) 404 .description(INFO_INSTALLDS_DESCRIPTION_BACKEND_TYPE.get()) 405 .defaultValue(BackendTypeHelper.filterSchemaBackendName( 406 new BackendTypeHelper().getBackendTypes().get(0).getName())) 407 .valuePlaceholder(INFO_INSTALLDS_BACKEND_TYPE_PLACEHOLDER.get()) 408 .buildArgument(); 409 addArgument(backendTypeArg); 410 } 411 412 /** 413 * Returns whether the command was launched in CLI mode or not. 414 * @return <CODE>true</CODE> if the command was launched to use CLI mode and 415 * <CODE>false</CODE> otherwise. 416 */ 417 public boolean isCli() 418 { 419 return cliArg.isPresent(); 420 } 421 422 @Override 423 public void parseArguments(String[] args) throws ArgumentException 424 { 425 LinkedHashSet<LocalizableMessage> errorMessages = new LinkedHashSet<>(); 426 try 427 { 428 super.parseArguments(args); 429 } 430 catch (ArgumentException ae) 431 { 432 logger.error(LocalizableMessage.raw("Error parsing arguments: "+ae, ae)); 433 errorMessages.add(ae.getMessageObject()); 434 } 435 436 if (!isUsageArgumentPresent() && !isVersionArgumentPresent()) 437 { 438 checkServerPassword(errorMessages); 439 checkProvidedPorts(errorMessages); 440 checkImportDataArguments(errorMessages); 441 checkSecurityArguments(errorMessages); 442 443 if (!errorMessages.isEmpty()) 444 { 445 throw new ArgumentException(ERR_CANNOT_INITIALIZE_ARGS.get( 446 Utils.getMessageFromCollection(errorMessages, Constants.LINE_SEPARATOR))); 447 } 448 } 449 } 450 451 /** 452 * Returns the directory manager password provided by the user. This method 453 * should be called after a call to parseArguments. 454 * @return the directory manager password provided by the user. 455 */ 456 public String getDirectoryManagerPassword() 457 { 458 if (directoryManagerPwdStringArg.isPresent()) 459 { 460 return directoryManagerPwdStringArg.getValue(); 461 } 462 else if (directoryManagerPwdFileArg.isPresent()) 463 { 464 return directoryManagerPwdFileArg.getValue(); 465 } 466 return null; 467 } 468 469 /** 470 * Returns the key store password provided by the user. This method should be 471 * called after a call to parseArguments. 472 * @return the key store password provided by the user. 473 */ 474 public String getKeyStorePassword() 475 { 476 if (keyStorePasswordArg.isPresent()) 477 { 478 return keyStorePasswordArg.getValue(); 479 } 480 else if (keyStorePasswordFileArg.isPresent()) 481 { 482 return keyStorePasswordFileArg.getValue(); 483 } 484 return null; 485 } 486 487 /** 488 * Checks that there are no conflicts with the directory manager passwords. 489 * If we are in no prompt mode, check that the password was provided. 490 * @param errorMessages the list of messages to which we add the error 491 * messages describing the problems encountered during the execution of the 492 * checking. 493 */ 494 private void checkServerPassword(Collection<LocalizableMessage> errorMessages) 495 { 496 addErrorMessageIfArgumentsConflict(errorMessages, directoryManagerPwdStringArg, directoryManagerPwdFileArg); 497 498 if (noPromptArg.isPresent() && !directoryManagerPwdStringArg.isPresent() && 499 !directoryManagerPwdFileArg.isPresent()) 500 { 501 errorMessages.add(ERR_INSTALLDS_NO_ROOT_PASSWORD.get( 502 directoryManagerPwdStringArg.getLongIdentifier(), 503 directoryManagerPwdFileArg.getLongIdentifier())); 504 } 505 } 506 507 /** 508 * Checks that there are no conflicts with the provided ports (like if the 509 * user provided the same port for different protocols). 510 * @param errorMessages the list of messages to which we add the error 511 * messages describing the problems encountered during the execution of the 512 * checking. 513 */ 514 private void checkProvidedPorts(Collection<LocalizableMessage> errorMessages) 515 { 516 try 517 { 518 Set<Integer> ports = new HashSet<>(); 519 ports.add(ldapPortArg.getIntValue()); 520 521 checkPortAlreadyUsed(ports, adminConnectorPortArg.getIntValue(), errorMessages, 522 ERR_CONFIGDS_PORT_ALREADY_SPECIFIED); 523 if (jmxPortArg.isPresent()) 524 { 525 checkPortAlreadyUsed(ports, jmxPortArg.getIntValue(), errorMessages, ERR_CONFIGDS_PORT_ALREADY_SPECIFIED); 526 } 527 if (ldapsPortArg.isPresent()) 528 { 529 checkPortAlreadyUsed(ports, ldapsPortArg.getIntValue(), errorMessages, ERR_CONFIGDS_PORT_ALREADY_SPECIFIED); 530 } 531 } 532 catch (ArgumentException ae) 533 { 534 logger.error(LocalizableMessage.raw("Unexpected error. "+ 535 "Assuming that it is caused by a previous parsing issue: "+ae, ae)); 536 } 537 } 538 539 private void checkPortAlreadyUsed(Set<Integer> ports, int port, Collection<LocalizableMessage> errorMessages, 540 Arg1<Object> errorMsg) 541 { 542 if (!ports.add(port)) 543 { 544 errorMessages.add(errorMsg.get(port)); 545 } 546 } 547 548 /** 549 * Checks that there are no conflicts with the import data arguments. 550 * 551 * @param errorMessages 552 * the list of messages to which we add the error messages describing 553 * the problems encountered during the execution of the checking. 554 */ 555 private void checkImportDataArguments(Collection<LocalizableMessage> errorMessages) 556 { 557 // Make sure that the user didn't provide conflicting arguments. 558 addErrorMessageIfArgumentsConflict(errorMessages, addBaseEntryArg, importLDIFArg); 559 addErrorMessageIfArgumentsConflict(errorMessages, addBaseEntryArg, sampleDataArg); 560 addErrorMessageIfArgumentsConflict(errorMessages, importLDIFArg, sampleDataArg); 561 addErrorMessageIfArgumentsConflict(errorMessages, addBaseEntryArg, rejectedImportFileArg); 562 addErrorMessageIfArgumentsConflict(errorMessages, rejectedImportFileArg, sampleDataArg); 563 addErrorMessageIfArgumentsConflict(errorMessages, addBaseEntryArg, skippedImportFileArg); 564 addErrorMessageIfArgumentsConflict(errorMessages, skippedImportFileArg, sampleDataArg); 565 566 final boolean noBaseDNProvided = !baseDNArg.isPresent() && baseDNArg.getDefaultValue() == null; 567 if (noPromptArg.isPresent() && noBaseDNProvided) 568 { 569 final Argument[] args = {importLDIFArg, addBaseEntryArg, sampleDataArg, backendTypeArg}; 570 for (Argument arg : args) 571 { 572 if (arg.isPresent()) 573 { 574 errorMessages.add(ERR_INSTALLDS_NO_BASE_DN_AND_CONFLICTING_ARG.get("--" + arg.getLongIdentifier())); 575 } 576 } 577 } 578 } 579 580 /** 581 * Checks that there are no conflicts with the security arguments. 582 * If we are in no prompt mode, check that all the information required has 583 * been provided (but not if this information is valid: we do not try to 584 * open the keystores or to check that the LDAPS port is in use). 585 * @param errorMessages the list of messages to which we add the error 586 * messages describing the problems encountered during the execution of the 587 * checking. 588 */ 589 private void checkSecurityArguments(Collection<LocalizableMessage> errorMessages) 590 { 591 boolean certificateRequired = ldapsPortArg.isPresent() || enableStartTLSArg.isPresent(); 592 593 int certificateType = 0; 594 if (generateSelfSignedCertificateArg.isPresent()) 595 { 596 certificateType++; 597 } 598 if (useJavaKeyStoreArg.isPresent()) 599 { 600 certificateType++; 601 } 602 if (useJCEKSArg.isPresent()) 603 { 604 certificateType++; 605 } 606 if (usePkcs11Arg.isPresent()) 607 { 608 certificateType++; 609 } 610 if (usePkcs12Arg.isPresent()) 611 { 612 certificateType++; 613 } 614 615 if (certificateType > 1) 616 { 617 errorMessages.add(ERR_INSTALLDS_SEVERAL_CERTIFICATE_TYPE_SPECIFIED.get()); 618 } 619 620 if (certificateRequired && noPromptArg.isPresent() && certificateType == 0) 621 { 622 errorMessages.add( 623 ERR_INSTALLDS_CERTIFICATE_REQUIRED_FOR_SSL_OR_STARTTLS.get()); 624 } 625 626 if (certificateType == 1) 627 { 628 if (!generateSelfSignedCertificateArg.isPresent()) 629 { 630 addErrorMessageIfArgumentsConflict(errorMessages, keyStorePasswordArg, keyStorePasswordFileArg); 631 632 // Check that we have one password in no prompt mode. 633 if (noPromptArg.isPresent() && !keyStorePasswordArg.isPresent() && 634 !keyStorePasswordFileArg.isPresent()) 635 { 636 errorMessages.add(ERR_INSTALLDS_NO_KEYSTORE_PASSWORD.get( 637 keyStorePasswordArg.getLongIdentifier(), 638 keyStorePasswordFileArg.getLongIdentifier())); 639 } 640 } 641 if (noPromptArg.isPresent() && !ldapsPortArg.isPresent() && 642 !enableStartTLSArg.isPresent()) 643 { 644 errorMessages.add(ERR_INSTALLDS_SSL_OR_STARTTLS_REQUIRED.get( 645 ldapsPortArg.getLongIdentifier(), 646 enableStartTLSArg.getLongIdentifier())); 647 } 648 } 649 } 650 651 /** 652 * Returns the timeout to be used to connect in milliseconds. The method 653 * must be called after parsing the arguments. 654 * @return the timeout to be used to connect in milliseconds. Returns 655 * {@code 0} if there is no timeout. 656 * @throws IllegalStateException if the method is called before 657 * parsing the arguments. 658 */ 659 public int getConnectTimeout() throws IllegalStateException 660 { 661 try 662 { 663 return connectTimeoutArg.getIntValue(); 664 } 665 catch (ArgumentException ae) 666 { 667 throw new IllegalStateException("Argument parser is not parsed: "+ae, ae); 668 } 669 } 670}