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