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