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 2006-2009 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_BINDPWD_FILE_PLACEHOLDER; 021import static com.forgerock.opendj.cli.CliMessages.INFO_KEYSTORE_PWD_FILE_PLACEHOLDER; 022import static com.forgerock.opendj.cli.CliMessages.INFO_PORT_PLACEHOLDER; 023import static com.forgerock.opendj.cli.CliMessages.INFO_TRUSTSTORE_PWD_FILE_PLACEHOLDER; 024import static com.forgerock.opendj.cli.Utils.*; 025import static com.forgerock.opendj.cli.CommonArguments.*; 026 027import static org.opends.messages.ToolMessages.*; 028import static org.opends.server.extensions.PasswordPolicyStateExtendedOperation.*; 029import static org.opends.server.protocols.ldap.LDAPResultCode.*; 030import static org.opends.server.util.ServerConstants.*; 031import static org.opends.server.util.StaticUtils.*; 032 033import java.io.IOException; 034import java.io.OutputStream; 035import java.io.PrintStream; 036import java.util.ArrayList; 037import java.util.HashSet; 038import java.util.LinkedList; 039import java.util.concurrent.atomic.AtomicInteger; 040 041import javax.net.ssl.SSLException; 042 043import org.forgerock.i18n.LocalizableMessage; 044import org.forgerock.opendj.io.ASN1; 045import org.forgerock.opendj.io.ASN1Reader; 046import org.forgerock.opendj.io.ASN1Writer; 047import org.forgerock.opendj.ldap.ByteStringBuilder; 048import org.opends.server.config.AdministrationConnector; 049import org.opends.server.core.DirectoryServer.DirectoryServerVersionHandler; 050import org.opends.server.loggers.JDKLogging; 051import org.opends.server.protocols.ldap.ExtendedRequestProtocolOp; 052import org.opends.server.protocols.ldap.ExtendedResponseProtocolOp; 053import org.opends.server.protocols.ldap.LDAPMessage; 054import org.opends.server.protocols.ldap.LDAPResultCode; 055import org.opends.server.types.NullOutputStream; 056import org.opends.server.util.EmbeddedUtils; 057import org.opends.server.util.cli.LDAPConnectionArgumentParser; 058 059import com.forgerock.opendj.cli.Argument; 060import com.forgerock.opendj.cli.ArgumentException; 061import com.forgerock.opendj.cli.BooleanArgument; 062import com.forgerock.opendj.cli.FileBasedArgument; 063import com.forgerock.opendj.cli.IntegerArgument; 064import com.forgerock.opendj.cli.MultiChoiceArgument; 065import com.forgerock.opendj.cli.StringArgument; 066import com.forgerock.opendj.cli.SubCommand; 067import com.forgerock.opendj.cli.SubCommandArgumentParser; 068 069/** 070 * This class provides a tool that can be used to perform various kinds of 071 * account management using the password policy state extended operation. 072 */ 073public class ManageAccount 074{ 075 /** The fully-qualified name of this class. */ 076 private static final String CLASS_NAME = 077 "org.opends.server.tools.ManageAccount"; 078 079 080 081 /** 082 * The name of the subcommand that will be used to get all password policy 083 * state information for the user. 084 */ 085 private static final String SC_GET_ALL = "get-all"; 086 087 088 089 /** 090 * The name of the subcommand that will be used to get the DN of the password 091 * policy for a given user. 092 */ 093 private static final String SC_GET_PASSWORD_POLICY_DN = 094 "get-password-policy-dn"; 095 096 097 098 /** 099 * The name of the subcommand that will be used to get the disabled state for 100 * a user. 101 */ 102 private static final String SC_GET_ACCOUNT_DISABLED_STATE = 103 "get-account-is-disabled"; 104 105 106 107 /** 108 * The name of the subcommand that will be used to set the disabled state for 109 * a user. 110 */ 111 private static final String SC_SET_ACCOUNT_DISABLED_STATE = 112 "set-account-is-disabled"; 113 114 115 116 /** 117 * The name of the subcommand that will be used to clear the disabled state 118 * for a user. 119 */ 120 private static final String SC_CLEAR_ACCOUNT_DISABLED_STATE = 121 "clear-account-is-disabled"; 122 123 124 125 /** 126 * The name of the subcommand that will be used to get the account expiration 127 * time. 128 */ 129 private static final String SC_GET_ACCOUNT_EXPIRATION_TIME = 130 "get-account-expiration-time"; 131 132 133 134 /** 135 * The name of the subcommand that will be used to set the account expiration 136 * time. 137 */ 138 private static final String SC_SET_ACCOUNT_EXPIRATION_TIME = 139 "set-account-expiration-time"; 140 141 142 143 /** 144 * The name of the subcommand that will be used to clear the account 145 * expiration time. 146 */ 147 private static final String SC_CLEAR_ACCOUNT_EXPIRATION_TIME = 148 "clear-account-expiration-time"; 149 150 151 152 /** 153 * The name of the subcommand that will be used to get the length of time 154 * before the account expires. 155 */ 156 private static final String SC_GET_SECONDS_UNTIL_ACCOUNT_EXPIRATION = 157 "get-seconds-until-account-expiration"; 158 159 160 161 /** 162 * The name of the subcommand that will be used to get the time the password 163 * was last changed. 164 */ 165 private static final String SC_GET_PASSWORD_CHANGED_TIME = 166 "get-password-changed-time"; 167 168 169 170 /** 171 * The name of the subcommand that will be used to set the time the password 172 * was last changed. 173 */ 174 private static final String SC_SET_PASSWORD_CHANGED_TIME = 175 "set-password-changed-time"; 176 177 178 179 /** 180 * The name of the subcommand that will be used to clear the time the password 181 * was last changed. 182 */ 183 private static final String SC_CLEAR_PASSWORD_CHANGED_TIME = 184 "clear-password-changed-time"; 185 186 187 188 /** 189 * The name of the subcommand that will be used to get the time the user was 190 * first warned about an upcoming password expiration. 191 */ 192 private static final String SC_GET_PASSWORD_EXP_WARNED_TIME = 193 "get-password-expiration-warned-time"; 194 195 196 197 /** 198 * The name of the subcommand that will be used to set the time the user was 199 * first warned about an upcoming password expiration. 200 */ 201 private static final String SC_SET_PASSWORD_EXP_WARNED_TIME = 202 "set-password-expiration-warned-time"; 203 204 205 206 /** 207 * The name of the subcommand that will be used to clear the time the user was 208 * first warned about an upcoming password expiration. 209 */ 210 private static final String SC_CLEAR_PASSWORD_EXP_WARNED_TIME = 211 "clear-password-expiration-warned-time"; 212 213 214 215 /** 216 * The name of the subcommand that will be used to get the length of time 217 * before the password expires. 218 */ 219 private static final String SC_GET_SECONDS_UNTIL_PASSWORD_EXPIRATION = 220 "get-seconds-until-password-expiration"; 221 222 223 224 /** 225 * The name of the subcommand that will be used to get the length of time 226 * before the user is first warned about an upcoming password expiration. 227 */ 228 private static final String SC_GET_SECONDS_UNTIL_PASSWORD_EXPIRATION_WARNING = 229 "get-seconds-until-password-expiration-warning"; 230 231 232 233 /** 234 * The name of the subcommand that will be used to get the authentication 235 * failure times for the user. 236 */ 237 private static final String SC_GET_AUTHENTICATION_FAILURE_TIMES = 238 "get-authentication-failure-times"; 239 240 241 242 /** 243 * The name of the subcommand that will be used to add an authentication 244 * failure time for the user. 245 */ 246 private static final String SC_ADD_AUTHENTICATION_FAILURE_TIME = 247 "add-authentication-failure-time"; 248 249 250 251 /** 252 * The name of the subcommand that will be used to set the authentication 253 * failure times for the user. 254 */ 255 private static final String SC_SET_AUTHENTICATION_FAILURE_TIMES = 256 "set-authentication-failure-times"; 257 258 259 260 /** 261 * The name of the subcommand that will be used to clear the authentication 262 * failure times for the user. 263 */ 264 private static final String SC_CLEAR_AUTHENTICATION_FAILURE_TIMES = 265 "clear-authentication-failure-times"; 266 267 268 269 /** 270 * The name of the subcommand that will be used to get the length of time 271 * before the user's account is unlocked. 272 */ 273 private static final String 274 SC_GET_SECONDS_UNTIL_AUTHENTICATION_FAILURE_UNLOCK = 275 "get-seconds-until-authentication-failure-unlock"; 276 277 278 279 /** 280 * The name of the subcommand that will be used to get the number of remaining 281 * authentication failures for the user. 282 */ 283 private static final String SC_GET_REMAINING_AUTHENTICATION_FAILURE_COUNT = 284 "get-remaining-authentication-failure-count"; 285 286 287 288 /** 289 * The name of the subcommand that will be used to get the last login time for 290 * the user. 291 */ 292 private static final String SC_GET_LAST_LOGIN_TIME = 293 "get-last-login-time"; 294 295 296 297 /** 298 * The name of the subcommand that will be used to set the last login time for 299 * the user. 300 */ 301 private static final String SC_SET_LAST_LOGIN_TIME = 302 "set-last-login-time"; 303 304 305 306 /** 307 * The name of the subcommand that will be used to clear the last login time 308 * for the user. 309 */ 310 private static final String SC_CLEAR_LAST_LOGIN_TIME = 311 "clear-last-login-time"; 312 313 314 315 /** 316 * The name of the subcommand that will be used to get the length of time 317 * before the account is idle locked. 318 */ 319 private static final String SC_GET_SECONDS_UNTIL_IDLE_LOCKOUT = 320 "get-seconds-until-idle-lockout"; 321 322 323 324 /** 325 * The name of the subcommand that will be used to get the password reset 326 * state for a user. 327 */ 328 private static final String SC_GET_PASSWORD_RESET_STATE = 329 "get-password-is-reset"; 330 331 332 333 /** 334 * The name of the subcommand that will be used to set the password reset 335 * state for a user. 336 */ 337 private static final String SC_SET_PASSWORD_RESET_STATE = 338 "set-password-is-reset"; 339 340 341 342 /** 343 * The name of the subcommand that will be used to clear the password reset 344 * state for a user. 345 */ 346 private static final String SC_CLEAR_PASSWORD_RESET_STATE = 347 "clear-password-is-reset"; 348 349 350 351 /** 352 * The name of the subcommand that will be used to get the length of time 353 * before the password reset lockout occurs. 354 */ 355 private static final String SC_GET_SECONDS_UNTIL_PASSWORD_RESET_LOCKOUT = 356 "get-seconds-until-password-reset-lockout"; 357 358 359 360 /** 361 * The name of the subcommand that will be used to get the grace login use 362 * times for the user. 363 */ 364 private static final String SC_GET_GRACE_LOGIN_USE_TIMES = 365 "get-grace-login-use-times"; 366 367 368 369 /** 370 * The name of the subcommand that will be used to add a grace login use time 371 * for the user. 372 */ 373 private static final String SC_ADD_GRACE_LOGIN_USE_TIME = 374 "add-grace-login-use-time"; 375 376 377 378 /** 379 * The name of the subcommand that will be used to set the grace login use 380 * times for the user. 381 */ 382 private static final String SC_SET_GRACE_LOGIN_USE_TIMES = 383 "set-grace-login-use-times"; 384 385 386 387 /** 388 * The name of the subcommand that will be used to clear the grace login use 389 * times for the user. 390 */ 391 private static final String SC_CLEAR_GRACE_LOGIN_USE_TIMES = 392 "clear-grace-login-use-times"; 393 394 395 396 /** 397 * The name of the subcommand that will be used to get number of remaining 398 * grace logins for the user. 399 */ 400 private static final String SC_GET_REMAINING_GRACE_LOGIN_COUNT = 401 "get-remaining-grace-login-count"; 402 403 404 405 /** 406 * The name of the subcommand that will be used to get the password changed by 407 * required time for the user. 408 */ 409 private static final String SC_GET_PASSWORD_CHANGED_BY_REQUIRED_TIME = 410 "get-password-changed-by-required-time"; 411 412 413 414 /** 415 * The name of the subcommand that will be used to set the password changed by 416 * required time for the user. 417 */ 418 private static final String SC_SET_PASSWORD_CHANGED_BY_REQUIRED_TIME = 419 "set-password-changed-by-required-time"; 420 421 422 423 /** 424 * The name of the subcommand that will be used to clear the password changed 425 * by required time for the user. 426 */ 427 private static final String SC_CLEAR_PASSWORD_CHANGED_BY_REQUIRED_TIME = 428 "clear-password-changed-by-required-time"; 429 430 431 432 /** 433 * The name of the subcommand that will be used to get the length of time 434 * before the user is required to change his/her password due to the required 435 * change time. 436 */ 437 private static final String SC_GET_SECONDS_UNTIL_REQUIRED_CHANGE_TIME = 438 "get-seconds-until-required-change-time"; 439 440 441 442 /** 443 * The name of the subcommand that will be used to get the password history 444 * state values. 445 */ 446 private static final String SC_GET_PASSWORD_HISTORY = "get-password-history"; 447 448 449 450 /** 451 * The name of the subcommand that will be used to clear the password history 452 * state values. 453 */ 454 private static final String SC_CLEAR_PASSWORD_HISTORY = 455 "clear-password-history"; 456 457 458 459 /** 460 * The name of the argument that will be used for holding the value(s) to use 461 * for the target operation. 462 */ 463 private static final String ARG_OP_VALUE = "operationValue"; 464 465 466 467 /** 468 * The value that will be used when encoding a password policy state operation 469 * that should not have any values. 470 */ 471 private static final String NO_VALUE = null; 472 473 474 475 /** The LDAP reader used to read responses from the server. */ 476 private static LDAPReader ldapReader; 477 478 /** The LDAP writer used to send requests to the server. */ 479 private static LDAPWriter ldapWriter; 480 481 /** The counter that will be used for LDAP message IDs. */ 482 private static AtomicInteger nextMessageID; 483 484 /** The connection to the server. */ 485 private static LDAPConnection connection; 486 487 /** The print stream to use when writing messages to standard error. */ 488 private static PrintStream err; 489 490 /** The print stream to use when writing messages to standard output. */ 491 private static PrintStream out; 492 493 /** The DN of the user to target with the operation. */ 494 private static String targetDNString; 495 496 /** The argument parser for this tool. */ 497 private static SubCommandArgumentParser argParser; 498 499 500 501 /** 502 * Parses the command-line arguments, connects to the server, and performs the 503 * appropriate processing. 504 * 505 * @param args The command-line arguments provided to this program. 506 */ 507 public static void main(String[] args) 508 { 509 int returnCode = main(args, true, System.out, System.err); 510 if (returnCode != 0) 511 { 512 System.exit(filterExitCode(returnCode)); 513 } 514 } 515 516 517 518 /** 519 * Parses the command-line arguments, connects to the server, and performs the 520 * appropriate processing. 521 * 522 * @param args The command-line arguments provided to this program. 523 * @param initServer Indicates whether to initialize the server. 524 * @param outStream The output stream to use for standard output, or 525 * {@code null} if standard output is not needed. 526 * @param errStream The output stream to use for standard error, or 527 * {@code null} if standard error is not needed. 528 * 529 * @return A result code indicating whether the processing was successful. 530 */ 531 public static int main(String[] args, Boolean initServer, 532 OutputStream outStream, OutputStream errStream) 533 { 534 out = NullOutputStream.wrapOrNullStream(outStream); 535 err = NullOutputStream.wrapOrNullStream(errStream); 536 JDKLogging.disableLogging(); 537 538 // Parse the command-line arguments provided to the program. 539 int result = parseArgsAndConnect(args, initServer); 540 if (result < 0) 541 { 542 // This should only happen if we're only displaying usage information or 543 // doing something else other than actually running the tool. 544 return LDAPResultCode.SUCCESS; 545 } 546 else if (result != LDAPResultCode.SUCCESS) 547 { 548 return result; 549 } 550 551 552 try 553 { 554 ByteStringBuilder builder = new ByteStringBuilder(); 555 ASN1Writer writer = ASN1.getWriter(builder); 556 557 try 558 { 559 writer.writeStartSequence(); 560 writer.writeOctetString(targetDNString); 561 562 // Use the subcommand provided to figure out how to encode the request. 563 writer.writeStartSequence(); 564 result = processSubcommand(writer); 565 if (result != LDAPResultCode.SUCCESS) 566 { 567 return result; 568 } 569 writer.writeEndSequence(); 570 571 writer.writeEndSequence(); 572 } 573 catch(Exception e) 574 { 575 // TODO: Better message 576 err.println(e); 577 } 578 579 580 ExtendedRequestProtocolOp extendedRequest = 581 new ExtendedRequestProtocolOp(OID_PASSWORD_POLICY_STATE_EXTOP, 582 builder.toByteString()); 583 584 LDAPMessage requestMessage = 585 new LDAPMessage(nextMessageID.getAndIncrement(), extendedRequest); 586 587 try 588 { 589 ldapWriter.writeMessage(requestMessage); 590 } 591 catch (Exception e) 592 { 593 printWrappedText(err, ERR_PWPSTATE_CANNOT_SEND_REQUEST_EXTOP.get(getExceptionMessage(e))); 594 return CLIENT_SIDE_SERVER_DOWN; 595 } 596 597 598 // Read the response from the server. 599 try 600 { 601 LDAPMessage responseMessage = ldapReader.readMessage(); 602 if (responseMessage == null) 603 { 604 printWrappedText(err, ERR_PWPSTATE_CONNECTION_CLOSED_READING_RESPONSE.get()); 605 return CLIENT_SIDE_SERVER_DOWN; 606 } 607 608 ExtendedResponseProtocolOp extendedResponse = 609 responseMessage.getExtendedResponseProtocolOp(); 610 611 int resultCode = extendedResponse.getResultCode(); 612 if (resultCode != LDAPResultCode.SUCCESS) 613 { 614 printWrappedText(err, ERR_PWPSTATE_REQUEST_FAILED.get( 615 resultCode, LDAPResultCode.toString(resultCode), extendedResponse.getErrorMessage())); 616 return resultCode; 617 } 618 619 ASN1Reader reader = ASN1.getReader(extendedResponse.getValue()); 620 reader.readStartSequence(); 621 622 // Skip the target user DN element 623 reader.skipElement(); 624 reader.readStartSequence(); 625 626 while(reader.hasNextElement()) 627 { 628 // Get the response value and parse its individual elements. 629 int opType; 630 ArrayList<String> opValues; 631 632 try 633 { 634 reader.readStartSequence(); 635 opType = (int)reader.readInteger(); 636 opValues = new ArrayList<>(); 637 if (reader.hasNextElement()) 638 { 639 reader.readStartSequence(); 640 while(reader.hasNextElement()) 641 { 642 opValues.add(reader.readOctetStringAsString()); 643 } 644 reader.readEndSequence(); 645 } 646 reader.readEndSequence(); 647 } 648 catch (Exception e) 649 { 650 printWrappedText(err, ERR_PWPSTATE_CANNOT_DECODE_RESPONSE_OP.get(getExceptionMessage(e))); 651 continue; 652 } 653 654 switch (opType) 655 { 656 case OP_GET_PASSWORD_POLICY_DN: 657 LocalizableMessage message = INFO_PWPSTATE_LABEL_PASSWORD_POLICY_DN.get(); 658 printLabelAndValues(message, opValues); 659 break; 660 661 case OP_GET_ACCOUNT_DISABLED_STATE: 662 message = INFO_PWPSTATE_LABEL_ACCOUNT_DISABLED_STATE.get(); 663 printLabelAndValues(message, opValues); 664 break; 665 666 case OP_GET_ACCOUNT_EXPIRATION_TIME: 667 message = INFO_PWPSTATE_LABEL_ACCOUNT_EXPIRATION_TIME.get(); 668 printLabelAndValues(message, opValues); 669 break; 670 671 case OP_GET_SECONDS_UNTIL_ACCOUNT_EXPIRATION: 672 message = 673 INFO_PWPSTATE_LABEL_SECONDS_UNTIL_ACCOUNT_EXPIRATION.get(); 674 printLabelAndValues(message, opValues); 675 break; 676 677 case OP_GET_PASSWORD_CHANGED_TIME: 678 message = INFO_PWPSTATE_LABEL_PASSWORD_CHANGED_TIME.get(); 679 printLabelAndValues(message, opValues); 680 break; 681 682 case OP_GET_PASSWORD_EXPIRATION_WARNED_TIME: 683 message = 684 INFO_PWPSTATE_LABEL_PASSWORD_EXPIRATION_WARNED_TIME.get(); 685 printLabelAndValues(message, opValues); 686 break; 687 688 case OP_GET_SECONDS_UNTIL_PASSWORD_EXPIRATION: 689 message = 690 INFO_PWPSTATE_LABEL_SECONDS_UNTIL_PASSWORD_EXPIRATION.get(); 691 printLabelAndValues(message, opValues); 692 break; 693 694 case OP_GET_SECONDS_UNTIL_PASSWORD_EXPIRATION_WARNING: 695 message = 696 INFO_PWPSTATE_LABEL_SECONDS_UNTIL_PASSWORD_EXPIRATION_WARNING 697 .get(); 698 printLabelAndValues(message, opValues); 699 break; 700 701 case OP_GET_AUTHENTICATION_FAILURE_TIMES: 702 message = INFO_PWPSTATE_LABEL_AUTH_FAILURE_TIMES.get(); 703 printLabelAndValues(message, opValues); 704 break; 705 706 case OP_GET_SECONDS_UNTIL_AUTHENTICATION_FAILURE_UNLOCK: 707 message = 708 INFO_PWPSTATE_LABEL_SECONDS_UNTIL_AUTH_FAILURE_UNLOCK.get(); 709 printLabelAndValues(message, opValues); 710 break; 711 712 case OP_GET_REMAINING_AUTHENTICATION_FAILURE_COUNT: 713 message = INFO_PWPSTATE_LABEL_REMAINING_AUTH_FAILURE_COUNT.get(); 714 printLabelAndValues(message, opValues); 715 break; 716 717 case OP_GET_LAST_LOGIN_TIME: 718 message = INFO_PWPSTATE_LABEL_LAST_LOGIN_TIME.get(); 719 printLabelAndValues(message, opValues); 720 break; 721 722 case OP_GET_SECONDS_UNTIL_IDLE_LOCKOUT: 723 message = INFO_PWPSTATE_LABEL_SECONDS_UNTIL_IDLE_LOCKOUT.get(); 724 printLabelAndValues(message, opValues); 725 break; 726 727 case OP_GET_PASSWORD_RESET_STATE: 728 message = INFO_PWPSTATE_LABEL_PASSWORD_RESET_STATE.get(); 729 printLabelAndValues(message, opValues); 730 break; 731 732 case OP_GET_SECONDS_UNTIL_PASSWORD_RESET_LOCKOUT: 733 message = 734 INFO_PWPSTATE_LABEL_SECONDS_UNTIL_PASSWORD_RESET_LOCKOUT 735 .get(); 736 printLabelAndValues(message, opValues); 737 break; 738 739 case OP_GET_GRACE_LOGIN_USE_TIMES: 740 message = INFO_PWPSTATE_LABEL_GRACE_LOGIN_USE_TIMES.get(); 741 printLabelAndValues(message, opValues); 742 break; 743 744 case OP_GET_REMAINING_GRACE_LOGIN_COUNT: 745 message = INFO_PWPSTATE_LABEL_REMAINING_GRACE_LOGIN_COUNT.get(); 746 printLabelAndValues(message, opValues); 747 break; 748 749 case OP_GET_PASSWORD_CHANGED_BY_REQUIRED_TIME: 750 message = 751 INFO_PWPSTATE_LABEL_PASSWORD_CHANGED_BY_REQUIRED_TIME.get(); 752 printLabelAndValues(message, opValues); 753 break; 754 755 case OP_GET_SECONDS_UNTIL_REQUIRED_CHANGE_TIME: 756 message = 757 INFO_PWPSTATE_LABEL_SECONDS_UNTIL_REQUIRED_CHANGE_TIME 758 .get(); 759 printLabelAndValues(message, opValues); 760 break; 761 762 case OP_GET_PASSWORD_HISTORY: 763 message = INFO_PWPSTATE_LABEL_PASSWORD_HISTORY.get(); 764 printLabelAndValues(message, opValues); 765 break; 766 767 default: 768 message = ERR_PWPSTATE_INVALID_RESPONSE_OP_TYPE.get(opType); 769 printWrappedText(err, message); 770 break; 771 } 772 } 773 reader.readEndSequence(); 774 reader.readEndSequence(); 775 } 776 catch (Exception e) 777 { 778 printWrappedText(err, ERR_PWPSTATE_CANNOT_DECODE_RESPONSE_MESSAGE.get(getExceptionMessage(e))); 779 return CLIENT_SIDE_SERVER_DOWN; 780 } 781 782 // If we've gotten here, then everything completed successfully. 783 return 0; 784 } 785 finally 786 { 787 // Close the connection to the server if it's active. 788 if (connection != null) 789 { 790 connection.close(nextMessageID); 791 } 792 } 793 } 794 795 796 797 /** 798 * Initializes the argument parser for this tool, parses the provided 799 * arguments, and establishes a connection to the server. 800 * 801 * @param args Command arguments to parse. 802 * @param initServer Indicates whether to initialize the server. 803 * @return A result code that indicates the result of the processing. A 804 * value of zero indicates that all processing completed 805 * successfully. A value of -1 indicates that only the usage 806 * information was displayed and no further action is required. 807 */ 808 private static int parseArgsAndConnect(String[] args, Boolean initServer) 809 { 810 argParser = new SubCommandArgumentParser( 811 CLASS_NAME, INFO_PWPSTATE_TOOL_DESCRIPTION.get(), 812 false); 813 argParser.setShortToolDescription(REF_SHORT_DESC_MANAGE_ACCOUNT.get()); 814 argParser.setVersionHandler(new DirectoryServerVersionHandler()); 815 816 BooleanArgument showUsage; 817 BooleanArgument trustAll; 818 FileBasedArgument bindPWFile; 819 FileBasedArgument keyStorePWFile; 820 FileBasedArgument trustStorePWFile; 821 IntegerArgument port; 822 StringArgument bindDN; 823 StringArgument bindPW; 824 StringArgument certNickname; 825 StringArgument host; 826 StringArgument keyStoreFile; 827 StringArgument keyStorePW; 828 StringArgument saslOption; 829 StringArgument targetDN; 830 StringArgument trustStoreFile; 831 StringArgument trustStorePW; 832 BooleanArgument verbose; 833 834 try 835 { 836 host = 837 StringArgument.builder(OPTION_LONG_HOST) 838 .shortIdentifier(OPTION_SHORT_HOST) 839 .description(INFO_PWPSTATE_DESCRIPTION_HOST.get()) 840 .defaultValue("127.0.0.1") 841 .valuePlaceholder(INFO_HOST_PLACEHOLDER.get()) 842 .buildArgument(); 843 argParser.addGlobalArgument(host); 844 845 port = 846 IntegerArgument.builder(OPTION_LONG_PORT) 847 .shortIdentifier(OPTION_SHORT_PORT) 848 .description(INFO_PWPSTATE_DESCRIPTION_PORT.get()) 849 .range(1, 65535) 850 .defaultValue(AdministrationConnector.DEFAULT_ADMINISTRATION_CONNECTOR_PORT) 851 .valuePlaceholder(INFO_PORT_PLACEHOLDER.get()) 852 .buildArgument(); 853 argParser.addGlobalArgument(port); 854 855 bindDN = 856 StringArgument.builder(OPTION_LONG_BINDDN) 857 .shortIdentifier(OPTION_SHORT_BINDDN) 858 .description(INFO_PWPSTATE_DESCRIPTION_BINDDN.get()) 859 .valuePlaceholder(INFO_BINDDN_PLACEHOLDER.get()) 860 .buildArgument(); 861 argParser.addGlobalArgument(bindDN); 862 863 bindPW = 864 StringArgument.builder(OPTION_LONG_BINDPWD) 865 .shortIdentifier(OPTION_SHORT_BINDPWD) 866 .description(INFO_PWPSTATE_DESCRIPTION_BINDPW.get()) 867 .valuePlaceholder(INFO_BINDPWD_PLACEHOLDER.get()) 868 .buildArgument(); 869 argParser.addGlobalArgument(bindPW); 870 871 bindPWFile = 872 FileBasedArgument.builder(OPTION_LONG_BINDPWD_FILE) 873 .shortIdentifier(OPTION_SHORT_BINDPWD_FILE) 874 .description(INFO_PWPSTATE_DESCRIPTION_BINDPWFILE.get()) 875 .valuePlaceholder(INFO_BINDPWD_FILE_PLACEHOLDER.get()) 876 .buildArgument(); 877 argParser.addGlobalArgument(bindPWFile); 878 879 targetDN = 880 StringArgument.builder("targetDN") 881 .shortIdentifier('b') 882 .description(INFO_PWPSTATE_DESCRIPTION_TARGETDN.get()) 883 .required() 884 .valuePlaceholder(INFO_TARGETDN_PLACEHOLDER.get()) 885 .buildArgument(); 886 argParser.addGlobalArgument(targetDN); 887 888 saslOption = 889 StringArgument.builder(OPTION_LONG_SASLOPTION) 890 .shortIdentifier(OPTION_SHORT_SASLOPTION) 891 .description(INFO_PWPSTATE_DESCRIPTION_SASLOPTIONS.get()) 892 .multiValued() 893 .valuePlaceholder(INFO_SASL_OPTION_PLACEHOLDER.get()) 894 .buildArgument(); 895 argParser.addGlobalArgument(saslOption); 896 897 trustAll = trustAllArgument(); 898 argParser.addGlobalArgument(trustAll); 899 900 keyStoreFile = 901 StringArgument.builder(OPTION_LONG_KEYSTOREPATH) 902 .shortIdentifier(OPTION_SHORT_KEYSTOREPATH) 903 .description(INFO_PWPSTATE_DESCRIPTION_KSFILE.get()) 904 .valuePlaceholder(INFO_KEYSTOREPATH_PLACEHOLDER.get()) 905 .buildArgument(); 906 argParser.addGlobalArgument(keyStoreFile); 907 908 keyStorePW = 909 StringArgument.builder(OPTION_LONG_KEYSTORE_PWD) 910 .shortIdentifier(OPTION_SHORT_KEYSTORE_PWD) 911 .description(INFO_PWPSTATE_DESCRIPTION_KSPW.get()) 912 .valuePlaceholder(INFO_KEYSTORE_PWD_PLACEHOLDER.get()) 913 .buildArgument(); 914 argParser.addGlobalArgument(keyStorePW); 915 916 keyStorePWFile = 917 FileBasedArgument.builder(OPTION_LONG_KEYSTORE_PWD_FILE) 918 .shortIdentifier(OPTION_SHORT_KEYSTORE_PWD_FILE) 919 .description(INFO_PWPSTATE_DESCRIPTION_KSPWFILE.get()) 920 .valuePlaceholder(INFO_KEYSTORE_PWD_FILE_PLACEHOLDER.get()) 921 .buildArgument(); 922 argParser.addGlobalArgument(keyStorePWFile); 923 924 certNickname = 925 StringArgument.builder("certNickname") 926 .shortIdentifier('N') 927 .description(INFO_DESCRIPTION_CERT_NICKNAME.get()) 928 .valuePlaceholder(INFO_NICKNAME_PLACEHOLDER.get()) 929 .buildArgument(); 930 argParser.addGlobalArgument(certNickname); 931 932 trustStoreFile = 933 StringArgument.builder(OPTION_LONG_TRUSTSTOREPATH) 934 .shortIdentifier(OPTION_SHORT_TRUSTSTOREPATH) 935 .description(INFO_PWPSTATE_DESCRIPTION_TSFILE.get()) 936 .valuePlaceholder(INFO_TRUSTSTOREPATH_PLACEHOLDER.get()) 937 .buildArgument(); 938 argParser.addGlobalArgument(trustStoreFile); 939 940 trustStorePW = 941 StringArgument.builder(OPTION_LONG_TRUSTSTORE_PWD) 942 .shortIdentifier('T') 943 .description(INFO_PWPSTATE_DESCRIPTION_TSPW.get()) 944 .valuePlaceholder(INFO_TRUSTSTORE_PWD_PLACEHOLDER.get()) 945 .buildArgument(); 946 argParser.addGlobalArgument(trustStorePW); 947 948 trustStorePWFile = 949 FileBasedArgument.builder(OPTION_LONG_TRUSTSTORE_PWD_FILE) 950 .shortIdentifier(OPTION_SHORT_TRUSTSTORE_PWD_FILE) 951 .description(INFO_PWPSTATE_DESCRIPTION_TSPWFILE.get()) 952 .valuePlaceholder(INFO_TRUSTSTORE_PWD_FILE_PLACEHOLDER.get()) 953 .buildArgument(); 954 argParser.addGlobalArgument(trustStorePWFile); 955 956 verbose = verboseArgument(); 957 argParser.addGlobalArgument(verbose); 958 959 showUsage = showUsageArgument(); 960 argParser.addGlobalArgument(showUsage); 961 argParser.setUsageArgument(showUsage, out); 962 963 964 HashSet<String> booleanValues = new HashSet<>(2); 965 booleanValues.add(INFO_MULTICHOICE_TRUE_VALUE.get().toString()); 966 booleanValues.add(INFO_MULTICHOICE_FALSE_VALUE.get().toString()); 967 968 969 LocalizableMessage msg = INFO_DESCRIPTION_PWPSTATE_GET_ALL.get(); 970 new SubCommand(argParser, SC_GET_ALL, msg); 971 972 msg = INFO_DESCRIPTION_PWPSTATE_GET_PASSWORD_POLICY_DN.get(); 973 new SubCommand(argParser, SC_GET_PASSWORD_POLICY_DN, msg); 974 975 msg = INFO_DESCRIPTION_PWPSTATE_GET_ACCOUNT_DISABLED_STATE.get(); 976 new SubCommand(argParser, SC_GET_ACCOUNT_DISABLED_STATE, msg); 977 978 msg = INFO_DESCRIPTION_PWPSTATE_SET_ACCOUNT_DISABLED_STATE.get(); 979 SubCommand sc = new SubCommand(argParser, SC_SET_ACCOUNT_DISABLED_STATE, 980 msg); 981 sc.addArgument(MultiChoiceArgument.<String>builder(ARG_OP_VALUE) 982 .shortIdentifier('O') 983 .description(INFO_DESCRIPTION_OPERATION_BOOLEAN_VALUE.get()) 984 .required() 985 .allowedValues(booleanValues) 986 .valuePlaceholder(INFO_TRUE_FALSE_PLACEHOLDER.get()) 987 .buildArgument()); 988 989 msg = INFO_DESCRIPTION_PWPSTATE_CLEAR_ACCOUNT_DISABLED_STATE.get(); 990 new SubCommand(argParser, SC_CLEAR_ACCOUNT_DISABLED_STATE, msg); 991 992 msg = INFO_DESCRIPTION_PWPSTATE_GET_ACCOUNT_EXPIRATION_TIME.get(); 993 new SubCommand(argParser, SC_GET_ACCOUNT_EXPIRATION_TIME, msg); 994 995 msg = INFO_DESCRIPTION_PWPSTATE_SET_ACCOUNT_EXPIRATION_TIME.get(); 996 sc = new SubCommand(argParser, SC_SET_ACCOUNT_EXPIRATION_TIME, msg); 997 sc.addArgument(StringArgument.builder(ARG_OP_VALUE) 998 .shortIdentifier('O') 999 .description(INFO_DESCRIPTION_OPERATION_TIME_VALUE.get()) 1000 .valuePlaceholder(INFO_TIME_PLACEHOLDER.get()) 1001 .buildArgument()); 1002 sc.setHidden(true); 1003 1004 msg = INFO_DESCRIPTION_PWPSTATE_CLEAR_ACCOUNT_EXPIRATION_TIME.get(); 1005 sc = new SubCommand(argParser, SC_CLEAR_ACCOUNT_EXPIRATION_TIME, msg); 1006 sc.setHidden(true); 1007 1008 msg = 1009 INFO_DESCRIPTION_PWPSTATE_GET_SECONDS_UNTIL_ACCOUNT_EXPIRATION 1010 .get(); 1011 new SubCommand(argParser, 1012 SC_GET_SECONDS_UNTIL_ACCOUNT_EXPIRATION, 1013 msg); 1014 1015 msg = INFO_DESCRIPTION_PWPSTATE_GET_PASSWORD_CHANGED_TIME.get(); 1016 new SubCommand(argParser, SC_GET_PASSWORD_CHANGED_TIME, msg); 1017 1018 msg = INFO_DESCRIPTION_PWPSTATE_SET_PASSWORD_CHANGED_TIME.get(); 1019 sc = new SubCommand(argParser, SC_SET_PASSWORD_CHANGED_TIME, msg); 1020 sc.addArgument(StringArgument.builder(ARG_OP_VALUE) 1021 .shortIdentifier('O') 1022 .description(INFO_DESCRIPTION_OPERATION_TIME_VALUE.get()) 1023 .valuePlaceholder(INFO_TIME_PLACEHOLDER.get()) 1024 .buildArgument()); 1025 sc.setHidden(true); 1026 1027 msg = INFO_DESCRIPTION_PWPSTATE_CLEAR_PASSWORD_CHANGED_TIME.get(); 1028 sc = new SubCommand(argParser, SC_CLEAR_PASSWORD_CHANGED_TIME, msg); 1029 sc.setHidden(true); 1030 1031 msg = INFO_DESCRIPTION_PWPSTATE_GET_PASSWORD_EXPIRATION_WARNED_TIME 1032 .get(); 1033 new SubCommand(argParser, SC_GET_PASSWORD_EXP_WARNED_TIME, msg); 1034 1035 msg = INFO_DESCRIPTION_PWPSTATE_SET_PASSWORD_EXPIRATION_WARNED_TIME 1036 .get(); 1037 sc = new SubCommand(argParser, SC_SET_PASSWORD_EXP_WARNED_TIME, msg); 1038 sc.addArgument(StringArgument.builder(ARG_OP_VALUE) 1039 .shortIdentifier('O') 1040 .description(INFO_DESCRIPTION_OPERATION_TIME_VALUE.get()) 1041 .valuePlaceholder(INFO_TIME_PLACEHOLDER.get()) 1042 .buildArgument()); 1043 sc.setHidden(true); 1044 1045 msg = INFO_DESCRIPTION_PWPSTATE_CLEAR_PASSWORD_EXPIRATION_WARNED_TIME 1046 .get(); 1047 sc = new SubCommand(argParser, SC_CLEAR_PASSWORD_EXP_WARNED_TIME, msg); 1048 sc.setHidden(true); 1049 1050 msg = INFO_DESCRIPTION_PWPSTATE_GET_SECONDS_UNTIL_PASSWORD_EXP.get(); 1051 new SubCommand(argParser, SC_GET_SECONDS_UNTIL_PASSWORD_EXPIRATION, 1052 msg); 1053 1054 msg = INFO_DESCRIPTION_PWPSTATE_GET_SECONDS_UNTIL_PASSWORD_EXP_WARNING 1055 .get(); 1056 new SubCommand(argParser, 1057 SC_GET_SECONDS_UNTIL_PASSWORD_EXPIRATION_WARNING, msg); 1058 1059 msg = INFO_DESCRIPTION_PWPSTATE_GET_AUTH_FAILURE_TIMES.get(); 1060 new SubCommand(argParser, SC_GET_AUTHENTICATION_FAILURE_TIMES, msg); 1061 1062 msg = INFO_DESCRIPTION_PWPSTATE_ADD_AUTH_FAILURE_TIME.get(); 1063 sc = new SubCommand(argParser, SC_ADD_AUTHENTICATION_FAILURE_TIME, 1064 msg); 1065 sc.addArgument(StringArgument.builder(ARG_OP_VALUE) 1066 .shortIdentifier('O') 1067 .description(INFO_DESCRIPTION_OPERATION_TIME_VALUE.get()) 1068 .multiValued() 1069 .valuePlaceholder(INFO_TIME_PLACEHOLDER.get()) 1070 .buildArgument()); 1071 sc.setHidden(true); 1072 1073 msg = INFO_DESCRIPTION_PWPSTATE_SET_AUTH_FAILURE_TIMES.get(); 1074 sc = new SubCommand(argParser, SC_SET_AUTHENTICATION_FAILURE_TIMES, 1075 msg); 1076 sc.addArgument(StringArgument.builder(ARG_OP_VALUE) 1077 .shortIdentifier('O') 1078 .description(INFO_DESCRIPTION_OPERATION_TIME_VALUES.get()) 1079 .multiValued() 1080 .valuePlaceholder(INFO_TIME_PLACEHOLDER.get()) 1081 .buildArgument()); 1082 sc.setHidden(true); 1083 1084 msg = INFO_DESCRIPTION_PWPSTATE_CLEAR_AUTH_FAILURE_TIMES.get(); 1085 sc = new SubCommand(argParser, SC_CLEAR_AUTHENTICATION_FAILURE_TIMES, 1086 msg); 1087 sc.setHidden(true); 1088 1089 msg = INFO_DESCRIPTION_PWPSTATE_GET_SECONDS_UNTIL_AUTH_FAILURE_UNLOCK 1090 .get(); 1091 new SubCommand(argParser, 1092 SC_GET_SECONDS_UNTIL_AUTHENTICATION_FAILURE_UNLOCK, 1093 msg); 1094 1095 msg = 1096 INFO_DESCRIPTION_PWPSTATE_GET_REMAINING_AUTH_FAILURE_COUNT.get(); 1097 new SubCommand(argParser, SC_GET_REMAINING_AUTHENTICATION_FAILURE_COUNT, 1098 msg); 1099 1100 msg = INFO_DESCRIPTION_PWPSTATE_GET_LAST_LOGIN_TIME.get(); 1101 new SubCommand(argParser, SC_GET_LAST_LOGIN_TIME, msg); 1102 1103 msg = INFO_DESCRIPTION_PWPSTATE_SET_LAST_LOGIN_TIME.get(); 1104 sc = new SubCommand(argParser, SC_SET_LAST_LOGIN_TIME, msg); 1105 sc.addArgument(StringArgument.builder(ARG_OP_VALUE) 1106 .shortIdentifier('O') 1107 .description(INFO_DESCRIPTION_OPERATION_TIME_VALUE.get()) 1108 .valuePlaceholder(INFO_TIME_PLACEHOLDER.get()) 1109 .buildArgument()); 1110 sc.setHidden(true); 1111 1112 msg = INFO_DESCRIPTION_PWPSTATE_CLEAR_LAST_LOGIN_TIME.get(); 1113 sc = new SubCommand(argParser, SC_CLEAR_LAST_LOGIN_TIME, msg); 1114 sc.setHidden(true); 1115 1116 msg = INFO_DESCRIPTION_PWPSTATE_GET_SECONDS_UNTIL_IDLE_LOCKOUT.get(); 1117 new SubCommand(argParser, SC_GET_SECONDS_UNTIL_IDLE_LOCKOUT, msg); 1118 1119 msg = INFO_DESCRIPTION_PWPSTATE_GET_PASSWORD_RESET_STATE.get(); 1120 new SubCommand(argParser, SC_GET_PASSWORD_RESET_STATE, msg); 1121 1122 msg = INFO_DESCRIPTION_PWPSTATE_SET_PASSWORD_RESET_STATE.get(); 1123 sc = new SubCommand(argParser, SC_SET_PASSWORD_RESET_STATE, msg); 1124 sc.addArgument(MultiChoiceArgument.<String>builder(ARG_OP_VALUE) 1125 .shortIdentifier('O') 1126 .description(INFO_DESCRIPTION_OPERATION_BOOLEAN_VALUE.get()) 1127 .required() 1128 .allowedValues(booleanValues) 1129 .valuePlaceholder(INFO_TRUE_FALSE_PLACEHOLDER.get()) 1130 .buildArgument()); 1131 sc.setHidden(true); 1132 1133 msg = INFO_DESCRIPTION_PWPSTATE_CLEAR_PASSWORD_RESET_STATE.get(); 1134 sc = new SubCommand(argParser, SC_CLEAR_PASSWORD_RESET_STATE, msg); 1135 sc.setHidden(true); 1136 1137 msg = INFO_DESCRIPTION_PWPSTATE_GET_SECONDS_UNTIL_RESET_LOCKOUT.get(); 1138 new SubCommand(argParser, SC_GET_SECONDS_UNTIL_PASSWORD_RESET_LOCKOUT, 1139 msg); 1140 1141 msg = INFO_DESCRIPTION_PWPSTATE_GET_GRACE_LOGIN_USE_TIMES.get(); 1142 new SubCommand(argParser, SC_GET_GRACE_LOGIN_USE_TIMES, msg); 1143 1144 msg = INFO_DESCRIPTION_PWPSTATE_ADD_GRACE_LOGIN_USE_TIME.get(); 1145 sc = new SubCommand(argParser, SC_ADD_GRACE_LOGIN_USE_TIME, msg); 1146 sc.addArgument(StringArgument.builder(ARG_OP_VALUE) 1147 .shortIdentifier('O') 1148 .description(INFO_DESCRIPTION_OPERATION_TIME_VALUE.get()) 1149 .multiValued() 1150 .valuePlaceholder(INFO_TIME_PLACEHOLDER.get()) 1151 .buildArgument()); 1152 sc.setHidden(true); 1153 1154 msg = INFO_DESCRIPTION_PWPSTATE_SET_GRACE_LOGIN_USE_TIMES.get(); 1155 sc = new SubCommand(argParser, SC_SET_GRACE_LOGIN_USE_TIMES, msg); 1156 sc.addArgument(StringArgument.builder(ARG_OP_VALUE) 1157 .shortIdentifier('O') 1158 .description(INFO_DESCRIPTION_OPERATION_TIME_VALUES.get()) 1159 .multiValued() 1160 .valuePlaceholder(INFO_TIME_PLACEHOLDER.get()) 1161 .buildArgument()); 1162 sc.setHidden(true); 1163 1164 msg = INFO_DESCRIPTION_PWPSTATE_CLEAR_GRACE_LOGIN_USE_TIMES.get(); 1165 sc = new SubCommand(argParser, SC_CLEAR_GRACE_LOGIN_USE_TIMES, msg); 1166 sc.setHidden(true); 1167 1168 msg = INFO_DESCRIPTION_PWPSTATE_GET_REMAINING_GRACE_LOGIN_COUNT.get(); 1169 new SubCommand(argParser, SC_GET_REMAINING_GRACE_LOGIN_COUNT, 1170 msg); 1171 1172 msg = INFO_DESCRIPTION_PWPSTATE_GET_PW_CHANGED_BY_REQUIRED_TIME.get(); 1173 new SubCommand(argParser, SC_GET_PASSWORD_CHANGED_BY_REQUIRED_TIME, 1174 msg); 1175 1176 msg = INFO_DESCRIPTION_PWPSTATE_SET_PW_CHANGED_BY_REQUIRED_TIME.get(); 1177 sc = new SubCommand(argParser, SC_SET_PASSWORD_CHANGED_BY_REQUIRED_TIME, 1178 msg); 1179 sc.addArgument(StringArgument.builder(ARG_OP_VALUE) 1180 .shortIdentifier('O') 1181 .description(INFO_DESCRIPTION_OPERATION_TIME_VALUE.get()) 1182 .valuePlaceholder(INFO_TIME_PLACEHOLDER.get()) 1183 .buildArgument()); 1184 sc.setHidden(true); 1185 1186 msg = 1187 INFO_DESCRIPTION_PWPSTATE_CLEAR_PW_CHANGED_BY_REQUIRED_TIME.get(); 1188 sc = new SubCommand(argParser, SC_CLEAR_PASSWORD_CHANGED_BY_REQUIRED_TIME, 1189 msg); 1190 sc.setHidden(true); 1191 1192 msg = 1193 INFO_DESCRIPTION_PWPSTATE_GET_SECONDS_UNTIL_REQUIRED_CHANGE_TIME 1194 .get(); 1195 new SubCommand(argParser, SC_GET_SECONDS_UNTIL_REQUIRED_CHANGE_TIME, 1196 msg); 1197 1198 msg = INFO_DESCRIPTION_PWPSTATE_GET_PASSWORD_HISTORY.get(); 1199 new SubCommand(argParser, SC_GET_PASSWORD_HISTORY, msg); 1200 1201 msg = INFO_DESCRIPTION_PWPSTATE_CLEAR_PASSWORD_HISTORY.get(); 1202 sc = new SubCommand(argParser, SC_CLEAR_PASSWORD_HISTORY, msg); 1203 sc.setHidden(true); 1204 } 1205 catch (ArgumentException ae) 1206 { 1207 printWrappedText(err, ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage())); 1208 return CLIENT_SIDE_LOCAL_ERROR; 1209 } 1210 1211 try 1212 { 1213 argParser.parseArguments(args); 1214 } 1215 catch (ArgumentException ae) 1216 { 1217 argParser.displayMessageAndUsageReference(err, ERR_ERROR_PARSING_ARGS.get(ae.getMessage())); 1218 return CLIENT_SIDE_PARAM_ERROR; 1219 } 1220 1221 1222 // If we should just display usage or version information, 1223 // then exit because it will have already been done. 1224 if (argParser.usageOrVersionDisplayed()) 1225 { 1226 return -1; 1227 } 1228 1229 1230 // Get the target DN as a string for later use. 1231 targetDNString = targetDN.getValue(); 1232 1233 // Bootstrap and initialize directory data structures. 1234 if (initServer) 1235 { 1236 EmbeddedUtils.initializeForClientUse(); 1237 } 1238 // Create the LDAP connection options object, which will be used to 1239 // customize the way that we connect to the server and specify a set of 1240 // basic defaults. 1241 LDAPConnectionOptions connectionOptions = new LDAPConnectionOptions(); 1242 connectionOptions.setVersionNumber(3); 1243 connectionOptions.setVerbose(verbose.isPresent()); 1244 1245 // If both a bind password and bind password file were provided, then 1246 // return an error. 1247 if (bindPW.isPresent() && bindPWFile.isPresent()) 1248 { 1249 printWrappedText(err, 1250 ERR_PWPSTATE_MUTUALLY_EXCLUSIVE_ARGUMENTS.get(bindPW.getLongIdentifier(), bindPWFile.getLongIdentifier())); 1251 return CLIENT_SIDE_PARAM_ERROR; 1252 } 1253 1254 // If both a key store password and key store password file were provided, 1255 // then return an error. 1256 if (keyStorePW.isPresent() && keyStorePWFile.isPresent()) 1257 { 1258 printWrappedText(err, ERR_PWPSTATE_MUTUALLY_EXCLUSIVE_ARGUMENTS.get( 1259 keyStorePW.getLongIdentifier(), keyStorePWFile.getLongIdentifier())); 1260 return CLIENT_SIDE_PARAM_ERROR; 1261 } 1262 1263 1264 // If both a trust store password and trust store password file were 1265 // provided, then return an error. 1266 if (trustStorePW.isPresent() && trustStorePWFile.isPresent()) 1267 { 1268 printWrappedText(err, ERR_PWPSTATE_MUTUALLY_EXCLUSIVE_ARGUMENTS.get( 1269 trustStorePW.getLongIdentifier(), trustStorePWFile.getLongIdentifier())); 1270 return CLIENT_SIDE_PARAM_ERROR; 1271 } 1272 1273 1274 // If we should blindly trust any certificate, then install the appropriate 1275 // SSL connection factory. 1276 try { 1277 String clientAlias; 1278 if (certNickname.isPresent()) { 1279 clientAlias = certNickname.getValue(); 1280 } else { 1281 clientAlias = null; 1282 } 1283 1284 SSLConnectionFactory sslConnectionFactory = new SSLConnectionFactory(); 1285 sslConnectionFactory.init(trustAll.isPresent(), keyStoreFile.getValue(), 1286 keyStorePW.getValue(), clientAlias, 1287 trustStoreFile.getValue(), 1288 trustStorePW.getValue()); 1289 1290 connectionOptions.setSSLConnectionFactory(sslConnectionFactory); 1291 } catch (SSLConnectionException sce) { 1292 printWrappedText(err, ERR_PWPSTATE_CANNOT_INITIALIZE_SSL.get(sce.getMessage())); 1293 return CLIENT_SIDE_LOCAL_ERROR; 1294 } 1295 1296 1297 // If one or more SASL options were provided, then make sure that one of 1298 // them was "mech" and specified a valid SASL mechanism. 1299 if (saslOption.isPresent()) 1300 { 1301 String mechanism = null; 1302 LinkedList<String> options = new LinkedList<>(); 1303 1304 for (String s : saslOption.getValues()) 1305 { 1306 int equalPos = s.indexOf('='); 1307 if (equalPos <= 0) 1308 { 1309 printWrappedText(err, ERR_PWPSTATE_CANNOT_PARSE_SASL_OPTION.get(s)); 1310 return CLIENT_SIDE_PARAM_ERROR; 1311 } 1312 else 1313 { 1314 String name = s.substring(0, equalPos); 1315 1316 if (name.equalsIgnoreCase("mech")) 1317 { 1318 mechanism = s; 1319 } 1320 else 1321 { 1322 options.add(s); 1323 } 1324 } 1325 } 1326 1327 if (mechanism == null) 1328 { 1329 printWrappedText(err, ERR_PWPSTATE_NO_SASL_MECHANISM.get()); 1330 return CLIENT_SIDE_PARAM_ERROR; 1331 } 1332 1333 connectionOptions.setSASLMechanism(mechanism); 1334 1335 for (String option : options) 1336 { 1337 connectionOptions.addSASLProperty(option); 1338 } 1339 } 1340 1341 1342 // Attempt to connect and authenticate to the Directory Server. 1343 nextMessageID = new AtomicInteger(1); 1344 try 1345 { 1346 connection = new LDAPConnection(host.getValue(), port.getIntValue(), 1347 connectionOptions, out, err); 1348 connection.connectToHost(bindDN.getValue(), 1349 LDAPConnectionArgumentParser.getPasswordValue(bindPW, bindPWFile, 1350 bindDN, out, err), 1351 nextMessageID); 1352 } 1353 catch (ArgumentException ae) 1354 { 1355 argParser.displayMessageAndUsageReference( 1356 err, ERR_PWPSTATE_CANNOT_DETERMINE_PORT.get(port.getLongIdentifier(), ae.getMessage())); 1357 return CLIENT_SIDE_PARAM_ERROR; 1358 } 1359 catch (LDAPConnectionException lce) 1360 { 1361 LocalizableMessage message; 1362 if (lce.getCause() != null && lce.getCause().getCause() != null && 1363 lce.getCause().getCause() instanceof SSLException) { 1364 message = ERR_PWPSTATE_CANNOT_CONNECT_SSL.get(host.getValue(), 1365 port.getValue()); 1366 } else { 1367 String hostPort = host.getValue() + ":" + port.getValue(); 1368 message = ERR_PWPSTATE_CANNOT_CONNECT.get(hostPort, 1369 lce.getMessage()); 1370 } 1371 printWrappedText(err, message); 1372 return CLIENT_SIDE_CONNECT_ERROR; 1373 } 1374 1375 ldapReader = connection.getLDAPReader(); 1376 ldapWriter = connection.getLDAPWriter(); 1377 1378 return SUCCESS; 1379 } 1380 1381 1382 1383 /** 1384 * Processes the subcommand from the provided argument parser and writes the 1385 * appropriate operation elements to the given writer. 1386 * 1387 * @param writer The ASN.1 writer used to write the operation elements. 1388 * 1389 * @return A result code indicating the results of the processing. 1390 */ 1391 private static int processSubcommand(ASN1Writer writer) throws IOException 1392 { 1393 SubCommand subCommand = argParser.getSubCommand(); 1394 if (subCommand == null) 1395 { 1396 printWrappedText(err, ERR_PWPSTATE_NO_SUBCOMMAND.get()); 1397 err.println(argParser.getUsage()); 1398 return CLIENT_SIDE_PARAM_ERROR; 1399 } 1400 1401 String subCommandName = subCommand.getName(); 1402 if (subCommandName.equals(SC_GET_ALL)) 1403 { 1404 // The list should stay empty for this one. 1405 } 1406 else if (subCommandName.equals(SC_GET_PASSWORD_POLICY_DN)) 1407 { 1408 encode(writer, OP_GET_PASSWORD_POLICY_DN, NO_VALUE); 1409 } 1410 else if (subCommandName.equals(SC_GET_ACCOUNT_DISABLED_STATE)) 1411 { 1412 encode(writer, OP_GET_ACCOUNT_DISABLED_STATE, NO_VALUE); 1413 } 1414 else if (subCommandName.equals(SC_SET_ACCOUNT_DISABLED_STATE)) 1415 { 1416 Argument a = subCommand.getArgumentForLongIdentifier(ARG_OP_VALUE); 1417 if (a != null && a.isPresent()) 1418 { 1419 String valueStr = a.getValue(); 1420 if (isTrueValue(valueStr)) 1421 { 1422 encode(writer, OP_SET_ACCOUNT_DISABLED_STATE, "true"); 1423 } 1424 else if (isFalseValue(valueStr)) 1425 { 1426 encode(writer, OP_SET_ACCOUNT_DISABLED_STATE, "false"); 1427 } 1428 else 1429 { 1430 printWrappedText(err, ERR_PWPSTATE_INVALID_BOOLEAN_VALUE.get(valueStr)); 1431 return CLIENT_SIDE_PARAM_ERROR; 1432 } 1433 } 1434 else 1435 { 1436 printWrappedText(err, ERR_PWPSTATE_NO_BOOLEAN_VALUE.get()); 1437 return CLIENT_SIDE_PARAM_ERROR; 1438 } 1439 } 1440 else if (subCommandName.equals(SC_CLEAR_ACCOUNT_DISABLED_STATE)) 1441 { 1442 encode(writer, OP_CLEAR_ACCOUNT_DISABLED_STATE, NO_VALUE); 1443 } 1444 else if (subCommandName.equals(SC_GET_ACCOUNT_EXPIRATION_TIME)) 1445 { 1446 encode(writer, OP_GET_ACCOUNT_EXPIRATION_TIME, NO_VALUE); 1447 } 1448 else if (subCommandName.equals(SC_SET_ACCOUNT_EXPIRATION_TIME)) 1449 { 1450 Argument a = subCommand.getArgumentForLongIdentifier(ARG_OP_VALUE); 1451 if (a != null && a.isPresent()) 1452 { 1453 encode(writer, OP_SET_ACCOUNT_EXPIRATION_TIME, a.getValue()); 1454 } 1455 else 1456 { 1457 encode(writer, OP_SET_ACCOUNT_EXPIRATION_TIME, NO_VALUE); 1458 } 1459 } 1460 else if (subCommandName.equals(SC_CLEAR_ACCOUNT_EXPIRATION_TIME)) 1461 { 1462 encode(writer, OP_CLEAR_ACCOUNT_EXPIRATION_TIME, NO_VALUE); 1463 } 1464 else if (subCommandName.equals(SC_GET_SECONDS_UNTIL_ACCOUNT_EXPIRATION)) 1465 { 1466 encode(writer, OP_GET_SECONDS_UNTIL_ACCOUNT_EXPIRATION, NO_VALUE); 1467 } 1468 else if (subCommandName.equals(SC_GET_PASSWORD_CHANGED_TIME)) 1469 { 1470 encode(writer, OP_GET_PASSWORD_CHANGED_TIME, NO_VALUE); 1471 } 1472 else if (subCommandName.equals(SC_SET_PASSWORD_CHANGED_TIME)) 1473 { 1474 Argument a = subCommand.getArgumentForLongIdentifier(ARG_OP_VALUE); 1475 if (a != null && a.isPresent()) 1476 { 1477 encode(writer, OP_SET_PASSWORD_CHANGED_TIME, a.getValue()); 1478 } 1479 else 1480 { 1481 encode(writer, OP_SET_PASSWORD_CHANGED_TIME, NO_VALUE); 1482 } 1483 } 1484 else if (subCommandName.equals(SC_CLEAR_PASSWORD_CHANGED_TIME)) 1485 { 1486 encode(writer, OP_CLEAR_PASSWORD_CHANGED_TIME, NO_VALUE); 1487 } 1488 else if(subCommandName.equals(SC_GET_PASSWORD_EXP_WARNED_TIME)) 1489 { 1490 encode(writer, OP_GET_PASSWORD_EXPIRATION_WARNED_TIME, NO_VALUE); 1491 } 1492 else if(subCommandName.equals(SC_SET_PASSWORD_EXP_WARNED_TIME)) 1493 { 1494 Argument a = subCommand.getArgumentForLongIdentifier(ARG_OP_VALUE); 1495 if (a != null && a.isPresent()) 1496 { 1497 encode(writer, OP_SET_PASSWORD_EXPIRATION_WARNED_TIME, 1498 a.getValue()); 1499 } 1500 else 1501 { 1502 encode(writer, OP_SET_PASSWORD_EXPIRATION_WARNED_TIME, 1503 NO_VALUE); 1504 } 1505 } 1506 else if(subCommandName.equals(SC_CLEAR_PASSWORD_EXP_WARNED_TIME)) 1507 { 1508 encode(writer, OP_CLEAR_PASSWORD_EXPIRATION_WARNED_TIME, 1509 NO_VALUE); 1510 } 1511 else if(subCommandName.equals(SC_GET_SECONDS_UNTIL_PASSWORD_EXPIRATION)) 1512 { 1513 encode(writer, OP_GET_SECONDS_UNTIL_PASSWORD_EXPIRATION, 1514 NO_VALUE); 1515 } 1516 else if(subCommandName.equals( 1517 SC_GET_SECONDS_UNTIL_PASSWORD_EXPIRATION_WARNING)) 1518 { 1519 encode(writer, OP_GET_SECONDS_UNTIL_PASSWORD_EXPIRATION_WARNING, 1520 NO_VALUE); 1521 } 1522 else if(subCommandName.equals(SC_GET_AUTHENTICATION_FAILURE_TIMES)) 1523 { 1524 encode(writer, OP_GET_AUTHENTICATION_FAILURE_TIMES, NO_VALUE); 1525 } 1526 else if(subCommandName.equals(SC_ADD_AUTHENTICATION_FAILURE_TIME)) 1527 { 1528 Argument a = subCommand.getArgumentForLongIdentifier(ARG_OP_VALUE); 1529 if (a != null && a.isPresent()) 1530 { 1531 encode(writer, OP_ADD_AUTHENTICATION_FAILURE_TIME, 1532 a.getValue()); 1533 } 1534 else 1535 { 1536 encode(writer, OP_ADD_AUTHENTICATION_FAILURE_TIME, NO_VALUE); 1537 } 1538 } 1539 else if(subCommandName.equals(SC_SET_AUTHENTICATION_FAILURE_TIMES)) 1540 { 1541 Argument a = subCommand.getArgumentForLongIdentifier(ARG_OP_VALUE); 1542 if (a != null && a.isPresent()) 1543 { 1544 ArrayList<String> valueList = new ArrayList<>(a.getValues()); 1545 String[] values = new String[valueList.size()]; 1546 valueList.toArray(values); 1547 1548 encode(writer, OP_SET_AUTHENTICATION_FAILURE_TIMES, values); 1549 } 1550 else 1551 { 1552 encode(writer, OP_SET_AUTHENTICATION_FAILURE_TIMES, NO_VALUE); 1553 } 1554 } 1555 else if(subCommandName.equals(SC_CLEAR_AUTHENTICATION_FAILURE_TIMES)) 1556 { 1557 encode(writer, OP_CLEAR_AUTHENTICATION_FAILURE_TIMES, NO_VALUE); 1558 } 1559 else if(subCommandName.equals( 1560 SC_GET_SECONDS_UNTIL_AUTHENTICATION_FAILURE_UNLOCK)) 1561 { 1562 encode(writer, OP_GET_SECONDS_UNTIL_AUTHENTICATION_FAILURE_UNLOCK, 1563 NO_VALUE); 1564 } 1565 else if(subCommandName.equals( 1566 SC_GET_REMAINING_AUTHENTICATION_FAILURE_COUNT)) 1567 { 1568 encode(writer, OP_GET_REMAINING_AUTHENTICATION_FAILURE_COUNT, 1569 NO_VALUE); 1570 } 1571 else if(subCommandName.equals(SC_GET_LAST_LOGIN_TIME)) 1572 { 1573 encode(writer, OP_GET_LAST_LOGIN_TIME, NO_VALUE); 1574 } 1575 else if(subCommandName.equals(SC_SET_LAST_LOGIN_TIME)) 1576 { 1577 Argument a = subCommand.getArgumentForLongIdentifier(ARG_OP_VALUE); 1578 if (a != null && a.isPresent()) 1579 { 1580 encode(writer, OP_SET_LAST_LOGIN_TIME, a.getValue()); 1581 } 1582 else 1583 { 1584 encode(writer, OP_SET_LAST_LOGIN_TIME, NO_VALUE); 1585 } 1586 } 1587 else if(subCommandName.equals(SC_CLEAR_LAST_LOGIN_TIME)) 1588 { 1589 encode(writer, OP_CLEAR_LAST_LOGIN_TIME, NO_VALUE); 1590 } 1591 else if(subCommandName.equals(SC_GET_SECONDS_UNTIL_IDLE_LOCKOUT)) 1592 { 1593 encode(writer, OP_GET_SECONDS_UNTIL_IDLE_LOCKOUT, NO_VALUE); 1594 } 1595 else if(subCommandName.equals(SC_GET_PASSWORD_RESET_STATE)) 1596 { 1597 encode(writer, OP_GET_PASSWORD_RESET_STATE, NO_VALUE); 1598 } 1599 else if(subCommandName.equals(SC_SET_PASSWORD_RESET_STATE)) 1600 { 1601 Argument a = subCommand.getArgumentForLongIdentifier(ARG_OP_VALUE); 1602 if (a != null && a.isPresent()) 1603 { 1604 String valueStr = a.getValue(); 1605 if (isTrueValue(valueStr)) 1606 { 1607 encode(writer, OP_SET_PASSWORD_RESET_STATE, "true"); 1608 } 1609 else if (isFalseValue(valueStr)) 1610 { 1611 encode(writer, OP_SET_PASSWORD_RESET_STATE, "false"); 1612 } 1613 else 1614 { 1615 printWrappedText(err, ERR_PWPSTATE_INVALID_BOOLEAN_VALUE.get(valueStr)); 1616 return CLIENT_SIDE_PARAM_ERROR; 1617 } 1618 } 1619 else 1620 { 1621 printWrappedText(err, ERR_PWPSTATE_NO_BOOLEAN_VALUE.get()); 1622 return CLIENT_SIDE_PARAM_ERROR; 1623 } 1624 } 1625 else if(subCommandName.equals(SC_CLEAR_PASSWORD_RESET_STATE)) 1626 { 1627 encode(writer, OP_GET_PASSWORD_RESET_STATE, NO_VALUE); 1628 } 1629 else if(subCommandName.equals(SC_GET_SECONDS_UNTIL_PASSWORD_RESET_LOCKOUT)) 1630 { 1631 encode(writer, OP_GET_SECONDS_UNTIL_PASSWORD_RESET_LOCKOUT, 1632 NO_VALUE); 1633 } 1634 else if(subCommandName.equals(SC_GET_GRACE_LOGIN_USE_TIMES)) 1635 { 1636 encode(writer, OP_GET_GRACE_LOGIN_USE_TIMES, NO_VALUE); 1637 } 1638 else if(subCommandName.equals(SC_ADD_GRACE_LOGIN_USE_TIME)) 1639 { 1640 Argument a = subCommand.getArgumentForLongIdentifier(ARG_OP_VALUE); 1641 if (a != null && a.isPresent()) 1642 { 1643 encode(writer, OP_ADD_GRACE_LOGIN_USE_TIME, a.getValue()); 1644 } 1645 else 1646 { 1647 encode(writer, OP_ADD_GRACE_LOGIN_USE_TIME, NO_VALUE); 1648 } 1649 } 1650 else if(subCommandName.equals(SC_SET_GRACE_LOGIN_USE_TIMES)) 1651 { 1652 Argument a = subCommand.getArgumentForLongIdentifier(ARG_OP_VALUE); 1653 if (a != null && a.isPresent()) 1654 { 1655 ArrayList<String> valueList = new ArrayList<>(a.getValues()); 1656 String[] values = new String[valueList.size()]; 1657 valueList.toArray(values); 1658 1659 encode(writer, OP_SET_GRACE_LOGIN_USE_TIMES, values); 1660 } 1661 else 1662 { 1663 encode(writer, OP_SET_GRACE_LOGIN_USE_TIMES, NO_VALUE); 1664 } 1665 } 1666 else if(subCommandName.equals(SC_CLEAR_GRACE_LOGIN_USE_TIMES)) 1667 { 1668 encode(writer, OP_CLEAR_GRACE_LOGIN_USE_TIMES, NO_VALUE); 1669 } 1670 else if(subCommandName.equals(SC_GET_REMAINING_GRACE_LOGIN_COUNT)) 1671 { 1672 encode(writer, OP_GET_REMAINING_GRACE_LOGIN_COUNT, NO_VALUE); 1673 } 1674 else if(subCommandName.equals(SC_GET_PASSWORD_CHANGED_BY_REQUIRED_TIME)) 1675 { 1676 encode(writer, OP_GET_PASSWORD_CHANGED_BY_REQUIRED_TIME, 1677 NO_VALUE); 1678 } 1679 else if(subCommandName.equals(SC_SET_PASSWORD_CHANGED_BY_REQUIRED_TIME)) 1680 { 1681 Argument a = subCommand.getArgumentForLongIdentifier(ARG_OP_VALUE); 1682 if (a != null && a.isPresent()) 1683 { 1684 encode(writer, OP_SET_PASSWORD_CHANGED_BY_REQUIRED_TIME, 1685 a.getValue()); 1686 } 1687 else 1688 { 1689 encode(writer, OP_SET_PASSWORD_CHANGED_BY_REQUIRED_TIME, 1690 NO_VALUE); 1691 } 1692 } 1693 else if(subCommandName.equals(SC_CLEAR_PASSWORD_CHANGED_BY_REQUIRED_TIME)) 1694 { 1695 encode(writer, OP_CLEAR_PASSWORD_CHANGED_BY_REQUIRED_TIME, 1696 NO_VALUE); 1697 } 1698 else if(subCommandName.equals(SC_GET_SECONDS_UNTIL_REQUIRED_CHANGE_TIME)) 1699 { 1700 encode(writer, OP_GET_SECONDS_UNTIL_REQUIRED_CHANGE_TIME, 1701 NO_VALUE); 1702 } 1703 else if (subCommandName.equals(SC_GET_PASSWORD_HISTORY)) 1704 { 1705 encode(writer, OP_GET_PASSWORD_HISTORY, NO_VALUE); 1706 } 1707 else if (subCommandName.equals(SC_CLEAR_PASSWORD_HISTORY)) 1708 { 1709 encode(writer, OP_CLEAR_PASSWORD_HISTORY, NO_VALUE); 1710 } 1711 else 1712 { 1713 printWrappedText(err, ERR_PWPSTATE_INVALID_SUBCOMMAND.get(subCommandName)); 1714 err.println(argParser.getUsage()); 1715 return CLIENT_SIDE_PARAM_ERROR; 1716 } 1717 1718 return SUCCESS; 1719 } 1720 1721 1722 1723 /** 1724 * Prints information about a password policy state variable to standard 1725 * output. 1726 * 1727 * @param msg The message ID for the message to use as the label. 1728 * @param values The set of values for the associated state variable. 1729 */ 1730 private static void printLabelAndValues(LocalizableMessage msg, ArrayList<String> values) 1731 { 1732 String label = String.valueOf(msg); 1733 if (values == null || values.isEmpty()) 1734 { 1735 out.print(label); 1736 out.println(":"); 1737 } 1738 else 1739 { 1740 for (String value : values) 1741 { 1742 out.print(label); 1743 out.print(": "); 1744 out.println(value); 1745 } 1746 } 1747 } 1748 1749 private static boolean isTrueValue(String value) 1750 { 1751 return INFO_MULTICHOICE_TRUE_VALUE.get().toString().equalsIgnoreCase(value); 1752 } 1753 1754 private static boolean isFalseValue(String value) 1755 { 1756 return INFO_MULTICHOICE_FALSE_VALUE.get().toString().equalsIgnoreCase( 1757 value); 1758 } 1759} 1760