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.io.OutputStream; 033 import java.io.PrintStream; 034 import java.util.ArrayList; 035 import java.util.concurrent.atomic.AtomicInteger; 036 037 import org.opends.server.controls.PasswordPolicyErrorType; 038 import org.opends.server.controls.PasswordPolicyResponseControl; 039 import org.opends.server.controls.PasswordPolicyWarningType; 040 import org.opends.server.protocols.asn1.ASN1Element; 041 import org.opends.server.protocols.asn1.ASN1OctetString; 042 import org.opends.server.protocols.asn1.ASN1Sequence; 043 import org.opends.server.protocols.ldap.ExtendedRequestProtocolOp; 044 import org.opends.server.protocols.ldap.ExtendedResponseProtocolOp; 045 import org.opends.server.protocols.ldap.LDAPControl; 046 import org.opends.server.protocols.ldap.LDAPMessage; 047 import org.opends.server.protocols.ldap.LDAPResultCode; 048 import org.opends.server.protocols.ldap.UnbindRequestProtocolOp; 049 import org.opends.server.types.DN; 050 import org.opends.server.types.NullOutputStream; 051 import org.opends.server.util.EmbeddedUtils; 052 import org.opends.server.util.args.ArgumentException; 053 import org.opends.server.util.args.ArgumentParser; 054 import org.opends.server.util.args.BooleanArgument; 055 import org.opends.server.util.args.FileBasedArgument; 056 import org.opends.server.util.args.IntegerArgument; 057 import org.opends.server.util.args.StringArgument; 058 059 import static org.opends.server.extensions.ExtensionsConstants.*; 060 import static org.opends.messages.ToolMessages.*; 061 import static org.opends.server.util.ServerConstants.*; 062 import static org.opends.server.util.StaticUtils.*; 063 import static org.opends.server.tools.ToolConstants.*; 064 065 066 067 /** 068 * This program provides a utility that uses the LDAP password modify extended 069 * operation to change the password for a user. It exposes the three primary 070 * options available for this operation, which are: 071 * 072 * <UL> 073 * <LI>The user identity whose password should be changed.</LI> 074 * <LI>The current password for the user.</LI> 075 * <LI>The new password for the user. 076 * </UL> 077 * 078 * All of these are optional components that may be included or omitted from the 079 * request. 080 */ 081 public class LDAPPasswordModify 082 { 083 /** 084 * The fully-qualified name of this class. 085 */ 086 private static final String CLASS_NAME = 087 "org.opends.server.tools.LDAPPasswordModify"; 088 089 090 091 092 /** 093 * Parses the command-line arguments, establishes a connection to the 094 * Directory Server, sends the password modify request, and reads the 095 * response. 096 * 097 * @param args The command-line arguments provided to this program. 098 */ 099 public static void main(String[] args) 100 { 101 int returnCode = mainPasswordModify(args, true, System.out, System.err); 102 if (returnCode != 0) 103 { 104 System.exit(filterExitCode(returnCode)); 105 } 106 } 107 108 109 110 /** 111 * Parses the command-line arguments, establishes a connection to the 112 * Directory Server, sends the password modify request, and reads the 113 * response. 114 * 115 * @param args The command-line arguments provided to this program. 116 * 117 * @return An integer value of zero if everything completed successfully, or 118 * a nonzero value if an error occurred. 119 */ 120 public static int mainPasswordModify(String[] args) 121 { 122 return mainPasswordModify(args, true, System.out, System.err); 123 } 124 125 126 127 /** 128 * Parses the command-line arguments, establishes a connection to the 129 * Directory Server, sends the password modify request, and reads the 130 * response. 131 * 132 * @param args The command-line arguments provided to this 133 * program. 134 * @param initializeServer Indicates whether to initialize the server. 135 * @param outStream The output stream to use for standard output. 136 * @param errStream The output stream to use for standard error. 137 * 138 * @return An integer value of zero if everything completed successfully, or 139 * a nonzero value if an error occurred. 140 */ 141 public static int mainPasswordModify(String[] args, boolean initializeServer, 142 OutputStream outStream, 143 OutputStream errStream) 144 { 145 PrintStream out; 146 if (outStream == null) 147 { 148 out = NullOutputStream.printStream(); 149 } 150 else 151 { 152 out = new PrintStream(outStream); 153 } 154 155 PrintStream err; 156 if (errStream == null) 157 { 158 err = NullOutputStream.printStream(); 159 } 160 else 161 { 162 err = new PrintStream(errStream); 163 } 164 165 166 // Create the arguments that will be used by this program. 167 BooleanArgument provideDNForAuthzID; 168 BooleanArgument showUsage; 169 BooleanArgument sslBlindTrust; 170 BooleanArgument useSSL; 171 BooleanArgument useStartTLS; 172 FileBasedArgument bindPWFile; 173 StringArgument certNickname = null; 174 FileBasedArgument currentPWFile; 175 FileBasedArgument newPWFile; 176 FileBasedArgument sslKeyStorePINFile; 177 FileBasedArgument sslTrustStorePINFile; 178 IntegerArgument ldapPort; 179 StringArgument authzID; 180 StringArgument bindDN; 181 StringArgument bindPW; 182 StringArgument controlStr; 183 StringArgument currentPW; 184 StringArgument ldapHost; 185 StringArgument newPW; 186 StringArgument sslKeyStore; 187 StringArgument sslKeyStorePIN; 188 StringArgument sslTrustStore; 189 StringArgument sslTrustStorePIN; 190 StringArgument propertiesFileArgument; 191 BooleanArgument noPropertiesFileArgument; 192 193 194 // Initialize the argument parser. 195 Message toolDescription = INFO_LDAPPWMOD_TOOL_DESCRIPTION.get(); 196 ArgumentParser argParser = new ArgumentParser(CLASS_NAME, toolDescription, 197 false); 198 199 try 200 { 201 propertiesFileArgument = new StringArgument("propertiesFilePath", 202 null, OPTION_LONG_PROP_FILE_PATH, 203 false, false, true, INFO_PROP_FILE_PATH_PLACEHOLDER.get(), null, null, 204 INFO_DESCRIPTION_PROP_FILE_PATH.get()); 205 argParser.addArgument(propertiesFileArgument); 206 argParser.setFilePropertiesArgument(propertiesFileArgument); 207 208 noPropertiesFileArgument = new BooleanArgument( 209 "noPropertiesFileArgument", null, OPTION_LONG_NO_PROP_FILE, 210 INFO_DESCRIPTION_NO_PROP_FILE.get()); 211 argParser.addArgument(noPropertiesFileArgument); 212 argParser.setNoPropertiesFileArgument(noPropertiesFileArgument); 213 214 ldapHost = new StringArgument("ldaphost", OPTION_SHORT_HOST, 215 OPTION_LONG_HOST, false, false, 216 true, INFO_HOST_PLACEHOLDER.get(), 217 "127.0.0.1", null, 218 INFO_LDAPPWMOD_DESCRIPTION_HOST.get()); 219 ldapHost.setPropertyName(OPTION_LONG_HOST); 220 argParser.addArgument(ldapHost); 221 222 223 ldapPort = new IntegerArgument( 224 "ldapport", OPTION_SHORT_PORT, 225 OPTION_LONG_PORT, false, false, 226 true, INFO_PORT_PLACEHOLDER.get(), 389, 227 null, true, 1, true, 228 65535, INFO_LDAPPWMOD_DESCRIPTION_PORT.get()); 229 ldapPort.setPropertyName(OPTION_LONG_PORT); 230 argParser.addArgument(ldapPort); 231 232 233 useSSL = new BooleanArgument("usessl", OPTION_SHORT_USE_SSL, 234 OPTION_LONG_USE_SSL, 235 INFO_LDAPPWMOD_DESCRIPTION_USE_SSL.get()); 236 useSSL.setPropertyName(OPTION_LONG_USE_SSL); 237 argParser.addArgument(useSSL); 238 239 240 useStartTLS = new BooleanArgument("usestarttls", OPTION_SHORT_START_TLS, 241 OPTION_LONG_START_TLS, 242 INFO_LDAPPWMOD_DESCRIPTION_USE_STARTTLS.get()); 243 useStartTLS.setPropertyName(OPTION_LONG_START_TLS); 244 argParser.addArgument(useStartTLS); 245 246 247 bindDN = new StringArgument("binddn", OPTION_SHORT_BINDDN, 248 OPTION_LONG_BINDDN, false, false, true, 249 INFO_BINDDN_PLACEHOLDER.get(), null, null, 250 INFO_LDAPPWMOD_DESCRIPTION_BIND_DN.get()); 251 bindDN.setPropertyName(OPTION_LONG_BINDDN); 252 argParser.addArgument(bindDN); 253 254 255 bindPW = new StringArgument("bindpw", OPTION_SHORT_BINDPWD, 256 OPTION_LONG_BINDPWD, false, false, 257 true, INFO_BINDPWD_PLACEHOLDER.get(), null, 258 null, 259 INFO_LDAPPWMOD_DESCRIPTION_BIND_PW.get()); 260 bindPW.setPropertyName(OPTION_LONG_BINDPWD); 261 argParser.addArgument(bindPW); 262 263 264 bindPWFile = 265 new FileBasedArgument("bindpwfile", OPTION_SHORT_BINDPWD_FILE, 266 OPTION_LONG_BINDPWD_FILE, false, 267 false, INFO_BINDPWD_FILE_PLACEHOLDER.get(), 268 null, null, 269 INFO_LDAPPWMOD_DESCRIPTION_BIND_PW_FILE.get()); 270 bindPWFile.setPropertyName(OPTION_LONG_BINDPWD_FILE); 271 argParser.addArgument(bindPWFile); 272 273 274 authzID = new StringArgument("authzid", 'a', "authzID", false, false, 275 true, INFO_PROXYAUTHID_PLACEHOLDER.get(), 276 null, null, 277 INFO_LDAPPWMOD_DESCRIPTION_AUTHZID.get()); 278 authzID.setPropertyName("authzID"); 279 argParser.addArgument(authzID); 280 281 282 provideDNForAuthzID = 283 new BooleanArgument("providednforauthzid", 'A',"provideDNForAuthzID", 284 INFO_LDAPPWMOD_DESCRIPTION_PROVIDE_DN_FOR_AUTHZID.get()); 285 provideDNForAuthzID.setPropertyName("provideDNForAuthzID"); 286 argParser.addArgument(provideDNForAuthzID); 287 288 289 newPW = new StringArgument("newpw", 'n', "newPassword", false, false, 290 true, INFO_NEW_PASSWORD_PLACEHOLDER.get(), 291 null, null, 292 INFO_LDAPPWMOD_DESCRIPTION_NEWPW.get()); 293 newPW.setPropertyName("newPassword"); 294 argParser.addArgument(newPW); 295 296 297 newPWFile = new FileBasedArgument( 298 "newpwfile", 'N', "newPasswordFile", 299 false, false, INFO_FILE_PLACEHOLDER.get(), null, null, 300 INFO_LDAPPWMOD_DESCRIPTION_NEWPWFILE.get()); 301 newPWFile.setPropertyName("newPasswordFile"); 302 argParser.addArgument(newPWFile); 303 304 305 currentPW = 306 new StringArgument("currentpw", 'c', "currentPassword", false, false, 307 true, INFO_CURRENT_PASSWORD_PLACEHOLDER.get(), 308 null, null, 309 INFO_LDAPPWMOD_DESCRIPTION_CURRENTPW.get()); 310 currentPW.setPropertyName("currentPassword"); 311 argParser.addArgument(currentPW); 312 313 314 currentPWFile = 315 new FileBasedArgument( 316 "currentpwfile", 'C', "currentPasswordFile", 317 false, false, INFO_FILE_PLACEHOLDER.get(), null, null, 318 INFO_LDAPPWMOD_DESCRIPTION_CURRENTPWFILE.get()); 319 currentPWFile.setPropertyName("currentPasswordFile"); 320 argParser.addArgument(currentPWFile); 321 322 323 sslBlindTrust = 324 new BooleanArgument("blindtrust", 'X', "trustAll", 325 INFO_LDAPPWMOD_DESCRIPTION_BLIND_TRUST.get()); 326 sslBlindTrust.setPropertyName("trustAll"); 327 argParser.addArgument(sslBlindTrust); 328 329 330 sslKeyStore = 331 new StringArgument("keystorepath", OPTION_SHORT_KEYSTOREPATH, 332 OPTION_LONG_KEYSTOREPATH, false, false, 333 true, INFO_KEYSTOREPATH_PLACEHOLDER.get(), null, 334 null, 335 INFO_LDAPPWMOD_DESCRIPTION_KEYSTORE.get()); 336 sslKeyStore.setPropertyName(OPTION_LONG_KEYSTOREPATH); 337 argParser.addArgument(sslKeyStore); 338 339 340 sslKeyStorePIN = 341 new StringArgument("keystorepassword", 342 OPTION_SHORT_KEYSTORE_PWD, 343 OPTION_LONG_KEYSTORE_PWD , 344 false, false, true, 345 INFO_KEYSTORE_PWD_PLACEHOLDER.get(), 346 null, null, 347 INFO_LDAPPWMOD_DESCRIPTION_KEYSTORE_PIN.get()); 348 sslKeyStorePIN.setPropertyName(OPTION_LONG_KEYSTORE_PWD); 349 argParser.addArgument(sslKeyStorePIN); 350 351 352 sslKeyStorePINFile = 353 new FileBasedArgument( 354 "keystorepasswordfile", 355 OPTION_SHORT_KEYSTORE_PWD_FILE, 356 OPTION_LONG_KEYSTORE_PWD_FILE, 357 false, false, INFO_KEYSTORE_PWD_FILE_PLACEHOLDER.get(), 358 null, null, 359 INFO_LDAPPWMOD_DESCRIPTION_KEYSTORE_PINFILE.get()); 360 sslKeyStorePINFile.setPropertyName(OPTION_LONG_KEYSTORE_PWD_FILE); 361 argParser.addArgument(sslKeyStorePINFile); 362 363 certNickname = new StringArgument("certnickname", null, "certNickname", 364 false, false, true, INFO_NICKNAME_PLACEHOLDER.get(), null, null, 365 INFO_DESCRIPTION_CERT_NICKNAME.get()); 366 certNickname.setPropertyName("certNickname"); 367 argParser.addArgument(certNickname); 368 369 370 371 sslTrustStore = 372 new StringArgument("truststorepath", 373 OPTION_SHORT_TRUSTSTOREPATH, 374 OPTION_LONG_TRUSTSTOREPATH, false, 375 false, true, 376 INFO_TRUSTSTOREPATH_PLACEHOLDER.get(), null, null, 377 INFO_LDAPPWMOD_DESCRIPTION_TRUSTSTORE.get()); 378 sslTrustStore.setPropertyName(OPTION_LONG_TRUSTSTOREPATH); 379 argParser.addArgument(sslTrustStore); 380 381 382 sslTrustStorePIN = 383 new StringArgument("truststorepassword", null, 384 OPTION_LONG_TRUSTSTORE_PWD, 385 false, false, true, 386 INFO_TRUSTSTORE_PWD_PLACEHOLDER.get(), null, null, 387 INFO_LDAPPWMOD_DESCRIPTION_TRUSTSTORE_PIN.get()); 388 sslTrustStorePIN.setPropertyName(OPTION_LONG_TRUSTSTORE_PWD); 389 argParser.addArgument(sslTrustStorePIN); 390 391 392 sslTrustStorePINFile = 393 new FileBasedArgument("truststorepasswordfile", 394 OPTION_SHORT_TRUSTSTORE_PWD_FILE, 395 OPTION_LONG_TRUSTSTORE_PWD_FILE, false, false, 396 INFO_TRUSTSTORE_PWD_FILE_PLACEHOLDER.get(), null, 397 null, INFO_LDAPPWMOD_DESCRIPTION_TRUSTSTORE_PINFILE.get()); 398 sslTrustStorePINFile.setPropertyName(OPTION_LONG_TRUSTSTORE_PWD_FILE); 399 argParser.addArgument(sslTrustStorePINFile); 400 401 402 controlStr = 403 new StringArgument("control", 'J', "control", false, true, true, 404 INFO_LDAP_CONTROL_PLACEHOLDER.get(), 405 null, null, INFO_DESCRIPTION_CONTROLS.get()); 406 controlStr.setPropertyName("control"); 407 argParser.addArgument(controlStr); 408 409 410 showUsage = new BooleanArgument("help", OPTION_SHORT_HELP, 411 OPTION_LONG_HELP, 412 INFO_DESCRIPTION_USAGE.get()); 413 argParser.addArgument(showUsage); 414 argParser.setUsageArgument(showUsage, out); 415 } 416 catch (ArgumentException ae) 417 { 418 Message message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage()); 419 420 err.println(wrapText(message, MAX_LINE_WIDTH)); 421 return 1; 422 } 423 424 425 // Parse the command-line arguments provided to this program. 426 try 427 { 428 argParser.parseArguments(args); 429 } 430 catch (ArgumentException ae) 431 { 432 Message message = ERR_ERROR_PARSING_ARGS.get(ae.getMessage()); 433 434 err.println(wrapText(message, MAX_LINE_WIDTH)); 435 err.println(argParser.getUsage()); 436 return 1; 437 } 438 439 440 // If the usage or version argument was provided, 441 // then we don't need to do anything else. 442 if (argParser.usageOrVersionDisplayed()) 443 { 444 return 0; 445 } 446 447 448 // Make sure that the user didn't specify any conflicting arguments. 449 if (bindPW.isPresent() && bindPWFile.isPresent()) 450 { 451 Message message = ERR_LDAPPWMOD_CONFLICTING_ARGS.get( 452 bindPW.getLongIdentifier(), 453 bindPWFile.getLongIdentifier()); 454 err.println(wrapText(message, MAX_LINE_WIDTH)); 455 return 1; 456 } 457 458 if (newPW.isPresent() && newPWFile.isPresent()) 459 { 460 Message message = ERR_LDAPPWMOD_CONFLICTING_ARGS.get( 461 newPW.getLongIdentifier(), 462 newPWFile.getLongIdentifier()); 463 err.println(wrapText(message, MAX_LINE_WIDTH)); 464 return 1; 465 } 466 467 if (currentPW.isPresent() && currentPWFile.isPresent()) 468 { 469 Message message = ERR_LDAPPWMOD_CONFLICTING_ARGS.get( 470 currentPW.getLongIdentifier(), 471 currentPWFile.getLongIdentifier()); 472 err.println(wrapText(message, MAX_LINE_WIDTH)); 473 return 1; 474 } 475 476 if (useSSL.isPresent() && useStartTLS.isPresent()) 477 { 478 Message message = ERR_LDAPPWMOD_CONFLICTING_ARGS.get( 479 useSSL.getLongIdentifier(), 480 useStartTLS.getLongIdentifier()); 481 err.println(wrapText(message, MAX_LINE_WIDTH)); 482 return 1; 483 } 484 485 if (sslKeyStorePIN.isPresent() && sslKeyStorePINFile.isPresent()) 486 { 487 Message message = ERR_TOOL_CONFLICTING_ARGS.get( 488 sslKeyStorePIN.getLongIdentifier(), 489 sslKeyStorePINFile.getLongIdentifier()); 490 err.println(wrapText(message, MAX_LINE_WIDTH)); 491 return 1; 492 } 493 494 if (sslTrustStorePIN.isPresent() && sslTrustStorePINFile.isPresent()) 495 { 496 Message message = ERR_TOOL_CONFLICTING_ARGS.get( 497 sslTrustStorePIN.getLongIdentifier(), 498 sslTrustStorePINFile.getLongIdentifier()); 499 err.println(wrapText(message, MAX_LINE_WIDTH)); 500 return 1; 501 } 502 503 504 // If a bind DN was provided, make sure that a password was given. If a 505 // password was given, make sure a bind DN was provided. If neither were 506 // given, then make sure that an authorization ID and the current password 507 // were provided. 508 if (bindDN.isPresent()) 509 { 510 if (! (bindPW.isPresent() || bindPWFile.isPresent())) 511 { 512 Message message = ERR_LDAPPWMOD_BIND_DN_AND_PW_MUST_BE_TOGETHER.get(); 513 514 err.println(wrapText(message, MAX_LINE_WIDTH)); 515 err.println(argParser.getUsage()); 516 return 1; 517 } 518 } 519 else if (bindPW.isPresent() || bindPWFile.isPresent()) 520 { 521 Message message = ERR_LDAPPWMOD_BIND_DN_AND_PW_MUST_BE_TOGETHER.get(); 522 523 err.println(wrapText(message, MAX_LINE_WIDTH)); 524 err.println(argParser.getUsage()); 525 return 1; 526 } 527 else 528 { 529 if (provideDNForAuthzID.isPresent()) 530 { 531 Message message = 532 ERR_LDAPPWMOD_DEPENDENT_ARGS.get( 533 provideDNForAuthzID.getLongIdentifier(), 534 bindDN.getLongIdentifier()); 535 err.println(wrapText(message, MAX_LINE_WIDTH)); 536 err.println(argParser.getUsage()); 537 return 1; 538 } 539 540 if (! (authzID.isPresent() && 541 (currentPW.isPresent() || currentPWFile.isPresent()))) 542 { 543 Message message = 544 ERR_LDAPPWMOD_ANON_REQUIRES_AUTHZID_AND_CURRENTPW.get(); 545 err.println(wrapText(message, MAX_LINE_WIDTH)); 546 err.println(argParser.getUsage()); 547 return 1; 548 } 549 } 550 551 552 // Get the host and port. 553 String host = ldapHost.getValue(); 554 int port; 555 try 556 { 557 port = ldapPort.getIntValue(); 558 } 559 catch (Exception e) 560 { 561 // This should never happen. 562 err.println(e); 563 return 1; 564 } 565 566 567 // If a control string was provided, then decode the requested controls. 568 ArrayList<LDAPControl> controls = new ArrayList<LDAPControl>(); 569 if(controlStr.isPresent()) 570 { 571 for (String ctrlString : controlStr.getValues()) 572 { 573 LDAPControl ctrl = LDAPToolUtils.getControl(ctrlString, err); 574 if(ctrl == null) 575 { 576 Message message = ERR_TOOL_INVALID_CONTROL_STRING.get(ctrlString); 577 err.println(wrapText(message, MAX_LINE_WIDTH)); 578 err.println(argParser.getUsage()); 579 return 1; 580 } 581 controls.add(ctrl); 582 } 583 } 584 585 586 // Perform a basic Directory Server bootstrap if appropriate. 587 if (initializeServer) 588 { 589 EmbeddedUtils.initializeForClientUse(); 590 } 591 592 593 // Establish a connection to the Directory Server. 594 AtomicInteger nextMessageID = new AtomicInteger(1); 595 LDAPConnectionOptions connectionOptions = new LDAPConnectionOptions(); 596 connectionOptions.setUseSSL(useSSL.isPresent()); 597 connectionOptions.setStartTLS(useStartTLS.isPresent()); 598 connectionOptions.setVersionNumber(3); 599 if(connectionOptions.useSSL() || connectionOptions.useStartTLS()) 600 { 601 String keyPIN = null; 602 if (sslKeyStorePIN.isPresent()) 603 { 604 keyPIN = sslKeyStorePIN.getValue(); 605 } 606 else if (sslKeyStorePINFile.isPresent()) 607 { 608 keyPIN = sslKeyStorePINFile.getValue(); 609 } 610 611 String trustPIN = null; 612 if (sslTrustStorePIN.isPresent()) 613 { 614 trustPIN = sslTrustStorePIN.getValue(); 615 } 616 else if (sslTrustStorePINFile.isPresent()) 617 { 618 trustPIN = sslTrustStorePINFile.getValue(); 619 } 620 621 try 622 { 623 String clientAlias; 624 if (certNickname.isPresent()) 625 { 626 clientAlias = certNickname.getValue(); 627 } 628 else 629 { 630 clientAlias = null; 631 } 632 SSLConnectionFactory sslConnectionFactory = new SSLConnectionFactory(); 633 sslConnectionFactory.init(sslBlindTrust.isPresent(), 634 sslKeyStore.getValue(), keyPIN, clientAlias, 635 sslTrustStore.getValue(), trustPIN); 636 connectionOptions.setSSLConnectionFactory(sslConnectionFactory); 637 } 638 catch (Exception e) 639 { 640 Message message = 641 ERR_LDAPPWMOD_ERROR_INITIALIZING_SSL.get(String.valueOf(e)); 642 err.println(wrapText(message, MAX_LINE_WIDTH)); 643 return 1; 644 } 645 } 646 647 LDAPConnection connection = new LDAPConnection(host, port, 648 connectionOptions, out, err); 649 String dn; 650 String pw; 651 if (bindPW.isPresent()) 652 { 653 dn = bindDN.getValue(); 654 pw = bindPW.getValue(); 655 } 656 else if (bindPWFile.isPresent()) 657 { 658 dn = bindDN.getValue(); 659 pw = bindPWFile.getValue(); 660 } 661 else 662 { 663 dn = null; 664 pw = null; 665 } 666 667 try 668 { 669 connection.connectToHost(dn, pw, nextMessageID); 670 } 671 catch (LDAPConnectionException lce) 672 { 673 Message message = ERR_LDAPPWMOD_CANNOT_CONNECT.get(lce.getMessage()); 674 err.println(wrapText(message, MAX_LINE_WIDTH)); 675 return lce.getResultCode(); 676 } 677 678 LDAPReader reader = connection.getLDAPReader(); 679 LDAPWriter writer = connection.getLDAPWriter(); 680 681 682 // Construct the password modify request. 683 ArrayList<ASN1Element> requestElements = new ArrayList<ASN1Element>(3); 684 if (authzID.isPresent()) 685 { 686 requestElements.add(new ASN1OctetString(TYPE_PASSWORD_MODIFY_USER_ID, 687 authzID.getValue())); 688 } 689 else if (provideDNForAuthzID.isPresent()) 690 { 691 requestElements.add(new ASN1OctetString(TYPE_PASSWORD_MODIFY_USER_ID, 692 "dn:" + dn)); 693 } 694 695 if (currentPW.isPresent()) 696 { 697 requestElements.add(new ASN1OctetString(TYPE_PASSWORD_MODIFY_OLD_PASSWORD, 698 currentPW.getValue())); 699 } 700 else if (currentPWFile.isPresent()) 701 { 702 requestElements.add(new ASN1OctetString(TYPE_PASSWORD_MODIFY_OLD_PASSWORD, 703 currentPWFile.getValue())); 704 } 705 else if (provideDNForAuthzID.isPresent()) 706 { 707 requestElements.add(new ASN1OctetString(TYPE_PASSWORD_MODIFY_OLD_PASSWORD, 708 pw)); 709 } 710 711 if (newPW.isPresent()) 712 { 713 requestElements.add(new ASN1OctetString(TYPE_PASSWORD_MODIFY_NEW_PASSWORD, 714 newPW.getValue())); 715 } 716 else if (newPWFile.isPresent()) 717 { 718 requestElements.add(new ASN1OctetString(TYPE_PASSWORD_MODIFY_NEW_PASSWORD, 719 newPWFile.getValue())); 720 } 721 722 ASN1OctetString requestValue = 723 new ASN1OctetString(new ASN1Sequence(requestElements).encode()); 724 725 ExtendedRequestProtocolOp extendedRequest = 726 new ExtendedRequestProtocolOp(OID_PASSWORD_MODIFY_REQUEST, 727 requestValue); 728 LDAPMessage requestMessage = 729 new LDAPMessage(nextMessageID.getAndIncrement(), extendedRequest, 730 controls); 731 732 733 // Send the request to the server and read the response. 734 try 735 { 736 writer.writeMessage(requestMessage); 737 } 738 catch (Exception e) 739 { 740 Message message = ERR_LDAPPWMOD_CANNOT_SEND_PWMOD_REQUEST.get( 741 String.valueOf(e)); 742 err.println(wrapText(message, MAX_LINE_WIDTH)); 743 744 try 745 { 746 requestMessage = new LDAPMessage(nextMessageID.getAndIncrement(), 747 new UnbindRequestProtocolOp()); 748 writer.writeMessage(requestMessage); 749 } 750 catch (Exception e2) {} 751 752 try 753 { 754 reader.close(); 755 writer.close(); 756 } catch (Exception e2) {} 757 758 return 1; 759 } 760 761 762 // Read the response from the server. 763 LDAPMessage responseMessage = null; 764 try 765 { 766 responseMessage = reader.readMessage(); 767 } 768 catch (Exception e) 769 { 770 Message message = ERR_LDAPPWMOD_CANNOT_READ_PWMOD_RESPONSE.get( 771 String.valueOf(e)); 772 err.println(wrapText(message, MAX_LINE_WIDTH)); 773 774 try 775 { 776 requestMessage = new LDAPMessage(nextMessageID.getAndIncrement(), 777 new UnbindRequestProtocolOp()); 778 writer.writeMessage(requestMessage); 779 } 780 catch (Exception e2) {} 781 782 try 783 { 784 reader.close(); 785 writer.close(); 786 } catch (Exception e2) {} 787 788 return 1; 789 } 790 791 792 // Make sure that the response was acceptable. 793 ExtendedResponseProtocolOp extendedResponse = 794 responseMessage.getExtendedResponseProtocolOp(); 795 int resultCode = extendedResponse.getResultCode(); 796 if (resultCode != LDAPResultCode.SUCCESS) 797 { 798 Message message = ERR_LDAPPWMOD_FAILED.get(resultCode); 799 err.println(wrapText(message, MAX_LINE_WIDTH)); 800 801 Message errorMessage = extendedResponse.getErrorMessage(); 802 if ((errorMessage != null) && (errorMessage.length() > 0)) 803 { 804 805 message = ERR_LDAPPWMOD_FAILURE_ERROR_MESSAGE.get(errorMessage); 806 err.println(wrapText(message, MAX_LINE_WIDTH)); 807 } 808 809 DN matchedDN = extendedResponse.getMatchedDN(); 810 if (matchedDN != null) 811 { 812 813 message = ERR_LDAPPWMOD_FAILURE_MATCHED_DN.get(matchedDN.toString()); 814 err.println(wrapText(message, MAX_LINE_WIDTH)); 815 } 816 817 try 818 { 819 requestMessage = new LDAPMessage(nextMessageID.getAndIncrement(), 820 new UnbindRequestProtocolOp()); 821 writer.writeMessage(requestMessage); 822 } 823 catch (Exception e) {} 824 825 try 826 { 827 reader.close(); 828 writer.close(); 829 } catch (Exception e) {} 830 831 return resultCode; 832 } 833 else 834 { 835 Message message = INFO_LDAPPWMOD_SUCCESSFUL.get(); 836 out.println(wrapText(message, MAX_LINE_WIDTH)); 837 838 Message additionalInfo = extendedResponse.getErrorMessage(); 839 if ((additionalInfo != null) && (additionalInfo.length() > 0)) 840 { 841 842 message = INFO_LDAPPWMOD_ADDITIONAL_INFO.get(additionalInfo); 843 out.println(wrapText(message, MAX_LINE_WIDTH)); 844 } 845 } 846 847 848 // See if the response included any controls that we recognize, and if so 849 // then handle them. 850 ArrayList<LDAPControl> responseControls = responseMessage.getControls(); 851 if (responseControls != null) 852 { 853 for (LDAPControl c : responseControls) 854 { 855 if (c.getOID().equals(OID_PASSWORD_POLICY_CONTROL)) 856 { 857 try 858 { 859 PasswordPolicyResponseControl pwPolicyControl = 860 PasswordPolicyResponseControl.decodeControl(c.getControl()); 861 862 PasswordPolicyWarningType pwPolicyWarningType = 863 pwPolicyControl.getWarningType(); 864 if (pwPolicyWarningType != null) 865 { 866 Message message = INFO_LDAPPWMOD_PWPOLICY_WARNING.get( 867 pwPolicyWarningType.toString(), 868 pwPolicyControl.getWarningValue()); 869 out.println(wrapText(message, MAX_LINE_WIDTH)); 870 } 871 872 PasswordPolicyErrorType pwPolicyErrorType = 873 pwPolicyControl.getErrorType(); 874 if (pwPolicyErrorType != null) 875 { 876 Message message = INFO_LDAPPWMOD_PWPOLICY_ERROR.get( 877 pwPolicyErrorType.toString()); 878 out.println(wrapText(message, MAX_LINE_WIDTH)); 879 } 880 } 881 catch (Exception e) 882 { 883 Message message = ERR_LDAPPWMOD_CANNOT_DECODE_PWPOLICY_CONTROL.get( 884 String.valueOf(e)); 885 err.println(wrapText(message, MAX_LINE_WIDTH)); 886 } 887 } 888 } 889 } 890 891 892 // See if the response included a generated password. 893 ASN1OctetString responseValue = extendedResponse.getValue(); 894 if (responseValue != null) 895 { 896 try 897 { 898 ASN1Sequence responseSequence = 899 ASN1Sequence.decodeAsSequence(responseValue.value()); 900 for (ASN1Element e : responseSequence.elements()) 901 { 902 if (e.getType() == TYPE_PASSWORD_MODIFY_GENERATED_PASSWORD) 903 { 904 Message message = INFO_LDAPPWMOD_GENERATED_PASSWORD.get( 905 e.decodeAsOctetString().stringValue()); 906 out.println(wrapText(message, MAX_LINE_WIDTH)); 907 } 908 else 909 { 910 Message message = ERR_LDAPPWMOD_UNRECOGNIZED_VALUE_TYPE.get( 911 byteToHex(e.getType())); 912 err.println(wrapText(message, MAX_LINE_WIDTH)); 913 } 914 } 915 } 916 catch (Exception e) 917 { 918 Message message = ERR_LDAPPWMOD_COULD_NOT_DECODE_RESPONSE_VALUE.get( 919 String.valueOf(e)); 920 err.println(wrapText(message, MAX_LINE_WIDTH)); 921 922 try 923 { 924 requestMessage = new LDAPMessage(nextMessageID.getAndIncrement(), 925 new UnbindRequestProtocolOp()); 926 writer.writeMessage(requestMessage); 927 } 928 catch (Exception e2) {} 929 930 try 931 { 932 reader.close(); 933 writer.close(); 934 } catch (Exception e2) {} 935 936 return 1; 937 } 938 } 939 940 941 // Unbind from the server and close the connection. 942 try 943 { 944 requestMessage = new LDAPMessage(nextMessageID.getAndIncrement(), 945 new UnbindRequestProtocolOp()); 946 writer.writeMessage(requestMessage); 947 } 948 catch (Exception e) {} 949 950 try 951 { 952 reader.close(); 953 writer.close(); 954 } catch (Exception e) {} 955 956 return 0; 957 } 958 } 959