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 2007-2010 Sun Microsystems, Inc. 015 * Portions Copyright 2011-2016 ForgeRock AS. 016 */ 017package org.opends.server.admin.client.cli; 018 019import static com.forgerock.opendj.cli.CommonArguments.*; 020import static com.forgerock.opendj.cli.ReturnCode.*; 021import static com.forgerock.opendj.cli.Utils.*; 022 023import static org.opends.messages.AdminToolMessages.*; 024import static org.opends.messages.ToolMessages.*; 025 026import java.io.File; 027import java.io.FileInputStream; 028import java.io.IOException; 029import java.net.InetAddress; 030import java.security.KeyStore; 031import java.security.KeyStoreException; 032import java.security.NoSuchAlgorithmException; 033import java.security.cert.CertificateException; 034import java.util.ArrayList; 035import java.util.LinkedHashSet; 036import java.util.List; 037import java.util.Set; 038 039import org.forgerock.i18n.LocalizableMessage; 040import org.forgerock.i18n.LocalizableMessageBuilder; 041import org.forgerock.i18n.LocalizableMessageDescriptor.Arg1; 042import org.forgerock.i18n.slf4j.LocalizedLogger; 043import org.forgerock.opendj.config.server.ConfigException; 044import org.forgerock.opendj.server.config.server.AdministrationConnectorCfg; 045import org.forgerock.opendj.server.config.server.FileBasedTrustManagerProviderCfg; 046import org.forgerock.opendj.server.config.server.RootCfg; 047import org.forgerock.opendj.server.config.server.TrustManagerProviderCfg; 048import org.opends.admin.ads.util.ApplicationTrustManager; 049import org.opends.server.config.AdministrationConnector; 050import org.opends.server.core.DirectoryServer; 051 052import com.forgerock.opendj.cli.Argument; 053import com.forgerock.opendj.cli.ArgumentException; 054import com.forgerock.opendj.cli.ArgumentParser; 055import com.forgerock.opendj.cli.BooleanArgument; 056import com.forgerock.opendj.cli.CliConstants; 057import com.forgerock.opendj.cli.FileBasedArgument; 058import com.forgerock.opendj.cli.IntegerArgument; 059import com.forgerock.opendj.cli.StringArgument; 060 061/** 062 * This is a commodity class that can be used to check the arguments required to 063 * establish a secure connection in the command line. It can be used to generate 064 * an ApplicationTrustManager object based on the options provided by the user 065 * in the command line. 066 */ 067public final class SecureConnectionCliArgs 068{ 069 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 070 071 private StringArgument hostNameArg; 072 private IntegerArgument portArg; 073 private StringArgument bindDnArg; 074 private StringArgument adminUidArg; 075 private FileBasedArgument bindPasswordFileArg; 076 private StringArgument bindPasswordArg; 077 private BooleanArgument trustAllArg; 078 private StringArgument trustStorePathArg; 079 private StringArgument trustStorePasswordArg; 080 private FileBasedArgument trustStorePasswordFileArg; 081 private StringArgument keyStorePathArg; 082 private StringArgument keyStorePasswordArg; 083 private FileBasedArgument keyStorePasswordFileArg; 084 private StringArgument certNicknameArg; 085 private BooleanArgument useSSLArg; 086 private BooleanArgument useStartTLSArg; 087 private StringArgument saslOptionArg; 088 private IntegerArgument connectTimeoutArg; 089 090 /** Private container for global arguments. */ 091 private Set<Argument> argList; 092 093 /** The trust manager. */ 094 private ApplicationTrustManager trustManager; 095 096 private boolean configurationInitialized; 097 098 /** Defines if the CLI always use the SSL connection type. */ 099 private final boolean alwaysSSL; 100 101 /** 102 * Creates a new instance of secure arguments. 103 * 104 * @param alwaysSSL 105 * If true, always use the SSL connection type. In this case, the 106 * arguments useSSL and startTLS are not present. 107 */ 108 public SecureConnectionCliArgs(boolean alwaysSSL) 109 { 110 this.alwaysSSL = alwaysSSL; 111 } 112 113 /** 114 * Indicates whether any of the arguments are present. 115 * 116 * @return boolean where true indicates that at least one of the arguments is 117 * present 118 */ 119 public boolean argumentsPresent() 120 { 121 if (argList != null) 122 { 123 for (Argument arg : argList) 124 { 125 if (arg.isPresent()) 126 { 127 return true; 128 } 129 } 130 } 131 return false; 132 } 133 134 /** 135 * Get the admin UID which has to be used for the command. 136 * 137 * @return The admin UID specified by the command line argument, or the 138 * default value, if not specified. 139 */ 140 public String getAdministratorUID() 141 { 142 if (adminUidArg.isPresent()) 143 { 144 return adminUidArg.getValue(); 145 } 146 return adminUidArg.getDefaultValue(); 147 } 148 149 /** 150 * Get the bindDN which has to be used for the command. 151 * 152 * @return The bindDN specified by the command line argument, or the default 153 * value, if not specified. 154 */ 155 public String getBindDN() 156 { 157 if (bindDnArg.isPresent()) 158 { 159 return bindDnArg.getValue(); 160 } 161 return bindDnArg.getDefaultValue(); 162 } 163 164 /** 165 * Initialize Global option. 166 * 167 * @throws ArgumentException 168 * If there is a problem with any of the parameters used to create 169 * this argument. 170 * @return a ArrayList with the options created. 171 */ 172 public Set<Argument> createGlobalArguments() throws ArgumentException 173 { 174 argList = new LinkedHashSet<>(); 175 176 useSSLArg = useSSLArgument(); 177 if (!alwaysSSL) 178 { 179 argList.add(useSSLArg); 180 } 181 else 182 { 183 // simulate that the useSSL arg has been given in the CLI 184 useSSLArg.setPresent(true); 185 } 186 187 useStartTLSArg = startTLSArgument(); 188 if (!alwaysSSL) 189 { 190 argList.add(useStartTLSArg); 191 } 192 193 hostNameArg = hostNameArgument(getDefaultHostName()); 194 argList.add(hostNameArg); 195 196 portArg = createPortArgument(AdministrationConnector.DEFAULT_ADMINISTRATION_CONNECTOR_PORT); 197 argList.add(portArg); 198 199 bindDnArg = bindDNArgument(CliConstants.DEFAULT_ROOT_USER_DN); 200 argList.add(bindDnArg); 201 202 // Classes that required admin UID to be not hidden must call createVisibleAdminUidArgument(localizedDescription) 203 adminUidArg = adminUidHiddenArgument(INFO_DESCRIPTION_ADMIN_UID.get()); 204 205 bindPasswordArg = bindPasswordArgument(); 206 argList.add(bindPasswordArg); 207 208 bindPasswordFileArg = bindPasswordFileArgument(); 209 argList.add(bindPasswordFileArg); 210 211 saslOptionArg = saslArgument(); 212 argList.add(saslOptionArg); 213 214 trustAllArg = trustAllArgument(); 215 argList.add(trustAllArg); 216 217 trustStorePathArg = trustStorePathArgument(); 218 argList.add(trustStorePathArg); 219 220 trustStorePasswordArg = trustStorePasswordArgument(); 221 argList.add(trustStorePasswordArg); 222 223 trustStorePasswordFileArg = trustStorePasswordFileArgument(); 224 argList.add(trustStorePasswordFileArg); 225 226 keyStorePathArg = keyStorePathArgument(); 227 argList.add(keyStorePathArg); 228 229 keyStorePasswordArg = keyStorePasswordArgument(); 230 argList.add(keyStorePasswordArg); 231 232 keyStorePasswordFileArg = keyStorePasswordFileArgument(); 233 argList.add(keyStorePasswordFileArg); 234 235 certNicknameArg = certNickNameArgument(); 236 argList.add(certNicknameArg); 237 238 connectTimeoutArg = connectTimeOutArgument(); 239 argList.add(connectTimeoutArg); 240 241 return argList; 242 } 243 244 /** 245 * Get the host name which has to be used for the command. 246 * 247 * @return The host name specified by the command line argument, or the 248 * default value, if not specified. 249 */ 250 public String getHostName() 251 { 252 if (hostNameArg.isPresent()) 253 { 254 return hostNameArg.getValue(); 255 } 256 return hostNameArg.getDefaultValue(); 257 } 258 259 /** 260 * Returns the current hostname. 261 * 262 * If the hostname resolution fails, this method returns {@literal "localhost"}. 263 * @return the current hostname 264 */ 265 public String getDefaultHostName() { 266 try 267 { 268 return InetAddress.getLocalHost().getHostName(); 269 } 270 catch (Exception e) 271 { 272 return "localhost"; 273 } 274 } 275 276 /** 277 * Get the port which has to be used for the command. 278 * 279 * @return The port specified by the command line argument, or the default 280 * value, if not specified. 281 */ 282 public String getPort() 283 { 284 if (portArg.isPresent()) 285 { 286 return portArg.getValue(); 287 } 288 return portArg.getDefaultValue(); 289 } 290 291 /** 292 * Indication if provided global options are validate. 293 * 294 * @param buf 295 * the LocalizableMessageBuilder to write the error messages. 296 * @return return code. 297 */ 298 int validateGlobalOptions(LocalizableMessageBuilder buf) 299 { 300 final List<LocalizableMessage> errors = new ArrayList<>(); 301 addErrorMessageIfArgumentsConflict(errors, bindPasswordArg, bindPasswordFileArg); 302 addErrorMessageIfArgumentsConflict(errors, trustAllArg, trustStorePathArg); 303 addErrorMessageIfArgumentsConflict(errors, trustAllArg, trustStorePasswordArg); 304 addErrorMessageIfArgumentsConflict(errors, trustAllArg, trustStorePasswordFileArg); 305 addErrorMessageIfArgumentsConflict(errors, trustStorePasswordArg, trustStorePasswordFileArg); 306 addErrorMessageIfArgumentsConflict(errors, useStartTLSArg, useSSLArg); 307 308 checkIfPathArgumentIsReadable(errors, trustStorePathArg, ERR_CANNOT_READ_TRUSTSTORE); 309 checkIfPathArgumentIsReadable(errors, keyStorePathArg, ERR_CANNOT_READ_KEYSTORE); 310 311 if (!errors.isEmpty()) 312 { 313 for (LocalizableMessage error : errors) 314 { 315 if (buf.length() > 0) 316 { 317 buf.append(LINE_SEPARATOR); 318 } 319 buf.append(error); 320 } 321 return CONFLICTING_ARGS.get(); 322 } 323 324 return SUCCESS.get(); 325 } 326 327 private void checkIfPathArgumentIsReadable(List<LocalizableMessage> errors, StringArgument pathArg, Arg1<Object> msg) 328 { 329 if (pathArg.isPresent() && !canRead(pathArg.getValue())) 330 { 331 errors.add(msg.get(pathArg.getValue())); 332 } 333 } 334 335 /** 336 * Indicate if the SSL mode is always used. 337 * 338 * @return True if SSL mode is always used. 339 */ 340 public boolean alwaysSSL() 341 { 342 return alwaysSSL; 343 } 344 345 /** 346 * Handle TrustStore. 347 * 348 * @return The trustStore manager to be used for the command. 349 */ 350 public ApplicationTrustManager getTrustManager() 351 { 352 if (trustManager == null) 353 { 354 KeyStore truststore = null; 355 if (trustAllArg.isPresent()) 356 { 357 // Running a null TrustManager will force createLdapsContext and 358 // createStartTLSContext to use a bindTrustManager. 359 return null; 360 } 361 else if (trustStorePathArg.isPresent()) 362 { 363 try (final FileInputStream fos = new FileInputStream(trustStorePathArg.getValue())) 364 { 365 String trustStorePasswordStringValue = null; 366 if (trustStorePasswordArg.isPresent()) 367 { 368 trustStorePasswordStringValue = trustStorePasswordArg.getValue(); 369 } 370 else if (trustStorePasswordFileArg.isPresent()) 371 { 372 trustStorePasswordStringValue = trustStorePasswordFileArg.getValue(); 373 } 374 375 if (trustStorePasswordStringValue != null) 376 { 377 trustStorePasswordStringValue = System.getProperty("javax.net.ssl.trustStorePassword"); 378 } 379 380 char[] trustStorePasswordValue = null; 381 if (trustStorePasswordStringValue != null) 382 { 383 trustStorePasswordValue = trustStorePasswordStringValue.toCharArray(); 384 } 385 386 truststore = KeyStore.getInstance(KeyStore.getDefaultType()); 387 truststore.load(fos, trustStorePasswordValue); 388 } 389 catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) 390 { 391 // Nothing to do: if this occurs we will systematically refuse the 392 // certificates. Maybe we should avoid this and be strict, but we 393 // are in a best effort mode. 394 logger.warn(LocalizableMessage.raw("Error with the truststore"), e); 395 } 396 } 397 trustManager = new ApplicationTrustManager(truststore); 398 } 399 return trustManager; 400 } 401 402 /** 403 * Returns {@code true} if we can read on the provided path and {@code false} 404 * otherwise. 405 * 406 * @param path 407 * the path. 408 * @return {@code true} if we can read on the provided path and {@code false} 409 * otherwise. 410 */ 411 private boolean canRead(String path) 412 { 413 final File file = new File(path); 414 return file.exists() && file.canRead(); 415 } 416 417 /** 418 * Returns the absolute path of the trust store file that appears on the 419 * config. Returns {@code null} if the trust store is not defined or it does 420 * not exist. 421 * 422 * @return the absolute path of the trust store file that appears on the 423 * config. 424 * @throws ConfigException 425 * if there is an error reading the configuration. 426 */ 427 public String getTruststoreFileFromConfig() throws ConfigException 428 { 429 String truststoreFileAbsolute = null; 430 TrustManagerProviderCfg trustManagerCfg = null; 431 AdministrationConnectorCfg administrationConnectorCfg = null; 432 433 boolean couldInitializeConfig = configurationInitialized; 434 // Initialization for admin framework 435 if (!configurationInitialized) 436 { 437 couldInitializeConfig = initializeConfiguration(); 438 } 439 if (couldInitializeConfig) 440 { 441 RootCfg root = DirectoryServer.getInstance().getServerContext().getRootConfig(); 442 administrationConnectorCfg = root.getAdministrationConnector(); 443 444 String trustManagerStr = administrationConnectorCfg.getTrustManagerProvider(); 445 trustManagerCfg = root.getTrustManagerProvider(trustManagerStr); 446 if (trustManagerCfg instanceof FileBasedTrustManagerProviderCfg) 447 { 448 FileBasedTrustManagerProviderCfg fileBasedTrustManagerCfg = (FileBasedTrustManagerProviderCfg) trustManagerCfg; 449 String truststoreFile = fileBasedTrustManagerCfg.getTrustStoreFile(); 450 // Check the file 451 if (truststoreFile.startsWith(File.separator)) 452 { 453 truststoreFileAbsolute = truststoreFile; 454 } 455 else 456 { 457 truststoreFileAbsolute = DirectoryServer.getInstanceRoot() + File.separator + truststoreFile; 458 } 459 File f = new File(truststoreFileAbsolute); 460 if (!f.exists() || !f.canRead() || f.isDirectory()) 461 { 462 truststoreFileAbsolute = null; 463 } 464 else 465 { 466 // Try to get the canonical path. 467 try 468 { 469 truststoreFileAbsolute = f.getCanonicalPath(); 470 } 471 catch (Throwable t) 472 { 473 // We can ignore this error. 474 } 475 } 476 } 477 } 478 return truststoreFileAbsolute; 479 } 480 481 /** 482 * Returns the admin port from the configuration. 483 * 484 * @return the admin port from the configuration. 485 * @throws ConfigException 486 * if an error occurs reading the configuration. 487 */ 488 public int getAdminPortFromConfig() throws ConfigException 489 { 490 // Initialization for admin framework 491 boolean couldInitializeConfiguration = configurationInitialized; 492 if (!configurationInitialized) 493 { 494 couldInitializeConfiguration = initializeConfiguration(); 495 } 496 if (couldInitializeConfiguration) 497 { 498 RootCfg root = DirectoryServer.getInstance().getServerContext().getRootConfig(); 499 return root.getAdministrationConnector().getListenPort(); 500 } 501 else 502 { 503 return AdministrationConnector.DEFAULT_ADMINISTRATION_CONNECTOR_PORT; 504 } 505 } 506 507 private boolean initializeConfiguration() 508 { 509 // check if the initialization is required 510 try 511 { 512 DirectoryServer.getInstance().getServerContext().getRootConfig().getAdministrationConnector(); 513 } 514 catch (Throwable th) 515 { 516 try 517 { 518 DirectoryServer.bootstrapClient(); 519 DirectoryServer.initializeJMX(); 520 DirectoryServer.getInstance().initializeConfiguration(); 521 } 522 catch (Exception ex) 523 { 524 // do nothing 525 return false; 526 } 527 } 528 configurationInitialized = true; 529 return true; 530 } 531 532 /** 533 * Returns the port to be used according to the configuration and the 534 * arguments provided by the user. This method should be called after the 535 * arguments have been parsed. 536 * 537 * @return the port to be used according to the configuration and the 538 * arguments provided by the user. 539 */ 540 public int getPortFromConfig() 541 { 542 int portNumber; 543 if (alwaysSSL()) 544 { 545 portNumber = AdministrationConnector.DEFAULT_ADMINISTRATION_CONNECTOR_PORT; 546 // Try to get the port from the config file 547 try 548 { 549 portNumber = getAdminPortFromConfig(); 550 } 551 catch (ConfigException ex) 552 { 553 // Nothing to do 554 } 555 } 556 else 557 { 558 portNumber = CliConstants.DEFAULT_SSL_PORT; 559 } 560 return portNumber; 561 } 562 563 /** 564 * Updates the default values of the port and the trust store with what is 565 * read in the configuration. 566 * 567 * @param parser 568 * The argument parser where the secure connection arguments were added. 569 */ 570 public void initArgumentsWithConfiguration(final ArgumentParser parser) { 571 try 572 { 573 portArg = createPortArgument(getPortFromConfig()); 574 trustStorePathArg = trustStorePathArgument(getTruststoreFileFromConfig()); 575 parser.replaceArgument(portArg); 576 parser.replaceArgument(trustStorePathArg); 577 } 578 catch (ConfigException | ArgumentException e) 579 { 580 logger.error(LocalizableMessage.raw( 581 "Internal error while reading arguments of this program from configuration"), e); 582 } 583 } 584 585 /** 586 * Replace the admin UID argument by a non hidden one. 587 * 588 * @param description 589 * The localized description for the non hidden admin UID argument. 590 */ 591 public void createVisibleAdminUidArgument(final LocalizableMessage description) 592 { 593 try 594 { 595 this.adminUidArg = adminUid(description); 596 } 597 catch (final ArgumentException unexpected) 598 { 599 throw new RuntimeException("Unexpected"); 600 } 601 } 602 603 private IntegerArgument createPortArgument(final int defaultValue) throws ArgumentException 604 { 605 return portArgument( 606 defaultValue, alwaysSSL ? INFO_DESCRIPTION_ADMIN_PORT.get() : INFO_DESCRIPTION_PORT.get()); 607 } 608 609 /** 610 * Return the 'keyStore' global argument. 611 * 612 * @return The 'keyStore' global argument. 613 */ 614 public StringArgument getKeyStorePathArg() { 615 return keyStorePathArg; 616 } 617 618 /** 619 * Return the 'hostName' global argument. 620 * 621 * @return The 'hostName' global argument. 622 */ 623 public StringArgument getHostNameArg() { 624 return hostNameArg; 625 } 626 627 /** 628 * Return the 'port' global argument. 629 * 630 * @return The 'port' global argument. 631 */ 632 public IntegerArgument getPortArg() { 633 return portArg; 634 } 635 636 /** 637 * Return the 'bindDN' global argument. 638 * 639 * @return The 'bindDN' global argument. 640 */ 641 public StringArgument getBindDnArg() { 642 return bindDnArg; 643 } 644 645 /** 646 * Return the 'adminUID' global argument. 647 * 648 * @return The 'adminUID' global argument. 649 */ 650 public StringArgument getAdminUidArg() { 651 return adminUidArg; 652 } 653 654 /** 655 * Return the 'bindPasswordFile' global argument. 656 * 657 * @return The 'bindPasswordFile' global argument. 658 */ 659 public FileBasedArgument getBindPasswordFileArg() { 660 return bindPasswordFileArg; 661 } 662 663 /** 664 * Return the 'bindPassword' global argument. 665 * 666 * @return The 'bindPassword' global argument. 667 */ 668 public StringArgument getBindPasswordArg() { 669 return bindPasswordArg; 670 } 671 672 /** 673 * Return the 'trustAllArg' global argument. 674 * 675 * @return The 'trustAllArg' global argument. 676 */ 677 public BooleanArgument getTrustAllArg() { 678 return trustAllArg; 679 } 680 681 /** 682 * Return the 'trustStore' global argument. 683 * 684 * @return The 'trustStore' global argument. 685 */ 686 public StringArgument getTrustStorePathArg() { 687 return trustStorePathArg; 688 } 689 690 /** 691 * Return the 'trustStorePassword' global argument. 692 * 693 * @return The 'trustStorePassword' global argument. 694 */ 695 public StringArgument getTrustStorePasswordArg() { 696 return trustStorePasswordArg; 697 } 698 699 /** 700 * Return the 'trustStorePasswordFile' global argument. 701 * 702 * @return The 'trustStorePasswordFile' global argument. 703 */ 704 public FileBasedArgument getTrustStorePasswordFileArg() { 705 return trustStorePasswordFileArg; 706 } 707 708 /** 709 * Return the 'keyStorePassword' global argument. 710 * 711 * @return The 'keyStorePassword' global argument. 712 */ 713 public StringArgument getKeyStorePasswordArg() { 714 return keyStorePasswordArg; 715 } 716 717 /** 718 * Return the 'keyStorePasswordFile' global argument. 719 * 720 * @return The 'keyStorePasswordFile' global argument. 721 */ 722 public FileBasedArgument getKeyStorePasswordFileArg() { 723 return keyStorePasswordFileArg; 724 } 725 726 /** 727 * Return the 'certNicknameArg' global argument. 728 * 729 * @return The 'certNicknameArg' global argument. 730 */ 731 public StringArgument getCertNicknameArg() { 732 return certNicknameArg; 733 } 734 735 /** 736 * Return the 'useSSLArg' global argument. 737 * 738 * @return The 'useSSLArg' global argument. 739 */ 740 public BooleanArgument getUseSSLArg() { 741 return useSSLArg; 742 } 743 744 /** 745 * Return the 'useStartTLSArg' global argument. 746 * 747 * @return The 'useStartTLSArg' global argument. 748 */ 749 public BooleanArgument getUseStartTLSArg() { 750 return useStartTLSArg; 751 } 752 753 /** 754 * Return the 'saslOption' argument. 755 * 756 * @return the 'saslOption' argument. 757 */ 758 public StringArgument getSaslOptionArg() { 759 return saslOptionArg; 760 } 761 762 /** 763 * Return the 'connectTimeout' argument. 764 * 765 * @return the 'connectTimeout' argument. 766 */ 767 public IntegerArgument getConnectTimeoutArg() { 768 return connectTimeoutArg; 769 } 770 771 /** 772 * Set the bind DN argument with the provided description. 773 * Note that this method will create a new {@link Argument} instance replacing the current one. 774 * 775 * @param description 776 * The localized description which will be used in help messages. 777 */ 778 public void setBindDnArgDescription(final LocalizableMessage description) 779 { 780 try 781 { 782 this.bindDnArg = bindDNArgument(CliConstants.DEFAULT_ROOT_USER_DN, description); 783 } 784 catch (final ArgumentException unexpected) 785 { 786 throw new RuntimeException("unexpected"); 787 } 788 } 789 790 /** 791 * Set the bind password argument. 792 * 793 * @param bindPasswordArg 794 * The argument which will replace the current one. 795 */ 796 public void setBindPasswordArgument(final StringArgument bindPasswordArg) 797 { 798 this.bindPasswordArg = bindPasswordArg; 799 } 800 801 /** 802 * Set the bind password file argument. 803 * 804 * @param bindPasswordFileArg 805 * The argument which will replace the current one. 806 */ 807 public void setBindPasswordFileArgument(final FileBasedArgument bindPasswordFileArg) 808 { 809 this.bindPasswordFileArg = bindPasswordFileArg; 810 } 811}