001/* 002 * Copyright 2019 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 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.extensions; 022 023 024 025import java.util.ArrayList; 026import java.util.List; 027 028import com.unboundid.asn1.ASN1Element; 029import com.unboundid.asn1.ASN1Integer; 030import com.unboundid.asn1.ASN1Null; 031import com.unboundid.asn1.ASN1OctetString; 032import com.unboundid.asn1.ASN1Sequence; 033import com.unboundid.ldap.sdk.Control; 034import com.unboundid.ldap.sdk.ExtendedRequest; 035import com.unboundid.ldap.sdk.LDAPConnection; 036import com.unboundid.ldap.sdk.LDAPException; 037import com.unboundid.ldap.sdk.ResultCode; 038import com.unboundid.util.Debug; 039import com.unboundid.util.NotMutable; 040import com.unboundid.util.StaticUtils; 041import com.unboundid.util.ThreadSafety; 042import com.unboundid.util.ThreadSafetyLevel; 043import com.unboundid.util.Validator; 044 045import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*; 046 047 048 049/** 050 * This class provides an implementation of an extended request that may be used 051 * to request that the server suggest one or more passwords that the client may 052 * use in new entries, password changes, or administrative password resets. 053 * <BR> 054 * <BLOCKQUOTE> 055 * <B>NOTE:</B> This class, and other classes within the 056 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 057 * supported for use against Ping Identity, UnboundID, and 058 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 059 * for proprietary functionality or for external specifications that are not 060 * considered stable or mature enough to be guaranteed to work in an 061 * interoperable way with other types of LDAP servers. 062 * </BLOCKQUOTE> 063 * <BR> 064 * This extended request has an OID of "1.3.6.1.4.1.30221.2.6.62" and a value\ 065 * with the following encoding: 066 * <BR><BR> 067 * <PRE> 068 * GeneratePasswordRequest ::= SEQUENCE { 069 * passwordPolicySelection CHOICE { 070 * defaultPolicy [0] NULL, 071 * passwordPolicyDN [1] LDAPDN, 072 * targetEntryDN [2] LDAPDN, 073 * ... }, 074 * numberOfPasswords [3] INTEGER DEFAULT 1, 075 * validationAttempts [4] INTEGER DEFAULT 5, 076 * ... } 077 * </PRE> 078 * <BR><BR> 079 * The "passwordPolicySelection" element allows the client to indicate which 080 * password policy (along with its associated password generator and password 081 * validators) should be used in the course of generating the passwords, and 082 * available options include: 083 * <UL> 084 * <LI>defaultPolicy -- Indicates that the server should use the default 085 * password policy as defined in the configuration.</LI> 086 * <LI>passwordPolicyDN -- Specifies the DN of the password policy that should 087 * be used.</LI> 088 * <LI>targetEntryDN -- Specifies the DN of the target entry for which the 089 * passwords are to be generated. If this entry exists, then the password 090 * policy that governs it will be used. If the entry does not exist, then 091 * the server will generate a stub of an entry with the provided DN and 092 * compute virtual attributes for that entry to account for the 093 * possibility that a password policy may be assigned by a virtual 094 * attribute, but will fall back to using the default password policy as 095 * defined in the configuration. 096 * </UL> 097 * <BR><BR> 098 * The "numberOfPasswords" element indicates the number of passwords that the 099 * server should generate, since it may be beneficial for the server to suggest 100 * multiple passwords and allow the user to choose one. If specified, then the 101 * value must be greater than or equal to one. 102 * <BR><BR> 103 * The "validationAttempts" element indicates the number of attempts that the 104 * server should make to generate each password in a way that will satisfy the 105 * set of validators associated with the selected password policy. A value of 106 * zero indicates that no validation should be performed. A value of one will 107 * cause the server to invoke password validators on each generated password, 108 * still returning that password but also including information about potential 109 * reasons that generated password may not pass validation. A value that is 110 * greater than one will cause the server to re-generate each password up to 111 * the specified number of times if the previous attempt resulted in a password 112 * that did not satisfy all of the associated password validators. In the event 113 * that no acceptable password could be generated after exhausting all attempts, 114 * the server will select the last one generated, but will provide a list of 115 * reasons that the password was not considered acceptable so that they may be 116 * provided to the end user as additional guidance when choosing a password. 117 * <BR><BR> 118 * If the generate password operation is processed successfully, then the server 119 * will return a {@link GeneratePasswordExtendedResult} response with the 120 * passwords that it generated and other relevant information. 121 */ 122@NotMutable() 123@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 124public final class GeneratePasswordExtendedRequest 125 extends ExtendedRequest 126{ 127 /** 128 * The OID (1.3.6.1.4.1.30221.2.6.62) for the generate password extended 129 * request. 130 */ 131 public static final String GENERATE_PASSWORD_REQUEST_OID = 132 "1.3.6.1.4.1.30221.2.6.62"; 133 134 135 136 /** 137 * The BER type to use for the element that specifies the number of passwords 138 * to generate. 139 */ 140 private static final byte TYPE_NUMBER_OF_PASSWORDS = (byte) 0x83; 141 142 143 144 /** 145 * The default value for the number of passwords to generate. 146 */ 147 private static final int DEFAULT_NUMBER_OF_PASSWORDS = 1; 148 149 150 151 /** 152 * The BER type to use for the element that specifies the number of validation 153 * attempts to perform. 154 */ 155 private static final byte TYPE_VALIDATION_ATTEMPTS = (byte) 0x84; 156 157 158 159 /** 160 * The default number of validation attempts to perform. 161 */ 162 private static final int DEFAULT_VALIDATION_ATTEMPTS = 5; 163 164 165 166 /** 167 * The serial version UID for this serializable class. 168 */ 169 private static final long serialVersionUID = -4264500486902843854L; 170 171 172 173 // The number of passwords that should be generated. 174 private final int numberOfPasswords; 175 176 // The number of validation attempts to make for each generated password. 177 private final int numberOfValidationAttempts; 178 179 // The password policy selection type for the request. 180 private final GeneratePasswordPolicySelectionType passwordPolicySelectionType; 181 182 // The DN of the password policy that should be used in conjunction with the 183 // PASSWORD_POLICY_DN password policy selection type. 184 private final String passwordPolicyDN; 185 186 // The DN of the target entry that should be used in conjunction with the 187 // TARGET_ENTRY_DN password policy selection type. 188 private final String targetEntryDN; 189 190 191 192 /** 193 * Creates a new generate password extended request with all the default 194 * settings. 195 * 196 * @param controls The set of controls to include in the request. It may be 197 * {@code null} or empty if there should not be any request 198 * controls. 199 */ 200 public GeneratePasswordExtendedRequest(final Control... controls) 201 { 202 this(GeneratePasswordPolicySelectionType.DEFAULT_POLICY, null, null, 203 DEFAULT_NUMBER_OF_PASSWORDS, DEFAULT_VALIDATION_ATTEMPTS, controls); 204 } 205 206 207 208 /** 209 * Creates a new generate password extended request with the provided 210 * settings. 211 * 212 * @param passwordPolicySelectionType 213 * The password policy selection type to use. It must not be 214 * {@code null}. 215 * @param passwordPolicyDN 216 * The password policy DN to use in conjunction with the 217 * {@link GeneratePasswordPolicySelectionType#PASSWORD_POLICY_DN} 218 * password policy selection type. It must be non-{@code null} 219 * when used in conjunction with that policy selection type, and 220 * it must be {@code null} for all other selection types. 221 * @param targetEntryDN 222 * The target entry DN to use in conjunction with the 223 * {@link GeneratePasswordPolicySelectionType#TARGET_ENTRY_DN} 224 * password policy selection type. It must be non-{@code null} 225 * when used in conjunction with that policy selection type, and 226 * it must be {@code null} for all other selection types. 227 * @param numberOfPasswords 228 * The number of passwords to generate. The value must be 229 * greater than or equal to one. 230 * @param numberOfValidationAttempts 231 * The number of attempts that should be made to generate each 232 * password in an attempt to obtain a password that satisfies the 233 * associated set of password validators. The value must be 234 * greater than or equal to zero. 235 * @param controls 236 * The set of controls to include in the request. It may be 237 * {@code null} or empty if there should not be any request 238 * controls. 239 */ 240 private GeneratePasswordExtendedRequest( 241 final GeneratePasswordPolicySelectionType passwordPolicySelectionType, 242 final String passwordPolicyDN, final String targetEntryDN, 243 final int numberOfPasswords, final int numberOfValidationAttempts, 244 final Control... controls) 245 { 246 super(GENERATE_PASSWORD_REQUEST_OID, 247 encodeValue(passwordPolicySelectionType, passwordPolicyDN, 248 targetEntryDN, numberOfPasswords, numberOfValidationAttempts), 249 controls); 250 251 this.passwordPolicySelectionType = passwordPolicySelectionType; 252 this.passwordPolicyDN = passwordPolicyDN; 253 this.targetEntryDN = targetEntryDN; 254 this.numberOfPasswords = numberOfPasswords; 255 this.numberOfValidationAttempts = numberOfValidationAttempts; 256 } 257 258 259 260 /** 261 * Uses the provided information to generate an ASN.1 octet string that may be 262 * used as the value of a generate password extended request. 263 * 264 * @param passwordPolicySelectionType 265 * The password policy selection type to use. It must not be 266 * {@code null}. 267 * @param passwordPolicyDN 268 * The password policy DN to use in conjunction with the 269 * {@link GeneratePasswordPolicySelectionType#PASSWORD_POLICY_DN} 270 * password policy selection type. It must be non-{@code null} 271 * when used in conjunction with that policy selection type, and 272 * it must be {@code null} for all other selection types. 273 * @param targetEntryDN 274 * The target entry DN to use in conjunction with the 275 * {@link GeneratePasswordPolicySelectionType#TARGET_ENTRY_DN} 276 * password policy selection type. It must be non-{@code null} 277 * when used in conjunction with that policy selection type, and 278 * it must be {@code null} for all other selection types. 279 * @param numberOfPasswords 280 * The number of passwords to generate. The value must be 281 * greater than or equal to one. 282 * @param numberOfValidationAttempts 283 * The number of attempts that should be made to generate each 284 * password in an attempt to obtain a password that satisfies the 285 * associated set of password validators. The value must be 286 * greater than or equal to zero. 287 * 288 * @return An ASN.1 octet string that may be used as the value of a generate 289 * password extended request with the provided information, or 290 * {@code null} if the request uses all the default settings and no 291 * value is needed. 292 */ 293 private static ASN1OctetString encodeValue( 294 final GeneratePasswordPolicySelectionType passwordPolicySelectionType, 295 final String passwordPolicyDN, final String targetEntryDN, 296 final int numberOfPasswords, final int numberOfValidationAttempts) 297 { 298 Validator.ensureNotNullWithMessage(passwordPolicySelectionType, 299 "GeneratePasswordExtendedRequest.passwordPolicySelectionType must " + 300 "not be null."); 301 302 final List<ASN1Element> elements = new ArrayList<>(3); 303 switch (passwordPolicySelectionType) 304 { 305 case DEFAULT_POLICY: 306 Validator.ensureTrue((passwordPolicyDN == null), 307 "GeneratePasswordExtendedRequest.passwordPolicyDN must be null " + 308 "when using a password policy selection type of " + 309 passwordPolicySelectionType + '.'); 310 Validator.ensureTrue((targetEntryDN == null), 311 "GeneratePasswordExtendedRequest.targetEntryDN must be null " + 312 "when using a password policy selection type of " + 313 passwordPolicySelectionType + '.'); 314 315 if ((numberOfPasswords == DEFAULT_NUMBER_OF_PASSWORDS) && 316 (numberOfValidationAttempts == DEFAULT_VALIDATION_ATTEMPTS)) 317 { 318 return null; 319 } 320 321 elements.add(new ASN1Null(passwordPolicySelectionType.getBERType())); 322 break; 323 324 case PASSWORD_POLICY_DN: 325 Validator.ensureNotNullWithMessage(passwordPolicyDN, 326 "GeneratePasswordExtendedRequest.passwordPolicyDN must not be " + 327 "null when using a password policy selection type of " + 328 passwordPolicySelectionType + '.'); 329 Validator.ensureTrue((targetEntryDN == null), 330 "GeneratePasswordExtendedRequest.targetEntryDN must be null " + 331 "when using a password policy selection type of " + 332 passwordPolicySelectionType + '.'); 333 334 elements.add(new ASN1OctetString( 335 passwordPolicySelectionType.getBERType(), passwordPolicyDN)); 336 break; 337 338 case TARGET_ENTRY_DN: 339 Validator.ensureTrue((passwordPolicyDN == null), 340 "GeneratePasswordExtendedRequest.passwordPolicyDN must be null " + 341 "when using a password policy selection type of " + 342 passwordPolicySelectionType + '.'); 343 Validator.ensureNotNullWithMessage(targetEntryDN, 344 "GeneratePasswordExtendedRequest.targetEntryDN must not be null " + 345 "when using a password policy selection type of " + 346 passwordPolicySelectionType + '.'); 347 348 elements.add(new ASN1OctetString( 349 passwordPolicySelectionType.getBERType(), targetEntryDN)); 350 break; 351 } 352 353 if (numberOfPasswords != DEFAULT_NUMBER_OF_PASSWORDS) 354 { 355 Validator.ensureTrue((numberOfPasswords >= 1), 356 "GeneratePasswordExtendedRequest.numberOfPasswords must be " + 357 "greater than or equal to one."); 358 elements.add(new ASN1Integer(TYPE_NUMBER_OF_PASSWORDS, 359 numberOfPasswords)); 360 } 361 362 if (numberOfValidationAttempts != DEFAULT_VALIDATION_ATTEMPTS) 363 { 364 Validator.ensureTrue((numberOfValidationAttempts >= 0), 365 "GeneratePasswordExtendedRequest.validationAttempts must be " + 366 "greater than or equal to zero."); 367 elements.add(new ASN1Integer(TYPE_VALIDATION_ATTEMPTS, 368 numberOfValidationAttempts)); 369 } 370 371 return new ASN1OctetString(new ASN1Sequence(elements).encode()); 372 } 373 374 375 376 /** 377 * Creates a new generate password extended request that is decoded from the 378 * provided generic request. 379 * 380 * @param request The extended request to be decoded as a generate password 381 * extended request. It must not be {@code null}. 382 * 383 * @throws LDAPException If the provided extended request cannot be decoded 384 * as a generate password request. 385 */ 386 public GeneratePasswordExtendedRequest(final ExtendedRequest request) 387 throws LDAPException 388 { 389 super(request); 390 391 final ASN1OctetString value = request.getValue(); 392 if (value == null) 393 { 394 passwordPolicySelectionType = 395 GeneratePasswordPolicySelectionType.DEFAULT_POLICY; 396 passwordPolicyDN = null; 397 targetEntryDN = null; 398 numberOfPasswords = DEFAULT_NUMBER_OF_PASSWORDS; 399 numberOfValidationAttempts = DEFAULT_VALIDATION_ATTEMPTS; 400 return; 401 } 402 403 try 404 { 405 final ASN1Element[] elements = 406 ASN1Sequence.decodeAsSequence(value.getValue()).elements(); 407 408 passwordPolicySelectionType = 409 GeneratePasswordPolicySelectionType.forType(elements[0].getType()); 410 if (passwordPolicySelectionType == null) 411 { 412 throw new LDAPException(ResultCode.DECODING_ERROR, 413 ERR_GENERATE_PASSWORD_REQUEST_UNSUPPORTED_SELECTION_TYPE.get( 414 StaticUtils.toHex(elements[0].getType()))); 415 } 416 417 switch (passwordPolicySelectionType) 418 { 419 case PASSWORD_POLICY_DN: 420 passwordPolicyDN = elements[0].decodeAsOctetString().stringValue(); 421 targetEntryDN = null; 422 break; 423 424 case TARGET_ENTRY_DN: 425 targetEntryDN = elements[0].decodeAsOctetString().stringValue(); 426 passwordPolicyDN = null; 427 break; 428 429 case DEFAULT_POLICY: 430 default: 431 passwordPolicyDN = null; 432 targetEntryDN = null; 433 break; 434 } 435 436 int numPasswords = DEFAULT_NUMBER_OF_PASSWORDS; 437 int numAttempts = DEFAULT_VALIDATION_ATTEMPTS; 438 for (int i=1; i < elements.length; i++) 439 { 440 switch (elements[i].getType()) 441 { 442 case TYPE_NUMBER_OF_PASSWORDS: 443 numPasswords = ASN1Integer.decodeAsInteger(elements[i]).intValue(); 444 if (numPasswords < 1) 445 { 446 throw new LDAPException(ResultCode.DECODING_ERROR, 447 ERR_GENERATE_PASSWORD_REQUEST_INVALID_NUM_PASSWORDS.get( 448 numPasswords)); 449 } 450 break; 451 452 case TYPE_VALIDATION_ATTEMPTS: 453 numAttempts = ASN1Integer.decodeAsInteger(elements[i]).intValue(); 454 if (numAttempts < 0) 455 { 456 throw new LDAPException(ResultCode.DECODING_ERROR, 457 ERR_GENERATE_PASSWORD_REQUEST_INVALID_NUM_ATTEMPTS.get( 458 numAttempts)); 459 } 460 break; 461 } 462 } 463 464 numberOfPasswords = numPasswords; 465 numberOfValidationAttempts = numAttempts; 466 } 467 catch (final LDAPException e) 468 { 469 Debug.debugException(e); 470 throw e; 471 } 472 catch (final Exception e) 473 { 474 Debug.debugException(e); 475 throw new LDAPException(ResultCode.DECODING_ERROR, 476 ERR_GENERATE_PASSWORD_REQUEST_DECODING_ERROR.get( 477 StaticUtils.getExceptionMessage(e)), 478 e); 479 } 480 } 481 482 483 484 /** 485 * Creates a generate password extended request that will use the default 486 * password policy (as defined in the server configuration) to determine which 487 * password generator and validators should be used. 488 * 489 * @param numberOfPasswords 490 * The number of passwords to generate. The value must be 491 * greater than or equal to one. 492 * @param numberOfValidationAttempts 493 * The number of attempts that should be made to generate each 494 * password in an attempt to obtain a password that satisfies the 495 * associated set of password validators. The value must be 496 * greater than or equal to zero. 497 * @param controls 498 * The set of controls to include in the request. It may be 499 * {@code null} or empty if there should not be any request 500 * controls. 501 * 502 * @return The generate password extended request that was created. 503 */ 504 public static GeneratePasswordExtendedRequest createDefaultPolicyRequest( 505 final int numberOfPasswords, 506 final int numberOfValidationAttempts, 507 final Control... controls) 508 { 509 return new GeneratePasswordExtendedRequest( 510 GeneratePasswordPolicySelectionType.DEFAULT_POLICY, null, null, 511 numberOfPasswords, numberOfValidationAttempts, controls); 512 } 513 514 515 516 /** 517 * Creates a generate password extended request that will use the password 518 * policy defined in the entry with the specified DN to determine which 519 * password generator and validators should be used. 520 * 521 * @param passwordPolicyDN 522 * The DN of the entry that defines the password policy to use to 523 * determine which password generator and validators should be 524 * used. It must not be {@code null}. 525 * @param numberOfPasswords 526 * The number of passwords to generate. The value must be 527 * greater than or equal to one. 528 * @param numberOfValidationAttempts 529 * The number of attempts that should be made to generate each 530 * password in an attempt to obtain a password that satisfies the 531 * associated set of password validators. The value must be 532 * greater than or equal to zero. 533 * @param controls 534 * The set of controls to include in the request. It may be 535 * {@code null} or empty if there should not be any request 536 * controls. 537 * 538 * @return The generate password extended request that was created. 539 */ 540 public static GeneratePasswordExtendedRequest createPasswordPolicyDNRequest( 541 final String passwordPolicyDN, final int numberOfPasswords, 542 final int numberOfValidationAttempts, 543 final Control... controls) 544 { 545 return new GeneratePasswordExtendedRequest( 546 GeneratePasswordPolicySelectionType.PASSWORD_POLICY_DN, 547 passwordPolicyDN, null, numberOfPasswords, numberOfValidationAttempts, 548 controls); 549 } 550 551 552 553 /** 554 * Creates a generate password extended request that will use the password 555 * policy that governs the specified entry to determine which 556 * password generator and validators should be used. If the target entry does 557 * not exist, then the server will generate a stub of an entry and compute 558 * virtual attributes for that entry to account for the possibility that the 559 * password policy may be specified using a virtual attribute. 560 * 561 * @param targetEntryDN 562 * The DN of the entry whose governing password policy should be 563 * used. It must not be {@code null}. 564 * @param numberOfPasswords 565 * The number of passwords to generate. The value must be 566 * greater than or equal to one. 567 * @param numberOfValidationAttempts 568 * The number of attempts that should be made to generate each 569 * password in an attempt to obtain a password that satisfies the 570 * associated set of password validators. The value must be 571 * greater than or equal to zero. 572 * @param controls 573 * The set of controls to include in the request. It may be 574 * {@code null} or empty if there should not be any request 575 * controls. 576 * 577 * @return The generate password extended request that was created. 578 */ 579 public static GeneratePasswordExtendedRequest createTargetEntryDNRequest( 580 final String targetEntryDN, final int numberOfPasswords, 581 final int numberOfValidationAttempts, 582 final Control... controls) 583 { 584 return new GeneratePasswordExtendedRequest( 585 GeneratePasswordPolicySelectionType.TARGET_ENTRY_DN, null, 586 targetEntryDN, numberOfPasswords, numberOfValidationAttempts, 587 controls); 588 } 589 590 591 592 /** 593 * Retrieves the password policy selection type for this request. 594 * 595 * @return The password policy selection type for this request. 596 */ 597 public GeneratePasswordPolicySelectionType getPasswordPolicySelectionType() 598 { 599 return passwordPolicySelectionType; 600 } 601 602 603 604 /** 605 * Retrieves the DN of the entry that defines the password policy that should 606 * be used when generating and validating passwords. This will only be 607 * available for the 608 * {@link GeneratePasswordPolicySelectionType#PASSWORD_POLICY_DN} password 609 * policy selection type. 610 * 611 * @return The DN of the entry that defines the password policy that should 612 * be used when generating and validating the passwords, or 613 * {@code null} if the password policy selection type is anything 614 * other than {@code PASSWORD_POLICY_DN}. 615 */ 616 public String getPasswordPolicyDN() 617 { 618 return passwordPolicyDN; 619 } 620 621 622 623 /** 624 * Retrieves the DN of the target entry whose governing password policy should 625 * be used when generating and validating passwords. This will only be 626 * available for the 627 * {@link GeneratePasswordPolicySelectionType#TARGET_ENTRY_DN} password 628 * policy selection type. 629 * 630 * @return The DN of the target entry whose governing password policy should 631 * be used when generating and validating the passwords, or 632 * {@code null} if the password policy selection type is anything 633 * other than {@code TARGET_ENTRY_DN}. 634 */ 635 public String getTargetEntryDN() 636 { 637 return targetEntryDN; 638 } 639 640 641 642 /** 643 * Retrieves the number of passwords that the client wants the server to 644 * generate. Note that the server may choose to generate fewer passwords than 645 * this, based on its configuration. 646 * 647 * @return The number of passwords that the client wants the server to 648 * generate. 649 */ 650 public int getNumberOfPasswords() 651 { 652 return numberOfPasswords; 653 } 654 655 656 657 /** 658 * Retrieves the number of maximum number of attempts that the client wants 659 * the server to make when generating each password in the hope that the 660 * generated password will satisfy the validation criteria specified in the 661 * associated password policy. Note that the server may choose to make fewer 662 * validation attempts than this, based on its configuration. 663 * 664 * @return The number maximum number of validation attempts that the client 665 * wants the server to make, or zero if the server should not attempt 666 * to validate the generated passwords. 667 */ 668 public int getNumberOfValidationAttempts() 669 { 670 return numberOfValidationAttempts; 671 } 672 673 674 675 /** 676 * {@inheritDoc} 677 */ 678 @Override() 679 protected GeneratePasswordExtendedResult process( 680 final LDAPConnection connection, final int depth) 681 throws LDAPException 682 { 683 return new GeneratePasswordExtendedResult(super.process(connection, depth)); 684 } 685 686 687 688 /** 689 * {@inheritDoc} 690 */ 691 @Override() 692 public GeneratePasswordExtendedRequest duplicate() 693 { 694 return duplicate(getControls()); 695 } 696 697 698 699 /** 700 * {@inheritDoc} 701 */ 702 @Override() 703 public GeneratePasswordExtendedRequest duplicate(final Control[] controls) 704 { 705 final GeneratePasswordExtendedRequest r = 706 new GeneratePasswordExtendedRequest(passwordPolicySelectionType, 707 passwordPolicyDN, targetEntryDN, numberOfPasswords, 708 numberOfValidationAttempts, controls); 709 r.setResponseTimeoutMillis(getResponseTimeoutMillis(null)); 710 return r; 711 } 712 713 714 715 /** 716 * {@inheritDoc} 717 */ 718 @Override() 719 public String getExtendedRequestName() 720 { 721 return INFO_GENERATE_PASSWORD_REQUEST_NAME.get(); 722 } 723 724 725 726 /** 727 * {@inheritDoc} 728 */ 729 @Override() 730 public void toString(final StringBuilder buffer) 731 { 732 buffer.append("GeneratePasswordExtendedRequest(" + 733 "passwordPolicySelectionType='"); 734 buffer.append(passwordPolicySelectionType.name()); 735 buffer.append('\''); 736 737 switch (passwordPolicySelectionType) 738 { 739 case PASSWORD_POLICY_DN: 740 buffer.append(", passwordPolicyDN='"); 741 buffer.append(passwordPolicyDN); 742 buffer.append('\''); 743 break; 744 case TARGET_ENTRY_DN: 745 buffer.append(", targetEntryDN='"); 746 buffer.append(targetEntryDN); 747 buffer.append('\''); 748 break; 749 } 750 751 buffer.append(", numberOfPasswords="); 752 buffer.append(numberOfPasswords); 753 buffer.append(", numberOfValidationAttempts="); 754 buffer.append(numberOfValidationAttempts); 755 756 final Control[] controls = getControls(); 757 if (controls.length > 0) 758 { 759 buffer.append(", controls={"); 760 for (int i=0; i < controls.length; i++) 761 { 762 if (i > 0) 763 { 764 buffer.append(", "); 765 } 766 767 buffer.append(controls[i]); 768 } 769 buffer.append('}'); 770 } 771 772 buffer.append(')'); 773 } 774}