001/* 002 * Copyright 2016-2018 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2016-2018 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 supportsMultipleServers() 500 { 501 return true; 502 } 503 504 505 506 /** 507 * {@inheritDoc} 508 */ 509 @Override() 510 protected boolean logToolInvocationByDefault() 511 { 512 return true; 513 } 514 515 516 517 /** 518 * {@inheritDoc} 519 */ 520 @Override() 521 public void addNonLDAPArguments(final ArgumentParser parser) 522 throws ArgumentException 523 { 524 // Get a copy of the argument parser for later use. 525 this.parser = parser; 526 527 528 // Get the current time formatted as a generalized time. 529 final String currentGeneralizedTime = 530 StaticUtils.encodeGeneralizedTime(System.currentTimeMillis()); 531 final String olderGeneralizedTime = 532 StaticUtils.encodeGeneralizedTime( 533 System.currentTimeMillis() - 12_345L); 534 535 536 // Define the global arguments used to indicate which users to target. 537 final DNArgument targetDN = new DNArgument('b', ARG_TARGET_DN, false, 0, 538 null, INFO_MANAGE_ACCT_ARG_DESC_TARGET_DN.get()); 539 targetDN.addLongIdentifier("userDN", true); 540 targetDN.addLongIdentifier("target-dn", true); 541 targetDN.addLongIdentifier("user-dn", true); 542 targetDN.setArgumentGroupName( 543 INFO_MANAGE_ACCT_ARG_GROUP_TARGET_USER_ARGS.get()); 544 parser.addArgument(targetDN); 545 546 final FileArgument dnInputFile = new FileArgument(null, ARG_DN_INPUT_FILE, 547 false, 0, null, INFO_MANAGE_ACCT_ARG_DESC_DN_FILE.get(), true, 548 true, true, false); 549 dnInputFile.addLongIdentifier("targetDNFile", true); 550 dnInputFile.addLongIdentifier("userDNFile", true); 551 dnInputFile.addLongIdentifier("dn-input-file", true); 552 dnInputFile.addLongIdentifier("target-dn-file", true); 553 dnInputFile.addLongIdentifier("user-dn-file", true); 554 dnInputFile.setArgumentGroupName( 555 INFO_MANAGE_ACCT_ARG_GROUP_TARGET_USER_ARGS.get()); 556 parser.addArgument(dnInputFile); 557 558 final FilterArgument targetFilter = new FilterArgument(null, 559 ARG_TARGET_FILTER, false, 0, null, 560 INFO_MANAGE_ACCT_ARG_DESC_TARGET_FILTER.get(ARG_BASE_DN)); 561 targetFilter.addLongIdentifier("target-filter", true); 562 targetFilter.setArgumentGroupName( 563 INFO_MANAGE_ACCT_ARG_GROUP_TARGET_USER_ARGS.get()); 564 parser.addArgument(targetFilter); 565 566 final FileArgument filterInputFile = new FileArgument(null, 567 ARG_FILTER_INPUT_FILE, false, 0, null, 568 INFO_MANAGE_ACCT_ARG_DESC_FILTER_INPUT_FILE.get(ARG_BASE_DN), 569 true, true, true, false); 570 filterInputFile.addLongIdentifier("targetFilterFile", true); 571 filterInputFile.addLongIdentifier("filter-input-file", true); 572 filterInputFile.addLongIdentifier("target-filter-file", true); 573 filterInputFile.setArgumentGroupName( 574 INFO_MANAGE_ACCT_ARG_GROUP_TARGET_USER_ARGS.get()); 575 parser.addArgument(filterInputFile); 576 577 final StringArgument targetUserID = new StringArgument(null, 578 ARG_TARGET_USER_ID, false, 0, null, 579 INFO_MANAGE_ACCT_ARG_DESC_TARGET_USER_ID.get(ARG_BASE_DN, 580 ARG_USER_ID_ATTRIBUTE)); 581 targetUserID.addLongIdentifier("userID", true); 582 targetUserID.addLongIdentifier("target-user-id", true); 583 targetUserID.addLongIdentifier("user-id", true); 584 targetUserID.setArgumentGroupName( 585 INFO_MANAGE_ACCT_ARG_GROUP_TARGET_USER_ARGS.get()); 586 parser.addArgument(targetUserID); 587 588 final FileArgument userIDInputFile = new FileArgument(null, 589 ARG_USER_ID_INPUT_FILE, false, 0, null, 590 INFO_MANAGE_ACCT_ARG_DESC_USER_ID_INPUT_FILE.get(ARG_BASE_DN, 591 ARG_USER_ID_ATTRIBUTE), 592 true, true, true, false); 593 userIDInputFile.addLongIdentifier("targetUserIDFile", true); 594 userIDInputFile.addLongIdentifier("user-id-input-file", true); 595 userIDInputFile.addLongIdentifier("target-user-id-file", true); 596 userIDInputFile.setArgumentGroupName( 597 INFO_MANAGE_ACCT_ARG_GROUP_TARGET_USER_ARGS.get()); 598 parser.addArgument(userIDInputFile); 599 600 final StringArgument userIDAttribute = new StringArgument(null, 601 ARG_USER_ID_ATTRIBUTE, false, 1, null, 602 INFO_MANAGE_ACCT_ARG_DESC_USER_ID_ATTR.get( 603 ARG_TARGET_USER_ID, ARG_USER_ID_INPUT_FILE, 604 DEFAULT_USER_ID_ATTRIBUTE), 605 DEFAULT_USER_ID_ATTRIBUTE); 606 userIDAttribute.addLongIdentifier("user-id-attribute", true); 607 userIDAttribute.setArgumentGroupName( 608 INFO_MANAGE_ACCT_ARG_GROUP_TARGET_USER_ARGS.get()); 609 parser.addArgument(userIDAttribute); 610 611 final DNArgument baseDN = new DNArgument(null, ARG_BASE_DN, false, 1, null, 612 INFO_MANAGE_ACCT_ARG_DESC_BASE_DN.get(ARG_TARGET_FILTER, 613 ARG_FILTER_INPUT_FILE, ARG_TARGET_USER_ID, 614 ARG_USER_ID_INPUT_FILE), 615 DEFAULT_BASE_DN); 616 baseDN.addLongIdentifier("base-dn", true); 617 baseDN.setArgumentGroupName( 618 INFO_MANAGE_ACCT_ARG_GROUP_TARGET_USER_ARGS.get()); 619 parser.addArgument(baseDN); 620 621 final IntegerArgument simplePageSize = new IntegerArgument('z', 622 ARG_SIMPLE_PAGE_SIZE, false, 1, null, 623 INFO_MANAGE_ACCT_ARG_DESC_SIMPLE_PAGE_SIZE.get(getToolName()), 1, 624 Integer.MAX_VALUE); 625 simplePageSize.addLongIdentifier("simple-page-size", true); 626 simplePageSize.setArgumentGroupName( 627 INFO_MANAGE_ACCT_ARG_GROUP_TARGET_USER_ARGS.get(getToolName())); 628 parser.addArgument(simplePageSize); 629 630 631 // Ensure that the user will be required ot provide at least one of the 632 // arguments to specify which users to target. 633 parser.addRequiredArgumentSet(targetDN, dnInputFile, targetFilter, 634 filterInputFile, targetUserID, userIDInputFile); 635 636 637 // Define the global arguments used to control the amount of load the tool 638 // should be permitted to generate. 639 final IntegerArgument numThreads = new IntegerArgument('t', ARG_NUM_THREADS, 640 false, 1, null, 641 INFO_MANAGE_ACCT_ARG_DESC_NUM_THREADS.get(getToolName()), 1, 642 Integer.MAX_VALUE, 1); 643 numThreads.addLongIdentifier("num-threads", true); 644 numThreads.setArgumentGroupName( 645 INFO_MANAGE_ACCT_ARG_GROUP_PERFORMANCE.get()); 646 parser.addArgument(numThreads); 647 648 final IntegerArgument numSearchThreads = new IntegerArgument(null, 649 ARG_NUM_SEARCH_THREADS, false, 1, null, 650 INFO_MANAGE_ACCT_ARG_DESC_NUM_SEARCH_THREADS.get(getToolName()), 1, 651 Integer.MAX_VALUE, 1); 652 numSearchThreads.addLongIdentifier("num-search-threads", true); 653 numSearchThreads.setArgumentGroupName( 654 INFO_MANAGE_ACCT_ARG_GROUP_PERFORMANCE.get()); 655 parser.addArgument(numSearchThreads); 656 657 final IntegerArgument ratePerSecond = new IntegerArgument('r', 658 ARG_RATE_PER_SECOND, false, 1, null, 659 INFO_MANAGE_ACCT_ARG_DESC_RATE_PER_SECOND.get( 660 ARG_VARIABLE_RATE_DATA), 661 1, Integer.MAX_VALUE); 662 ratePerSecond.addLongIdentifier("rate-per-second", true); 663 ratePerSecond.setArgumentGroupName( 664 INFO_MANAGE_ACCT_ARG_GROUP_PERFORMANCE.get()); 665 parser.addArgument(ratePerSecond); 666 667 final FileArgument variableRateData = new FileArgument(null, 668 ARG_VARIABLE_RATE_DATA, false, 1, null, 669 INFO_MANAGE_ACCT_ARG_DESC_VARIABLE_RATE_DATA.get( 670 ARG_RATE_PER_SECOND), 671 true, true, true, false); 672 variableRateData.addLongIdentifier("variable-rate-data", true); 673 variableRateData.setArgumentGroupName( 674 INFO_MANAGE_ACCT_ARG_GROUP_PERFORMANCE.get()); 675 parser.addArgument(variableRateData); 676 677 final FileArgument generateSampleRateFile = new FileArgument(null, 678 ARG_GENERATE_SAMPLE_RATE_FILE, false, 1, null, 679 INFO_MANAGE_ACCT_ARG_DESC_GENERATE_SAMPLE_RATE_FILE.get( 680 ARG_VARIABLE_RATE_DATA), 681 false, true, true, false); 682 generateSampleRateFile.addLongIdentifier("generate-sample-rate-file", true); 683 generateSampleRateFile.setArgumentGroupName( 684 INFO_MANAGE_ACCT_ARG_GROUP_PERFORMANCE.get()); 685 generateSampleRateFile.setUsageArgument(true); 686 parser.addArgument(generateSampleRateFile); 687 688 689 // Define the global arguments tht pertain to the reject file. 690 final FileArgument rejectFile = new FileArgument('R', ARG_REJECT_FILE, 691 false, 1, null, INFO_MANAGE_ACCT_ARG_DESC_REJECT_FILE.get(), 692 false, true, true, false); 693 rejectFile.addLongIdentifier("reject-file", true); 694 parser.addArgument(rejectFile); 695 696 final BooleanArgument appendToRejectFile = new BooleanArgument(null, 697 ARG_APPEND_TO_REJECT_FILE, 1, 698 INFO_MANAGE_ACCT_ARG_DESC_APPEND_TO_REJECT_FILE.get( 699 rejectFile.getIdentifierString())); 700 appendToRejectFile.addLongIdentifier("append-to-reject-file", true); 701 parser.addArgument(appendToRejectFile); 702 703 parser.addDependentArgumentSet(appendToRejectFile, rejectFile); 704 705 706 // Define the argument used to suppress result operations without values. 707 final BooleanArgument suppressEmptyResultOperations = 708 new BooleanArgument(null, ARG_SUPPRESS_EMPTY_RESULT_OPERATIONS, 709 1, 710 INFO_MANAGE_ACCT_ARG_DESC_SUPPRESS_EMPTY_RESULT_OPERATIONS.get( 711 getToolName())); 712 parser.addArgument(suppressEmptyResultOperations); 713 714 715 // Define the subcommand used to retrieve all state information for a user. 716 createSubCommand(ManageAccountSubCommandType.GET_ALL, 717 INFO_MANAGE_ACCT_SC_GET_ALL_EXAMPLE.get(EXAMPLE_TARGET_USER_DN)); 718 719 720 // Define the subcommand used to retrieve the password policy DN for a user. 721 createSubCommand(ManageAccountSubCommandType.GET_PASSWORD_POLICY_DN, 722 INFO_MANAGE_ACCT_SC_GET_POLICY_DN_EXAMPLE.get(EXAMPLE_TARGET_USER_DN)); 723 724 725 // Define the subcommand to determine whether the account is usable. 726 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_IS_USABLE, 727 INFO_MANAGE_ACCT_SC_GET_IS_USABLE_EXAMPLE.get(EXAMPLE_TARGET_USER_DN)); 728 729 730 // Define the subcommand to retrieve the set of password policy state 731 // account usability notice messages. 732 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_USABILITY_NOTICES, 733 INFO_MANAGE_ACCT_SC_GET_USABILITY_NOTICES_EXAMPLE.get( 734 EXAMPLE_TARGET_USER_DN)); 735 736 737 // Define the subcommand to retrieve the set of password policy state 738 // account usability warning messages. 739 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_USABILITY_WARNINGS, 740 INFO_MANAGE_ACCT_SC_GET_USABILITY_WARNINGS_EXAMPLE.get( 741 EXAMPLE_TARGET_USER_DN)); 742 743 744 // Define the subcommand to retrieve the set of password policy state 745 // account usability error messages. 746 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_USABILITY_ERRORS, 747 INFO_MANAGE_ACCT_SC_GET_USABILITY_ERRORS_EXAMPLE.get( 748 EXAMPLE_TARGET_USER_DN)); 749 750 751 // Define the subcommand to retrieve the password changed time for a user. 752 createSubCommand(ManageAccountSubCommandType.GET_PASSWORD_CHANGED_TIME, 753 INFO_MANAGE_ACCT_SC_GET_PW_CHANGED_TIME_EXAMPLE.get( 754 EXAMPLE_TARGET_USER_DN)); 755 756 757 // Define the subcommand to set the password changed time for a user. 758 final ArgumentParser setPWChangedTimeParser = 759 createSubCommandParser( 760 ManageAccountSubCommandType.SET_PASSWORD_CHANGED_TIME); 761 762 final TimestampArgument setPWChangedTimeValueArg = new TimestampArgument( 763 'O', "passwordChangedTime", false, 1, null, 764 INFO_MANAGE_ACCT_SC_SET_PW_CHANGED_TIME_ARG_VALUE.get()); 765 setPWChangedTimeValueArg.addLongIdentifier("operationValue", true); 766 setPWChangedTimeValueArg.addLongIdentifier("password-changed-time", true); 767 setPWChangedTimeValueArg.addLongIdentifier("operation-value", true); 768 setPWChangedTimeParser.addArgument(setPWChangedTimeValueArg); 769 770 createSubCommand(ManageAccountSubCommandType.SET_PASSWORD_CHANGED_TIME, 771 setPWChangedTimeParser, 772 createSubCommandExample( 773 ManageAccountSubCommandType.SET_PASSWORD_CHANGED_TIME, 774 INFO_MANAGE_ACCT_SC_SET_PW_CHANGED_TIME_EXAMPLE.get( 775 EXAMPLE_TARGET_USER_DN, currentGeneralizedTime), 776 "--passwordChangedTime", currentGeneralizedTime)); 777 778 779 // Define the subcommand to clear the password changed time for a user. 780 createSubCommand(ManageAccountSubCommandType.CLEAR_PASSWORD_CHANGED_TIME, 781 INFO_MANAGE_ACCT_SC_CLEAR_PW_CHANGED_TIME_EXAMPLE.get( 782 EXAMPLE_TARGET_USER_DN)); 783 784 785 // Define the subcommand to determine whether a user account is disabled. 786 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_IS_DISABLED, 787 INFO_MANAGE_ACCT_SC_GET_IS_DISABLED_EXAMPLE.get( 788 EXAMPLE_TARGET_USER_DN)); 789 790 791 // Define the subcommand to specify whether a user's account is disabled. 792 final ArgumentParser setAcctDisabledParser = 793 createSubCommandParser( 794 ManageAccountSubCommandType.SET_ACCOUNT_IS_DISABLED); 795 796 final BooleanValueArgument setAcctDisabledValueArg = 797 new BooleanValueArgument('O', "accountIsDisabled", true, null, 798 INFO_MANAGE_ACCT_SC_SET_IS_DISABLED_ARG_VALUE.get()); 799 setAcctDisabledValueArg.addLongIdentifier("operationValue", true); 800 setAcctDisabledValueArg.addLongIdentifier("account-is-disabled", true); 801 setAcctDisabledValueArg.addLongIdentifier("operation-value", true); 802 setAcctDisabledParser.addArgument(setAcctDisabledValueArg); 803 804 createSubCommand(ManageAccountSubCommandType.SET_ACCOUNT_IS_DISABLED, 805 setAcctDisabledParser, 806 createSubCommandExample( 807 ManageAccountSubCommandType.SET_ACCOUNT_IS_DISABLED, 808 INFO_MANAGE_ACCT_SC_SET_IS_DISABLED_EXAMPLE.get( 809 EXAMPLE_TARGET_USER_DN), 810 "--accountIsDisabled", "true")); 811 812 813 // Define the subcommand to clear the account disabled state. 814 createSubCommand(ManageAccountSubCommandType.CLEAR_ACCOUNT_IS_DISABLED, 815 INFO_MANAGE_ACCT_SC_CLEAR_IS_DISABLED_EXAMPLE.get( 816 EXAMPLE_TARGET_USER_DN)); 817 818 819 // Define the subcommand to retrieve the account activation time for a user. 820 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_ACTIVATION_TIME, 821 INFO_MANAGE_ACCT_SC_GET_ACCT_ACT_TIME_EXAMPLE.get( 822 EXAMPLE_TARGET_USER_DN)); 823 824 825 // Define the subcommand to set the account activation time for a user. 826 final ArgumentParser setAcctActivationTimeParser = 827 createSubCommandParser( 828 ManageAccountSubCommandType.SET_ACCOUNT_ACTIVATION_TIME); 829 830 final TimestampArgument setAcctActivationTimeValueArg = 831 new TimestampArgument('O', "accountActivationTime", false, 1, null, 832 INFO_MANAGE_ACCT_SC_SET_ACCT_ACT_TIME_ARG_VALUE.get()); 833 setAcctActivationTimeValueArg.addLongIdentifier("operationValue", true); 834 setAcctActivationTimeValueArg.addLongIdentifier("account-activation-time", 835 true); 836 setAcctActivationTimeValueArg.addLongIdentifier("operation-value", true); 837 setAcctActivationTimeParser.addArgument(setAcctActivationTimeValueArg); 838 839 createSubCommand(ManageAccountSubCommandType.SET_ACCOUNT_ACTIVATION_TIME, 840 setAcctActivationTimeParser, 841 createSubCommandExample( 842 ManageAccountSubCommandType.SET_ACCOUNT_ACTIVATION_TIME, 843 INFO_MANAGE_ACCT_SC_SET_ACCT_ACT_TIME_EXAMPLE.get( 844 EXAMPLE_TARGET_USER_DN, currentGeneralizedTime), 845 "--accountActivationTime", currentGeneralizedTime)); 846 847 848 // Define the subcommand to clear the account activation time for a user. 849 createSubCommand(ManageAccountSubCommandType.CLEAR_ACCOUNT_ACTIVATION_TIME, 850 INFO_MANAGE_ACCT_SC_CLEAR_ACCT_ACT_TIME_EXAMPLE.get( 851 EXAMPLE_TARGET_USER_DN)); 852 853 854 // Define the subcommand to retrieve the length of time until a user's 855 // account is activated. 856 createSubCommand( 857 ManageAccountSubCommandType.GET_SECONDS_UNTIL_ACCOUNT_ACTIVATION, 858 INFO_MANAGE_ACCT_SC_GET_SECONDS_UNTIL_ACCT_ACT_EXAMPLE.get( 859 EXAMPLE_TARGET_USER_DN)); 860 861 862 // Define the subcommand to determine whether a user's account is not yet 863 // active. 864 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_IS_NOT_YET_ACTIVE, 865 INFO_MANAGE_ACCT_SC_GET_ACCT_NOT_YET_ACTIVE_EXAMPLE.get( 866 EXAMPLE_TARGET_USER_DN)); 867 868 869 // Define the subcommand to retrieve the account expiration time for a user. 870 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_EXPIRATION_TIME, 871 INFO_MANAGE_ACCT_SC_GET_ACCT_EXP_TIME_EXAMPLE.get( 872 EXAMPLE_TARGET_USER_DN)); 873 874 875 // Define the subcommand to set the account expiration time for a user. 876 final ArgumentParser setAcctExpirationTimeParser = 877 createSubCommandParser( 878 ManageAccountSubCommandType.SET_ACCOUNT_EXPIRATION_TIME); 879 880 final TimestampArgument setAcctExpirationTimeValueArg = 881 new TimestampArgument('O', "accountExpirationTime", false, 1, null, 882 INFO_MANAGE_ACCT_SC_SET_ACCT_EXP_TIME_ARG_VALUE.get()); 883 setAcctExpirationTimeValueArg.addLongIdentifier("operationValue", true); 884 setAcctExpirationTimeValueArg.addLongIdentifier("account-expiration-time", 885 true); 886 setAcctExpirationTimeValueArg.addLongIdentifier("operation-value", true); 887 setAcctExpirationTimeParser.addArgument(setAcctExpirationTimeValueArg); 888 889 createSubCommand(ManageAccountSubCommandType.SET_ACCOUNT_EXPIRATION_TIME, 890 setAcctExpirationTimeParser, 891 createSubCommandExample( 892 ManageAccountSubCommandType.SET_ACCOUNT_EXPIRATION_TIME, 893 INFO_MANAGE_ACCT_SC_SET_ACCT_EXP_TIME_EXAMPLE.get( 894 EXAMPLE_TARGET_USER_DN, currentGeneralizedTime), 895 "--accountExpirationTime", currentGeneralizedTime)); 896 897 898 // Define the subcommand to clear the account expiration time for a user. 899 createSubCommand(ManageAccountSubCommandType.CLEAR_ACCOUNT_EXPIRATION_TIME, 900 INFO_MANAGE_ACCT_SC_CLEAR_ACCT_EXP_TIME_EXAMPLE.get( 901 EXAMPLE_TARGET_USER_DN)); 902 903 904 // Define the subcommand to retrieve the length of time until a user's 905 // account is expired. 906 createSubCommand( 907 ManageAccountSubCommandType.GET_SECONDS_UNTIL_ACCOUNT_EXPIRATION, 908 INFO_MANAGE_ACCT_SC_GET_SECONDS_UNTIL_ACCT_EXP_EXAMPLE.get( 909 EXAMPLE_TARGET_USER_DN)); 910 911 912 // Define the subcommand to determine whether a user's account is expired. 913 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_IS_EXPIRED, 914 INFO_MANAGE_ACCT_SC_GET_ACCT_IS_EXPIRED_EXAMPLE.get( 915 EXAMPLE_TARGET_USER_DN)); 916 917 918 // Define the subcommand to retrieve a user's password expiration warned 919 // time. 920 createSubCommand( 921 ManageAccountSubCommandType.GET_PASSWORD_EXPIRATION_WARNED_TIME, 922 INFO_MANAGE_ACCT_SC_GET_PW_EXP_WARNED_TIME_EXAMPLE.get( 923 EXAMPLE_TARGET_USER_DN)); 924 925 926 // Define the subcommand to set a user's password expiration warned time. 927 final ArgumentParser setPWExpWarnedTimeParser = 928 createSubCommandParser( 929 ManageAccountSubCommandType.SET_PASSWORD_EXPIRATION_WARNED_TIME); 930 931 final TimestampArgument setPWExpWarnedTimeValueArg = 932 new TimestampArgument('O', "passwordExpirationWarnedTime", false, 1, 933 null, INFO_MANAGE_ACCT_SC_SET_PW_EXP_WARNED_TIME_ARG_VALUE.get()); 934 setPWExpWarnedTimeValueArg.addLongIdentifier("operationValue", true); 935 setPWExpWarnedTimeValueArg.addLongIdentifier( 936 "password-expiration-warned-time", true); 937 setPWExpWarnedTimeValueArg.addLongIdentifier("operation-value", true); 938 setPWExpWarnedTimeParser.addArgument(setPWExpWarnedTimeValueArg); 939 940 createSubCommand( 941 ManageAccountSubCommandType.SET_PASSWORD_EXPIRATION_WARNED_TIME, 942 setPWExpWarnedTimeParser, 943 createSubCommandExample( 944 ManageAccountSubCommandType.SET_PASSWORD_EXPIRATION_WARNED_TIME, 945 INFO_MANAGE_ACCT_SC_SET_PW_EXP_WARNED_TIME_EXAMPLE.get( 946 EXAMPLE_TARGET_USER_DN, currentGeneralizedTime), 947 "--passwordExpirationWarnedTime", currentGeneralizedTime)); 948 949 950 // Define the subcommand to clear a user's password expiration warned time. 951 createSubCommand( 952 ManageAccountSubCommandType.CLEAR_PASSWORD_EXPIRATION_WARNED_TIME, 953 INFO_MANAGE_ACCT_SC_CLEAR_PW_EXP_WARNED_TIME_EXAMPLE.get( 954 EXAMPLE_TARGET_USER_DN)); 955 956 957 // Define the subcommand to get the number of seconds until a user is 958 // eligible to receive a password expiration warning. 959 createSubCommand( 960 ManageAccountSubCommandType. 961 GET_SECONDS_UNTIL_PASSWORD_EXPIRATION_WARNING, 962 INFO_MANAGE_ACCT_SC_GET_SECONDS_UNTIL_PW_EXP_WARNING_EXAMPLE.get( 963 EXAMPLE_TARGET_USER_DN)); 964 965 966 // Define the subcommand to retrieve a user's password expiration time. 967 createSubCommand(ManageAccountSubCommandType.GET_PASSWORD_EXPIRATION_TIME, 968 INFO_MANAGE_ACCT_SC_GET_PW_EXP_TIME_EXAMPLE.get( 969 EXAMPLE_TARGET_USER_DN)); 970 971 972 // Define the subcommand to get the number of seconds until a user's 973 // password expires. 974 createSubCommand( 975 ManageAccountSubCommandType.GET_SECONDS_UNTIL_PASSWORD_EXPIRATION, 976 INFO_MANAGE_ACCT_SC_GET_SECONDS_UNTIL_PW_EXP_EXAMPLE.get( 977 EXAMPLE_TARGET_USER_DN)); 978 979 980 // Define the subcommand to determine whether a user's password is expired. 981 createSubCommand(ManageAccountSubCommandType.GET_PASSWORD_IS_EXPIRED, 982 INFO_MANAGE_ACCT_SC_GET_PW_IS_EXPIRED_EXAMPLE.get( 983 EXAMPLE_TARGET_USER_DN)); 984 985 986 // Define the subcommand to determine whether an account is failure locked. 987 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_IS_FAILURE_LOCKED, 988 INFO_MANAGE_ACCT_SC_GET_ACCT_FAILURE_LOCKED_EXAMPLE.get( 989 EXAMPLE_TARGET_USER_DN)); 990 991 992 // Define the subcommand to specify whether an account is failure locked. 993 final ArgumentParser setIsFailureLockedParser = 994 createSubCommandParser( 995 ManageAccountSubCommandType.SET_ACCOUNT_IS_FAILURE_LOCKED); 996 997 final BooleanValueArgument setIsFailureLockedValueArg = 998 new BooleanValueArgument('O', "accountIsFailureLocked", true, null, 999 INFO_MANAGE_ACCT_SC_SET_ACCT_FAILURE_LOCKED_ARG_VALUE.get()); 1000 setIsFailureLockedValueArg.addLongIdentifier("operationValue", true); 1001 setIsFailureLockedValueArg.addLongIdentifier("account-is-failure-locked", 1002 true); 1003 setIsFailureLockedValueArg.addLongIdentifier("operation-value", true); 1004 setIsFailureLockedParser.addArgument(setIsFailureLockedValueArg); 1005 1006 createSubCommand(ManageAccountSubCommandType.SET_ACCOUNT_IS_FAILURE_LOCKED, 1007 setIsFailureLockedParser, 1008 createSubCommandExample( 1009 ManageAccountSubCommandType.SET_ACCOUNT_IS_FAILURE_LOCKED, 1010 INFO_MANAGE_ACCT_SC_SET_ACCT_FAILURE_LOCKED_EXAMPLE.get( 1011 EXAMPLE_TARGET_USER_DN), 1012 "--accountIsFailureLocked", "true")); 1013 1014 1015 // Define the subcommand to get the time an account was failure locked. 1016 createSubCommand(ManageAccountSubCommandType.GET_FAILURE_LOCKOUT_TIME, 1017 INFO_MANAGE_ACCT_SC_GET_FAILURE_LOCKED_TIME_EXAMPLE.get( 1018 EXAMPLE_TARGET_USER_DN)); 1019 1020 1021 // Define the subcommand to get the length of time until a failure-locked 1022 // account will be automatically unlocked. 1023 createSubCommand( 1024 ManageAccountSubCommandType. 1025 GET_SECONDS_UNTIL_AUTHENTICATION_FAILURE_UNLOCK, 1026 INFO_MANAGE_ACCT_SC_GET_SECONDS_UNTIL_FAILURE_UNLOCK_EXAMPLE.get( 1027 EXAMPLE_TARGET_USER_DN)); 1028 1029 1030 // Define the subcommand to determine the authentication failure times. 1031 createSubCommand( 1032 ManageAccountSubCommandType.GET_AUTHENTICATION_FAILURE_TIMES, 1033 INFO_MANAGE_ACCT_SC_GET_AUTH_FAILURE_TIMES_EXAMPLE.get( 1034 EXAMPLE_TARGET_USER_DN)); 1035 1036 1037 // Define the subcommand to add values to the set of authentication failure 1038 // times. 1039 final ArgumentParser addAuthFailureTimeParser = 1040 createSubCommandParser( 1041 ManageAccountSubCommandType.ADD_AUTHENTICATION_FAILURE_TIME); 1042 1043 final TimestampArgument addAuthFailureTimeValueArg = 1044 new TimestampArgument('O', "authenticationFailureTime", false, 0, null, 1045 INFO_MANAGE_ACCT_SC_ADD_AUTH_FAILURE_TIME_ARG_VALUE.get()); 1046 addAuthFailureTimeValueArg.addLongIdentifier("operationValue", true); 1047 addAuthFailureTimeValueArg.addLongIdentifier( 1048 "authentication-failure-time", true); 1049 addAuthFailureTimeValueArg.addLongIdentifier("operation-value", true); 1050 addAuthFailureTimeParser.addArgument(addAuthFailureTimeValueArg); 1051 1052 createSubCommand( 1053 ManageAccountSubCommandType.ADD_AUTHENTICATION_FAILURE_TIME, 1054 addAuthFailureTimeParser, 1055 createSubCommandExample( 1056 ManageAccountSubCommandType.ADD_AUTHENTICATION_FAILURE_TIME, 1057 INFO_MANAGE_ACCT_SC_ADD_AUTH_FAILURE_TIME_EXAMPLE.get( 1058 EXAMPLE_TARGET_USER_DN))); 1059 1060 1061 // Define the subcommand to replace the authentication failure times. 1062 final ArgumentParser setAuthFailureTimesParser = 1063 createSubCommandParser( 1064 ManageAccountSubCommandType.SET_AUTHENTICATION_FAILURE_TIMES); 1065 1066 final TimestampArgument setAuthFailureTimesValueArg = 1067 new TimestampArgument('O', "authenticationFailureTime", false, 0, null, 1068 INFO_MANAGE_ACCT_SC_SET_AUTH_FAILURE_TIMES_ARG_VALUE.get()); 1069 setAuthFailureTimesValueArg.addLongIdentifier("operationValue", true); 1070 setAuthFailureTimesValueArg.addLongIdentifier( 1071 "authentication-failure-time", true); 1072 setAuthFailureTimesValueArg.addLongIdentifier("operation-value", true); 1073 setAuthFailureTimesParser.addArgument(setAuthFailureTimesValueArg); 1074 1075 createSubCommand( 1076 ManageAccountSubCommandType.SET_AUTHENTICATION_FAILURE_TIMES, 1077 setAuthFailureTimesParser, 1078 createSubCommandExample( 1079 ManageAccountSubCommandType.SET_AUTHENTICATION_FAILURE_TIMES, 1080 INFO_MANAGE_ACCT_SC_SET_AUTH_FAILURE_TIMES_EXAMPLE.get( 1081 EXAMPLE_TARGET_USER_DN, olderGeneralizedTime, 1082 currentGeneralizedTime), 1083 "--authenticationFailureTime", olderGeneralizedTime, 1084 "--authenticationFailureTime", currentGeneralizedTime)); 1085 1086 1087 // Define the subcommand to clear the authentication failure times. 1088 createSubCommand( 1089 ManageAccountSubCommandType.CLEAR_AUTHENTICATION_FAILURE_TIMES, 1090 INFO_MANAGE_ACCT_SC_CLEAR_AUTH_FAILURE_TIMES_EXAMPLE.get( 1091 EXAMPLE_TARGET_USER_DN)); 1092 1093 1094 // Define the subcommand to get the remaining authentication failure count. 1095 createSubCommand( 1096 ManageAccountSubCommandType.GET_REMAINING_AUTHENTICATION_FAILURE_COUNT, 1097 INFO_MANAGE_ACCT_SC_GET_REMAINING_FAILURE_COUNT_EXAMPLE.get( 1098 EXAMPLE_TARGET_USER_DN)); 1099 1100 1101 // Define the subcommand to determine whether the account is idle locked. 1102 createSubCommand(ManageAccountSubCommandType.GET_ACCOUNT_IS_IDLE_LOCKED, 1103 INFO_MANAGE_ACCT_SC_GET_ACCT_IDLE_LOCKED_EXAMPLE.get( 1104 EXAMPLE_TARGET_USER_DN)); 1105 1106 1107 // Define the subcommand to get the length of time until the account is 1108 // idle locked. 1109 createSubCommand(ManageAccountSubCommandType.GET_SECONDS_UNTIL_IDLE_LOCKOUT, 1110 INFO_MANAGE_ACCT_SC_GET_SECONDS_UNTIL_IDLE_LOCKOUT_EXAMPLE.get( 1111 EXAMPLE_TARGET_USER_DN)); 1112 1113 1114 // Define the subcommand to get the idle lockout time for an account. 1115 createSubCommand(ManageAccountSubCommandType.GET_IDLE_LOCKOUT_TIME, 1116 INFO_MANAGE_ACCT_SC_GET_IDLE_LOCKOUT_TIME_EXAMPLE.get( 1117 EXAMPLE_TARGET_USER_DN)); 1118 1119 1120 // Define the subcommand to determine whether a user's password has been 1121 // reset. 1122 createSubCommand(ManageAccountSubCommandType.GET_MUST_CHANGE_PASSWORD, 1123 INFO_MANAGE_ACCT_SC_GET_MUST_CHANGE_PW_EXAMPLE.get( 1124 EXAMPLE_TARGET_USER_DN)); 1125 1126 1127 // Define the subcommand to specify whether a user's password has been 1128 // reset. 1129 final ArgumentParser setPWIsResetParser = 1130 createSubCommandParser( 1131 ManageAccountSubCommandType.SET_MUST_CHANGE_PASSWORD); 1132 1133 final BooleanValueArgument setPWIsResetValueArg = 1134 new BooleanValueArgument('O', "mustChangePassword", true, null, 1135 INFO_MANAGE_ACCT_SC_SET_MUST_CHANGE_PW_ARG_VALUE.get()); 1136 setPWIsResetValueArg.addLongIdentifier("passwordIsReset", true); 1137 setPWIsResetValueArg.addLongIdentifier("operationValue", true); 1138 setPWIsResetValueArg.addLongIdentifier("must-change-password", true); 1139 setPWIsResetValueArg.addLongIdentifier("password-is-reset", true); 1140 setPWIsResetValueArg.addLongIdentifier("operation-value", true); 1141 setPWIsResetParser.addArgument(setPWIsResetValueArg); 1142 1143 createSubCommand(ManageAccountSubCommandType.SET_MUST_CHANGE_PASSWORD, 1144 setPWIsResetParser, 1145 createSubCommandExample( 1146 ManageAccountSubCommandType.SET_MUST_CHANGE_PASSWORD, 1147 INFO_MANAGE_ACCT_SC_SET_MUST_CHANGE_PW_EXAMPLE.get( 1148 EXAMPLE_TARGET_USER_DN), 1149 "--mustChangePassword", "true")); 1150 1151 1152 // Define the subcommand to clear the password reset state information. 1153 createSubCommand(ManageAccountSubCommandType.CLEAR_MUST_CHANGE_PASSWORD, 1154 INFO_MANAGE_ACCT_SC_CLEAR_MUST_CHANGE_PW_EXAMPLE.get( 1155 EXAMPLE_TARGET_USER_DN)); 1156 1157 1158 // Define the subcommand to determine whether the account is reset locked. 1159 createSubCommand( 1160 ManageAccountSubCommandType.GET_ACCOUNT_IS_PASSWORD_RESET_LOCKED, 1161 INFO_MANAGE_ACCT_SC_GET_ACCT_IS_RESET_LOCKED_EXAMPLE.get( 1162 EXAMPLE_TARGET_USER_DN)); 1163 1164 1165 // Define the subcommand to get the length of time until the password is 1166 // reset locked. 1167 createSubCommand( 1168 ManageAccountSubCommandType.GET_SECONDS_UNTIL_PASSWORD_RESET_LOCKOUT, 1169 INFO_MANAGE_ACCT_SC_GET_SECONDS_UNTIL_RESET_LOCKOUT_EXAMPLE.get( 1170 EXAMPLE_TARGET_USER_DN)); 1171 1172 1173 // Define the subcommand to get the password reset lockout time. 1174 createSubCommand( 1175 ManageAccountSubCommandType.GET_PASSWORD_RESET_LOCKOUT_TIME, 1176 INFO_MANAGE_ACCT_SC_GET_RESET_LOCKOUT_TIME_EXAMPLE.get( 1177 EXAMPLE_TARGET_USER_DN)); 1178 1179 1180 // Define the subcommand to get the last login time. 1181 createSubCommand(ManageAccountSubCommandType.GET_LAST_LOGIN_TIME, 1182 INFO_MANAGE_ACCT_SC_GET_LAST_LOGIN_TIME_EXAMPLE.get( 1183 EXAMPLE_TARGET_USER_DN)); 1184 1185 1186 // Define the subcommand to set the last login time. 1187 final ArgumentParser setLastLoginTimeParser = 1188 createSubCommandParser( 1189 ManageAccountSubCommandType.SET_LAST_LOGIN_TIME); 1190 1191 final TimestampArgument setLastLoginTimeValueArg = new TimestampArgument( 1192 'O', "lastLoginTime", false, 1, null, 1193 INFO_MANAGE_ACCT_SC_SET_LAST_LOGIN_TIME_ARG_VALUE.get()); 1194 setLastLoginTimeValueArg.addLongIdentifier("operationValue", true); 1195 setLastLoginTimeValueArg.addLongIdentifier("last-login-time", true); 1196 setLastLoginTimeValueArg.addLongIdentifier("operation-value", true); 1197 setLastLoginTimeParser.addArgument(setLastLoginTimeValueArg); 1198 1199 createSubCommand(ManageAccountSubCommandType.SET_LAST_LOGIN_TIME, 1200 setLastLoginTimeParser, 1201 createSubCommandExample( 1202 ManageAccountSubCommandType.SET_LAST_LOGIN_TIME, 1203 INFO_MANAGE_ACCT_SC_SET_LAST_LOGIN_TIME_EXAMPLE.get( 1204 EXAMPLE_TARGET_USER_DN, currentGeneralizedTime), 1205 "--lastLoginTime", currentGeneralizedTime)); 1206 1207 1208 // Define the subcommand to clear the last login time. 1209 createSubCommand(ManageAccountSubCommandType.CLEAR_LAST_LOGIN_TIME, 1210 INFO_MANAGE_ACCT_SC_CLEAR_LAST_LOGIN_TIME_EXAMPLE.get( 1211 EXAMPLE_TARGET_USER_DN)); 1212 1213 1214 // Define the subcommand to get the last login IP address. 1215 createSubCommand(ManageAccountSubCommandType.GET_LAST_LOGIN_IP_ADDRESS, 1216 INFO_MANAGE_ACCT_SC_GET_LAST_LOGIN_IP_EXAMPLE.get( 1217 EXAMPLE_TARGET_USER_DN)); 1218 1219 1220 // Define the subcommand to set the last login IP address. 1221 final ArgumentParser setLastLoginIPParser = 1222 createSubCommandParser( 1223 ManageAccountSubCommandType.SET_LAST_LOGIN_IP_ADDRESS); 1224 1225 final StringArgument setLastLoginIPValueArg = new StringArgument('O', 1226 "lastLoginIPAddress", true, 1, null, 1227 INFO_MANAGE_ACCT_SC_SET_LAST_LOGIN_IP_ARG_VALUE.get()); 1228 setLastLoginIPValueArg.addLongIdentifier("operationValue", true); 1229 setLastLoginIPValueArg.addLongIdentifier("last-login-ip-address", true); 1230 setLastLoginIPValueArg.addLongIdentifier("operation-value", true); 1231 setLastLoginIPValueArg.addValueValidator( 1232 new IPAddressArgumentValueValidator()); 1233 setLastLoginIPParser.addArgument(setLastLoginIPValueArg); 1234 1235 1236 createSubCommand(ManageAccountSubCommandType.SET_LAST_LOGIN_IP_ADDRESS, 1237 setLastLoginIPParser, 1238 createSubCommandExample( 1239 ManageAccountSubCommandType.SET_LAST_LOGIN_IP_ADDRESS, 1240 INFO_MANAGE_ACCT_SC_SET_LAST_LOGIN_IP_EXAMPLE.get( 1241 EXAMPLE_TARGET_USER_DN, "1.2.3.4"), 1242 "--lastLoginIPAddress", "1.2.3.4")); 1243 1244 1245 // Define the subcommand to clear the last login IP address. 1246 createSubCommand(ManageAccountSubCommandType.CLEAR_LAST_LOGIN_IP_ADDRESS, 1247 INFO_MANAGE_ACCT_SC_CLEAR_LAST_LOGIN_IP_EXAMPLE.get( 1248 EXAMPLE_TARGET_USER_DN)); 1249 1250 1251 // Define the subcommand to get the grace login use times. 1252 createSubCommand(ManageAccountSubCommandType.GET_GRACE_LOGIN_USE_TIMES, 1253 INFO_MANAGE_ACCT_SC_GET_GRACE_LOGIN_TIMES_EXAMPLE.get( 1254 EXAMPLE_TARGET_USER_DN)); 1255 1256 1257 // Define the subcommand to add values to the set of grace login use times. 1258 final ArgumentParser addGraceLoginTimeParser = 1259 createSubCommandParser( 1260 ManageAccountSubCommandType.ADD_GRACE_LOGIN_USE_TIME); 1261 1262 final TimestampArgument addGraceLoginTimeValueArg = 1263 new TimestampArgument('O', "graceLoginUseTime", false, 0, null, 1264 INFO_MANAGE_ACCT_SC_ADD_GRACE_LOGIN_TIME_ARG_VALUE.get()); 1265 addGraceLoginTimeValueArg.addLongIdentifier("operationValue", true); 1266 addGraceLoginTimeValueArg.addLongIdentifier("grace-login-use-time", true); 1267 addGraceLoginTimeValueArg.addLongIdentifier("operation-value", true); 1268 addGraceLoginTimeParser.addArgument(addGraceLoginTimeValueArg); 1269 1270 createSubCommand(ManageAccountSubCommandType.ADD_GRACE_LOGIN_USE_TIME, 1271 addGraceLoginTimeParser, 1272 createSubCommandExample( 1273 ManageAccountSubCommandType.ADD_GRACE_LOGIN_USE_TIME, 1274 INFO_MANAGE_ACCT_SC_ADD_GRACE_LOGIN_TIME_EXAMPLE.get( 1275 EXAMPLE_TARGET_USER_DN))); 1276 1277 1278 // Define the subcommand to replace the set of grace login use times. 1279 final ArgumentParser setGraceLoginTimesParser = 1280 createSubCommandParser( 1281 ManageAccountSubCommandType.SET_GRACE_LOGIN_USE_TIMES); 1282 1283 final TimestampArgument setGraceLoginTimesValueArg = 1284 new TimestampArgument('O', "graceLoginUseTime", false, 0, null, 1285 INFO_MANAGE_ACCT_SC_SET_GRACE_LOGIN_TIMES_ARG_VALUE.get()); 1286 setGraceLoginTimesValueArg.addLongIdentifier("operationValue", true); 1287 setGraceLoginTimesValueArg.addLongIdentifier("grace-login-use-time", true); 1288 setGraceLoginTimesValueArg.addLongIdentifier("operation-value", true); 1289 setGraceLoginTimesParser.addArgument(setGraceLoginTimesValueArg); 1290 1291 createSubCommand(ManageAccountSubCommandType.SET_GRACE_LOGIN_USE_TIMES, 1292 setGraceLoginTimesParser, 1293 createSubCommandExample( 1294 ManageAccountSubCommandType.SET_GRACE_LOGIN_USE_TIMES, 1295 INFO_MANAGE_ACCT_SC_SET_GRACE_LOGIN_TIMES_EXAMPLE.get( 1296 EXAMPLE_TARGET_USER_DN, olderGeneralizedTime, 1297 currentGeneralizedTime), 1298 "--graceLoginUseTime", olderGeneralizedTime, 1299 "--graceLoginUseTime", currentGeneralizedTime)); 1300 1301 1302 // Define the subcommand to clear the grace login use times. 1303 createSubCommand(ManageAccountSubCommandType.CLEAR_GRACE_LOGIN_USE_TIMES, 1304 INFO_MANAGE_ACCT_SC_CLEAR_GRACE_LOGIN_TIMES_EXAMPLE.get( 1305 EXAMPLE_TARGET_USER_DN)); 1306 1307 1308 // Define the subcommand to get the remaining grace login count. 1309 createSubCommand( 1310 ManageAccountSubCommandType.GET_REMAINING_GRACE_LOGIN_COUNT, 1311 INFO_MANAGE_ACCT_SC_GET_REMAINING_GRACE_LOGIN_COUNT_EXAMPLE.get( 1312 EXAMPLE_TARGET_USER_DN)); 1313 1314 1315 // Define the subcommand to get the password changed by required time value. 1316 createSubCommand( 1317 ManageAccountSubCommandType.GET_PASSWORD_CHANGED_BY_REQUIRED_TIME, 1318 INFO_MANAGE_ACCT_SC_GET_PW_CHANGED_BY_REQ_TIME_EXAMPLE.get( 1319 EXAMPLE_TARGET_USER_DN)); 1320 1321 1322 // Define the subcommand to set the password changed by required time value. 1323 final ArgumentParser setPWChangedByReqTimeParser = 1324 createSubCommandParser(ManageAccountSubCommandType. 1325 SET_PASSWORD_CHANGED_BY_REQUIRED_TIME); 1326 1327 final TimestampArgument setPWChangedByReqTimeValueArg = 1328 new TimestampArgument('O', "passwordChangedByRequiredTime", false, 1, 1329 null, 1330 INFO_MANAGE_ACCT_SC_SET_PW_CHANGED_BY_REQ_TIME_ARG_VALUE.get()); 1331 setPWChangedByReqTimeValueArg.addLongIdentifier("operationValue", true); 1332 setPWChangedByReqTimeValueArg.addLongIdentifier( 1333 "password-changed-by-required-time", true); 1334 setPWChangedByReqTimeValueArg.addLongIdentifier("operation-value", true); 1335 setPWChangedByReqTimeParser.addArgument( 1336 setPWChangedByReqTimeValueArg); 1337 1338 createSubCommand( 1339 ManageAccountSubCommandType.SET_PASSWORD_CHANGED_BY_REQUIRED_TIME, 1340 setPWChangedByReqTimeParser, 1341 createSubCommandExample( 1342 ManageAccountSubCommandType.SET_PASSWORD_CHANGED_BY_REQUIRED_TIME, 1343 INFO_MANAGE_ACCT_SC_SET_PW_CHANGED_BY_REQ_TIME_EXAMPLE.get( 1344 EXAMPLE_TARGET_USER_DN))); 1345 1346 1347 // Define the subcommand to clear the password changed by required time 1348 // value. 1349 createSubCommand( 1350 ManageAccountSubCommandType.CLEAR_PASSWORD_CHANGED_BY_REQUIRED_TIME, 1351 INFO_MANAGE_ACCT_SC_CLEAR_PW_CHANGED_BY_REQ_TIME_EXAMPLE.get( 1352 EXAMPLE_TARGET_USER_DN)); 1353 1354 1355 // Define the subcommand to get the length of time until the required change 1356 // time. 1357 createSubCommand( 1358 ManageAccountSubCommandType. 1359 GET_SECONDS_UNTIL_REQUIRED_PASSWORD_CHANGE_TIME, 1360 INFO_MANAGE_ACCT_SC_GET_SECS_UNTIL_REQ_CHANGE_TIME_EXAMPLE.get( 1361 EXAMPLE_TARGET_USER_DN)); 1362 1363 1364 // Define the subcommand to get the password history count. 1365 createSubCommand(ManageAccountSubCommandType.GET_PASSWORD_HISTORY_COUNT, 1366 INFO_MANAGE_ACCT_SC_GET_PW_HISTORY_COUNT_EXAMPLE.get( 1367 EXAMPLE_TARGET_USER_DN)); 1368 1369 1370 // Define the subcommand to clear a user's password history. 1371 createSubCommand(ManageAccountSubCommandType.CLEAR_PASSWORD_HISTORY, 1372 INFO_MANAGE_ACCT_SC_CLEAR_PW_HISTORY_EXAMPLE.get( 1373 EXAMPLE_TARGET_USER_DN)); 1374 1375 1376 // Define the subcommand to determine whether a user has a retired password. 1377 createSubCommand(ManageAccountSubCommandType.GET_HAS_RETIRED_PASSWORD, 1378 INFO_MANAGE_ACCT_SC_GET_HAS_RETIRED_PW_EXAMPLE.get( 1379 EXAMPLE_TARGET_USER_DN)); 1380 1381 1382 // Define the subcommand to retrieve the time that a user's former password 1383 // was retired. 1384 createSubCommand(ManageAccountSubCommandType.GET_PASSWORD_RETIRED_TIME, 1385 INFO_MANAGE_ACCT_SC_GET_PW_RETIRED_TIME_EXAMPLE.get( 1386 EXAMPLE_TARGET_USER_DN)); 1387 1388 1389 // Define the subcommand to retrieve the retired password expiration time. 1390 createSubCommand( 1391 ManageAccountSubCommandType.GET_RETIRED_PASSWORD_EXPIRATION_TIME, 1392 INFO_MANAGE_ACCT_SC_GET_RETIRED_PW_EXP_TIME_EXAMPLE.get( 1393 EXAMPLE_TARGET_USER_DN)); 1394 1395 1396 // Define the subcommand to purge a retired password. 1397 createSubCommand(ManageAccountSubCommandType.CLEAR_RETIRED_PASSWORD, 1398 INFO_MANAGE_ACCT_SC_PURGE_RETIRED_PW_EXAMPLE.get( 1399 EXAMPLE_TARGET_USER_DN)); 1400 1401 1402 // Define the subcommand to get the available SASL mechanisms for a user. 1403 createSubCommand(ManageAccountSubCommandType.GET_AVAILABLE_SASL_MECHANISMS, 1404 INFO_MANAGE_ACCT_SC_GET_AVAILABLE_SASL_MECHS_EXAMPLE.get( 1405 EXAMPLE_TARGET_USER_DN)); 1406 1407 1408 // Define the subcommand to get the available OTP delivery mechanisms for a 1409 // user. 1410 createSubCommand( 1411 ManageAccountSubCommandType.GET_AVAILABLE_OTP_DELIVERY_MECHANISMS, 1412 INFO_MANAGE_ACCT_SC_GET_AVAILABLE_OTP_MECHS_EXAMPLE.get( 1413 EXAMPLE_TARGET_USER_DN)); 1414 1415 1416 // Define the subcommand to determine whether a user has at least one TOTP 1417 // shared secret. 1418 createSubCommand(ManageAccountSubCommandType.GET_HAS_TOTP_SHARED_SECRET, 1419 INFO_MANAGE_ACCT_SC_GET_HAS_TOTP_SHARED_SECRET_EXAMPLE.get( 1420 EXAMPLE_TARGET_USER_DN)); 1421 1422 1423 // Define the subcommand to add a value to the set of TOTP shared secrets 1424 // for a user. 1425 final ArgumentParser addTOTPSharedSecretParser = 1426 createSubCommandParser( 1427 ManageAccountSubCommandType.ADD_TOTP_SHARED_SECRET); 1428 1429 final StringArgument addTOTPSharedSecretValueArg = 1430 new StringArgument('O', "totpSharedSecret", true, 0, null, 1431 INFO_MANAGE_ACCT_SC_ADD_YUBIKEY_ID_ARG_VALUE.get()); 1432 addTOTPSharedSecretValueArg.addLongIdentifier("operationValue", true); 1433 addTOTPSharedSecretValueArg.addLongIdentifier("totp-shared-secret", true); 1434 addTOTPSharedSecretValueArg.addLongIdentifier("operation-value", true); 1435 addTOTPSharedSecretValueArg.setSensitive(true); 1436 addTOTPSharedSecretParser.addArgument( 1437 addTOTPSharedSecretValueArg); 1438 1439 createSubCommand(ManageAccountSubCommandType.ADD_TOTP_SHARED_SECRET, 1440 addTOTPSharedSecretParser, 1441 createSubCommandExample( 1442 ManageAccountSubCommandType.ADD_TOTP_SHARED_SECRET, 1443 INFO_MANAGE_ACCT_SC_ADD_TOTP_SHARED_SECRET_EXAMPLE.get( 1444 "abcdefghijklmnop", EXAMPLE_TARGET_USER_DN), 1445 "--totpSharedSecret", "abcdefghijklmnop")); 1446 1447 1448 // Define the subcommand to remove a value from the set of TOTP shared 1449 // secrets for a user. 1450 final ArgumentParser removeTOTPSharedSecretParser = 1451 createSubCommandParser( 1452 ManageAccountSubCommandType.REMOVE_TOTP_SHARED_SECRET); 1453 1454 final StringArgument removeTOTPSharedSecretValueArg = 1455 new StringArgument('O', "totpSharedSecret", true, 0, null, 1456 INFO_MANAGE_ACCT_SC_REMOVE_YUBIKEY_ID_ARG_VALUE.get()); 1457 removeTOTPSharedSecretValueArg.addLongIdentifier("operationValue", true); 1458 removeTOTPSharedSecretValueArg.addLongIdentifier("totp-shared-secret", 1459 true); 1460 removeTOTPSharedSecretValueArg.addLongIdentifier("operation-value", true); 1461 removeTOTPSharedSecretValueArg.setSensitive(true); 1462 removeTOTPSharedSecretParser.addArgument( 1463 removeTOTPSharedSecretValueArg); 1464 1465 createSubCommand(ManageAccountSubCommandType.REMOVE_TOTP_SHARED_SECRET, 1466 removeTOTPSharedSecretParser, 1467 createSubCommandExample( 1468 ManageAccountSubCommandType.REMOVE_TOTP_SHARED_SECRET, 1469 INFO_MANAGE_ACCT_SC_REMOVE_TOTP_SHARED_SECRET_EXAMPLE.get( 1470 "abcdefghijklmnop", EXAMPLE_TARGET_USER_DN), 1471 "--totpSharedSecret", "abcdefghijklmnop")); 1472 1473 1474 // Define the subcommand to replace set of TOTP shared secrets for a user. 1475 final ArgumentParser setTOTPSharedSecretsParser = 1476 createSubCommandParser( 1477 ManageAccountSubCommandType.SET_TOTP_SHARED_SECRETS); 1478 1479 final StringArgument setTOTPSharedSecretsValueArg = 1480 new StringArgument('O', "totpSharedSecret", true, 0, null, 1481 INFO_MANAGE_ACCT_SC_SET_TOTP_SHARED_SECRETS_ARG_VALUE.get()); 1482 setTOTPSharedSecretsValueArg.addLongIdentifier("operationValue", true); 1483 setTOTPSharedSecretsValueArg.addLongIdentifier("totp-shared-secret", true); 1484 setTOTPSharedSecretsValueArg.addLongIdentifier("operation-value", true); 1485 setTOTPSharedSecretsValueArg.setSensitive(true); 1486 setTOTPSharedSecretsParser.addArgument( 1487 setTOTPSharedSecretsValueArg); 1488 1489 createSubCommand(ManageAccountSubCommandType.SET_TOTP_SHARED_SECRETS, 1490 setTOTPSharedSecretsParser, 1491 createSubCommandExample( 1492 ManageAccountSubCommandType.SET_TOTP_SHARED_SECRETS, 1493 INFO_MANAGE_ACCT_SC_SET_TOTP_SHARED_SECRETS_EXAMPLE.get( 1494 EXAMPLE_TARGET_USER_DN, "abcdefghijklmnop"), 1495 "--totpSharedSecret", "abcdefghijklmnop")); 1496 1497 1498 // Define the subcommand to clear the set of TOTP shared secrets for a user. 1499 createSubCommand( 1500 ManageAccountSubCommandType.CLEAR_TOTP_SHARED_SECRETS, 1501 INFO_MANAGE_ACCT_SC_CLEAR_TOTP_SHARED_SECRETS_EXAMPLE.get( 1502 EXAMPLE_TARGET_USER_DN)); 1503 1504 1505 // Define the subcommand to determine whether a user has at least one 1506 // registered YubiKey OTP device public ID. 1507 createSubCommand( 1508 ManageAccountSubCommandType.GET_HAS_REGISTERED_YUBIKEY_PUBLIC_ID, 1509 INFO_MANAGE_ACCT_SC_GET_HAS_YUBIKEY_ID_EXAMPLE.get( 1510 EXAMPLE_TARGET_USER_DN)); 1511 1512 1513 // Define the subcommand to get the set of registered YubiKey OTP device 1514 // public IDs for a user. 1515 createSubCommand( 1516 ManageAccountSubCommandType.GET_REGISTERED_YUBIKEY_PUBLIC_IDS, 1517 INFO_MANAGE_ACCT_SC_GET_YUBIKEY_IDS_EXAMPLE.get( 1518 EXAMPLE_TARGET_USER_DN)); 1519 1520 1521 // Define the subcommand to add a value to the set of registered YubiKey OTP 1522 // device public IDs for a user. 1523 final ArgumentParser addRegisteredYubiKeyPublicIDParser = 1524 createSubCommandParser( 1525 ManageAccountSubCommandType.ADD_REGISTERED_YUBIKEY_PUBLIC_ID); 1526 1527 final StringArgument addRegisteredYubiKeyPublicIDValueArg = 1528 new StringArgument('O', "publicID", true, 0, null, 1529 INFO_MANAGE_ACCT_SC_ADD_YUBIKEY_ID_ARG_VALUE.get()); 1530 addRegisteredYubiKeyPublicIDValueArg.addLongIdentifier("operationValue", 1531 true); 1532 addRegisteredYubiKeyPublicIDValueArg.addLongIdentifier("public-id", true); 1533 addRegisteredYubiKeyPublicIDValueArg.addLongIdentifier("operation-value", 1534 true); 1535 addRegisteredYubiKeyPublicIDParser.addArgument( 1536 addRegisteredYubiKeyPublicIDValueArg); 1537 1538 createSubCommand( 1539 ManageAccountSubCommandType.ADD_REGISTERED_YUBIKEY_PUBLIC_ID, 1540 addRegisteredYubiKeyPublicIDParser, 1541 createSubCommandExample( 1542 ManageAccountSubCommandType.ADD_REGISTERED_YUBIKEY_PUBLIC_ID, 1543 INFO_MANAGE_ACCT_SC_ADD_YUBIKEY_ID_EXAMPLE.get( 1544 "abcdefghijkl", EXAMPLE_TARGET_USER_DN), 1545 "--publicID", "abcdefghijkl")); 1546 1547 1548 // Define the subcommand to remove a value from the set of registered 1549 // YubiKey OTP device public IDs for a user. 1550 final ArgumentParser removeRegisteredYubiKeyPublicIDParser = 1551 createSubCommandParser( 1552 ManageAccountSubCommandType.REMOVE_REGISTERED_YUBIKEY_PUBLIC_ID); 1553 1554 final StringArgument removeRegisteredYubiKeyPublicIDValueArg = 1555 new StringArgument('O', "publicID", true, 0, null, 1556 INFO_MANAGE_ACCT_SC_REMOVE_YUBIKEY_ID_ARG_VALUE.get()); 1557 removeRegisteredYubiKeyPublicIDValueArg.addLongIdentifier("operationValue", 1558 true); 1559 removeRegisteredYubiKeyPublicIDValueArg.addLongIdentifier("public-id", 1560 true); 1561 removeRegisteredYubiKeyPublicIDValueArg.addLongIdentifier("operation-value", 1562 true); 1563 removeRegisteredYubiKeyPublicIDParser.addArgument( 1564 removeRegisteredYubiKeyPublicIDValueArg); 1565 1566 createSubCommand( 1567 ManageAccountSubCommandType.REMOVE_REGISTERED_YUBIKEY_PUBLIC_ID, 1568 removeRegisteredYubiKeyPublicIDParser, 1569 createSubCommandExample( 1570 ManageAccountSubCommandType.REMOVE_REGISTERED_YUBIKEY_PUBLIC_ID, 1571 INFO_MANAGE_ACCT_SC_REMOVE_YUBIKEY_ID_EXAMPLE.get( 1572 "abcdefghijkl", EXAMPLE_TARGET_USER_DN), 1573 "--publicID", "abcdefghijkl")); 1574 1575 1576 // Define the subcommand to replace set of registered YubiKey OTP device 1577 // public IDs for a user. 1578 final ArgumentParser setRegisteredYubiKeyPublicIDParser = 1579 createSubCommandParser( 1580 ManageAccountSubCommandType.SET_REGISTERED_YUBIKEY_PUBLIC_IDS); 1581 1582 final StringArgument setRegisteredYubiKeyPublicIDValueArg = 1583 new StringArgument('O', "publicID", true, 0, null, 1584 INFO_MANAGE_ACCT_SC_SET_YUBIKEY_IDS_ARG_VALUE.get()); 1585 setRegisteredYubiKeyPublicIDValueArg.addLongIdentifier("operationValue", 1586 true); 1587 setRegisteredYubiKeyPublicIDValueArg.addLongIdentifier("public-id", true); 1588 setRegisteredYubiKeyPublicIDValueArg.addLongIdentifier("operation-value", 1589 true); 1590 setRegisteredYubiKeyPublicIDParser.addArgument( 1591 setRegisteredYubiKeyPublicIDValueArg); 1592 1593 createSubCommand( 1594 ManageAccountSubCommandType.SET_REGISTERED_YUBIKEY_PUBLIC_IDS, 1595 setRegisteredYubiKeyPublicIDParser, 1596 createSubCommandExample( 1597 ManageAccountSubCommandType.SET_REGISTERED_YUBIKEY_PUBLIC_IDS, 1598 INFO_MANAGE_ACCT_SC_SET_YUBIKEY_IDS_EXAMPLE.get( 1599 EXAMPLE_TARGET_USER_DN, "abcdefghijkl"), 1600 "--publicID", "abcdefghijkl")); 1601 1602 1603 // Define the subcommand to clear the set of registered YubiKey OTP device 1604 // public IDs for a user. 1605 createSubCommand( 1606 ManageAccountSubCommandType.CLEAR_REGISTERED_YUBIKEY_PUBLIC_IDS, 1607 INFO_MANAGE_ACCT_SC_CLEAR_YUBIKEY_IDS_EXAMPLE.get( 1608 EXAMPLE_TARGET_USER_DN)); 1609 1610 1611 // Define the subcommand to determine whether a user has at least one static 1612 // password. 1613 createSubCommand(ManageAccountSubCommandType.GET_HAS_STATIC_PASSWORD, 1614 INFO_MANAGE_ACCT_SC_GET_HAS_STATIC_PW_EXAMPLE.get( 1615 EXAMPLE_TARGET_USER_DN)); 1616 } 1617 1618 1619 1620 /** 1621 * Creates an argument parser for the provided subcommand type. It will not 1622 * have any arguments associated with it. 1623 * 1624 * @param type The subcommand type for which to create the argument parser. 1625 * 1626 * @return The created argument parser. 1627 * 1628 * @throws ArgumentException If a problem is encountered while creating the 1629 * argument parser. 1630 */ 1631 private static ArgumentParser createSubCommandParser( 1632 final ManageAccountSubCommandType type) 1633 throws ArgumentException 1634 { 1635 return new ArgumentParser(type.getPrimaryName(), type.getDescription()); 1636 } 1637 1638 1639 1640 /** 1641 * Generates an example usage map for a specified subcommand. 1642 * 1643 * @param t The subcommand type. 1644 * @param description The description to use for the example. 1645 * @param args The set of arguments to include in the example, 1646 * excluding the subcommand name and the arguments used 1647 * to connect and authenticate to the server. This may 1648 * be empty if no additional arguments are needed. 1649 * 1650 * @return The generated example usage map. 1651 */ 1652 private static LinkedHashMap<String[],String> createSubCommandExample( 1653 final ManageAccountSubCommandType t, 1654 final String description, final String... args) 1655 { 1656 final LinkedHashMap<String[], String> examples = new LinkedHashMap<>(1); 1657 createSubCommandExample(examples, t, description, args); 1658 return examples; 1659 } 1660 1661 1662 1663 /** 1664 * Adds an example for a specified subcommand to the given map. 1665 * 1666 * @param examples The map to which the example should be added. 1667 * @param t The subcommand type. 1668 * @param description The description to use for the example. 1669 * @param args The set of arguments to include in the example, 1670 * excluding the subcommand name and the arguments used 1671 * to connect and authenticate to the server. This may 1672 * be empty if no additional arguments are needed. 1673 */ 1674 private static void createSubCommandExample( 1675 final LinkedHashMap<String[], String> examples, 1676 final ManageAccountSubCommandType t, final String description, 1677 final String... args) 1678 { 1679 final ArrayList<String> argList = new ArrayList<>(10 + args.length); 1680 argList.add(t.getPrimaryName()); 1681 argList.add("--hostname"); 1682 argList.add("server.example.com"); 1683 argList.add("--port"); 1684 argList.add("389"); 1685 argList.add("--bindDN"); 1686 argList.add("uid=admin,dc=example,dc=com"); 1687 argList.add("--promptForBindPassword"); 1688 argList.add("--targetDN"); 1689 argList.add("uid=jdoe,ou=People,dc=example,dc=com"); 1690 1691 if (args.length > 0) 1692 { 1693 argList.addAll(Arrays.asList(args)); 1694 } 1695 1696 final String[] argArray = new String[argList.size()]; 1697 argList.toArray(argArray); 1698 1699 examples.put(argArray, description); 1700 } 1701 1702 1703 1704 /** 1705 * Creates a subcommand with the provided information. 1706 * 1707 * @param subcommandType The subcommand type. 1708 * @param exampleDescription The description to use for the 1709 * automatically-generated example. 1710 * 1711 * @throws ArgumentException If a problem is encountered while creating the 1712 * subcommand. 1713 */ 1714 private void createSubCommand( 1715 final ManageAccountSubCommandType subcommandType, 1716 final String exampleDescription) 1717 throws ArgumentException 1718 { 1719 final ArgumentParser subcommandParser = 1720 createSubCommandParser(subcommandType); 1721 1722 final LinkedHashMap<String[],String> examples = 1723 createSubCommandExample(subcommandType, exampleDescription); 1724 1725 createSubCommand(subcommandType, subcommandParser, examples); 1726 } 1727 1728 1729 1730 /** 1731 * Creates a subcommand with the provided information. 1732 * 1733 * @param subcommandType The subcommand type. 1734 * @param subcommandParser The argument parser for the subcommand-specific 1735 * arguments. 1736 * @param examples The example usages for the subcommand. 1737 * 1738 * @throws ArgumentException If a problem is encountered while creating the 1739 * subcommand. 1740 */ 1741 private void createSubCommand( 1742 final ManageAccountSubCommandType subcommandType, 1743 final ArgumentParser subcommandParser, 1744 final LinkedHashMap<String[],String> examples) 1745 throws ArgumentException 1746 { 1747 final SubCommand subCommand = new SubCommand( 1748 subcommandType.getPrimaryName(), subcommandType.getDescription(), 1749 subcommandParser, examples); 1750 1751 for (final String alternateName : subcommandType.getAlternateNames()) 1752 { 1753 subCommand.addName(alternateName, true); 1754 } 1755 1756 parser.addSubCommand(subCommand); 1757 } 1758 1759 1760 1761 /** 1762 * {@inheritDoc} 1763 */ 1764 @Override() 1765 public LDAPConnectionOptions getConnectionOptions() 1766 { 1767 return connectionOptions; 1768 } 1769 1770 1771 1772 /** 1773 * {@inheritDoc} 1774 */ 1775 @Override() 1776 public ResultCode doToolProcessing() 1777 { 1778 // If we should just generate a sample rate data file, then do that now. 1779 final FileArgument generateSampleRateFile = 1780 parser.getFileArgument(ARG_GENERATE_SAMPLE_RATE_FILE); 1781 if (generateSampleRateFile.isPresent()) 1782 { 1783 try 1784 { 1785 RateAdjustor.writeSampleVariableRateFile( 1786 generateSampleRateFile.getValue()); 1787 return ResultCode.SUCCESS; 1788 } 1789 catch (final Exception e) 1790 { 1791 Debug.debugException(e); 1792 wrapErr(0, WRAP_COLUMN, 1793 ERR_MANAGE_ACCT_CANNOT_GENERATE_SAMPLE_RATE_FILE.get( 1794 generateSampleRateFile.getValue().getAbsolutePath(), 1795 StaticUtils.getExceptionMessage(e))); 1796 return ResultCode.LOCAL_ERROR; 1797 } 1798 } 1799 1800 1801 // If we need to create a fixed-rate barrier and/or use a variable rate 1802 // definition, then set that up. 1803 final IntegerArgument ratePerSecond = 1804 parser.getIntegerArgument(ARG_RATE_PER_SECOND); 1805 final FileArgument variableRateData = 1806 parser.getFileArgument(ARG_VARIABLE_RATE_DATA); 1807 if (ratePerSecond.isPresent() || variableRateData.isPresent()) 1808 { 1809 if (ratePerSecond.isPresent()) 1810 { 1811 rateLimiter = new FixedRateBarrier(1000L, ratePerSecond.getValue()); 1812 } 1813 else 1814 { 1815 rateLimiter = new FixedRateBarrier(1000L, Integer.MAX_VALUE); 1816 } 1817 1818 if (variableRateData.isPresent()) 1819 { 1820 try 1821 { 1822 rateAdjustor = RateAdjustor.newInstance(rateLimiter, 1823 ratePerSecond.getValue(), variableRateData.getValue()); 1824 } 1825 catch (final Exception e) 1826 { 1827 Debug.debugException(e); 1828 wrapErr(0, WRAP_COLUMN, 1829 ERR_MANAGE_ACCT_CANNOT_CREATE_RATE_ADJUSTOR.get( 1830 variableRateData.getValue().getAbsolutePath(), 1831 StaticUtils.getExceptionMessage(e))); 1832 return ResultCode.PARAM_ERROR; 1833 } 1834 } 1835 } 1836 1837 1838 // Create the connection pool to use for all processing. 1839 final LDAPConnectionPool pool; 1840 final int numSearchThreads = 1841 parser.getIntegerArgument(ARG_NUM_SEARCH_THREADS).getValue(); 1842 try 1843 { 1844 final int numOperationThreads = 1845 parser.getIntegerArgument(ARG_NUM_THREADS).getValue(); 1846 pool = getConnectionPool(numOperationThreads, 1847 (numOperationThreads + numSearchThreads)); 1848 1849 // Explicitly disable automatic retry, since it probably won't work 1850 // reliably for extended operations anyway. We'll handle retry manually. 1851 pool.setRetryFailedOperationsDueToInvalidConnections(false); 1852 1853 // Set a maximum connection age of 30 minutes. 1854 pool.setMaxConnectionAgeMillis(1_800_000L); 1855 } 1856 catch (final LDAPException le) 1857 { 1858 Debug.debugException(le); 1859 1860 wrapErr(0, WRAP_COLUMN, 1861 ERR_MANAGE_ACCT_CANNOT_CREATE_CONNECTION_POOL.get(getToolName(), 1862 le.getMessage())); 1863 return le.getResultCode(); 1864 } 1865 1866 1867 try 1868 { 1869 // Create the output writer. This should always succeed. 1870 outputWriter = new LDIFWriter(getOut()); 1871 1872 1873 1874 // Create the reject writer if appropriate. 1875 final FileArgument rejectFile = parser.getFileArgument(ARG_REJECT_FILE); 1876 if (rejectFile.isPresent()) 1877 { 1878 final BooleanArgument appendToRejectFile = 1879 parser.getBooleanArgument(ARG_APPEND_TO_REJECT_FILE); 1880 1881 try 1882 { 1883 rejectWriter = new LDIFWriter(new FileOutputStream( 1884 rejectFile.getValue(), appendToRejectFile.isPresent())); 1885 } 1886 catch (final Exception e) 1887 { 1888 Debug.debugException(e); 1889 wrapErr(0, WRAP_COLUMN, 1890 ERR_MANAGE_ACCT_CANNOT_CREATE_REJECT_WRITER.get( 1891 rejectFile.getValue().getAbsolutePath(), 1892 StaticUtils.getExceptionMessage(e))); 1893 return ResultCode.LOCAL_ERROR; 1894 } 1895 } 1896 1897 1898 // Create the processor that will be used to actually perform the 1899 // manage-account operation processing for each entry. 1900 final ManageAccountProcessor processor; 1901 try 1902 { 1903 processor = new ManageAccountProcessor(this, pool, rateLimiter, 1904 outputWriter, rejectWriter); 1905 } 1906 catch (final LDAPException le) 1907 { 1908 Debug.debugException(le); 1909 wrapErr(0, WRAP_COLUMN, 1910 ERR_MANAGE_ACCT_CANNOT_CREATE_PROCESSOR.get( 1911 StaticUtils.getExceptionMessage(le))); 1912 return le.getResultCode(); 1913 } 1914 1915 1916 // If we should use a rate adjustor, then start it now. 1917 if (rateAdjustor != null) 1918 { 1919 rateAdjustor.start(); 1920 } 1921 1922 1923 // If any targetDN values were provided, then process them now. 1924 final DNArgument targetDN = parser.getDNArgument(ARG_TARGET_DN); 1925 if (targetDN.isPresent()) 1926 { 1927 for (final DN dn : targetDN.getValues()) 1928 { 1929 if (cancelRequested()) 1930 { 1931 return ResultCode.USER_CANCELED; 1932 } 1933 1934 processor.process(dn.toString()); 1935 } 1936 } 1937 1938 1939 // If any DN input files were specified, then process them now. 1940 final FileArgument dnInputFile = 1941 parser.getFileArgument(ARG_DN_INPUT_FILE); 1942 if (dnInputFile.isPresent()) 1943 { 1944 for (final File f : dnInputFile.getValues()) 1945 { 1946 DNFileReader reader = null; 1947 try 1948 { 1949 reader = new DNFileReader(f); 1950 while (true) 1951 { 1952 if (cancelRequested()) 1953 { 1954 return ResultCode.USER_CANCELED; 1955 } 1956 1957 final DN dn; 1958 try 1959 { 1960 dn = reader.readDN(); 1961 } 1962 catch (final LDAPException le) 1963 { 1964 Debug.debugException(le); 1965 processor.handleMessage(le.getMessage(), true); 1966 continue; 1967 } 1968 1969 if (dn == null) 1970 { 1971 break; 1972 } 1973 1974 processor.process(dn.toString()); 1975 } 1976 } 1977 catch (final Exception e) 1978 { 1979 Debug.debugException(e); 1980 processor.handleMessage( 1981 ERR_MANAGE_ACCT_ERROR_READING_DN_FILE.get( 1982 f.getAbsolutePath(), StaticUtils.getExceptionMessage(e)), 1983 true); 1984 } 1985 finally 1986 { 1987 if (reader != null) 1988 { 1989 try 1990 { 1991 reader.close(); 1992 } 1993 catch (final Exception e2) 1994 { 1995 Debug.debugException(e2); 1996 } 1997 } 1998 } 1999 } 2000 } 2001 2002 2003 // If any target filters were specified, then process them now. 2004 final FilterArgument targetFilter = 2005 parser.getFilterArgument(ARG_TARGET_FILTER); 2006 if (targetFilter.isPresent()) 2007 { 2008 searchProcessor = 2009 new ManageAccountSearchProcessor(this, processor, pool); 2010 for (final Filter f : targetFilter.getValues()) 2011 { 2012 searchProcessor.processFilter(f); 2013 } 2014 } 2015 2016 2017 // If any filter input files were specified, then process them now. 2018 final FileArgument filterInputFile = 2019 parser.getFileArgument(ARG_FILTER_INPUT_FILE); 2020 if (filterInputFile.isPresent()) 2021 { 2022 if (searchProcessor == null) 2023 { 2024 searchProcessor = 2025 new ManageAccountSearchProcessor(this, processor, pool); 2026 } 2027 2028 for (final File f : filterInputFile.getValues()) 2029 { 2030 FilterFileReader reader = null; 2031 try 2032 { 2033 reader = new FilterFileReader(f); 2034 while (true) 2035 { 2036 if (cancelRequested()) 2037 { 2038 return ResultCode.USER_CANCELED; 2039 } 2040 2041 final Filter filter; 2042 try 2043 { 2044 filter = reader.readFilter(); 2045 } 2046 catch (final LDAPException le) 2047 { 2048 Debug.debugException(le); 2049 processor.handleMessage(le.getMessage(), true); 2050 continue; 2051 } 2052 2053 if (filter == null) 2054 { 2055 break; 2056 } 2057 2058 searchProcessor.processFilter(filter); 2059 } 2060 } 2061 catch (final Exception e) 2062 { 2063 Debug.debugException(e); 2064 processor.handleMessage( 2065 ERR_MANAGE_ACCT_ERROR_READING_FILTER_FILE.get( 2066 f.getAbsolutePath(), StaticUtils.getExceptionMessage(e)), 2067 true); 2068 } 2069 finally 2070 { 2071 if (reader != null) 2072 { 2073 try 2074 { 2075 reader.close(); 2076 } 2077 catch (final Exception e2) 2078 { 2079 Debug.debugException(e2); 2080 } 2081 } 2082 } 2083 } 2084 } 2085 2086 2087 // If any target user IDs were specified, then process them now. 2088 final StringArgument targetUserID = 2089 parser.getStringArgument(ARG_TARGET_USER_ID); 2090 if (targetUserID.isPresent()) 2091 { 2092 if (searchProcessor == null) 2093 { 2094 searchProcessor = 2095 new ManageAccountSearchProcessor(this, processor, pool); 2096 } 2097 2098 for (final String userID : targetUserID.getValues()) 2099 { 2100 searchProcessor.processUserID(userID); 2101 } 2102 } 2103 2104 2105 // If any user ID input files were specified, then process them now. 2106 final FileArgument userIDInputFile = 2107 parser.getFileArgument(ARG_USER_ID_INPUT_FILE); 2108 if (userIDInputFile.isPresent()) 2109 { 2110 if (searchProcessor == null) 2111 { 2112 searchProcessor = 2113 new ManageAccountSearchProcessor(this, processor, pool); 2114 } 2115 2116 for (final File f : userIDInputFile.getValues()) 2117 { 2118 BufferedReader reader = null; 2119 try 2120 { 2121 reader = new BufferedReader(new FileReader(f)); 2122 while (true) 2123 { 2124 if (cancelRequested()) 2125 { 2126 return ResultCode.USER_CANCELED; 2127 } 2128 2129 final String line = reader.readLine(); 2130 if (line == null) 2131 { 2132 break; 2133 } 2134 2135 if ((line.length() == 0) || line.startsWith("#")) 2136 { 2137 continue; 2138 } 2139 2140 searchProcessor.processUserID(line.trim()); 2141 } 2142 } 2143 catch (final Exception e) 2144 { 2145 Debug.debugException(e); 2146 processor.handleMessage( 2147 ERR_MANAGE_ACCT_ERROR_READING_USER_ID_FILE.get( 2148 f.getAbsolutePath(), StaticUtils.getExceptionMessage(e)), 2149 true); 2150 } 2151 finally 2152 { 2153 if (reader != null) 2154 { 2155 try 2156 { 2157 reader.close(); 2158 } 2159 catch (final Exception e2) 2160 { 2161 Debug.debugException(e2); 2162 } 2163 } 2164 } 2165 } 2166 } 2167 2168 2169 allFiltersProvided.set(true); 2170 if (searchProcessor != null) 2171 { 2172 searchProcessor.waitForCompletion(); 2173 } 2174 2175 allDNsProvided.set(true); 2176 processor.waitForCompletion(); 2177 } 2178 finally 2179 { 2180 pool.close(); 2181 2182 if (rejectWriter != null) 2183 { 2184 try 2185 { 2186 rejectWriter.close(); 2187 } 2188 catch (final Exception e) 2189 { 2190 Debug.debugException(e); 2191 } 2192 } 2193 } 2194 2195 2196 // If we've gotten here, then we can consider the command successful, even 2197 // if some of the operations failed. 2198 return ResultCode.SUCCESS; 2199 } 2200 2201 2202 2203 /** 2204 * Retrieves the argument parser for this tool. 2205 * 2206 * @return The argument parser for this tool. 2207 */ 2208 ArgumentParser getArgumentParser() 2209 { 2210 return parser; 2211 } 2212 2213 2214 2215 /** 2216 * Indicates whether the tool should cancel its processing. 2217 * 2218 * @return {@code true} if the tool should cancel its processing, or 2219 * {@code false} if not. 2220 */ 2221 boolean cancelRequested() 2222 { 2223 return cancelRequested.get(); 2224 } 2225 2226 2227 2228 /** 2229 * Indicates whether the manage-account processor has been provided with all 2230 * of the DNs of all of the entries to process. 2231 * 2232 * @return {@code true} if the manage-account processor has been provided 2233 * with all of the DNs of all of the entries to process, or 2234 * {@code false} if not. 2235 */ 2236 boolean allDNsProvided() 2237 { 2238 return allDNsProvided.get(); 2239 } 2240 2241 2242 2243 /** 2244 * Indicates whether the manage-account search processor has been provided 2245 * with all of the filters to use to identify entries to process. 2246 * 2247 * @return {@code true} if the manage-account search processor has been 2248 * provided with all of the filters to use to identify entries to 2249 * process, or {@code false} if not. 2250 */ 2251 boolean allFiltersProvided() 2252 { 2253 return allFiltersProvided.get(); 2254 } 2255 2256 2257 2258 /** 2259 * {@inheritDoc} 2260 */ 2261 @Override() 2262 protected boolean registerShutdownHook() 2263 { 2264 return true; 2265 } 2266 2267 2268 2269 /** 2270 * {@inheritDoc} 2271 */ 2272 @Override() 2273 protected void doShutdownHookProcessing(final ResultCode resultCode) 2274 { 2275 cancelRequested.set(true); 2276 2277 if (rateLimiter != null) 2278 { 2279 rateLimiter.shutdownRequested(); 2280 } 2281 2282 if (searchProcessor != null) 2283 { 2284 searchProcessor.cancelSearches(); 2285 } 2286 } 2287 2288 2289 2290 /** 2291 * Performs any processing that may be necessary in response to the provided 2292 * unsolicited notification that has been received from the server. 2293 * 2294 * @param connection The connection on which the unsolicited notification 2295 * was received. 2296 * @param notification The unsolicited notification that has been received 2297 * from the server. 2298 */ 2299 @Override() 2300 public void handleUnsolicitedNotification(final LDAPConnection connection, 2301 final ExtendedResult notification) 2302 { 2303 final String message = NOTE_MANAGE_ACCT_UNSOLICITED_NOTIFICATION.get( 2304 String.valueOf(connection), String.valueOf(notification)); 2305 if (outputWriter == null) 2306 { 2307 err(); 2308 err("* " + message); 2309 err(); 2310 } 2311 else 2312 { 2313 try 2314 { 2315 outputWriter.writeComment(message, true, true); 2316 outputWriter.flush(); 2317 } 2318 catch (final Exception e) 2319 { 2320 // We can't really do anything about this. 2321 Debug.debugException(e); 2322 } 2323 } 2324 } 2325 2326 2327 2328 /** 2329 * {@inheritDoc} 2330 */ 2331 @Override() 2332 public LinkedHashMap<String[],String> getExampleUsages() 2333 { 2334 final LinkedHashMap<String[],String> examples = new LinkedHashMap<>(4); 2335 2336 createSubCommandExample(examples, 2337 ManageAccountSubCommandType.GET_ALL, 2338 INFO_MANAGE_ACCT_SC_GET_ALL_EXAMPLE.get(EXAMPLE_TARGET_USER_DN)); 2339 2340 createSubCommandExample(examples, 2341 ManageAccountSubCommandType.GET_ACCOUNT_USABILITY_ERRORS, 2342 INFO_MANAGE_ACCT_SC_GET_USABILITY_ERRORS_EXAMPLE.get( 2343 EXAMPLE_TARGET_USER_DN)); 2344 2345 createSubCommandExample(examples, 2346 ManageAccountSubCommandType.SET_ACCOUNT_IS_DISABLED, 2347 INFO_MANAGE_ACCT_SC_SET_IS_DISABLED_EXAMPLE.get( 2348 EXAMPLE_TARGET_USER_DN), 2349 "--accountIsDisabled", "true"); 2350 2351 createSubCommandExample(examples, 2352 ManageAccountSubCommandType.CLEAR_AUTHENTICATION_FAILURE_TIMES, 2353 INFO_MANAGE_ACCT_SC_CLEAR_AUTH_FAILURE_TIMES_EXAMPLE.get( 2354 EXAMPLE_TARGET_USER_DN)); 2355 2356 return examples; 2357 } 2358}