001/* 002 * Copyright 2016-2019 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2016-2019 Ping Identity Corporation 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.ldap.sdk.unboundidds.tools; 022 023 024 025import java.io.BufferedReader; 026import java.io.File; 027import java.io.FileOutputStream; 028import java.io.FileReader; 029import java.io.OutputStream; 030import java.util.ArrayList; 031import java.util.Arrays; 032import java.util.LinkedHashMap; 033import java.util.concurrent.atomic.AtomicBoolean; 034 035import com.unboundid.ldap.sdk.DN; 036import com.unboundid.ldap.sdk.ExtendedResult; 037import com.unboundid.ldap.sdk.Filter; 038import com.unboundid.ldap.sdk.LDAPConnection; 039import com.unboundid.ldap.sdk.LDAPConnectionOptions; 040import com.unboundid.ldap.sdk.LDAPConnectionPool; 041import com.unboundid.ldap.sdk.LDAPException; 042import com.unboundid.ldap.sdk.ResultCode; 043import com.unboundid.ldap.sdk.UnsolicitedNotificationHandler; 044import com.unboundid.ldap.sdk.Version; 045import com.unboundid.ldif.LDIFWriter; 046import com.unboundid.util.Debug; 047import com.unboundid.util.DNFileReader; 048import com.unboundid.util.LDAPCommandLineTool; 049import com.unboundid.util.FilterFileReader; 050import com.unboundid.util.FixedRateBarrier; 051import com.unboundid.util.RateAdjustor; 052import com.unboundid.util.StaticUtils; 053import com.unboundid.util.ThreadSafety; 054import com.unboundid.util.ThreadSafetyLevel; 055import com.unboundid.util.args.ArgumentException; 056import com.unboundid.util.args.ArgumentParser; 057import com.unboundid.util.args.BooleanArgument; 058import com.unboundid.util.args.BooleanValueArgument; 059import com.unboundid.util.args.DNArgument; 060import com.unboundid.util.args.FileArgument; 061import com.unboundid.util.args.FilterArgument; 062import com.unboundid.util.args.IPAddressArgumentValueValidator; 063import com.unboundid.util.args.IntegerArgument; 064import com.unboundid.util.args.StringArgument; 065import com.unboundid.util.args.TimestampArgument; 066import com.unboundid.util.args.SubCommand; 067 068import static com.unboundid.ldap.sdk.unboundidds.tools.ToolMessages.*; 069 070 071 072/** 073 * This class provides a tool that can be used to perform a variety of account 074 * management functions against user entries in the Ping Identity, UnboundID, 075 * or Nokia/Alcatel-Lucent 8661 Directory Server. It primarily uses the 076 * password policy state extended operation for its processing. 077 * <BR> 078 * <BLOCKQUOTE> 079 * <B>NOTE:</B> This class, and other classes within the 080 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 081 * supported for use against Ping Identity, UnboundID, and 082 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 083 * for proprietary functionality or for external specifications that are not 084 * considered stable or mature enough to be guaranteed to work in an 085 * interoperable way with other types of LDAP servers. 086 * </BLOCKQUOTE> 087 */ 088@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) 089public final class ManageAccount 090 extends LDAPCommandLineTool 091 implements UnsolicitedNotificationHandler 092{ 093 /** 094 * The column at which to wrap long lines. 095 */ 096 private static final int WRAP_COLUMN = StaticUtils.TERMINAL_WIDTH_COLUMNS - 1; 097 098 099 100 /** 101 * The primary name of the argument used to indicate that the tool should 102 * append to the reject file rather than overwrite it. 103 */ 104 private static final String ARG_APPEND_TO_REJECT_FILE = "appendToRejectFile"; 105 106 107 108 /** 109 * The primary name of the argument used to specify a base DN to use for 110 * searches. 111 */ 112 static final String ARG_BASE_DN = "baseDN"; 113 114 115 116 /** 117 * The primary name of the argument used to specify the path to a file to a 118 * sample variable rate data file to create. 119 */ 120 private static final String ARG_GENERATE_SAMPLE_RATE_FILE = 121 "generateSampleRateFile"; 122 123 124 125 /** 126 * The primary name of the argument used to specify the path to a file 127 * containing the DNs of the users on which to operate. 128 */ 129 private static final String ARG_DN_INPUT_FILE = "dnInputFile"; 130 131 132 133 /** 134 * The primary name of the argument used to specify the path to a file 135 * containing search filters to use to identify users. 136 */ 137 private static final String ARG_FILTER_INPUT_FILE = "filterInputFile"; 138 139 140 141 /** 142 * The primary name of the argument used to specify the number of threads to 143 * use to process search operations to identify which users to target. 144 */ 145 static final String ARG_NUM_SEARCH_THREADS = "numSearchThreads"; 146 147 148 149 /** 150 * The primary name of the argument used to specify the number of threads to 151 * use to perform manage-account processing. 152 */ 153 static final String ARG_NUM_THREADS = "numThreads"; 154 155 156 157 /** 158 * The primary name of the argument used to specify the target rate of 159 * operations per second. 160 */ 161 private static final String ARG_RATE_PER_SECOND = "ratePerSecond"; 162 163 164 165 /** 166 * The primary name of the argument used to specify the path to a reject file 167 * to create. 168 */ 169 private static final String ARG_REJECT_FILE = "rejectFile"; 170 171 172 173 /** 174 * The primary name of the argument used to specify the simple page size to 175 * use when performing searches. 176 */ 177 static final String ARG_SIMPLE_PAGE_SIZE = "simplePageSize"; 178 179 180 181 /** 182 * The primary name of the argument used to suppress result operation types 183 * without values. 184 */ 185 static final String ARG_SUPPRESS_EMPTY_RESULT_OPERATIONS = 186 "suppressEmptyResultOperations"; 187 188 189 190 /** 191 * The primary name of the argument used to specify the DN of the user on 192 * which to operate. 193 */ 194 private static final String ARG_TARGET_DN = "targetDN"; 195 196 197 198 /** 199 * The primary name of the argument used to specify a search filter to use to 200 * identify users. 201 */ 202 private static final String ARG_TARGET_FILTER = "targetFilter"; 203 204 205 206 /** 207 * The primary name of the argument used to specify the user IDs of target 208 * users. 209 */ 210 private static final String ARG_TARGET_USER_ID = "targetUserID"; 211 212 213 214 /** 215 * The primary name of the argument used to specify the name of the attribute 216 * to identify which user has a given user ID. 217 */ 218 static final String ARG_USER_ID_ATTRIBUTE = "userIDAttribute"; 219 220 221 222 /** 223 * The primary name of the argument used to specify the path to a file 224 * containing the user IDs of the target users. 225 */ 226 private static final String ARG_USER_ID_INPUT_FILE = "userIDInputFile"; 227 228 229 230 /** 231 * The primary name of the argument used to specify the path to a variable 232 * rate data file. 233 */ 234 private static final String ARG_VARIABLE_RATE_DATA = "variableRateData"; 235 236 237 238 /** 239 * The default search base DN. 240 */ 241 private static final DN DEFAULT_BASE_DN = DN.NULL_DN; 242 243 244 245 /** 246 * The default user ID attribute. 247 */ 248 private static final String DEFAULT_USER_ID_ATTRIBUTE = "uid"; 249 250 251 252 /** 253 * A target user DN to use in examples. 254 */ 255 private static final String EXAMPLE_TARGET_USER_DN = 256 "uid=jdoe,ou=People,dc=example,dc=com"; 257 258 259 260 // The argument parser for this tool. 261 private volatile ArgumentParser parser; 262 263 // Indicates whether all DNs have been provided to the manage-account 264 // processor. 265 private final AtomicBoolean allDNsProvided; 266 267 // Indicates whether all filters have been provided to the manage-account 268 // search processor. 269 private final AtomicBoolean allFiltersProvided; 270 271 // Indicates whether a request has been made to cancel processing. 272 private final AtomicBoolean cancelRequested; 273 274 // The rate limiter to use for this tool. 275 private volatile FixedRateBarrier rateLimiter; 276 277 // The LDAP connection options to use for connections created by this tool. 278 private final LDAPConnectionOptions connectionOptions; 279 280 // The LDIF writer to use to write information about successful and failed 281 // operations. 282 private volatile LDIFWriter outputWriter; 283 284 // The LDIF writer to use to write information about failed operations. 285 private volatile LDIFWriter rejectWriter; 286 287 // The search processor for this tool. 288 private volatile ManageAccountSearchProcessor searchProcessor; 289 290 // The rate adjustor to use to vary the load over time. 291 private volatile RateAdjustor rateAdjustor; 292 293 294 295 /** 296 * Invokes the tool with the provided set of arguments. 297 * 298 * @param args The command-line arguments provided to this tool. 299 */ 300 public static void main(final String... args) 301 { 302 final ResultCode resultCode = main(System.out, System.err, args); 303 if (resultCode != ResultCode.SUCCESS) 304 { 305 System.exit(resultCode.intValue()); 306 } 307 } 308 309 310 311 /** 312 * Invokes the tool with the provided set of arguments. 313 * 314 * @param out The output stream to use for standard out. It may be 315 * {@code null} if standard out should be suppressed. 316 * @param err The output stream to use for standard error. It may be 317 * {@code null} if standard error should be suppressed. 318 * @param args The command-line arguments provided to this tool. 319 * 320 * @return A result code with the status of the tool processing. Any result 321 * code other than {@link ResultCode#SUCCESS} should be considered a 322 * failure. 323 */ 324 public static ResultCode main(final OutputStream out, final OutputStream err, 325 final String... args) 326 { 327 final ManageAccount tool = new ManageAccount(out, err); 328 329 final boolean origCommentAboutBase64EncodedValues = 330 LDIFWriter.commentAboutBase64EncodedValues(); 331 LDIFWriter.setCommentAboutBase64EncodedValues(true); 332 try 333 { 334 return tool.runTool(args); 335 } 336 finally 337 { 338 LDIFWriter.setCommentAboutBase64EncodedValues( 339 origCommentAboutBase64EncodedValues); 340 } 341 } 342 343 344 345 /** 346 * Creates a new instance of this tool with the provided arguments. 347 * 348 * @param out The output stream to use for standard out. It may be 349 * {@code null} if standard out should be suppressed. 350 * @param err The output stream to use for standard error. It may be 351 * {@code null} if standard error should be suppressed. 352 */ 353 public ManageAccount(final OutputStream out, final OutputStream err) 354 { 355 super(out, err); 356 357 connectionOptions = new LDAPConnectionOptions(); 358 connectionOptions.setUnsolicitedNotificationHandler(this); 359 360 allDNsProvided = new AtomicBoolean(false); 361 allFiltersProvided = new AtomicBoolean(false); 362 cancelRequested = new AtomicBoolean(false); 363 364 parser = null; 365 rateLimiter = null; 366 rateAdjustor = null; 367 outputWriter = null; 368 rejectWriter = null; 369 searchProcessor = null; 370 } 371 372 373 374 /** 375 * {@inheritDoc} 376 */ 377 @Override() 378 public String getToolName() 379 { 380 return "manage-account"; 381 } 382 383 384 385 /** 386 * {@inheritDoc} 387 */ 388 @Override() 389 public String getToolDescription() 390 { 391 return INFO_MANAGE_ACCT_TOOL_DESC.get(); 392 } 393 394 395 396 /** 397 * {@inheritDoc} 398 */ 399 @Override() 400 public String getToolVersion() 401 { 402 return Version.NUMERIC_VERSION_STRING; 403 } 404 405 406 407 /** 408 * {@inheritDoc} 409 */ 410 @Override() 411 public boolean supportsInteractiveMode() 412 { 413 return true; 414 } 415 416 417 418 /** 419 * {@inheritDoc} 420 */ 421 @Override() 422 public boolean defaultsToInteractiveMode() 423 { 424 return true; 425 } 426 427 428 429 /** 430 * {@inheritDoc} 431 */ 432 @Override() 433 public boolean supportsPropertiesFile() 434 { 435 return true; 436 } 437 438 439 440 /** 441 * {@inheritDoc} 442 */ 443 @Override() 444 protected boolean supportsOutputFile() 445 { 446 return true; 447 } 448 449 450 451 /** 452 * {@inheritDoc} 453 */ 454 @Override() 455 protected boolean supportsAuthentication() 456 { 457 return true; 458 } 459 460 461 462 /** 463 * {@inheritDoc} 464 */ 465 @Override() 466 protected boolean defaultToPromptForBindPassword() 467 { 468 return true; 469 } 470 471 472 473 /** 474 * {@inheritDoc} 475 */ 476 @Override() 477 protected boolean supportsSASLHelp() 478 { 479 return true; 480 } 481 482 483 484 /** 485 * {@inheritDoc} 486 */ 487 @Override() 488 protected boolean includeAlternateLongIdentifiers() 489 { 490 return true; 491 } 492 493 494 495 /** 496 * {@inheritDoc} 497 */ 498 @Override() 499 protected boolean supportsSSLDebugging() 500 { 501 return true; 502 } 503 504 505 506 /** 507 * {@inheritDoc} 508 */ 509 @Override() 510 protected boolean supportsMultipleServers() 511 { 512 return true; 513 } 514 515 516 517 /** 518 * {@inheritDoc} 519 */ 520 @Override() 521 protected boolean logToolInvocationByDefault() 522 { 523 return true; 524 } 525 526 527 528 /** 529 * {@inheritDoc} 530 */ 531 @Override() 532 public void addNonLDAPArguments(final ArgumentParser parser) 533 throws ArgumentException 534 { 535 // Get a copy of the argument parser for later use. 536 this.parser = parser; 537 538 539 // Get the current time formatted as a generalized time. 540 final String currentGeneralizedTime = 541 StaticUtils.encodeGeneralizedTime(System.currentTimeMillis()); 542 final String olderGeneralizedTime = 543 StaticUtils.encodeGeneralizedTime( 544 System.currentTimeMillis() - 12_345L); 545 546 547 // Define the global arguments used to indicate which users to target. 548 final DNArgument targetDN = new DNArgument('b', ARG_TARGET_DN, false, 0, 549 null, INFO_MANAGE_ACCT_ARG_DESC_TARGET_DN.get()); 550 targetDN.addLongIdentifier("userDN", true); 551 targetDN.addLongIdentifier("target-dn", true); 552 targetDN.addLongIdentifier("user-dn", true); 553 targetDN.setArgumentGroupName( 554 INFO_MANAGE_ACCT_ARG_GROUP_TARGET_USER_ARGS.get()); 555 parser.addArgument(targetDN); 556 557 final FileArgument dnInputFile = new FileArgument(null, ARG_DN_INPUT_FILE, 558 false, 0, null, INFO_MANAGE_ACCT_ARG_DESC_DN_FILE.get(), true, 559 true, true, false); 560 dnInputFile.addLongIdentifier("targetDNFile", true); 561 dnInputFile.addLongIdentifier("userDNFile", true); 562 dnInputFile.addLongIdentifier("dn-input-file", true); 563 dnInputFile.addLongIdentifier("target-dn-file", true); 564 dnInputFile.addLongIdentifier("user-dn-file", true); 565 dnInputFile.setArgumentGroupName( 566 INFO_MANAGE_ACCT_ARG_GROUP_TARGET_USER_ARGS.get()); 567 parser.addArgument(dnInputFile); 568 569 final FilterArgument targetFilter = new FilterArgument(null, 570 ARG_TARGET_FILTER, false, 0, null, 571 INFO_MANAGE_ACCT_ARG_DESC_TARGET_FILTER.get(ARG_BASE_DN)); 572 targetFilter.addLongIdentifier("target-filter", true); 573 targetFilter.setArgumentGroupName( 574 INFO_MANAGE_ACCT_ARG_GROUP_TARGET_USER_ARGS.get()); 575 parser.addArgument(targetFilter); 576 577 final FileArgument filterInputFile = new FileArgument(null, 578 ARG_FILTER_INPUT_FILE, false, 0, null, 579 INFO_MANAGE_ACCT_ARG_DESC_FILTER_INPUT_FILE.get(ARG_BASE_DN), 580 true, true, true, false); 581 filterInputFile.addLongIdentifier("targetFilterFile", true); 582 filterInputFile.addLongIdentifier("filter-input-file", true); 583 filterInputFile.addLongIdentifier("target-filter-file", true); 584 filterInputFile.setArgumentGroupName( 585 INFO_MANAGE_ACCT_ARG_GROUP_TARGET_USER_ARGS.get()); 586 parser.addArgument(filterInputFile); 587 588 final StringArgument targetUserID = new StringArgument(null, 589 ARG_TARGET_USER_ID, false, 0, null, 590 INFO_MANAGE_ACCT_ARG_DESC_TARGET_USER_ID.get(ARG_BASE_DN, 591 ARG_USER_ID_ATTRIBUTE)); 592 targetUserID.addLongIdentifier("userID", true); 593 targetUserID.addLongIdentifier("target-user-id", true); 594 targetUserID.addLongIdentifier("user-id", true); 595 targetUserID.setArgumentGroupName( 596 INFO_MANAGE_ACCT_ARG_GROUP_TARGET_USER_ARGS.get()); 597 parser.addArgument(targetUserID); 598 599 final FileArgument userIDInputFile = new FileArgument(null, 600 ARG_USER_ID_INPUT_FILE, false, 0, null, 601 INFO_MANAGE_ACCT_ARG_DESC_USER_ID_INPUT_FILE.get(ARG_BASE_DN, 602 ARG_USER_ID_ATTRIBUTE), 603 true, true, true, false); 604 userIDInputFile.addLongIdentifier("targetUserIDFile", true); 605 userIDInputFile.addLongIdentifier("user-id-input-file", true); 606 userIDInputFile.addLongIdentifier("target-user-id-file", true); 607 userIDInputFile.setArgumentGroupName( 608 INFO_MANAGE_ACCT_ARG_GROUP_TARGET_USER_ARGS.get()); 609 parser.addArgument(userIDInputFile); 610 611 final StringArgument userIDAttribute = new StringArgument(null, 612 ARG_USER_ID_ATTRIBUTE, false, 1, null, 613 INFO_MANAGE_ACCT_ARG_DESC_USER_ID_ATTR.get( 614 ARG_TARGET_USER_ID, ARG_USER_ID_INPUT_FILE, 615 DEFAULT_USER_ID_ATTRIBUTE), 616 DEFAULT_USER_ID_ATTRIBUTE); 617 userIDAttribute.addLongIdentifier("user-id-attribute", true); 618 userIDAttribute.setArgumentGroupName( 619 INFO_MANAGE_ACCT_ARG_GROUP_TARGET_USER_ARGS.get()); 620 parser.addArgument(userIDAttribute); 621 622 final DNArgument baseDN = new DNArgument(null, ARG_BASE_DN, false, 1, null, 623 INFO_MANAGE_ACCT_ARG_DESC_BASE_DN.get(ARG_TARGET_FILTER, 624 ARG_FILTER_INPUT_FILE, ARG_TARGET_USER_ID, 625 ARG_USER_ID_INPUT_FILE), 626 DEFAULT_BASE_DN); 627 baseDN.addLongIdentifier("base-dn", true); 628 baseDN.setArgumentGroupName( 629 INFO_MANAGE_ACCT_ARG_GROUP_TARGET_USER_ARGS.get()); 630 parser.addArgument(baseDN); 631 632 final IntegerArgument simplePageSize = new IntegerArgument('z', 633 ARG_SIMPLE_PAGE_SIZE, false, 1, null, 634 INFO_MANAGE_ACCT_ARG_DESC_SIMPLE_PAGE_SIZE.get(getToolName()), 1, 635 Integer.MAX_VALUE); 636 simplePageSize.addLongIdentifier("simple-page-size", true); 637 simplePageSize.setArgumentGroupName( 638 INFO_MANAGE_ACCT_ARG_GROUP_TARGET_USER_ARGS.get(getToolName())); 639 parser.addArgument(simplePageSize); 640 641 642 // Ensure that the user will be required ot provide at least one of the 643 // arguments to specify which users to target. 644 parser.addRequiredArgumentSet(targetDN, dnInputFile, targetFilter, 645 filterInputFile, targetUserID, userIDInputFile); 646 647 648 // Define the global arguments used to control the amount of load the tool 649 // should be permitted to generate. 650 final IntegerArgument numThreads = new IntegerArgument('t', ARG_NUM_THREADS, 651 false, 1, null, 652 INFO_MANAGE_ACCT_ARG_DESC_NUM_THREADS.get(getToolName()), 1, 653 Integer.MAX_VALUE, 1); 654 numThreads.addLongIdentifier("num-threads", true); 655 numThreads.setArgumentGroupName( 656 INFO_MANAGE_ACCT_ARG_GROUP_PERFORMANCE.get()); 657 parser.addArgument(numThreads); 658 659 final IntegerArgument numSearchThreads = new IntegerArgument(null, 660 ARG_NUM_SEARCH_THREADS, false, 1, null, 661 INFO_MANAGE_ACCT_ARG_DESC_NUM_SEARCH_THREADS.get(getToolName()), 1, 662 Integer.MAX_VALUE, 1); 663 numSearchThreads.addLongIdentifier("num-search-threads", true); 664 numSearchThreads.setArgumentGroupName( 665 INFO_MANAGE_ACCT_ARG_GROUP_PERFORMANCE.get()); 666 parser.addArgument(numSearchThreads); 667 668 final IntegerArgument ratePerSecond = new IntegerArgument('r', 669 ARG_RATE_PER_SECOND, false, 1, null, 670 INFO_MANAGE_ACCT_ARG_DESC_RATE_PER_SECOND.get( 671 ARG_VARIABLE_RATE_DATA), 672 1, Integer.MAX_VALUE); 673 ratePerSecond.addLongIdentifier("rate-per-second", true); 674 ratePerSecond.setArgumentGroupName( 675 INFO_MANAGE_ACCT_ARG_GROUP_PERFORMANCE.get()); 676 parser.addArgument(ratePerSecond); 677 678 final FileArgument variableRateData = new FileArgument(null, 679 ARG_VARIABLE_RATE_DATA, false, 1, null, 680 INFO_MANAGE_ACCT_ARG_DESC_VARIABLE_RATE_DATA.get( 681 ARG_RATE_PER_SECOND), 682 true, true, true, false); 683 variableRateData.addLongIdentifier("variable-rate-data", true); 684 variableRateData.setArgumentGroupName( 685 INFO_MANAGE_ACCT_ARG_GROUP_PERFORMANCE.get()); 686 parser.addArgument(variableRateData); 687 688 final FileArgument generateSampleRateFile = new FileArgument(null, 689 ARG_GENERATE_SAMPLE_RATE_FILE, false, 1, null, 690 INFO_MANAGE_ACCT_ARG_DESC_GENERATE_SAMPLE_RATE_FILE.get( 691 ARG_VARIABLE_RATE_DATA), 692 false, true, true, false); 693 generateSampleRateFile.addLongIdentifier("generate-sample-rate-file", true); 694 generateSampleRateFile.setArgumentGroupName( 695 INFO_MANAGE_ACCT_ARG_GROUP_PERFORMANCE.get()); 696 generateSampleRateFile.setUsageArgument(true); 697 parser.addArgument(generateSampleRateFile); 698 699 700 // Define the global arguments tht pertain to the reject file. 701 final FileArgument rejectFile = new FileArgument('R', ARG_REJECT_FILE, 702 false, 1, null, INFO_MANAGE_ACCT_ARG_DESC_REJECT_FILE.get(), 703 false, true, true, false); 704 rejectFile.addLongIdentifier("reject-file", true); 705 parser.addArgument(rejectFile); 706 707 final BooleanArgument appendToRejectFile = new BooleanArgument(null, 708 ARG_APPEND_TO_REJECT_FILE, 1, 709 INFO_MANAGE_ACCT_ARG_DESC_APPEND_TO_REJECT_FILE.get( 710 rejectFile.getIdentifierString())); 711 appendToRejectFile.addLongIdentifier("append-to-reject-file", true); 712 parser.addArgument(appendToRejectFile); 713 714 parser.addDependentArgumentSet(appendToRejectFile, rejectFile); 715 716 717 // Define the argument used to suppress result operations without values. 718 final BooleanArgument suppressEmptyResultOperations = 719 new BooleanArgument(null, ARG_SUPPRESS_EMPTY_RESULT_OPERATIONS, 720 1, 721 INFO_MANAGE_ACCT_ARG_DESC_SUPPRESS_EMPTY_RESULT_OPERATIONS.get( 722 getToolName())); 723 parser.addArgument(suppressEmptyResultOperations); 724 725 726 // Define the subcommand used to retrieve all state information for a user. 727 createSubCommand(ManageAccountSubCommandType.GET_ALL, 728 INFO_MANAGE_ACCT_SC_GET_ALL_EXAMPLE.get(EXAMPLE_TARGET_USER_DN)); 729 730 731 // Define the subcommand used to retrieve the password policy DN for a user. 732 createSubCommand(ManageAccountSubCommandType.GET_PASSWORD_POLICY_DN, 733 INFO_MANAGE_ACCT_SC_GET_POLICY_DN_EXAMPLE.get(EXAMPLE_TARGET_USER_DN)); 734 735 736 // Define the subcommand to determine whether the account is usable. 737 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_IS_USABLE, 738 INFO_MANAGE_ACCT_SC_GET_IS_USABLE_EXAMPLE.get(EXAMPLE_TARGET_USER_DN)); 739 740 741 // Define the subcommand to retrieve the set of password policy state 742 // account usability notice messages. 743 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_USABILITY_NOTICES, 744 INFO_MANAGE_ACCT_SC_GET_USABILITY_NOTICES_EXAMPLE.get( 745 EXAMPLE_TARGET_USER_DN)); 746 747 748 // Define the subcommand to retrieve the set of password policy state 749 // account usability warning messages. 750 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_USABILITY_WARNINGS, 751 INFO_MANAGE_ACCT_SC_GET_USABILITY_WARNINGS_EXAMPLE.get( 752 EXAMPLE_TARGET_USER_DN)); 753 754 755 // Define the subcommand to retrieve the set of password policy state 756 // account usability error messages. 757 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_USABILITY_ERRORS, 758 INFO_MANAGE_ACCT_SC_GET_USABILITY_ERRORS_EXAMPLE.get( 759 EXAMPLE_TARGET_USER_DN)); 760 761 762 // Define the subcommand to retrieve the password changed time for a user. 763 createSubCommand(ManageAccountSubCommandType.GET_PASSWORD_CHANGED_TIME, 764 INFO_MANAGE_ACCT_SC_GET_PW_CHANGED_TIME_EXAMPLE.get( 765 EXAMPLE_TARGET_USER_DN)); 766 767 768 // Define the subcommand to set the password changed time for a user. 769 final ArgumentParser setPWChangedTimeParser = 770 createSubCommandParser( 771 ManageAccountSubCommandType.SET_PASSWORD_CHANGED_TIME); 772 773 final TimestampArgument setPWChangedTimeValueArg = new TimestampArgument( 774 'O', "passwordChangedTime", false, 1, null, 775 INFO_MANAGE_ACCT_SC_SET_PW_CHANGED_TIME_ARG_VALUE.get()); 776 setPWChangedTimeValueArg.addLongIdentifier("operationValue", true); 777 setPWChangedTimeValueArg.addLongIdentifier("password-changed-time", true); 778 setPWChangedTimeValueArg.addLongIdentifier("operation-value", true); 779 setPWChangedTimeParser.addArgument(setPWChangedTimeValueArg); 780 781 createSubCommand(ManageAccountSubCommandType.SET_PASSWORD_CHANGED_TIME, 782 setPWChangedTimeParser, 783 createSubCommandExample( 784 ManageAccountSubCommandType.SET_PASSWORD_CHANGED_TIME, 785 INFO_MANAGE_ACCT_SC_SET_PW_CHANGED_TIME_EXAMPLE.get( 786 EXAMPLE_TARGET_USER_DN, currentGeneralizedTime), 787 "--passwordChangedTime", currentGeneralizedTime)); 788 789 790 // Define the subcommand to clear the password changed time for a user. 791 createSubCommand(ManageAccountSubCommandType.CLEAR_PASSWORD_CHANGED_TIME, 792 INFO_MANAGE_ACCT_SC_CLEAR_PW_CHANGED_TIME_EXAMPLE.get( 793 EXAMPLE_TARGET_USER_DN)); 794 795 796 // Define the subcommand to determine whether a user account is disabled. 797 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_IS_DISABLED, 798 INFO_MANAGE_ACCT_SC_GET_IS_DISABLED_EXAMPLE.get( 799 EXAMPLE_TARGET_USER_DN)); 800 801 802 // Define the subcommand to specify whether a user's account is disabled. 803 final ArgumentParser setAcctDisabledParser = 804 createSubCommandParser( 805 ManageAccountSubCommandType.SET_ACCOUNT_IS_DISABLED); 806 807 final BooleanValueArgument setAcctDisabledValueArg = 808 new BooleanValueArgument('O', "accountIsDisabled", true, null, 809 INFO_MANAGE_ACCT_SC_SET_IS_DISABLED_ARG_VALUE.get()); 810 setAcctDisabledValueArg.addLongIdentifier("operationValue", true); 811 setAcctDisabledValueArg.addLongIdentifier("account-is-disabled", true); 812 setAcctDisabledValueArg.addLongIdentifier("operation-value", true); 813 setAcctDisabledParser.addArgument(setAcctDisabledValueArg); 814 815 createSubCommand(ManageAccountSubCommandType.SET_ACCOUNT_IS_DISABLED, 816 setAcctDisabledParser, 817 createSubCommandExample( 818 ManageAccountSubCommandType.SET_ACCOUNT_IS_DISABLED, 819 INFO_MANAGE_ACCT_SC_SET_IS_DISABLED_EXAMPLE.get( 820 EXAMPLE_TARGET_USER_DN), 821 "--accountIsDisabled", "true")); 822 823 824 // Define the subcommand to clear the account disabled state. 825 createSubCommand(ManageAccountSubCommandType.CLEAR_ACCOUNT_IS_DISABLED, 826 INFO_MANAGE_ACCT_SC_CLEAR_IS_DISABLED_EXAMPLE.get( 827 EXAMPLE_TARGET_USER_DN)); 828 829 830 // Define the subcommand to retrieve the account activation time for a user. 831 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_ACTIVATION_TIME, 832 INFO_MANAGE_ACCT_SC_GET_ACCT_ACT_TIME_EXAMPLE.get( 833 EXAMPLE_TARGET_USER_DN)); 834 835 836 // Define the subcommand to set the account activation time for a user. 837 final ArgumentParser setAcctActivationTimeParser = 838 createSubCommandParser( 839 ManageAccountSubCommandType.SET_ACCOUNT_ACTIVATION_TIME); 840 841 final TimestampArgument setAcctActivationTimeValueArg = 842 new TimestampArgument('O', "accountActivationTime", false, 1, null, 843 INFO_MANAGE_ACCT_SC_SET_ACCT_ACT_TIME_ARG_VALUE.get()); 844 setAcctActivationTimeValueArg.addLongIdentifier("operationValue", true); 845 setAcctActivationTimeValueArg.addLongIdentifier("account-activation-time", 846 true); 847 setAcctActivationTimeValueArg.addLongIdentifier("operation-value", true); 848 setAcctActivationTimeParser.addArgument(setAcctActivationTimeValueArg); 849 850 createSubCommand(ManageAccountSubCommandType.SET_ACCOUNT_ACTIVATION_TIME, 851 setAcctActivationTimeParser, 852 createSubCommandExample( 853 ManageAccountSubCommandType.SET_ACCOUNT_ACTIVATION_TIME, 854 INFO_MANAGE_ACCT_SC_SET_ACCT_ACT_TIME_EXAMPLE.get( 855 EXAMPLE_TARGET_USER_DN, currentGeneralizedTime), 856 "--accountActivationTime", currentGeneralizedTime)); 857 858 859 // Define the subcommand to clear the account activation time for a user. 860 createSubCommand(ManageAccountSubCommandType.CLEAR_ACCOUNT_ACTIVATION_TIME, 861 INFO_MANAGE_ACCT_SC_CLEAR_ACCT_ACT_TIME_EXAMPLE.get( 862 EXAMPLE_TARGET_USER_DN)); 863 864 865 // Define the subcommand to retrieve the length of time until a user's 866 // account is activated. 867 createSubCommand( 868 ManageAccountSubCommandType.GET_SECONDS_UNTIL_ACCOUNT_ACTIVATION, 869 INFO_MANAGE_ACCT_SC_GET_SECONDS_UNTIL_ACCT_ACT_EXAMPLE.get( 870 EXAMPLE_TARGET_USER_DN)); 871 872 873 // Define the subcommand to determine whether a user's account is not yet 874 // active. 875 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_IS_NOT_YET_ACTIVE, 876 INFO_MANAGE_ACCT_SC_GET_ACCT_NOT_YET_ACTIVE_EXAMPLE.get( 877 EXAMPLE_TARGET_USER_DN)); 878 879 880 // Define the subcommand to retrieve the account expiration time for a user. 881 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_EXPIRATION_TIME, 882 INFO_MANAGE_ACCT_SC_GET_ACCT_EXP_TIME_EXAMPLE.get( 883 EXAMPLE_TARGET_USER_DN)); 884 885 886 // Define the subcommand to set the account expiration time for a user. 887 final ArgumentParser setAcctExpirationTimeParser = 888 createSubCommandParser( 889 ManageAccountSubCommandType.SET_ACCOUNT_EXPIRATION_TIME); 890 891 final TimestampArgument setAcctExpirationTimeValueArg = 892 new TimestampArgument('O', "accountExpirationTime", false, 1, null, 893 INFO_MANAGE_ACCT_SC_SET_ACCT_EXP_TIME_ARG_VALUE.get()); 894 setAcctExpirationTimeValueArg.addLongIdentifier("operationValue", true); 895 setAcctExpirationTimeValueArg.addLongIdentifier("account-expiration-time", 896 true); 897 setAcctExpirationTimeValueArg.addLongIdentifier("operation-value", true); 898 setAcctExpirationTimeParser.addArgument(setAcctExpirationTimeValueArg); 899 900 createSubCommand(ManageAccountSubCommandType.SET_ACCOUNT_EXPIRATION_TIME, 901 setAcctExpirationTimeParser, 902 createSubCommandExample( 903 ManageAccountSubCommandType.SET_ACCOUNT_EXPIRATION_TIME, 904 INFO_MANAGE_ACCT_SC_SET_ACCT_EXP_TIME_EXAMPLE.get( 905 EXAMPLE_TARGET_USER_DN, currentGeneralizedTime), 906 "--accountExpirationTime", currentGeneralizedTime)); 907 908 909 // Define the subcommand to clear the account expiration time for a user. 910 createSubCommand(ManageAccountSubCommandType.CLEAR_ACCOUNT_EXPIRATION_TIME, 911 INFO_MANAGE_ACCT_SC_CLEAR_ACCT_EXP_TIME_EXAMPLE.get( 912 EXAMPLE_TARGET_USER_DN)); 913 914 915 // Define the subcommand to retrieve the length of time until a user's 916 // account is expired. 917 createSubCommand( 918 ManageAccountSubCommandType.GET_SECONDS_UNTIL_ACCOUNT_EXPIRATION, 919 INFO_MANAGE_ACCT_SC_GET_SECONDS_UNTIL_ACCT_EXP_EXAMPLE.get( 920 EXAMPLE_TARGET_USER_DN)); 921 922 923 // Define the subcommand to determine whether a user's account is expired. 924 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_IS_EXPIRED, 925 INFO_MANAGE_ACCT_SC_GET_ACCT_IS_EXPIRED_EXAMPLE.get( 926 EXAMPLE_TARGET_USER_DN)); 927 928 929 // Define the subcommand to retrieve a user's password expiration warned 930 // time. 931 createSubCommand( 932 ManageAccountSubCommandType.GET_PASSWORD_EXPIRATION_WARNED_TIME, 933 INFO_MANAGE_ACCT_SC_GET_PW_EXP_WARNED_TIME_EXAMPLE.get( 934 EXAMPLE_TARGET_USER_DN)); 935 936 937 // Define the subcommand to set a user's password expiration warned time. 938 final ArgumentParser setPWExpWarnedTimeParser = 939 createSubCommandParser( 940 ManageAccountSubCommandType.SET_PASSWORD_EXPIRATION_WARNED_TIME); 941 942 final TimestampArgument setPWExpWarnedTimeValueArg = 943 new TimestampArgument('O', "passwordExpirationWarnedTime", false, 1, 944 null, INFO_MANAGE_ACCT_SC_SET_PW_EXP_WARNED_TIME_ARG_VALUE.get()); 945 setPWExpWarnedTimeValueArg.addLongIdentifier("operationValue", true); 946 setPWExpWarnedTimeValueArg.addLongIdentifier( 947 "password-expiration-warned-time", true); 948 setPWExpWarnedTimeValueArg.addLongIdentifier("operation-value", true); 949 setPWExpWarnedTimeParser.addArgument(setPWExpWarnedTimeValueArg); 950 951 createSubCommand( 952 ManageAccountSubCommandType.SET_PASSWORD_EXPIRATION_WARNED_TIME, 953 setPWExpWarnedTimeParser, 954 createSubCommandExample( 955 ManageAccountSubCommandType.SET_PASSWORD_EXPIRATION_WARNED_TIME, 956 INFO_MANAGE_ACCT_SC_SET_PW_EXP_WARNED_TIME_EXAMPLE.get( 957 EXAMPLE_TARGET_USER_DN, currentGeneralizedTime), 958 "--passwordExpirationWarnedTime", currentGeneralizedTime)); 959 960 961 // Define the subcommand to clear a user's password expiration warned time. 962 createSubCommand( 963 ManageAccountSubCommandType.CLEAR_PASSWORD_EXPIRATION_WARNED_TIME, 964 INFO_MANAGE_ACCT_SC_CLEAR_PW_EXP_WARNED_TIME_EXAMPLE.get( 965 EXAMPLE_TARGET_USER_DN)); 966 967 968 // Define the subcommand to get the number of seconds until a user is 969 // eligible to receive a password expiration warning. 970 createSubCommand( 971 ManageAccountSubCommandType. 972 GET_SECONDS_UNTIL_PASSWORD_EXPIRATION_WARNING, 973 INFO_MANAGE_ACCT_SC_GET_SECONDS_UNTIL_PW_EXP_WARNING_EXAMPLE.get( 974 EXAMPLE_TARGET_USER_DN)); 975 976 977 // Define the subcommand to retrieve a user's password expiration time. 978 createSubCommand(ManageAccountSubCommandType.GET_PASSWORD_EXPIRATION_TIME, 979 INFO_MANAGE_ACCT_SC_GET_PW_EXP_TIME_EXAMPLE.get( 980 EXAMPLE_TARGET_USER_DN)); 981 982 983 // Define the subcommand to get the number of seconds until a user's 984 // password expires. 985 createSubCommand( 986 ManageAccountSubCommandType.GET_SECONDS_UNTIL_PASSWORD_EXPIRATION, 987 INFO_MANAGE_ACCT_SC_GET_SECONDS_UNTIL_PW_EXP_EXAMPLE.get( 988 EXAMPLE_TARGET_USER_DN)); 989 990 991 // Define the subcommand to determine whether a user's password is expired. 992 createSubCommand(ManageAccountSubCommandType.GET_PASSWORD_IS_EXPIRED, 993 INFO_MANAGE_ACCT_SC_GET_PW_IS_EXPIRED_EXAMPLE.get( 994 EXAMPLE_TARGET_USER_DN)); 995 996 997 // Define the subcommand to determine whether an account is failure locked. 998 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_IS_FAILURE_LOCKED, 999 INFO_MANAGE_ACCT_SC_GET_ACCT_FAILURE_LOCKED_EXAMPLE.get( 1000 EXAMPLE_TARGET_USER_DN)); 1001 1002 1003 // Define the subcommand to specify whether an account is failure locked. 1004 final ArgumentParser setIsFailureLockedParser = 1005 createSubCommandParser( 1006 ManageAccountSubCommandType.SET_ACCOUNT_IS_FAILURE_LOCKED); 1007 1008 final BooleanValueArgument setIsFailureLockedValueArg = 1009 new BooleanValueArgument('O', "accountIsFailureLocked", true, null, 1010 INFO_MANAGE_ACCT_SC_SET_ACCT_FAILURE_LOCKED_ARG_VALUE.get()); 1011 setIsFailureLockedValueArg.addLongIdentifier("operationValue", true); 1012 setIsFailureLockedValueArg.addLongIdentifier("account-is-failure-locked", 1013 true); 1014 setIsFailureLockedValueArg.addLongIdentifier("operation-value", true); 1015 setIsFailureLockedParser.addArgument(setIsFailureLockedValueArg); 1016 1017 createSubCommand(ManageAccountSubCommandType.SET_ACCOUNT_IS_FAILURE_LOCKED, 1018 setIsFailureLockedParser, 1019 createSubCommandExample( 1020 ManageAccountSubCommandType.SET_ACCOUNT_IS_FAILURE_LOCKED, 1021 INFO_MANAGE_ACCT_SC_SET_ACCT_FAILURE_LOCKED_EXAMPLE.get( 1022 EXAMPLE_TARGET_USER_DN), 1023 "--accountIsFailureLocked", "true")); 1024 1025 1026 // Define the subcommand to get the time an account was failure locked. 1027 createSubCommand(ManageAccountSubCommandType.GET_FAILURE_LOCKOUT_TIME, 1028 INFO_MANAGE_ACCT_SC_GET_FAILURE_LOCKED_TIME_EXAMPLE.get( 1029 EXAMPLE_TARGET_USER_DN)); 1030 1031 1032 // Define the subcommand to get the length of time until a failure-locked 1033 // account will be automatically unlocked. 1034 createSubCommand( 1035 ManageAccountSubCommandType. 1036 GET_SECONDS_UNTIL_AUTHENTICATION_FAILURE_UNLOCK, 1037 INFO_MANAGE_ACCT_SC_GET_SECONDS_UNTIL_FAILURE_UNLOCK_EXAMPLE.get( 1038 EXAMPLE_TARGET_USER_DN)); 1039 1040 1041 // Define the subcommand to determine the authentication failure times. 1042 createSubCommand( 1043 ManageAccountSubCommandType.GET_AUTHENTICATION_FAILURE_TIMES, 1044 INFO_MANAGE_ACCT_SC_GET_AUTH_FAILURE_TIMES_EXAMPLE.get( 1045 EXAMPLE_TARGET_USER_DN)); 1046 1047 1048 // Define the subcommand to add values to the set of authentication failure 1049 // times. 1050 final ArgumentParser addAuthFailureTimeParser = 1051 createSubCommandParser( 1052 ManageAccountSubCommandType.ADD_AUTHENTICATION_FAILURE_TIME); 1053 1054 final TimestampArgument addAuthFailureTimeValueArg = 1055 new TimestampArgument('O', "authenticationFailureTime", false, 0, null, 1056 INFO_MANAGE_ACCT_SC_ADD_AUTH_FAILURE_TIME_ARG_VALUE.get()); 1057 addAuthFailureTimeValueArg.addLongIdentifier("operationValue", true); 1058 addAuthFailureTimeValueArg.addLongIdentifier( 1059 "authentication-failure-time", true); 1060 addAuthFailureTimeValueArg.addLongIdentifier("operation-value", true); 1061 addAuthFailureTimeParser.addArgument(addAuthFailureTimeValueArg); 1062 1063 createSubCommand( 1064 ManageAccountSubCommandType.ADD_AUTHENTICATION_FAILURE_TIME, 1065 addAuthFailureTimeParser, 1066 createSubCommandExample( 1067 ManageAccountSubCommandType.ADD_AUTHENTICATION_FAILURE_TIME, 1068 INFO_MANAGE_ACCT_SC_ADD_AUTH_FAILURE_TIME_EXAMPLE.get( 1069 EXAMPLE_TARGET_USER_DN))); 1070 1071 1072 // Define the subcommand to replace the authentication failure times. 1073 final ArgumentParser setAuthFailureTimesParser = 1074 createSubCommandParser( 1075 ManageAccountSubCommandType.SET_AUTHENTICATION_FAILURE_TIMES); 1076 1077 final TimestampArgument setAuthFailureTimesValueArg = 1078 new TimestampArgument('O', "authenticationFailureTime", false, 0, null, 1079 INFO_MANAGE_ACCT_SC_SET_AUTH_FAILURE_TIMES_ARG_VALUE.get()); 1080 setAuthFailureTimesValueArg.addLongIdentifier("operationValue", true); 1081 setAuthFailureTimesValueArg.addLongIdentifier( 1082 "authentication-failure-time", true); 1083 setAuthFailureTimesValueArg.addLongIdentifier("operation-value", true); 1084 setAuthFailureTimesParser.addArgument(setAuthFailureTimesValueArg); 1085 1086 createSubCommand( 1087 ManageAccountSubCommandType.SET_AUTHENTICATION_FAILURE_TIMES, 1088 setAuthFailureTimesParser, 1089 createSubCommandExample( 1090 ManageAccountSubCommandType.SET_AUTHENTICATION_FAILURE_TIMES, 1091 INFO_MANAGE_ACCT_SC_SET_AUTH_FAILURE_TIMES_EXAMPLE.get( 1092 EXAMPLE_TARGET_USER_DN, olderGeneralizedTime, 1093 currentGeneralizedTime), 1094 "--authenticationFailureTime", olderGeneralizedTime, 1095 "--authenticationFailureTime", currentGeneralizedTime)); 1096 1097 1098 // Define the subcommand to clear the authentication failure times. 1099 createSubCommand( 1100 ManageAccountSubCommandType.CLEAR_AUTHENTICATION_FAILURE_TIMES, 1101 INFO_MANAGE_ACCT_SC_CLEAR_AUTH_FAILURE_TIMES_EXAMPLE.get( 1102 EXAMPLE_TARGET_USER_DN)); 1103 1104 1105 // Define the subcommand to get the remaining authentication failure count. 1106 createSubCommand( 1107 ManageAccountSubCommandType.GET_REMAINING_AUTHENTICATION_FAILURE_COUNT, 1108 INFO_MANAGE_ACCT_SC_GET_REMAINING_FAILURE_COUNT_EXAMPLE.get( 1109 EXAMPLE_TARGET_USER_DN)); 1110 1111 1112 // Define the subcommand to determine whether the account is idle locked. 1113 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_IS_IDLE_LOCKED, 1114 INFO_MANAGE_ACCT_SC_GET_ACCT_IDLE_LOCKED_EXAMPLE.get( 1115 EXAMPLE_TARGET_USER_DN)); 1116 1117 1118 // Define the subcommand to get the length of time until the account is 1119 // idle locked. 1120 createSubCommand(ManageAccountSubCommandType.GET_SECONDS_UNTIL_IDLE_LOCKOUT, 1121 INFO_MANAGE_ACCT_SC_GET_SECONDS_UNTIL_IDLE_LOCKOUT_EXAMPLE.get( 1122 EXAMPLE_TARGET_USER_DN)); 1123 1124 1125 // Define the subcommand to get the idle lockout time for an account. 1126 createSubCommand(ManageAccountSubCommandType.GET_IDLE_LOCKOUT_TIME, 1127 INFO_MANAGE_ACCT_SC_GET_IDLE_LOCKOUT_TIME_EXAMPLE.get( 1128 EXAMPLE_TARGET_USER_DN)); 1129 1130 1131 // Define the subcommand to determine whether a user's password has been 1132 // reset. 1133 createSubCommand(ManageAccountSubCommandType.GET_MUST_CHANGE_PASSWORD, 1134 INFO_MANAGE_ACCT_SC_GET_MUST_CHANGE_PW_EXAMPLE.get( 1135 EXAMPLE_TARGET_USER_DN)); 1136 1137 1138 // Define the subcommand to specify whether a user's password has been 1139 // reset. 1140 final ArgumentParser setPWIsResetParser = 1141 createSubCommandParser( 1142 ManageAccountSubCommandType.SET_MUST_CHANGE_PASSWORD); 1143 1144 final BooleanValueArgument setPWIsResetValueArg = 1145 new BooleanValueArgument('O', "mustChangePassword", true, null, 1146 INFO_MANAGE_ACCT_SC_SET_MUST_CHANGE_PW_ARG_VALUE.get()); 1147 setPWIsResetValueArg.addLongIdentifier("passwordIsReset", true); 1148 setPWIsResetValueArg.addLongIdentifier("operationValue", true); 1149 setPWIsResetValueArg.addLongIdentifier("must-change-password", true); 1150 setPWIsResetValueArg.addLongIdentifier("password-is-reset", true); 1151 setPWIsResetValueArg.addLongIdentifier("operation-value", true); 1152 setPWIsResetParser.addArgument(setPWIsResetValueArg); 1153 1154 createSubCommand(ManageAccountSubCommandType.SET_MUST_CHANGE_PASSWORD, 1155 setPWIsResetParser, 1156 createSubCommandExample( 1157 ManageAccountSubCommandType.SET_MUST_CHANGE_PASSWORD, 1158 INFO_MANAGE_ACCT_SC_SET_MUST_CHANGE_PW_EXAMPLE.get( 1159 EXAMPLE_TARGET_USER_DN), 1160 "--mustChangePassword", "true")); 1161 1162 1163 // Define the subcommand to clear the password reset state information. 1164 createSubCommand(ManageAccountSubCommandType.CLEAR_MUST_CHANGE_PASSWORD, 1165 INFO_MANAGE_ACCT_SC_CLEAR_MUST_CHANGE_PW_EXAMPLE.get( 1166 EXAMPLE_TARGET_USER_DN)); 1167 1168 1169 // Define the subcommand to determine whether the account is reset locked. 1170 createSubCommand( 1171 ManageAccountSubCommandType.GET_ACCOUNT_IS_PASSWORD_RESET_LOCKED, 1172 INFO_MANAGE_ACCT_SC_GET_ACCT_IS_RESET_LOCKED_EXAMPLE.get( 1173 EXAMPLE_TARGET_USER_DN)); 1174 1175 1176 // Define the subcommand to get the length of time until the password is 1177 // reset locked. 1178 createSubCommand( 1179 ManageAccountSubCommandType.GET_SECONDS_UNTIL_PASSWORD_RESET_LOCKOUT, 1180 INFO_MANAGE_ACCT_SC_GET_SECONDS_UNTIL_RESET_LOCKOUT_EXAMPLE.get( 1181 EXAMPLE_TARGET_USER_DN)); 1182 1183 1184 // Define the subcommand to get the password reset lockout time. 1185 createSubCommand( 1186 ManageAccountSubCommandType.GET_PASSWORD_RESET_LOCKOUT_TIME, 1187 INFO_MANAGE_ACCT_SC_GET_RESET_LOCKOUT_TIME_EXAMPLE.get( 1188 EXAMPLE_TARGET_USER_DN)); 1189 1190 1191 // Define the subcommand to get the last login time. 1192 createSubCommand(ManageAccountSubCommandType.GET_LAST_LOGIN_TIME, 1193 INFO_MANAGE_ACCT_SC_GET_LAST_LOGIN_TIME_EXAMPLE.get( 1194 EXAMPLE_TARGET_USER_DN)); 1195 1196 1197 // Define the subcommand to set the last login time. 1198 final ArgumentParser setLastLoginTimeParser = 1199 createSubCommandParser( 1200 ManageAccountSubCommandType.SET_LAST_LOGIN_TIME); 1201 1202 final TimestampArgument setLastLoginTimeValueArg = new TimestampArgument( 1203 'O', "lastLoginTime", false, 1, null, 1204 INFO_MANAGE_ACCT_SC_SET_LAST_LOGIN_TIME_ARG_VALUE.get()); 1205 setLastLoginTimeValueArg.addLongIdentifier("operationValue", true); 1206 setLastLoginTimeValueArg.addLongIdentifier("last-login-time", true); 1207 setLastLoginTimeValueArg.addLongIdentifier("operation-value", true); 1208 setLastLoginTimeParser.addArgument(setLastLoginTimeValueArg); 1209 1210 createSubCommand(ManageAccountSubCommandType.SET_LAST_LOGIN_TIME, 1211 setLastLoginTimeParser, 1212 createSubCommandExample( 1213 ManageAccountSubCommandType.SET_LAST_LOGIN_TIME, 1214 INFO_MANAGE_ACCT_SC_SET_LAST_LOGIN_TIME_EXAMPLE.get( 1215 EXAMPLE_TARGET_USER_DN, currentGeneralizedTime), 1216 "--lastLoginTime", currentGeneralizedTime)); 1217 1218 1219 // Define the subcommand to clear the last login time. 1220 createSubCommand(ManageAccountSubCommandType.CLEAR_LAST_LOGIN_TIME, 1221 INFO_MANAGE_ACCT_SC_CLEAR_LAST_LOGIN_TIME_EXAMPLE.get( 1222 EXAMPLE_TARGET_USER_DN)); 1223 1224 1225 // Define the subcommand to get the last login IP address. 1226 createSubCommand(ManageAccountSubCommandType.GET_LAST_LOGIN_IP_ADDRESS, 1227 INFO_MANAGE_ACCT_SC_GET_LAST_LOGIN_IP_EXAMPLE.get( 1228 EXAMPLE_TARGET_USER_DN)); 1229 1230 1231 // Define the subcommand to set the last login IP address. 1232 final ArgumentParser setLastLoginIPParser = 1233 createSubCommandParser( 1234 ManageAccountSubCommandType.SET_LAST_LOGIN_IP_ADDRESS); 1235 1236 final StringArgument setLastLoginIPValueArg = new StringArgument('O', 1237 "lastLoginIPAddress", true, 1, null, 1238 INFO_MANAGE_ACCT_SC_SET_LAST_LOGIN_IP_ARG_VALUE.get()); 1239 setLastLoginIPValueArg.addLongIdentifier("operationValue", true); 1240 setLastLoginIPValueArg.addLongIdentifier("last-login-ip-address", true); 1241 setLastLoginIPValueArg.addLongIdentifier("operation-value", true); 1242 setLastLoginIPValueArg.addValueValidator( 1243 new IPAddressArgumentValueValidator()); 1244 setLastLoginIPParser.addArgument(setLastLoginIPValueArg); 1245 1246 1247 createSubCommand(ManageAccountSubCommandType.SET_LAST_LOGIN_IP_ADDRESS, 1248 setLastLoginIPParser, 1249 createSubCommandExample( 1250 ManageAccountSubCommandType.SET_LAST_LOGIN_IP_ADDRESS, 1251 INFO_MANAGE_ACCT_SC_SET_LAST_LOGIN_IP_EXAMPLE.get( 1252 EXAMPLE_TARGET_USER_DN, "1.2.3.4"), 1253 "--lastLoginIPAddress", "1.2.3.4")); 1254 1255 1256 // Define the subcommand to clear the last login IP address. 1257 createSubCommand(ManageAccountSubCommandType.CLEAR_LAST_LOGIN_IP_ADDRESS, 1258 INFO_MANAGE_ACCT_SC_CLEAR_LAST_LOGIN_IP_EXAMPLE.get( 1259 EXAMPLE_TARGET_USER_DN)); 1260 1261 1262 // Define the subcommand to get the grace login use times. 1263 createSubCommand(ManageAccountSubCommandType.GET_GRACE_LOGIN_USE_TIMES, 1264 INFO_MANAGE_ACCT_SC_GET_GRACE_LOGIN_TIMES_EXAMPLE.get( 1265 EXAMPLE_TARGET_USER_DN)); 1266 1267 1268 // Define the subcommand to add values to the set of grace login use times. 1269 final ArgumentParser addGraceLoginTimeParser = 1270 createSubCommandParser( 1271 ManageAccountSubCommandType.ADD_GRACE_LOGIN_USE_TIME); 1272 1273 final TimestampArgument addGraceLoginTimeValueArg = 1274 new TimestampArgument('O', "graceLoginUseTime", false, 0, null, 1275 INFO_MANAGE_ACCT_SC_ADD_GRACE_LOGIN_TIME_ARG_VALUE.get()); 1276 addGraceLoginTimeValueArg.addLongIdentifier("operationValue", true); 1277 addGraceLoginTimeValueArg.addLongIdentifier("grace-login-use-time", true); 1278 addGraceLoginTimeValueArg.addLongIdentifier("operation-value", true); 1279 addGraceLoginTimeParser.addArgument(addGraceLoginTimeValueArg); 1280 1281 createSubCommand(ManageAccountSubCommandType.ADD_GRACE_LOGIN_USE_TIME, 1282 addGraceLoginTimeParser, 1283 createSubCommandExample( 1284 ManageAccountSubCommandType.ADD_GRACE_LOGIN_USE_TIME, 1285 INFO_MANAGE_ACCT_SC_ADD_GRACE_LOGIN_TIME_EXAMPLE.get( 1286 EXAMPLE_TARGET_USER_DN))); 1287 1288 1289 // Define the subcommand to replace the set of grace login use times. 1290 final ArgumentParser setGraceLoginTimesParser = 1291 createSubCommandParser( 1292 ManageAccountSubCommandType.SET_GRACE_LOGIN_USE_TIMES); 1293 1294 final TimestampArgument setGraceLoginTimesValueArg = 1295 new TimestampArgument('O', "graceLoginUseTime", false, 0, null, 1296 INFO_MANAGE_ACCT_SC_SET_GRACE_LOGIN_TIMES_ARG_VALUE.get()); 1297 setGraceLoginTimesValueArg.addLongIdentifier("operationValue", true); 1298 setGraceLoginTimesValueArg.addLongIdentifier("grace-login-use-time", true); 1299 setGraceLoginTimesValueArg.addLongIdentifier("operation-value", true); 1300 setGraceLoginTimesParser.addArgument(setGraceLoginTimesValueArg); 1301 1302 createSubCommand(ManageAccountSubCommandType.SET_GRACE_LOGIN_USE_TIMES, 1303 setGraceLoginTimesParser, 1304 createSubCommandExample( 1305 ManageAccountSubCommandType.SET_GRACE_LOGIN_USE_TIMES, 1306 INFO_MANAGE_ACCT_SC_SET_GRACE_LOGIN_TIMES_EXAMPLE.get( 1307 EXAMPLE_TARGET_USER_DN, olderGeneralizedTime, 1308 currentGeneralizedTime), 1309 "--graceLoginUseTime", olderGeneralizedTime, 1310 "--graceLoginUseTime", currentGeneralizedTime)); 1311 1312 1313 // Define the subcommand to clear the grace login use times. 1314 createSubCommand(ManageAccountSubCommandType.CLEAR_GRACE_LOGIN_USE_TIMES, 1315 INFO_MANAGE_ACCT_SC_CLEAR_GRACE_LOGIN_TIMES_EXAMPLE.get( 1316 EXAMPLE_TARGET_USER_DN)); 1317 1318 1319 // Define the subcommand to get the remaining grace login count. 1320 createSubCommand( 1321 ManageAccountSubCommandType.GET_REMAINING_GRACE_LOGIN_COUNT, 1322 INFO_MANAGE_ACCT_SC_GET_REMAINING_GRACE_LOGIN_COUNT_EXAMPLE.get( 1323 EXAMPLE_TARGET_USER_DN)); 1324 1325 1326 // Define the subcommand to get the password changed by required time value. 1327 createSubCommand( 1328 ManageAccountSubCommandType.GET_PASSWORD_CHANGED_BY_REQUIRED_TIME, 1329 INFO_MANAGE_ACCT_SC_GET_PW_CHANGED_BY_REQ_TIME_EXAMPLE.get( 1330 EXAMPLE_TARGET_USER_DN)); 1331 1332 1333 // Define the subcommand to set the password changed by required time value. 1334 final ArgumentParser setPWChangedByReqTimeParser = 1335 createSubCommandParser(ManageAccountSubCommandType. 1336 SET_PASSWORD_CHANGED_BY_REQUIRED_TIME); 1337 1338 final TimestampArgument setPWChangedByReqTimeValueArg = 1339 new TimestampArgument('O', "passwordChangedByRequiredTime", false, 1, 1340 null, 1341 INFO_MANAGE_ACCT_SC_SET_PW_CHANGED_BY_REQ_TIME_ARG_VALUE.get()); 1342 setPWChangedByReqTimeValueArg.addLongIdentifier("operationValue", true); 1343 setPWChangedByReqTimeValueArg.addLongIdentifier( 1344 "password-changed-by-required-time", true); 1345 setPWChangedByReqTimeValueArg.addLongIdentifier("operation-value", true); 1346 setPWChangedByReqTimeParser.addArgument( 1347 setPWChangedByReqTimeValueArg); 1348 1349 createSubCommand( 1350 ManageAccountSubCommandType.SET_PASSWORD_CHANGED_BY_REQUIRED_TIME, 1351 setPWChangedByReqTimeParser, 1352 createSubCommandExample( 1353 ManageAccountSubCommandType.SET_PASSWORD_CHANGED_BY_REQUIRED_TIME, 1354 INFO_MANAGE_ACCT_SC_SET_PW_CHANGED_BY_REQ_TIME_EXAMPLE.get( 1355 EXAMPLE_TARGET_USER_DN))); 1356 1357 1358 // Define the subcommand to clear the password changed by required time 1359 // value. 1360 createSubCommand( 1361 ManageAccountSubCommandType.CLEAR_PASSWORD_CHANGED_BY_REQUIRED_TIME, 1362 INFO_MANAGE_ACCT_SC_CLEAR_PW_CHANGED_BY_REQ_TIME_EXAMPLE.get( 1363 EXAMPLE_TARGET_USER_DN)); 1364 1365 1366 // Define the subcommand to get the length of time until the required change 1367 // time. 1368 createSubCommand( 1369 ManageAccountSubCommandType. 1370 GET_SECONDS_UNTIL_REQUIRED_PASSWORD_CHANGE_TIME, 1371 INFO_MANAGE_ACCT_SC_GET_SECS_UNTIL_REQ_CHANGE_TIME_EXAMPLE.get( 1372 EXAMPLE_TARGET_USER_DN)); 1373 1374 1375 // Define the subcommand to get the password history count. 1376 createSubCommand(ManageAccountSubCommandType.GET_PASSWORD_HISTORY_COUNT, 1377 INFO_MANAGE_ACCT_SC_GET_PW_HISTORY_COUNT_EXAMPLE.get( 1378 EXAMPLE_TARGET_USER_DN)); 1379 1380 1381 // Define the subcommand to clear a user's password history. 1382 createSubCommand(ManageAccountSubCommandType.CLEAR_PASSWORD_HISTORY, 1383 INFO_MANAGE_ACCT_SC_CLEAR_PW_HISTORY_EXAMPLE.get( 1384 EXAMPLE_TARGET_USER_DN)); 1385 1386 1387 // Define the subcommand to determine whether a user has a retired password. 1388 createSubCommand(ManageAccountSubCommandType.GET_HAS_RETIRED_PASSWORD, 1389 INFO_MANAGE_ACCT_SC_GET_HAS_RETIRED_PW_EXAMPLE.get( 1390 EXAMPLE_TARGET_USER_DN)); 1391 1392 1393 // Define the subcommand to retrieve the time that a user's former password 1394 // was retired. 1395 createSubCommand(ManageAccountSubCommandType.GET_PASSWORD_RETIRED_TIME, 1396 INFO_MANAGE_ACCT_SC_GET_PW_RETIRED_TIME_EXAMPLE.get( 1397 EXAMPLE_TARGET_USER_DN)); 1398 1399 1400 // Define the subcommand to retrieve the retired password expiration time. 1401 createSubCommand( 1402 ManageAccountSubCommandType.GET_RETIRED_PASSWORD_EXPIRATION_TIME, 1403 INFO_MANAGE_ACCT_SC_GET_RETIRED_PW_EXP_TIME_EXAMPLE.get( 1404 EXAMPLE_TARGET_USER_DN)); 1405 1406 1407 // Define the subcommand to purge a retired password. 1408 createSubCommand(ManageAccountSubCommandType.CLEAR_RETIRED_PASSWORD, 1409 INFO_MANAGE_ACCT_SC_PURGE_RETIRED_PW_EXAMPLE.get( 1410 EXAMPLE_TARGET_USER_DN)); 1411 1412 1413 // Define the subcommand to get the available SASL mechanisms for a user. 1414 createSubCommand(ManageAccountSubCommandType.GET_AVAILABLE_SASL_MECHANISMS, 1415 INFO_MANAGE_ACCT_SC_GET_AVAILABLE_SASL_MECHS_EXAMPLE.get( 1416 EXAMPLE_TARGET_USER_DN)); 1417 1418 1419 // Define the subcommand to get the available OTP delivery mechanisms for a 1420 // user. 1421 createSubCommand( 1422 ManageAccountSubCommandType.GET_AVAILABLE_OTP_DELIVERY_MECHANISMS, 1423 INFO_MANAGE_ACCT_SC_GET_AVAILABLE_OTP_MECHS_EXAMPLE.get( 1424 EXAMPLE_TARGET_USER_DN)); 1425 1426 1427 // Define the subcommand to determine whether a user has at least one TOTP 1428 // shared secret. 1429 createSubCommand(ManageAccountSubCommandType.GET_HAS_TOTP_SHARED_SECRET, 1430 INFO_MANAGE_ACCT_SC_GET_HAS_TOTP_SHARED_SECRET_EXAMPLE.get( 1431 EXAMPLE_TARGET_USER_DN)); 1432 1433 1434 // Define the subcommand to add a value to the set of TOTP shared secrets 1435 // for a user. 1436 final ArgumentParser addTOTPSharedSecretParser = 1437 createSubCommandParser( 1438 ManageAccountSubCommandType.ADD_TOTP_SHARED_SECRET); 1439 1440 final StringArgument addTOTPSharedSecretValueArg = 1441 new StringArgument('O', "totpSharedSecret", true, 0, null, 1442 INFO_MANAGE_ACCT_SC_ADD_YUBIKEY_ID_ARG_VALUE.get()); 1443 addTOTPSharedSecretValueArg.addLongIdentifier("operationValue", true); 1444 addTOTPSharedSecretValueArg.addLongIdentifier("totp-shared-secret", true); 1445 addTOTPSharedSecretValueArg.addLongIdentifier("operation-value", true); 1446 addTOTPSharedSecretValueArg.setSensitive(true); 1447 addTOTPSharedSecretParser.addArgument( 1448 addTOTPSharedSecretValueArg); 1449 1450 createSubCommand(ManageAccountSubCommandType.ADD_TOTP_SHARED_SECRET, 1451 addTOTPSharedSecretParser, 1452 createSubCommandExample( 1453 ManageAccountSubCommandType.ADD_TOTP_SHARED_SECRET, 1454 INFO_MANAGE_ACCT_SC_ADD_TOTP_SHARED_SECRET_EXAMPLE.get( 1455 "abcdefghijklmnop", EXAMPLE_TARGET_USER_DN), 1456 "--totpSharedSecret", "abcdefghijklmnop")); 1457 1458 1459 // Define the subcommand to remove a value from the set of TOTP shared 1460 // secrets for a user. 1461 final ArgumentParser removeTOTPSharedSecretParser = 1462 createSubCommandParser( 1463 ManageAccountSubCommandType.REMOVE_TOTP_SHARED_SECRET); 1464 1465 final StringArgument removeTOTPSharedSecretValueArg = 1466 new StringArgument('O', "totpSharedSecret", true, 0, null, 1467 INFO_MANAGE_ACCT_SC_REMOVE_YUBIKEY_ID_ARG_VALUE.get()); 1468 removeTOTPSharedSecretValueArg.addLongIdentifier("operationValue", true); 1469 removeTOTPSharedSecretValueArg.addLongIdentifier("totp-shared-secret", 1470 true); 1471 removeTOTPSharedSecretValueArg.addLongIdentifier("operation-value", true); 1472 removeTOTPSharedSecretValueArg.setSensitive(true); 1473 removeTOTPSharedSecretParser.addArgument( 1474 removeTOTPSharedSecretValueArg); 1475 1476 createSubCommand(ManageAccountSubCommandType.REMOVE_TOTP_SHARED_SECRET, 1477 removeTOTPSharedSecretParser, 1478 createSubCommandExample( 1479 ManageAccountSubCommandType.REMOVE_TOTP_SHARED_SECRET, 1480 INFO_MANAGE_ACCT_SC_REMOVE_TOTP_SHARED_SECRET_EXAMPLE.get( 1481 "abcdefghijklmnop", EXAMPLE_TARGET_USER_DN), 1482 "--totpSharedSecret", "abcdefghijklmnop")); 1483 1484 1485 // Define the subcommand to replace set of TOTP shared secrets for a user. 1486 final ArgumentParser setTOTPSharedSecretsParser = 1487 createSubCommandParser( 1488 ManageAccountSubCommandType.SET_TOTP_SHARED_SECRETS); 1489 1490 final StringArgument setTOTPSharedSecretsValueArg = 1491 new StringArgument('O', "totpSharedSecret", true, 0, null, 1492 INFO_MANAGE_ACCT_SC_SET_TOTP_SHARED_SECRETS_ARG_VALUE.get()); 1493 setTOTPSharedSecretsValueArg.addLongIdentifier("operationValue", true); 1494 setTOTPSharedSecretsValueArg.addLongIdentifier("totp-shared-secret", true); 1495 setTOTPSharedSecretsValueArg.addLongIdentifier("operation-value", true); 1496 setTOTPSharedSecretsValueArg.setSensitive(true); 1497 setTOTPSharedSecretsParser.addArgument( 1498 setTOTPSharedSecretsValueArg); 1499 1500 createSubCommand(ManageAccountSubCommandType.SET_TOTP_SHARED_SECRETS, 1501 setTOTPSharedSecretsParser, 1502 createSubCommandExample( 1503 ManageAccountSubCommandType.SET_TOTP_SHARED_SECRETS, 1504 INFO_MANAGE_ACCT_SC_SET_TOTP_SHARED_SECRETS_EXAMPLE.get( 1505 EXAMPLE_TARGET_USER_DN, "abcdefghijklmnop"), 1506 "--totpSharedSecret", "abcdefghijklmnop")); 1507 1508 1509 // Define the subcommand to clear the set of TOTP shared secrets for a user. 1510 createSubCommand( 1511 ManageAccountSubCommandType.CLEAR_TOTP_SHARED_SECRETS, 1512 INFO_MANAGE_ACCT_SC_CLEAR_TOTP_SHARED_SECRETS_EXAMPLE.get( 1513 EXAMPLE_TARGET_USER_DN)); 1514 1515 1516 // Define the subcommand to determine whether a user has at least one 1517 // registered YubiKey OTP device public ID. 1518 createSubCommand( 1519 ManageAccountSubCommandType.GET_HAS_REGISTERED_YUBIKEY_PUBLIC_ID, 1520 INFO_MANAGE_ACCT_SC_GET_HAS_YUBIKEY_ID_EXAMPLE.get( 1521 EXAMPLE_TARGET_USER_DN)); 1522 1523 1524 // Define the subcommand to get the set of registered YubiKey OTP device 1525 // public IDs for a user. 1526 createSubCommand( 1527 ManageAccountSubCommandType.GET_REGISTERED_YUBIKEY_PUBLIC_IDS, 1528 INFO_MANAGE_ACCT_SC_GET_YUBIKEY_IDS_EXAMPLE.get( 1529 EXAMPLE_TARGET_USER_DN)); 1530 1531 1532 // Define the subcommand to add a value to the set of registered YubiKey OTP 1533 // device public IDs for a user. 1534 final ArgumentParser addRegisteredYubiKeyPublicIDParser = 1535 createSubCommandParser( 1536 ManageAccountSubCommandType.ADD_REGISTERED_YUBIKEY_PUBLIC_ID); 1537 1538 final StringArgument addRegisteredYubiKeyPublicIDValueArg = 1539 new StringArgument('O', "publicID", true, 0, null, 1540 INFO_MANAGE_ACCT_SC_ADD_YUBIKEY_ID_ARG_VALUE.get()); 1541 addRegisteredYubiKeyPublicIDValueArg.addLongIdentifier("operationValue", 1542 true); 1543 addRegisteredYubiKeyPublicIDValueArg.addLongIdentifier("public-id", true); 1544 addRegisteredYubiKeyPublicIDValueArg.addLongIdentifier("operation-value", 1545 true); 1546 addRegisteredYubiKeyPublicIDParser.addArgument( 1547 addRegisteredYubiKeyPublicIDValueArg); 1548 1549 createSubCommand( 1550 ManageAccountSubCommandType.ADD_REGISTERED_YUBIKEY_PUBLIC_ID, 1551 addRegisteredYubiKeyPublicIDParser, 1552 createSubCommandExample( 1553 ManageAccountSubCommandType.ADD_REGISTERED_YUBIKEY_PUBLIC_ID, 1554 INFO_MANAGE_ACCT_SC_ADD_YUBIKEY_ID_EXAMPLE.get( 1555 "abcdefghijkl", EXAMPLE_TARGET_USER_DN), 1556 "--publicID", "abcdefghijkl")); 1557 1558 1559 // Define the subcommand to remove a value from the set of registered 1560 // YubiKey OTP device public IDs for a user. 1561 final ArgumentParser removeRegisteredYubiKeyPublicIDParser = 1562 createSubCommandParser( 1563 ManageAccountSubCommandType.REMOVE_REGISTERED_YUBIKEY_PUBLIC_ID); 1564 1565 final StringArgument removeRegisteredYubiKeyPublicIDValueArg = 1566 new StringArgument('O', "publicID", true, 0, null, 1567 INFO_MANAGE_ACCT_SC_REMOVE_YUBIKEY_ID_ARG_VALUE.get()); 1568 removeRegisteredYubiKeyPublicIDValueArg.addLongIdentifier("operationValue", 1569 true); 1570 removeRegisteredYubiKeyPublicIDValueArg.addLongIdentifier("public-id", 1571 true); 1572 removeRegisteredYubiKeyPublicIDValueArg.addLongIdentifier("operation-value", 1573 true); 1574 removeRegisteredYubiKeyPublicIDParser.addArgument( 1575 removeRegisteredYubiKeyPublicIDValueArg); 1576 1577 createSubCommand( 1578 ManageAccountSubCommandType.REMOVE_REGISTERED_YUBIKEY_PUBLIC_ID, 1579 removeRegisteredYubiKeyPublicIDParser, 1580 createSubCommandExample( 1581 ManageAccountSubCommandType.REMOVE_REGISTERED_YUBIKEY_PUBLIC_ID, 1582 INFO_MANAGE_ACCT_SC_REMOVE_YUBIKEY_ID_EXAMPLE.get( 1583 "abcdefghijkl", EXAMPLE_TARGET_USER_DN), 1584 "--publicID", "abcdefghijkl")); 1585 1586 1587 // Define the subcommand to replace set of registered YubiKey OTP device 1588 // public IDs for a user. 1589 final ArgumentParser setRegisteredYubiKeyPublicIDParser = 1590 createSubCommandParser( 1591 ManageAccountSubCommandType.SET_REGISTERED_YUBIKEY_PUBLIC_IDS); 1592 1593 final StringArgument setRegisteredYubiKeyPublicIDValueArg = 1594 new StringArgument('O', "publicID", true, 0, null, 1595 INFO_MANAGE_ACCT_SC_SET_YUBIKEY_IDS_ARG_VALUE.get()); 1596 setRegisteredYubiKeyPublicIDValueArg.addLongIdentifier("operationValue", 1597 true); 1598 setRegisteredYubiKeyPublicIDValueArg.addLongIdentifier("public-id", true); 1599 setRegisteredYubiKeyPublicIDValueArg.addLongIdentifier("operation-value", 1600 true); 1601 setRegisteredYubiKeyPublicIDParser.addArgument( 1602 setRegisteredYubiKeyPublicIDValueArg); 1603 1604 createSubCommand( 1605 ManageAccountSubCommandType.SET_REGISTERED_YUBIKEY_PUBLIC_IDS, 1606 setRegisteredYubiKeyPublicIDParser, 1607 createSubCommandExample( 1608 ManageAccountSubCommandType.SET_REGISTERED_YUBIKEY_PUBLIC_IDS, 1609 INFO_MANAGE_ACCT_SC_SET_YUBIKEY_IDS_EXAMPLE.get( 1610 EXAMPLE_TARGET_USER_DN, "abcdefghijkl"), 1611 "--publicID", "abcdefghijkl")); 1612 1613 1614 // Define the subcommand to clear the set of registered YubiKey OTP device 1615 // public IDs for a user. 1616 createSubCommand( 1617 ManageAccountSubCommandType.CLEAR_REGISTERED_YUBIKEY_PUBLIC_IDS, 1618 INFO_MANAGE_ACCT_SC_CLEAR_YUBIKEY_IDS_EXAMPLE.get( 1619 EXAMPLE_TARGET_USER_DN)); 1620 1621 1622 // Define the subcommand to determine whether a user has at least one static 1623 // password. 1624 createSubCommand(ManageAccountSubCommandType.GET_HAS_STATIC_PASSWORD, 1625 INFO_MANAGE_ACCT_SC_GET_HAS_STATIC_PW_EXAMPLE.get( 1626 EXAMPLE_TARGET_USER_DN)); 1627 } 1628 1629 1630 1631 /** 1632 * Creates an argument parser for the provided subcommand type. It will not 1633 * have any arguments associated with it. 1634 * 1635 * @param type The subcommand type for which to create the argument parser. 1636 * 1637 * @return The created argument parser. 1638 * 1639 * @throws ArgumentException If a problem is encountered while creating the 1640 * argument parser. 1641 */ 1642 private static ArgumentParser createSubCommandParser( 1643 final ManageAccountSubCommandType type) 1644 throws ArgumentException 1645 { 1646 return new ArgumentParser(type.getPrimaryName(), type.getDescription()); 1647 } 1648 1649 1650 1651 /** 1652 * Generates an example usage map for a specified subcommand. 1653 * 1654 * @param t The subcommand type. 1655 * @param description The description to use for the example. 1656 * @param args The set of arguments to include in the example, 1657 * excluding the subcommand name and the arguments used 1658 * to connect and authenticate to the server. This may 1659 * be empty if no additional arguments are needed. 1660 * 1661 * @return The generated example usage map. 1662 */ 1663 private static LinkedHashMap<String[],String> createSubCommandExample( 1664 final ManageAccountSubCommandType t, 1665 final String description, final String... args) 1666 { 1667 final LinkedHashMap<String[], String> examples = 1668 new LinkedHashMap<>(StaticUtils.computeMapCapacity(1)); 1669 createSubCommandExample(examples, t, description, args); 1670 return examples; 1671 } 1672 1673 1674 1675 /** 1676 * Adds an example for a specified subcommand to the given map. 1677 * 1678 * @param examples The map to which the example should be added. 1679 * @param t The subcommand type. 1680 * @param description The description to use for the example. 1681 * @param args The set of arguments to include in the example, 1682 * excluding the subcommand name and the arguments used 1683 * to connect and authenticate to the server. This may 1684 * be empty if no additional arguments are needed. 1685 */ 1686 private static void createSubCommandExample( 1687 final LinkedHashMap<String[], String> examples, 1688 final ManageAccountSubCommandType t, final String description, 1689 final String... args) 1690 { 1691 final ArrayList<String> argList = new ArrayList<>(10 + args.length); 1692 argList.add(t.getPrimaryName()); 1693 argList.add("--hostname"); 1694 argList.add("server.example.com"); 1695 argList.add("--port"); 1696 argList.add("389"); 1697 argList.add("--bindDN"); 1698 argList.add("uid=admin,dc=example,dc=com"); 1699 argList.add("--promptForBindPassword"); 1700 argList.add("--targetDN"); 1701 argList.add("uid=jdoe,ou=People,dc=example,dc=com"); 1702 1703 if (args.length > 0) 1704 { 1705 argList.addAll(Arrays.asList(args)); 1706 } 1707 1708 final String[] argArray = new String[argList.size()]; 1709 argList.toArray(argArray); 1710 1711 examples.put(argArray, description); 1712 } 1713 1714 1715 1716 /** 1717 * Creates a subcommand with the provided information. 1718 * 1719 * @param subcommandType The subcommand type. 1720 * @param exampleDescription The description to use for the 1721 * automatically-generated example. 1722 * 1723 * @throws ArgumentException If a problem is encountered while creating the 1724 * subcommand. 1725 */ 1726 private void createSubCommand( 1727 final ManageAccountSubCommandType subcommandType, 1728 final String exampleDescription) 1729 throws ArgumentException 1730 { 1731 final ArgumentParser subcommandParser = 1732 createSubCommandParser(subcommandType); 1733 1734 final LinkedHashMap<String[],String> examples = 1735 createSubCommandExample(subcommandType, exampleDescription); 1736 1737 createSubCommand(subcommandType, subcommandParser, examples); 1738 } 1739 1740 1741 1742 /** 1743 * Creates a subcommand with the provided information. 1744 * 1745 * @param subcommandType The subcommand type. 1746 * @param subcommandParser The argument parser for the subcommand-specific 1747 * arguments. 1748 * @param examples The example usages for the subcommand. 1749 * 1750 * @throws ArgumentException If a problem is encountered while creating the 1751 * subcommand. 1752 */ 1753 private void createSubCommand( 1754 final ManageAccountSubCommandType subcommandType, 1755 final ArgumentParser subcommandParser, 1756 final LinkedHashMap<String[],String> examples) 1757 throws ArgumentException 1758 { 1759 final SubCommand subCommand = new SubCommand( 1760 subcommandType.getPrimaryName(), subcommandType.getDescription(), 1761 subcommandParser, examples); 1762 1763 for (final String alternateName : subcommandType.getAlternateNames()) 1764 { 1765 subCommand.addName(alternateName, true); 1766 } 1767 1768 parser.addSubCommand(subCommand); 1769 } 1770 1771 1772 1773 /** 1774 * {@inheritDoc} 1775 */ 1776 @Override() 1777 public LDAPConnectionOptions getConnectionOptions() 1778 { 1779 return connectionOptions; 1780 } 1781 1782 1783 1784 /** 1785 * {@inheritDoc} 1786 */ 1787 @Override() 1788 public ResultCode doToolProcessing() 1789 { 1790 // If we should just generate a sample rate data file, then do that now. 1791 final FileArgument generateSampleRateFile = 1792 parser.getFileArgument(ARG_GENERATE_SAMPLE_RATE_FILE); 1793 if (generateSampleRateFile.isPresent()) 1794 { 1795 try 1796 { 1797 RateAdjustor.writeSampleVariableRateFile( 1798 generateSampleRateFile.getValue()); 1799 return ResultCode.SUCCESS; 1800 } 1801 catch (final Exception e) 1802 { 1803 Debug.debugException(e); 1804 wrapErr(0, WRAP_COLUMN, 1805 ERR_MANAGE_ACCT_CANNOT_GENERATE_SAMPLE_RATE_FILE.get( 1806 generateSampleRateFile.getValue().getAbsolutePath(), 1807 StaticUtils.getExceptionMessage(e))); 1808 return ResultCode.LOCAL_ERROR; 1809 } 1810 } 1811 1812 1813 // If we need to create a fixed-rate barrier and/or use a variable rate 1814 // definition, then set that up. 1815 final IntegerArgument ratePerSecond = 1816 parser.getIntegerArgument(ARG_RATE_PER_SECOND); 1817 final FileArgument variableRateData = 1818 parser.getFileArgument(ARG_VARIABLE_RATE_DATA); 1819 if (ratePerSecond.isPresent() || variableRateData.isPresent()) 1820 { 1821 if (ratePerSecond.isPresent()) 1822 { 1823 rateLimiter = new FixedRateBarrier(1000L, ratePerSecond.getValue()); 1824 } 1825 else 1826 { 1827 rateLimiter = new FixedRateBarrier(1000L, Integer.MAX_VALUE); 1828 } 1829 1830 if (variableRateData.isPresent()) 1831 { 1832 try 1833 { 1834 rateAdjustor = RateAdjustor.newInstance(rateLimiter, 1835 ratePerSecond.getValue(), variableRateData.getValue()); 1836 } 1837 catch (final Exception e) 1838 { 1839 Debug.debugException(e); 1840 wrapErr(0, WRAP_COLUMN, 1841 ERR_MANAGE_ACCT_CANNOT_CREATE_RATE_ADJUSTOR.get( 1842 variableRateData.getValue().getAbsolutePath(), 1843 StaticUtils.getExceptionMessage(e))); 1844 return ResultCode.PARAM_ERROR; 1845 } 1846 } 1847 } 1848 1849 1850 // Create the connection pool to use for all processing. 1851 final LDAPConnectionPool pool; 1852 final int numSearchThreads = 1853 parser.getIntegerArgument(ARG_NUM_SEARCH_THREADS).getValue(); 1854 try 1855 { 1856 final int numOperationThreads = 1857 parser.getIntegerArgument(ARG_NUM_THREADS).getValue(); 1858 pool = getConnectionPool(numOperationThreads, 1859 (numOperationThreads + numSearchThreads)); 1860 1861 // Explicitly disable automatic retry, since it probably won't work 1862 // reliably for extended operations anyway. We'll handle retry manually. 1863 pool.setRetryFailedOperationsDueToInvalidConnections(false); 1864 1865 // Set a maximum connection age of 30 minutes. 1866 pool.setMaxConnectionAgeMillis(1_800_000L); 1867 } 1868 catch (final LDAPException le) 1869 { 1870 Debug.debugException(le); 1871 1872 wrapErr(0, WRAP_COLUMN, 1873 ERR_MANAGE_ACCT_CANNOT_CREATE_CONNECTION_POOL.get(getToolName(), 1874 le.getMessage())); 1875 return le.getResultCode(); 1876 } 1877 1878 1879 try 1880 { 1881 // Create the output writer. This should always succeed. 1882 outputWriter = new LDIFWriter(getOut()); 1883 1884 1885 1886 // Create the reject writer if appropriate. 1887 final FileArgument rejectFile = parser.getFileArgument(ARG_REJECT_FILE); 1888 if (rejectFile.isPresent()) 1889 { 1890 final BooleanArgument appendToRejectFile = 1891 parser.getBooleanArgument(ARG_APPEND_TO_REJECT_FILE); 1892 1893 try 1894 { 1895 rejectWriter = new LDIFWriter(new FileOutputStream( 1896 rejectFile.getValue(), appendToRejectFile.isPresent())); 1897 } 1898 catch (final Exception e) 1899 { 1900 Debug.debugException(e); 1901 wrapErr(0, WRAP_COLUMN, 1902 ERR_MANAGE_ACCT_CANNOT_CREATE_REJECT_WRITER.get( 1903 rejectFile.getValue().getAbsolutePath(), 1904 StaticUtils.getExceptionMessage(e))); 1905 return ResultCode.LOCAL_ERROR; 1906 } 1907 } 1908 1909 1910 // Create the processor that will be used to actually perform the 1911 // manage-account operation processing for each entry. 1912 final ManageAccountProcessor processor; 1913 try 1914 { 1915 processor = new ManageAccountProcessor(this, pool, rateLimiter, 1916 outputWriter, rejectWriter); 1917 } 1918 catch (final LDAPException le) 1919 { 1920 Debug.debugException(le); 1921 wrapErr(0, WRAP_COLUMN, 1922 ERR_MANAGE_ACCT_CANNOT_CREATE_PROCESSOR.get( 1923 StaticUtils.getExceptionMessage(le))); 1924 return le.getResultCode(); 1925 } 1926 1927 1928 // If we should use a rate adjustor, then start it now. 1929 if (rateAdjustor != null) 1930 { 1931 rateAdjustor.start(); 1932 } 1933 1934 1935 // If any targetDN values were provided, then process them now. 1936 final DNArgument targetDN = parser.getDNArgument(ARG_TARGET_DN); 1937 if (targetDN.isPresent()) 1938 { 1939 for (final DN dn : targetDN.getValues()) 1940 { 1941 if (cancelRequested()) 1942 { 1943 return ResultCode.USER_CANCELED; 1944 } 1945 1946 processor.process(dn.toString()); 1947 } 1948 } 1949 1950 1951 // If any DN input files were specified, then process them now. 1952 final FileArgument dnInputFile = 1953 parser.getFileArgument(ARG_DN_INPUT_FILE); 1954 if (dnInputFile.isPresent()) 1955 { 1956 for (final File f : dnInputFile.getValues()) 1957 { 1958 DNFileReader reader = null; 1959 try 1960 { 1961 reader = new DNFileReader(f); 1962 while (true) 1963 { 1964 if (cancelRequested()) 1965 { 1966 return ResultCode.USER_CANCELED; 1967 } 1968 1969 final DN dn; 1970 try 1971 { 1972 dn = reader.readDN(); 1973 } 1974 catch (final LDAPException le) 1975 { 1976 Debug.debugException(le); 1977 processor.handleMessage(le.getMessage(), true); 1978 continue; 1979 } 1980 1981 if (dn == null) 1982 { 1983 break; 1984 } 1985 1986 processor.process(dn.toString()); 1987 } 1988 } 1989 catch (final Exception e) 1990 { 1991 Debug.debugException(e); 1992 processor.handleMessage( 1993 ERR_MANAGE_ACCT_ERROR_READING_DN_FILE.get( 1994 f.getAbsolutePath(), StaticUtils.getExceptionMessage(e)), 1995 true); 1996 } 1997 finally 1998 { 1999 if (reader != null) 2000 { 2001 try 2002 { 2003 reader.close(); 2004 } 2005 catch (final Exception e2) 2006 { 2007 Debug.debugException(e2); 2008 } 2009 } 2010 } 2011 } 2012 } 2013 2014 2015 // If any target filters were specified, then process them now. 2016 final FilterArgument targetFilter = 2017 parser.getFilterArgument(ARG_TARGET_FILTER); 2018 if (targetFilter.isPresent()) 2019 { 2020 searchProcessor = 2021 new ManageAccountSearchProcessor(this, processor, pool); 2022 for (final Filter f : targetFilter.getValues()) 2023 { 2024 searchProcessor.processFilter(f); 2025 } 2026 } 2027 2028 2029 // If any filter input files were specified, then process them now. 2030 final FileArgument filterInputFile = 2031 parser.getFileArgument(ARG_FILTER_INPUT_FILE); 2032 if (filterInputFile.isPresent()) 2033 { 2034 if (searchProcessor == null) 2035 { 2036 searchProcessor = 2037 new ManageAccountSearchProcessor(this, processor, pool); 2038 } 2039 2040 for (final File f : filterInputFile.getValues()) 2041 { 2042 FilterFileReader reader = null; 2043 try 2044 { 2045 reader = new FilterFileReader(f); 2046 while (true) 2047 { 2048 if (cancelRequested()) 2049 { 2050 return ResultCode.USER_CANCELED; 2051 } 2052 2053 final Filter filter; 2054 try 2055 { 2056 filter = reader.readFilter(); 2057 } 2058 catch (final LDAPException le) 2059 { 2060 Debug.debugException(le); 2061 processor.handleMessage(le.getMessage(), true); 2062 continue; 2063 } 2064 2065 if (filter == null) 2066 { 2067 break; 2068 } 2069 2070 searchProcessor.processFilter(filter); 2071 } 2072 } 2073 catch (final Exception e) 2074 { 2075 Debug.debugException(e); 2076 processor.handleMessage( 2077 ERR_MANAGE_ACCT_ERROR_READING_FILTER_FILE.get( 2078 f.getAbsolutePath(), StaticUtils.getExceptionMessage(e)), 2079 true); 2080 } 2081 finally 2082 { 2083 if (reader != null) 2084 { 2085 try 2086 { 2087 reader.close(); 2088 } 2089 catch (final Exception e2) 2090 { 2091 Debug.debugException(e2); 2092 } 2093 } 2094 } 2095 } 2096 } 2097 2098 2099 // If any target user IDs were specified, then process them now. 2100 final StringArgument targetUserID = 2101 parser.getStringArgument(ARG_TARGET_USER_ID); 2102 if (targetUserID.isPresent()) 2103 { 2104 if (searchProcessor == null) 2105 { 2106 searchProcessor = 2107 new ManageAccountSearchProcessor(this, processor, pool); 2108 } 2109 2110 for (final String userID : targetUserID.getValues()) 2111 { 2112 searchProcessor.processUserID(userID); 2113 } 2114 } 2115 2116 2117 // If any user ID input files were specified, then process them now. 2118 final FileArgument userIDInputFile = 2119 parser.getFileArgument(ARG_USER_ID_INPUT_FILE); 2120 if (userIDInputFile.isPresent()) 2121 { 2122 if (searchProcessor == null) 2123 { 2124 searchProcessor = 2125 new ManageAccountSearchProcessor(this, processor, pool); 2126 } 2127 2128 for (final File f : userIDInputFile.getValues()) 2129 { 2130 BufferedReader reader = null; 2131 try 2132 { 2133 reader = new BufferedReader(new FileReader(f)); 2134 while (true) 2135 { 2136 if (cancelRequested()) 2137 { 2138 return ResultCode.USER_CANCELED; 2139 } 2140 2141 final String line = reader.readLine(); 2142 if (line == null) 2143 { 2144 break; 2145 } 2146 2147 if ((line.length() == 0) || line.startsWith("#")) 2148 { 2149 continue; 2150 } 2151 2152 searchProcessor.processUserID(line.trim()); 2153 } 2154 } 2155 catch (final Exception e) 2156 { 2157 Debug.debugException(e); 2158 processor.handleMessage( 2159 ERR_MANAGE_ACCT_ERROR_READING_USER_ID_FILE.get( 2160 f.getAbsolutePath(), StaticUtils.getExceptionMessage(e)), 2161 true); 2162 } 2163 finally 2164 { 2165 if (reader != null) 2166 { 2167 try 2168 { 2169 reader.close(); 2170 } 2171 catch (final Exception e2) 2172 { 2173 Debug.debugException(e2); 2174 } 2175 } 2176 } 2177 } 2178 } 2179 2180 2181 allFiltersProvided.set(true); 2182 if (searchProcessor != null) 2183 { 2184 searchProcessor.waitForCompletion(); 2185 } 2186 2187 allDNsProvided.set(true); 2188 processor.waitForCompletion(); 2189 } 2190 finally 2191 { 2192 pool.close(); 2193 2194 if (rejectWriter != null) 2195 { 2196 try 2197 { 2198 rejectWriter.close(); 2199 } 2200 catch (final Exception e) 2201 { 2202 Debug.debugException(e); 2203 } 2204 } 2205 } 2206 2207 2208 // If we've gotten here, then we can consider the command successful, even 2209 // if some of the operations failed. 2210 return ResultCode.SUCCESS; 2211 } 2212 2213 2214 2215 /** 2216 * Retrieves the argument parser for this tool. 2217 * 2218 * @return The argument parser for this tool. 2219 */ 2220 ArgumentParser getArgumentParser() 2221 { 2222 return parser; 2223 } 2224 2225 2226 2227 /** 2228 * Indicates whether the tool should cancel its processing. 2229 * 2230 * @return {@code true} if the tool should cancel its processing, or 2231 * {@code false} if not. 2232 */ 2233 boolean cancelRequested() 2234 { 2235 return cancelRequested.get(); 2236 } 2237 2238 2239 2240 /** 2241 * Indicates whether the manage-account processor has been provided with all 2242 * of the DNs of all of the entries to process. 2243 * 2244 * @return {@code true} if the manage-account processor has been provided 2245 * with all of the DNs of all of the entries to process, or 2246 * {@code false} if not. 2247 */ 2248 boolean allDNsProvided() 2249 { 2250 return allDNsProvided.get(); 2251 } 2252 2253 2254 2255 /** 2256 * Indicates whether the manage-account search processor has been provided 2257 * with all of the filters to use to identify entries to process. 2258 * 2259 * @return {@code true} if the manage-account search processor has been 2260 * provided with all of the filters to use to identify entries to 2261 * process, or {@code false} if not. 2262 */ 2263 boolean allFiltersProvided() 2264 { 2265 return allFiltersProvided.get(); 2266 } 2267 2268 2269 2270 /** 2271 * {@inheritDoc} 2272 */ 2273 @Override() 2274 protected boolean registerShutdownHook() 2275 { 2276 return true; 2277 } 2278 2279 2280 2281 /** 2282 * {@inheritDoc} 2283 */ 2284 @Override() 2285 protected void doShutdownHookProcessing(final ResultCode resultCode) 2286 { 2287 cancelRequested.set(true); 2288 2289 if (rateLimiter != null) 2290 { 2291 rateLimiter.shutdownRequested(); 2292 } 2293 2294 if (searchProcessor != null) 2295 { 2296 searchProcessor.cancelSearches(); 2297 } 2298 } 2299 2300 2301 2302 /** 2303 * Performs any processing that may be necessary in response to the provided 2304 * unsolicited notification that has been received from the server. 2305 * 2306 * @param connection The connection on which the unsolicited notification 2307 * was received. 2308 * @param notification The unsolicited notification that has been received 2309 * from the server. 2310 */ 2311 @Override() 2312 public void handleUnsolicitedNotification(final LDAPConnection connection, 2313 final ExtendedResult notification) 2314 { 2315 final String message = NOTE_MANAGE_ACCT_UNSOLICITED_NOTIFICATION.get( 2316 String.valueOf(connection), String.valueOf(notification)); 2317 if (outputWriter == null) 2318 { 2319 err(); 2320 err("* " + message); 2321 err(); 2322 } 2323 else 2324 { 2325 try 2326 { 2327 outputWriter.writeComment(message, true, true); 2328 outputWriter.flush(); 2329 } 2330 catch (final Exception e) 2331 { 2332 // We can't really do anything about this. 2333 Debug.debugException(e); 2334 } 2335 } 2336 } 2337 2338 2339 2340 /** 2341 * {@inheritDoc} 2342 */ 2343 @Override() 2344 public LinkedHashMap<String[],String> getExampleUsages() 2345 { 2346 final LinkedHashMap<String[],String> examples = 2347 new LinkedHashMap<>(StaticUtils.computeMapCapacity(4)); 2348 2349 createSubCommandExample(examples, 2350 ManageAccountSubCommandType.GET_ALL, 2351 INFO_MANAGE_ACCT_SC_GET_ALL_EXAMPLE.get(EXAMPLE_TARGET_USER_DN)); 2352 2353 createSubCommandExample(examples, 2354 ManageAccountSubCommandType.GET_ACCOUNT_USABILITY_ERRORS, 2355 INFO_MANAGE_ACCT_SC_GET_USABILITY_ERRORS_EXAMPLE.get( 2356 EXAMPLE_TARGET_USER_DN)); 2357 2358 createSubCommandExample(examples, 2359 ManageAccountSubCommandType.SET_ACCOUNT_IS_DISABLED, 2360 INFO_MANAGE_ACCT_SC_SET_IS_DISABLED_EXAMPLE.get( 2361 EXAMPLE_TARGET_USER_DN), 2362 "--accountIsDisabled", "true"); 2363 2364 createSubCommandExample(examples, 2365 ManageAccountSubCommandType.CLEAR_AUTHENTICATION_FAILURE_TIMES, 2366 INFO_MANAGE_ACCT_SC_CLEAR_AUTH_FAILURE_TIMES_EXAMPLE.get( 2367 EXAMPLE_TARGET_USER_DN)); 2368 2369 return examples; 2370 } 2371}