if (userIdentity == null)
{
// This request must be targeted at changing the password for the
// currently-authenticated user. Make sure that the user actually is
// authenticated.
ClientConnection clientConnection = operation.getClientConnection();
AuthenticationInfo authInfo = clientConnection.getAuthenticationInfo();
if ((! authInfo.isAuthenticated()) || (requestorEntry == null))
{
operation.setResultCode(ResultCode.UNWILLING_TO_PERFORM);
operation.appendErrorMessage(
ERR_EXTOP_PASSMOD_NO_AUTH_OR_USERID.get());
return;
}
// Retrieve a write lock on that user's entry.
userDN = requestorEntry.getDN();
for (int i=0; i < 3; i++)
{
userLock = LockManager.lockWrite(userDN);
if (userLock != null)
{
break;
}
}
if (userLock == null)
{
operation.setResultCode(DirectoryServer.getServerErrorResultCode());
Message message =
ERR_EXTOP_PASSMOD_CANNOT_LOCK_USER_ENTRY.get(
String.valueOf(userDN));
operation.appendErrorMessage(message);
return;
}
userEntry = requestorEntry;
}
else
{
// There was a userIdentity field in the request.
String authzIDStr = userIdentity.toString();
String lowerAuthzIDStr = toLowerCase(authzIDStr);
if (lowerAuthzIDStr.startsWith("dn:"))
{
try
{
userDN = DN.decode(authzIDStr.substring(3));
}
catch (DirectoryException de)
{
if (debugEnabled())
{
TRACER.debugCaught(DebugLogLevel.ERROR, de);
}
operation.setResultCode(ResultCode.INVALID_DN_SYNTAX);
operation.appendErrorMessage(
ERR_EXTOP_PASSMOD_CANNOT_DECODE_AUTHZ_DN.get(authzIDStr));
return;
}
// If the provided DN is an alternate DN for a root user, then replace
// it with the actual root DN.
DN actualRootDN = DirectoryServer.getActualRootBindDN(userDN);
if (actualRootDN != null)
{
userDN = actualRootDN;
}
userEntry = getEntryByDN(operation, userDN);
if (userEntry == null)
{
return;
}
}
else if (lowerAuthzIDStr.startsWith("u:"))
{
try
{
userEntry = identityMapper.getEntryForID(authzIDStr.substring(2));
if (userEntry == null)
{
operation.setResultCode(ResultCode.NO_SUCH_OBJECT);
operation.appendErrorMessage(
ERR_EXTOP_PASSMOD_CANNOT_MAP_USER.get(authzIDStr));
return;
}
else
{
userDN = userEntry.getDN();
}
}
catch (DirectoryException de)
{
if (debugEnabled())
{
TRACER.debugCaught(DebugLogLevel.ERROR, de);
}
//Encountered an exception while resolving identity.
operation.setResultCode(de.getResultCode());
operation.appendErrorMessage(ERR_EXTOP_PASSMOD_ERROR_MAPPING_USER
.get(authzIDStr,de.getMessageObject()));
return;
}
}
// the userIdentity provided does not follow Authorization Identity
// form. RFC3062 declaration "may or may not be an LDAPDN" allows
// for pretty much anything in that field. we gonna try to parse it
// as DN first then if that fails as user ID.
else
{
try
{
userDN = DN.decode(authzIDStr);
}
catch (DirectoryException de)
{
if (debugEnabled())
{
TRACER.debugCaught(DebugLogLevel.ERROR, de);
}
// IGNORE.
}
if ((userDN != null) && (!userDN.isNullDN())) {
// If the provided DN is an alternate DN for a root user,
// then replace it with the actual root DN.
DN actualRootDN = DirectoryServer.getActualRootBindDN(userDN);
if (actualRootDN != null) {
userDN = actualRootDN;
}
userEntry = getEntryByDN(operation, userDN);
} else {
try
{
userEntry = identityMapper.getEntryForID(authzIDStr);
}
catch (DirectoryException de)
{
if (debugEnabled())
{
TRACER.debugCaught(DebugLogLevel.ERROR, de);
}
// IGNORE.
}
}
if (userEntry == null) {
// The userIdentity was invalid.
operation.setResultCode(ResultCode.PROTOCOL_ERROR);
operation.appendErrorMessage(
ERR_EXTOP_PASSMOD_INVALID_AUTHZID_STRING.get(authzIDStr));
return;
}
else
{
userDN = userEntry.getDN();
}
}
}
// At this point, we should have the user entry. Get the associated
// password policy.
PasswordPolicyState pwPolicyState;
try
{
pwPolicyState = new PasswordPolicyState(userEntry, false);
}
catch (DirectoryException de)
{
if (debugEnabled())
{
TRACER.debugCaught(DebugLogLevel.ERROR, de);
}
operation.setResultCode(DirectoryServer.getServerErrorResultCode());
operation.appendErrorMessage(
ERR_EXTOP_PASSMOD_CANNOT_GET_PW_POLICY.get(
String.valueOf(userDN),
de.getMessageObject()));
return;
}
// Determine whether the user is changing his own password or if it's an
// administrative reset. If it's an administrative reset, then the
// requester must have the PASSWORD_RESET privilege.
boolean selfChange;
if (userIdentity == null)
{
selfChange = true;
}
else if (requestorEntry == null)
{
selfChange = (oldPassword != null);
}
else
{
selfChange = userDN.equals(requestorEntry.getDN());
}
if (! selfChange)
{
ClientConnection clientConnection = operation.getClientConnection();
if (! clientConnection.hasPrivilege(Privilege.PASSWORD_RESET,
operation))
{
operation.appendErrorMessage(
ERR_EXTOP_PASSMOD_INSUFFICIENT_PRIVILEGES.get());
operation.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);