use of com.unboundid.ldap.sdk.extensions.PasswordModifyExtendedResult in project ldapsdk by pingidentity.
the class MultiUpdateExtendedResultTestCase method testSuccessWithResults.
/**
* Tests the behavior when creating a success result that contains multiple
* operation results.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testSuccessWithResults() throws Exception {
final Control[] opControls = { new Control("1.2.3.4"), new Control("1.2.3.5", true) };
final ArrayList<ObjectPair<OperationType, LDAPResult>> results = new ArrayList<ObjectPair<OperationType, LDAPResult>>(5);
results.add(new ObjectPair<OperationType, LDAPResult>(OperationType.ADD, new LDAPResult(-1, ResultCode.ADMIN_LIMIT_EXCEEDED, null, null, null, opControls)));
results.add(new ObjectPair<OperationType, LDAPResult>(OperationType.DELETE, new LDAPResult(-1, ResultCode.ASSERTION_FAILED)));
results.add(new ObjectPair<OperationType, LDAPResult>(OperationType.EXTENDED, new PasswordModifyExtendedResult(-1, ResultCode.INVALID_CREDENTIALS, null, null, null, null, null)));
results.add(new ObjectPair<OperationType, LDAPResult>(OperationType.MODIFY, new LDAPResult(-1, ResultCode.ATTRIBUTE_OR_VALUE_EXISTS)));
results.add(new ObjectPair<OperationType, LDAPResult>(OperationType.MODIFY_DN, new LDAPResult(-1, ResultCode.UNWILLING_TO_PERFORM)));
final Control[] controls = { new Control("1.2.3.6"), new Control("1.2.3.7", true) };
MultiUpdateExtendedResult r = new MultiUpdateExtendedResult(1, ResultCode.SUCCESS, null, null, null, MultiUpdateChangesApplied.PARTIAL, results, controls);
r = new MultiUpdateExtendedResult(r);
assertNotNull(r.getResultCode());
assertEquals(r.getResultCode(), ResultCode.SUCCESS);
assertNull(r.getDiagnosticMessage());
assertNull(r.getMatchedDN());
assertNotNull(r.getReferralURLs());
assertEquals(r.getReferralURLs().length, 0);
assertNotNull(r.getChangesApplied());
assertEquals(r.getChangesApplied(), MultiUpdateChangesApplied.PARTIAL);
assertNotNull(r.getResults());
assertEquals(r.getResults().size(), 5);
assertEquals(r.getResults().get(0).getFirst(), OperationType.ADD);
assertEquals(r.getResults().get(0).getSecond().getResultCode(), ResultCode.ADMIN_LIMIT_EXCEEDED);
assertEquals(r.getResults().get(1).getFirst(), OperationType.DELETE);
assertEquals(r.getResults().get(1).getSecond().getResultCode(), ResultCode.ASSERTION_FAILED);
assertEquals(r.getResults().get(2).getFirst(), OperationType.EXTENDED);
assertTrue(r.getResults().get(2).getSecond() instanceof ExtendedResult);
assertEquals(r.getResults().get(2).getSecond().getResultCode(), ResultCode.INVALID_CREDENTIALS);
assertEquals(r.getResults().get(3).getFirst(), OperationType.MODIFY);
assertEquals(r.getResults().get(3).getSecond().getResultCode(), ResultCode.ATTRIBUTE_OR_VALUE_EXISTS);
assertEquals(r.getResults().get(4).getFirst(), OperationType.MODIFY_DN);
assertEquals(r.getResults().get(4).getSecond().getResultCode(), ResultCode.UNWILLING_TO_PERFORM);
assertNotNull(r.getResponseControls());
assertEquals(r.getResponseControls().length, 2);
assertNotNull(r.getExtendedResultName());
assertNotNull(r.toString());
}
use of com.unboundid.ldap.sdk.extensions.PasswordModifyExtendedResult in project ldapsdk by pingidentity.
the class PasswordModifyExtendedOperationHandler method processExtendedOperation.
/**
* {@inheritDoc}
*/
@Override()
@NotNull()
public ExtendedResult processExtendedOperation(@NotNull final InMemoryRequestHandler handler, final int messageID, @NotNull final ExtendedRequest request) {
// This extended operation handler supports the no operation control. If
// any other control is present, then reject it if it's critical.
boolean noOperation = false;
for (final Control c : request.getControls()) {
if (c.getOID().equalsIgnoreCase(NoOpRequestControl.NO_OP_REQUEST_OID)) {
noOperation = true;
} else if (c.isCritical()) {
return new ExtendedResult(messageID, ResultCode.UNAVAILABLE_CRITICAL_EXTENSION, ERR_PW_MOD_EXTOP_UNSUPPORTED_CONTROL.get(c.getOID()), null, null, null, null, null);
}
}
// Decode the request.
final PasswordModifyExtendedRequest pwModRequest;
try {
pwModRequest = new PasswordModifyExtendedRequest(request);
} catch (final LDAPException le) {
Debug.debugException(le);
return new ExtendedResult(messageID, le.getResultCode(), le.getDiagnosticMessage(), le.getMatchedDN(), le.getReferralURLs(), null, null, null);
}
// Get the elements of the request.
final String userIdentity = pwModRequest.getUserIdentity();
final byte[] oldPWBytes = pwModRequest.getOldPasswordBytes();
final byte[] newPWBytes = pwModRequest.getNewPasswordBytes();
// Determine the DN of the target user.
final DN targetDN;
if (userIdentity == null) {
targetDN = handler.getAuthenticatedDN();
} else {
// The user identity should generally be a DN, but we'll also allow an
// authorization ID.
final String lowerUserIdentity = StaticUtils.toLowerCase(userIdentity);
if (lowerUserIdentity.startsWith("dn:") || lowerUserIdentity.startsWith("u:")) {
try {
targetDN = handler.getDNForAuthzID(userIdentity);
} catch (final LDAPException le) {
Debug.debugException(le);
return new PasswordModifyExtendedResult(messageID, le.getResultCode(), le.getMessage(), le.getMatchedDN(), le.getReferralURLs(), null, le.getResponseControls());
}
} else {
try {
targetDN = new DN(userIdentity);
} catch (final LDAPException le) {
Debug.debugException(le);
return new PasswordModifyExtendedResult(messageID, ResultCode.INVALID_DN_SYNTAX, ERR_PW_MOD_EXTOP_CANNOT_PARSE_USER_IDENTITY.get(userIdentity), null, null, null, null);
}
}
}
if ((targetDN == null) || targetDN.isNullDN()) {
return new PasswordModifyExtendedResult(messageID, ResultCode.UNWILLING_TO_PERFORM, ERR_PW_MOD_NO_IDENTITY.get(), null, null, null, null);
}
final Entry userEntry = handler.getEntry(targetDN);
if (userEntry == null) {
return new PasswordModifyExtendedResult(messageID, ResultCode.UNWILLING_TO_PERFORM, ERR_PW_MOD_EXTOP_CANNOT_GET_USER_ENTRY.get(targetDN.toString()), null, null, null, null);
}
// Make sure that the server is configured with at least one password
// attribute.
final List<String> passwordAttributes = handler.getPasswordAttributes();
if (passwordAttributes.isEmpty()) {
return new PasswordModifyExtendedResult(messageID, ResultCode.UNWILLING_TO_PERFORM, ERR_PW_MOD_EXTOP_NO_PW_ATTRS.get(), null, null, null, null);
}
// determine whether it is acceptable for no password to have been given.
if (oldPWBytes == null) {
if (handler.getAuthenticatedDN().isNullDN()) {
return new PasswordModifyExtendedResult(messageID, ResultCode.UNWILLING_TO_PERFORM, ERR_PW_MOD_EXTOP_NO_AUTHENTICATION.get(), null, null, null, null);
}
} else {
final List<InMemoryDirectoryServerPassword> passwordList = handler.getPasswordsInEntry(userEntry, pwModRequest.getRawOldPassword());
if (passwordList.isEmpty()) {
return new PasswordModifyExtendedResult(messageID, ResultCode.INVALID_CREDENTIALS, null, null, null, null, null);
}
}
// If no new password was provided, then generate a random password to use.
final byte[] pwBytes;
final ASN1OctetString genPW;
if (newPWBytes == null) {
final SecureRandom random = ThreadLocalSecureRandom.get();
final byte[] pwAlphabet = StaticUtils.getBytes("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
pwBytes = new byte[8];
for (int i = 0; i < pwBytes.length; i++) {
pwBytes[i] = pwAlphabet[random.nextInt(pwAlphabet.length)];
}
genPW = new ASN1OctetString(pwBytes);
} else {
genPW = null;
pwBytes = newPWBytes;
}
// Construct the set of modifications to apply to the user entry. Iterate
// through the passwords
final List<InMemoryDirectoryServerPassword> existingPasswords = handler.getPasswordsInEntry(userEntry, null);
final ArrayList<Modification> mods = new ArrayList<>(existingPasswords.size() + 1);
if (existingPasswords.isEmpty()) {
mods.add(new Modification(ModificationType.REPLACE, passwordAttributes.get(0), pwBytes));
} else {
final HashSet<String> usedPWAttrs = new HashSet<>(StaticUtils.computeMapCapacity(existingPasswords.size()));
for (final InMemoryDirectoryServerPassword p : existingPasswords) {
final String attr = StaticUtils.toLowerCase(p.getAttributeName());
if (usedPWAttrs.isEmpty()) {
usedPWAttrs.add(attr);
mods.add(new Modification(ModificationType.REPLACE, p.getAttributeName(), pwBytes));
} else if (!usedPWAttrs.contains(attr)) {
usedPWAttrs.add(attr);
mods.add(new Modification(ModificationType.REPLACE, p.getAttributeName()));
}
}
}
// appropriate result now.
if (noOperation) {
return new PasswordModifyExtendedResult(messageID, ResultCode.NO_OPERATION, INFO_PW_MOD_EXTOP_NO_OP.get(), null, null, genPW, null);
}
// Attempt to modify the user password.
try {
handler.modifyEntry(userEntry.getDN(), mods);
return new PasswordModifyExtendedResult(messageID, ResultCode.SUCCESS, null, null, null, genPW, null);
} catch (final LDAPException le) {
Debug.debugException(le);
return new PasswordModifyExtendedResult(messageID, le.getResultCode(), ERR_PW_MOD_EXTOP_CANNOT_CHANGE_PW.get(userEntry.getDN(), le.getMessage()), le.getMatchedDN(), le.getReferralURLs(), null, null);
}
}
use of com.unboundid.ldap.sdk.extensions.PasswordModifyExtendedResult in project ldapsdk by pingidentity.
the class LDAPPasswordModify method followPasswordModifyReferral.
/**
* Attempts to follow a referral that was returned in response to a password
* modify extended request.
*
* @param request The extended request that was sent.
* @param result The extended result that was received,
* including the referral details.
* @param receivedOnConnection The LDAP connection on which the referral
* result was received.
* @param referralCount The number of referrals that have been
* returned so far. If this is too high, then
* subsequent referrals will not be followed.
*
* @return A result code that indicates whether the password update was
* successful.
*/
@NotNull()
private ResultCode followPasswordModifyReferral(@NotNull final PasswordModifyExtendedRequest request, @NotNull final PasswordModifyExtendedResult result, @NotNull final LDAPConnection receivedOnConnection, final int referralCount) {
final List<LDAPURL> referralURLs = new ArrayList<>();
for (final String urlString : result.getReferralURLs()) {
try {
referralURLs.add(new LDAPURL(urlString));
} catch (final LDAPException e) {
Debug.debugException(e);
}
}
if (referralURLs.isEmpty()) {
logCompletionMessage(true, ERR_PWMOD_EXTOP_NO_VALID_REFERRAL_URLS.get(String.valueOf(result)));
return ResultCode.REFERRAL;
}
LDAPException firstException = null;
for (final LDAPURL url : referralURLs) {
try (LDAPConnection referralConnection = receivedOnConnection.getReferralConnection(url, receivedOnConnection)) {
final String referredUserIdentity;
if (url.getBaseDN().isNullDN()) {
referredUserIdentity = request.getUserIdentity();
} else {
referredUserIdentity = url.getBaseDN().toString();
}
final PasswordModifyExtendedRequest referralRequest = new PasswordModifyExtendedRequest(referredUserIdentity, request.getOldPassword(), request.getNewPassword(), request.getControls());
final PasswordModifyExtendedResult referralResult = (PasswordModifyExtendedResult) referralConnection.processExtendedOperation(referralRequest);
out();
out(INFO_PWMOD_EXTOP_RESULT_HEADER.get());
for (final String line : ResultUtils.formatResult(referralResult, true, 0, WRAP_COLUMN)) {
out(line);
}
out();
final String generatedPassword = referralResult.getGeneratedPassword();
if (referralResult.getResultCode() == ResultCode.SUCCESS) {
logCompletionMessage(false, INFO_PWMOD_EXTOP_SUCCESSFUL.get());
if (generatedPassword != null) {
out();
wrapOut(0, WRAP_COLUMN, INFO_PWMOD_SERVER_GENERATED_PW.get(generatedPassword));
}
return ResultCode.SUCCESS;
} else if (referralResult.getResultCode() == ResultCode.NO_OPERATION) {
logCompletionMessage(false, INFO_PWMOD_EXTOP_NO_OP.get());
if (generatedPassword != null) {
out();
wrapOut(0, WRAP_COLUMN, INFO_PWMOD_SERVER_GENERATED_PW.get(generatedPassword));
}
return ResultCode.SUCCESS;
} else if (referralResult.getResultCode() == ResultCode.REFERRAL) {
final int maxReferralCount = receivedOnConnection.getConnectionOptions().getReferralHopLimit();
if (referralCount > maxReferralCount) {
logCompletionMessage(true, ERR_PWMOD_TOO_MANY_REFERRALS.get());
return ResultCode.REFERRAL_LIMIT_EXCEEDED;
} else {
return followPasswordModifyReferral(referralRequest, referralResult, referralConnection, (referralCount + 1));
}
} else {
if (firstException == null) {
firstException = new LDAPExtendedOperationException(referralResult);
}
}
} catch (final LDAPException e) {
Debug.debugException(e);
if (firstException == null) {
firstException = e;
}
}
}
logCompletionMessage(true, ERR_PWMOD_FOLLOW_REFERRAL_FAILED.get(String.valueOf(firstException.getResultCode()), firstException.getDiagnosticMessage()));
return firstException.getResultCode();
}
use of com.unboundid.ldap.sdk.extensions.PasswordModifyExtendedResult in project ldapsdk by pingidentity.
the class InMemoryDirectoryServerPasswordModifyTestCase method testControls.
/**
* Tests the behavior of the extended operation with request controls.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testControls() throws Exception {
final InMemoryDirectoryServer ds = getTestDS(true, true);
final LDAPConnection conn = ds.getConnection();
conn.bind("uid=test.user,ou=People,dc=example,dc=com", "password");
// Verify that the attempt to change the password will fail with a
// critical control.
Control[] controls = { new Control("1.2.3.4", true) };
PasswordModifyExtendedResult result = (PasswordModifyExtendedResult) conn.processExtendedOperation(new PasswordModifyExtendedRequest(null, null, "newPassword", controls));
assertEquals(result.getResultCode(), ResultCode.UNAVAILABLE_CRITICAL_EXTENSION);
// Verify that the attempt will succeed with only non-critical controls.
controls = new Control[] { new Control("1.2.3.4", false) };
result = (PasswordModifyExtendedResult) conn.processExtendedOperation(new PasswordModifyExtendedRequest(null, null, "newPassword", controls));
assertEquals(result.getResultCode(), ResultCode.SUCCESS);
conn.close();
}
use of com.unboundid.ldap.sdk.extensions.PasswordModifyExtendedResult in project ldapsdk by pingidentity.
the class InMemoryDirectoryServerPasswordModifyTestCase method testAuthenticatedAsAdditionalBindUser.
/**
* Provides test coverage for the password modify operation when requested
* by a client authenticated as an additional bind user.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testAuthenticatedAsAdditionalBindUser() throws Exception {
final InMemoryDirectoryServer ds = getTestDS(true, true);
ds.add("dn: uid=another.user,ou=People,dc=example,dc=com", "objectClass: top", "objectClass: person", "objectClass: organizationalPerson", "objectClass: inetOrgPerson", "uid: another.user", "givenName: Another", "sn: User", "cn: Another User", "userPassword: password");
final LDAPConnection conn = ds.getConnection();
conn.bind("cn=Directory Manager", "password");
// Verify that the attempt will fail for the authenticated user when
// supplied only with a new password.
PasswordModifyExtendedResult result = (PasswordModifyExtendedResult) conn.processExtendedOperation(new PasswordModifyExtendedRequest("newPassword1"));
assertEquals(result.getResultCode(), ResultCode.UNWILLING_TO_PERFORM);
assertNull(result.getGeneratedPassword());
// Verify that the attempt will fail for the authenticated user when
// supplied with both old and new passwords and the old password is wrong.
result = (PasswordModifyExtendedResult) conn.processExtendedOperation(new PasswordModifyExtendedRequest("wrongPassword", "newPassword2"));
assertEquals(result.getResultCode(), ResultCode.UNWILLING_TO_PERFORM);
assertNull(result.getGeneratedPassword());
// Verify that the attempt will fail for the authenticated user when
// supplied with both old and new passwords and the old password is correct.
result = (PasswordModifyExtendedResult) conn.processExtendedOperation(new PasswordModifyExtendedRequest("password", "newPassword2"));
assertEquals(result.getResultCode(), ResultCode.UNWILLING_TO_PERFORM);
assertNull(result.getGeneratedPassword());
// Verify that the attempt to change the password will succeed for a
// different regular user when the identity is provided as a DN.
result = (PasswordModifyExtendedResult) conn.processExtendedOperation(new PasswordModifyExtendedRequest("uid=another.user,ou=People,dc=example,dc=com", null, "newPassword1"));
assertEquals(result.getResultCode(), ResultCode.SUCCESS);
assertNull(result.getGeneratedPassword());
// Verify that the attempt to change the password will succeed for a
// different regular user when the identity is provided as an authzID.
result = (PasswordModifyExtendedResult) conn.processExtendedOperation(new PasswordModifyExtendedRequest("u:another.user", null, "newPassword2"));
assertEquals(result.getResultCode(), ResultCode.SUCCESS);
assertNull(result.getGeneratedPassword());
// Verify that the attempt to change the password will fail for a target
// user that does not exist.
result = (PasswordModifyExtendedResult) conn.processExtendedOperation(new PasswordModifyExtendedRequest("cn=missing,dc=example,dc=com", null, "newPassword4"));
assertEquals(result.getResultCode(), ResultCode.UNWILLING_TO_PERFORM);
assertNull(result.getGeneratedPassword());
conn.close();
}
Aggregations