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