use of com.unboundid.ldap.protocol.LDAPMessage in project ldapsdk by pingidentity.
the class UNBOUNDIDTESTServer method run.
/**
* Performs the processing for this server.
*/
@Override()
public void run() {
try {
serverSocket = new ServerSocket(0);
listenPort = serverSocket.getLocalPort();
while (!stopRequested.get()) {
// Accept a connection from a client.
clientSocket = serverSocket.accept();
final InputStream inputStream = clientSocket.getInputStream();
final OutputStream outputStream = clientSocket.getOutputStream();
final ASN1StreamReader asn1Reader = new ASN1StreamReader(inputStream, 0);
// The client must first send an UNBOUNDID-TEST bind request with no
// credentials.
LDAPMessage requestMessage = LDAPMessage.readFrom(asn1Reader, false);
BindRequestProtocolOp bindRequestOp = requestMessage.getBindRequestProtocolOp();
assertEquals(bindRequestOp.getSASLMechanism(), "UNBOUNDID-TEST");
assertNull(bindRequestOp.getSASLCredentials());
// Return a "SASL bind in progress" response.
LDAPMessage responseMessage = new LDAPMessage(requestMessage.getMessageID(), new BindResponseProtocolOp(ResultCode.SASL_BIND_IN_PROGRESS_INT_VALUE, null, null, null, null));
outputStream.write(responseMessage.encode().encode());
outputStream.flush();
// The next request must be an UNBOUNDID-TEST bind request with
// credentials. We won't do anything to validate the credentials, but
// we will look at the third element to see what QoP the client
// requested.
requestMessage = LDAPMessage.readFrom(asn1Reader, false);
bindRequestOp = requestMessage.getBindRequestProtocolOp();
assertEquals(bindRequestOp.getSASLMechanism(), "UNBOUNDID-TEST");
assertNotNull(bindRequestOp.getSASLCredentials());
final ASN1Sequence credSequence = ASN1Sequence.decodeAsSequence(bindRequestOp.getSASLCredentials().getValue());
final ASN1Element[] credElements = credSequence.elements();
final SASLQualityOfProtection qop = SASLQualityOfProtection.forName(ASN1OctetString.decodeAsOctetString(credElements[2]).stringValue());
assertNotNull(qop);
final boolean qopEncode = ((qop == SASLQualityOfProtection.AUTH_INT) || (qop == SASLQualityOfProtection.AUTH_CONF));
// Return a "success" response. Include server SASL credentials with
// the requested QoP.
responseMessage = new LDAPMessage(requestMessage.getMessageID(), new BindResponseProtocolOp(ResultCode.SUCCESS_INT_VALUE, null, null, null, new ASN1OctetString(qop.toString())));
outputStream.write(responseMessage.encode().encode());
outputStream.flush();
// request.
if (qopEncode) {
for (int i = 0; i < 4; i++) {
inputStream.read();
}
}
requestMessage = LDAPMessage.readFrom(asn1Reader, false);
final SearchRequestProtocolOp searchRequestOp = requestMessage.getSearchRequestProtocolOp();
assertEquals(searchRequestOp.getBaseDN(), "");
assertEquals(searchRequestOp.getScope(), SearchScope.BASE);
assertEquals(searchRequestOp.getFilter(), Filter.createPresenceFilter("objectClass"));
assertEquals(searchRequestOp.getAttributes(), Arrays.asList("1.1"));
// Return a search result entry message with a DN but no attributes.
responseMessage = new LDAPMessage(requestMessage.getMessageID(), new SearchResultEntryProtocolOp("", Collections.<Attribute>emptyList()));
byte[] messageBytes = responseMessage.encode().encode();
if (qopEncode) {
// Since we know it's a tiny response, we know the length will be
// less than 127 bytes, so we can cheat.
outputStream.write(0);
outputStream.write(0);
outputStream.write(0);
outputStream.write(messageBytes.length);
}
outputStream.write(messageBytes);
outputStream.flush();
// Return a "success" search result done message.
responseMessage = new LDAPMessage(requestMessage.getMessageID(), new SearchResultDoneProtocolOp(ResultCode.SUCCESS_INT_VALUE, null, null, null));
messageBytes = responseMessage.encode().encode();
if (qopEncode) {
// Since we know it's a tiny response, we know the length will be
// less than 127 bytes, so we can cheat.
outputStream.write(0);
outputStream.write(0);
outputStream.write(0);
outputStream.write(messageBytes.length);
}
outputStream.write(messageBytes);
outputStream.flush();
// The next request should be an unbind request.
if (qopEncode) {
for (int i = 0; i < 4; i++) {
inputStream.read();
}
}
requestMessage = LDAPMessage.readFrom(asn1Reader, false);
final UnbindRequestProtocolOp unbindRequestOp = requestMessage.getUnbindRequestProtocolOp();
// Close the connection.
try {
asn1Reader.close();
} catch (final Exception e) {
}
try {
outputStream.close();
} catch (final Exception e) {
}
try {
clientSocket.close();
} catch (final Exception e) {
}
clientSocket = null;
}
} catch (final Exception e) {
stopServer();
}
}
use of com.unboundid.ldap.protocol.LDAPMessage in project ldapsdk by pingidentity.
the class InMemoryRequestHandler method processModifyDNRequest.
/**
* Attempts to process the provided modify DN request. The attempt will fail
* if any of the following conditions is true:
* <UL>
* <LI>There is a problem with any of the request controls.</LI>
* <LI>The modify DN request contains a malformed target DN, new RDN, or
* new superior DN.</LI>
* <LI>The original or new DN is that of the root DSE.</LI>
* <LI>The original or new DN is that of the subschema subentry.</LI>
* <LI>The new DN of the entry would conflict with the DN of an existing
* entry.</LI>
* <LI>The new DN of the entry would exist outside the set of defined
* base DNs.</LI>
* <LI>The new DN of the entry is not a defined base DN and does not exist
* immediately below an existing entry.</LI>
* </UL>
*
* @param messageID The message ID of the LDAP message containing the modify
* DN request.
* @param request The modify DN request that was included in the LDAP
* message that was received.
* @param controls The set of controls included in the LDAP message. It
* may be empty if there were no controls, but will not be
* {@code null}.
*
* @return The {@link LDAPMessage} containing the response to send to the
* client. The protocol op in the {@code LDAPMessage} must be an
* {@code ModifyDNResponseProtocolOp}.
*/
@Override()
@NotNull()
public LDAPMessage processModifyDNRequest(final int messageID, @NotNull final ModifyDNRequestProtocolOp request, @NotNull final List<Control> controls) {
synchronized (entryMap) {
// Sleep before processing, if appropriate.
sleepBeforeProcessing();
// Process the provided request controls.
final Map<String, Control> controlMap;
try {
controlMap = RequestControlPreProcessor.processControls(LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_DN_REQUEST, controls);
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(le.getResultCode().intValue(), null, le.getMessage(), null));
}
final ArrayList<Control> responseControls = new ArrayList<>(1);
// If this operation type is not allowed, then reject it.
final boolean isInternalOp = controlMap.containsKey(OID_INTERNAL_OPERATION_REQUEST_CONTROL);
if ((!isInternalOp) && (!config.getAllowedOperationTypes().contains(OperationType.MODIFY_DN))) {
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, null, ERR_MEM_HANDLER_MODIFY_DN_NOT_ALLOWED.get(), null));
}
// client is authenticated.
if ((authenticatedDN.isNullDN() && config.getAuthenticationRequiredOperationTypes().contains(OperationType.MODIFY_DN))) {
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.INSUFFICIENT_ACCESS_RIGHTS_INT_VALUE, null, ERR_MEM_HANDLER_MODIFY_DN_REQUIRES_AUTH.get(), null));
}
// without actually doing any further processing.
try {
final ASN1OctetString txnID = processTransactionRequest(messageID, request, controlMap);
if (txnID != null) {
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.SUCCESS_INT_VALUE, null, INFO_MEM_HANDLER_OP_IN_TXN.get(txnID.stringValue()), null));
}
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(le.getResultCode().intValue(), le.getMatchedDN(), le.getDiagnosticMessage(), StaticUtils.toList(le.getReferralURLs())), le.getResponseControls());
}
// Get the parsed target DN, new RDN, and new superior DN values.
final DN dn;
final Schema schema = schemaRef.get();
try {
dn = new DN(request.getDN(), schema);
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.INVALID_DN_SYNTAX_INT_VALUE, null, ERR_MEM_HANDLER_MOD_DN_MALFORMED_DN.get(request.getDN(), le.getMessage()), null));
}
final RDN newRDN;
try {
newRDN = new RDN(request.getNewRDN(), schema);
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.INVALID_DN_SYNTAX_INT_VALUE, null, ERR_MEM_HANDLER_MOD_DN_MALFORMED_NEW_RDN.get(request.getDN(), request.getNewRDN(), le.getMessage()), null));
}
final DN newSuperiorDN;
final String newSuperiorString = request.getNewSuperiorDN();
if (newSuperiorString == null) {
newSuperiorDN = null;
} else {
try {
newSuperiorDN = new DN(newSuperiorString, schema);
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.INVALID_DN_SYNTAX_INT_VALUE, null, ERR_MEM_HANDLER_MOD_DN_MALFORMED_NEW_SUPERIOR.get(request.getDN(), request.getNewSuperiorDN(), le.getMessage()), null));
}
}
// See if the target entry or one of its superiors is a smart referral.
if (!controlMap.containsKey(ManageDsaITRequestControl.MANAGE_DSA_IT_REQUEST_OID)) {
final Entry referralEntry = findNearestReferral(dn);
if (referralEntry != null) {
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.REFERRAL_INT_VALUE, referralEntry.getDN(), INFO_MEM_HANDLER_REFERRAL_ENCOUNTERED.get(), getReferralURLs(dn, referralEntry)));
}
}
// changelog entry.
if (dn.isNullDN()) {
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, null, ERR_MEM_HANDLER_MOD_DN_ROOT_DSE.get(), null));
} else if (dn.equals(subschemaSubentryDN)) {
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, null, ERR_MEM_HANDLER_MOD_DN_SOURCE_IS_SCHEMA.get(), null));
} else if (dn.isDescendantOf(changeLogBaseDN, true)) {
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, null, ERR_MEM_HANDLER_MOD_DN_SOURCE_IS_CHANGELOG.get(), null));
}
// Construct the new DN.
final DN newDN;
if (newSuperiorDN == null) {
final DN originalParent = dn.getParent();
if (originalParent == null) {
newDN = new DN(newRDN);
} else {
newDN = new DN(newRDN, originalParent);
}
} else {
newDN = new DN(newRDN, newSuperiorDN);
}
// If the new DN matches the old DN, then fail.
if (newDN.equals(dn)) {
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, null, ERR_MEM_HANDLER_MOD_DN_NEW_DN_SAME_AS_OLD.get(request.getDN()), null));
}
// If the new DN is below a smart referral, then fail.
if (!controlMap.containsKey(ManageDsaITRequestControl.MANAGE_DSA_IT_REQUEST_OID)) {
final Entry referralEntry = findNearestReferral(newDN);
if (referralEntry != null) {
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, referralEntry.getDN(), ERR_MEM_HANDLER_MOD_DN_NEW_DN_BELOW_REFERRAL.get(request.getDN(), referralEntry.getDN().toString(), newDN.toString()), null));
}
}
// If the target entry doesn't exist, then fail.
final Entry originalEntry = entryMap.get(dn);
if (originalEntry == null) {
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.NO_SUCH_OBJECT_INT_VALUE, getMatchedDNString(dn), ERR_MEM_HANDLER_MOD_DN_NO_SUCH_ENTRY.get(request.getDN()), null));
}
// If the new DN matches the subschema subentry DN, then fail.
if (newDN.equals(subschemaSubentryDN)) {
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.ENTRY_ALREADY_EXISTS_INT_VALUE, null, ERR_MEM_HANDLER_MOD_DN_TARGET_IS_SCHEMA.get(request.getDN(), newDN.toString()), null));
}
// If the new DN is at or below the changelog base DN, then fail.
if (newDN.isDescendantOf(changeLogBaseDN, true)) {
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, null, ERR_MEM_HANDLER_MOD_DN_TARGET_IS_CHANGELOG.get(request.getDN(), newDN.toString()), null));
}
// If the new DN already exists, then fail.
if (entryMap.containsKey(newDN)) {
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.ENTRY_ALREADY_EXISTS_INT_VALUE, null, ERR_MEM_HANDLER_MOD_DN_TARGET_ALREADY_EXISTS.get(request.getDN(), newDN.toString()), null));
}
// fail.
if (baseDNs.contains(newDN)) {
// The modify DN can be processed.
} else {
final DN newParent = newDN.getParent();
if ((newParent != null) && entryMap.containsKey(newParent)) {
// The modify DN can be processed.
} else {
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.NO_SUCH_OBJECT_INT_VALUE, getMatchedDNString(newDN), ERR_MEM_HANDLER_MOD_DN_PARENT_DOESNT_EXIST.get(request.getDN(), newDN.toString()), null));
}
}
// Create a copy of the entry and update it to reflect the new DN (with
// attribute value changes).
final RDN originalRDN = dn.getRDN();
final Entry updatedEntry = originalEntry.duplicate();
updatedEntry.setDN(newDN);
if (request.deleteOldRDN()) {
final String[] oldRDNNames = originalRDN.getAttributeNames();
final byte[][] oldRDNValues = originalRDN.getByteArrayAttributeValues();
for (int i = 0; i < oldRDNNames.length; i++) {
updatedEntry.removeAttributeValue(oldRDNNames[i], oldRDNValues[i]);
}
}
final String[] newRDNNames = newRDN.getAttributeNames();
final byte[][] newRDNValues = newRDN.getByteArrayAttributeValues();
for (int i = 0; i < newRDNNames.length; i++) {
final MatchingRule matchingRule = MatchingRule.selectEqualityMatchingRule(newRDNNames[i], schema);
updatedEntry.addAttribute(new Attribute(newRDNNames[i], matchingRule, newRDNValues[i]));
}
// If a schema was provided, then make sure the updated entry conforms to
// the schema. Also, reject the attempt if any of the new RDN attributes
// is marked with NO-USER-MODIFICATION.
final EntryValidator entryValidator = entryValidatorRef.get();
if (entryValidator != null) {
final ArrayList<String> invalidReasons = new ArrayList<>(1);
if (!entryValidator.entryIsValid(updatedEntry, invalidReasons)) {
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.OBJECT_CLASS_VIOLATION_INT_VALUE, null, ERR_MEM_HANDLER_MOD_DN_VIOLATES_SCHEMA.get(request.getDN(), StaticUtils.concatenateStrings(invalidReasons)), null));
}
final String[] oldRDNNames = originalRDN.getAttributeNames();
for (int i = 0; i < oldRDNNames.length; i++) {
final String name = oldRDNNames[i];
final AttributeTypeDefinition at = schema.getAttributeType(name);
if ((!isInternalOp) && (at != null) && at.isNoUserModification()) {
final byte[] value = originalRDN.getByteArrayAttributeValues()[i];
if (!updatedEntry.hasAttributeValue(name, value)) {
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.CONSTRAINT_VIOLATION_INT_VALUE, null, ERR_MEM_HANDLER_MOD_DN_NO_USER_MOD.get(request.getDN(), name), null));
}
}
}
for (int i = 0; i < newRDNNames.length; i++) {
final String name = newRDNNames[i];
final AttributeTypeDefinition at = schema.getAttributeType(name);
if ((!isInternalOp) && (at != null) && at.isNoUserModification()) {
final byte[] value = newRDN.getByteArrayAttributeValues()[i];
if (!originalEntry.hasAttributeValue(name, value)) {
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.CONSTRAINT_VIOLATION_INT_VALUE, null, ERR_MEM_HANDLER_MOD_DN_NO_USER_MOD.get(request.getDN(), name), null));
}
}
}
}
// Perform the appropriate processing for the assertion and proxied
// authorization controls
final DN authzDN;
try {
handleAssertionRequestControl(controlMap, originalEntry);
authzDN = handleProxiedAuthControl(controlMap);
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(le.getResultCode().intValue(), null, le.getMessage(), null));
}
// attributes.
if (generateOperationalAttributes) {
updatedEntry.setAttribute(new Attribute("modifiersName", DistinguishedNameMatchingRule.getInstance(), authzDN.toString()));
updatedEntry.setAttribute(new Attribute("modifyTimestamp", GeneralizedTimeMatchingRule.getInstance(), StaticUtils.encodeGeneralizedTime(new Date())));
updatedEntry.setAttribute(new Attribute("entryDN", DistinguishedNameMatchingRule.getInstance(), newDN.toNormalizedString()));
}
// Perform the appropriate processing for the pre-read and post-read
// controls.
final PreReadResponseControl preReadResponse = handlePreReadControl(controlMap, originalEntry);
if (preReadResponse != null) {
responseControls.add(preReadResponse);
}
final PostReadResponseControl postReadResponse = handlePostReadControl(controlMap, updatedEntry);
if (postReadResponse != null) {
responseControls.add(postReadResponse);
}
// Remove the old entry and add the new one.
entryMap.remove(dn);
entryMap.put(newDN, new ReadOnlyEntry(updatedEntry));
indexDelete(originalEntry);
indexAdd(updatedEntry);
// If the target entry had any subordinates, then rename them as well.
final RDN[] oldDNComps = dn.getRDNs();
final RDN[] newDNComps = newDN.getRDNs();
final Set<DN> dnSet = new LinkedHashSet<>(entryMap.keySet());
for (final DN mapEntryDN : dnSet) {
if (mapEntryDN.isDescendantOf(dn, false)) {
final Entry o = entryMap.remove(mapEntryDN);
final Entry e = o.duplicate();
final RDN[] oldMapEntryComps = mapEntryDN.getRDNs();
final int compsToSave = oldMapEntryComps.length - oldDNComps.length;
final RDN[] newMapEntryComps = new RDN[compsToSave + newDNComps.length];
System.arraycopy(oldMapEntryComps, 0, newMapEntryComps, 0, compsToSave);
System.arraycopy(newDNComps, 0, newMapEntryComps, compsToSave, newDNComps.length);
final DN newMapEntryDN = new DN(newMapEntryComps);
e.setDN(newMapEntryDN);
if (generateOperationalAttributes) {
e.setAttribute(new Attribute("entryDN", DistinguishedNameMatchingRule.getInstance(), newMapEntryDN.toNormalizedString()));
}
entryMap.put(newMapEntryDN, new ReadOnlyEntry(e));
indexDelete(o);
indexAdd(e);
handleReferentialIntegrityModifyDN(mapEntryDN, newMapEntryDN);
}
}
addChangeLogEntry(request, authzDN);
handleReferentialIntegrityModifyDN(dn, newDN);
return new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.SUCCESS_INT_VALUE, null, null, null), responseControls);
}
}
use of com.unboundid.ldap.protocol.LDAPMessage in project ldapsdk by pingidentity.
the class InMemoryRequestHandler method add.
/**
* Processes the provided add request.
* <BR><BR>
* This method may be used regardless of whether the server is listening for
* client connections, and regardless of whether add operations are allowed in
* the server.
*
* @param addRequest The add request to be processed. It must not be
* {@code null}.
*
* @return The result of processing the add operation.
*
* @throws LDAPException If the server rejects the add request, or if a
* problem is encountered while sending the request or
* reading the response.
*/
@NotNull()
public LDAPResult add(@NotNull final AddRequest addRequest) throws LDAPException {
final ArrayList<Control> requestControlList = new ArrayList<>(addRequest.getControlList());
requestControlList.add(new Control(OID_INTERNAL_OPERATION_REQUEST_CONTROL, false));
final LDAPMessage responseMessage = processAddRequest(1, new AddRequestProtocolOp(addRequest.getDN(), addRequest.getAttributes()), requestControlList);
final AddResponseProtocolOp addResponse = responseMessage.getAddResponseProtocolOp();
final LDAPResult ldapResult = new LDAPResult(responseMessage.getMessageID(), ResultCode.valueOf(addResponse.getResultCode()), addResponse.getDiagnosticMessage(), addResponse.getMatchedDN(), addResponse.getReferralURLs(), responseMessage.getControls());
switch(addResponse.getResultCode()) {
case ResultCode.SUCCESS_INT_VALUE:
case ResultCode.NO_OPERATION_INT_VALUE:
return ldapResult;
default:
throw new LDAPException(ldapResult);
}
}
use of com.unboundid.ldap.protocol.LDAPMessage in project ldapsdk by pingidentity.
the class InMemoryRequestHandler method processDeleteRequest.
/**
* Attempts to process the provided delete request. The attempt will fail if
* any of the following conditions is true:
* <UL>
* <LI>There is a problem with any of the request controls.</LI>
* <LI>The delete request contains a malformed target DN.</LI>
* <LI>The target entry is the root DSE.</LI>
* <LI>The target entry is the subschema subentry.</LI>
* <LI>The target entry is at or below the changelog base entry.</LI>
* <LI>The target entry does not exist.</LI>
* <LI>The target entry has one or more subordinate entries.</LI>
* </UL>
*
* @param messageID The message ID of the LDAP message containing the delete
* request.
* @param request The delete request that was included in the LDAP message
* that was received.
* @param controls The set of controls included in the LDAP message. It
* may be empty if there were no controls, but will not be
* {@code null}.
*
* @return The {@link LDAPMessage} containing the response to send to the
* client. The protocol op in the {@code LDAPMessage} must be a
* {@code DeleteResponseProtocolOp}.
*/
@Override()
@NotNull()
public LDAPMessage processDeleteRequest(final int messageID, @NotNull final DeleteRequestProtocolOp request, @NotNull final List<Control> controls) {
synchronized (entryMap) {
// Sleep before processing, if appropriate.
sleepBeforeProcessing();
// Process the provided request controls.
final Map<String, Control> controlMap;
try {
controlMap = RequestControlPreProcessor.processControls(LDAPMessage.PROTOCOL_OP_TYPE_DELETE_REQUEST, controls);
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new DeleteResponseProtocolOp(le.getResultCode().intValue(), null, le.getMessage(), null));
}
final ArrayList<Control> responseControls = new ArrayList<>(1);
// If this operation type is not allowed, then reject it.
final boolean isInternalOp = controlMap.containsKey(OID_INTERNAL_OPERATION_REQUEST_CONTROL);
if ((!isInternalOp) && (!config.getAllowedOperationTypes().contains(OperationType.DELETE))) {
return new LDAPMessage(messageID, new DeleteResponseProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, null, ERR_MEM_HANDLER_DELETE_NOT_ALLOWED.get(), null));
}
// client is authenticated.
if ((authenticatedDN.isNullDN() && config.getAuthenticationRequiredOperationTypes().contains(OperationType.DELETE))) {
return new LDAPMessage(messageID, new DeleteResponseProtocolOp(ResultCode.INSUFFICIENT_ACCESS_RIGHTS_INT_VALUE, null, ERR_MEM_HANDLER_DELETE_REQUIRES_AUTH.get(), null));
}
// without actually doing any further processing.
try {
final ASN1OctetString txnID = processTransactionRequest(messageID, request, controlMap);
if (txnID != null) {
return new LDAPMessage(messageID, new DeleteResponseProtocolOp(ResultCode.SUCCESS_INT_VALUE, null, INFO_MEM_HANDLER_OP_IN_TXN.get(txnID.stringValue()), null));
}
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new DeleteResponseProtocolOp(le.getResultCode().intValue(), le.getMatchedDN(), le.getDiagnosticMessage(), StaticUtils.toList(le.getReferralURLs())), le.getResponseControls());
}
// Get the parsed target DN.
final DN dn;
try {
dn = new DN(request.getDN(), schemaRef.get());
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new DeleteResponseProtocolOp(ResultCode.INVALID_DN_SYNTAX_INT_VALUE, null, ERR_MEM_HANDLER_DELETE_MALFORMED_DN.get(request.getDN(), le.getMessage()), null));
}
// See if the target entry or one of its superiors is a smart referral.
if (!controlMap.containsKey(ManageDsaITRequestControl.MANAGE_DSA_IT_REQUEST_OID)) {
final Entry referralEntry = findNearestReferral(dn);
if (referralEntry != null) {
return new LDAPMessage(messageID, new DeleteResponseProtocolOp(ResultCode.REFERRAL_INT_VALUE, referralEntry.getDN(), INFO_MEM_HANDLER_REFERRAL_ENCOUNTERED.get(), getReferralURLs(dn, referralEntry)));
}
}
// entry.
if (dn.isNullDN()) {
return new LDAPMessage(messageID, new DeleteResponseProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, null, ERR_MEM_HANDLER_DELETE_ROOT_DSE.get(), null));
} else if (dn.equals(subschemaSubentryDN)) {
return new LDAPMessage(messageID, new DeleteResponseProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, null, ERR_MEM_HANDLER_DELETE_SCHEMA.get(subschemaSubentryDN.toString()), null));
} else if (dn.isDescendantOf(changeLogBaseDN, true)) {
return new LDAPMessage(messageID, new DeleteResponseProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, null, ERR_MEM_HANDLER_DELETE_CHANGELOG.get(request.getDN()), null));
}
// Get the target entry. If it does not exist, then fail.
final Entry entry = entryMap.get(dn);
if (entry == null) {
return new LDAPMessage(messageID, new DeleteResponseProtocolOp(ResultCode.NO_SUCH_OBJECT_INT_VALUE, getMatchedDNString(dn), ERR_MEM_HANDLER_DELETE_NO_SUCH_ENTRY.get(request.getDN()), null));
}
// Create a list with the DN of the target entry, and all the DNs of its
// subordinates. If the entry has subordinates and the subtree delete
// control was not provided, then fail.
final ArrayList<DN> subordinateDNs = new ArrayList<>(entryMap.size());
for (final DN mapEntryDN : entryMap.keySet()) {
if (mapEntryDN.isDescendantOf(dn, false)) {
subordinateDNs.add(mapEntryDN);
}
}
if ((!subordinateDNs.isEmpty()) && (!controlMap.containsKey(SubtreeDeleteRequestControl.SUBTREE_DELETE_REQUEST_OID))) {
return new LDAPMessage(messageID, new DeleteResponseProtocolOp(ResultCode.NOT_ALLOWED_ON_NONLEAF_INT_VALUE, null, ERR_MEM_HANDLER_DELETE_HAS_SUBORDINATES.get(request.getDN()), null));
}
// Handle the necessary processing for the assertion, pre-read, and
// proxied auth controls.
final DN authzDN;
try {
handleAssertionRequestControl(controlMap, entry);
final PreReadResponseControl preReadResponse = handlePreReadControl(controlMap, entry);
if (preReadResponse != null) {
responseControls.add(preReadResponse);
}
authzDN = handleProxiedAuthControl(controlMap);
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new DeleteResponseProtocolOp(le.getResultCode().intValue(), null, le.getMessage(), null));
}
// that the changelog will show the deletes in the appropriate order.
for (int i = (subordinateDNs.size() - 1); i >= 0; i--) {
final DN subordinateDN = subordinateDNs.get(i);
final Entry subEntry = entryMap.remove(subordinateDN);
indexDelete(subEntry);
addDeleteChangeLogEntry(subEntry, authzDN);
handleReferentialIntegrityDelete(subordinateDN);
}
// Finally, remove the target entry and create a changelog entry for it.
entryMap.remove(dn);
indexDelete(entry);
addDeleteChangeLogEntry(entry, authzDN);
handleReferentialIntegrityDelete(dn);
return new LDAPMessage(messageID, new DeleteResponseProtocolOp(ResultCode.SUCCESS_INT_VALUE, null, null, null), responseControls);
}
}
use of com.unboundid.ldap.protocol.LDAPMessage in project ldapsdk by pingidentity.
the class InMemoryRequestHandler method processExtendedRequest.
/**
* Attempts to process the provided extended request, if an extended operation
* handler is defined for the given request OID.
*
* @param messageID The message ID of the LDAP message containing the
* extended request.
* @param request The extended request that was included in the LDAP
* message that was received.
* @param controls The set of controls included in the LDAP message. It
* may be empty if there were no controls, but will not be
* {@code null}.
*
* @return The {@link LDAPMessage} containing the response to send to the
* client. The protocol op in the {@code LDAPMessage} must be an
* {@code ExtendedResponseProtocolOp}.
*/
@Override()
@NotNull()
public LDAPMessage processExtendedRequest(final int messageID, @NotNull final ExtendedRequestProtocolOp request, @NotNull final List<Control> controls) {
synchronized (entryMap) {
// Sleep before processing, if appropriate.
sleepBeforeProcessing();
boolean isInternalOp = false;
for (final Control c : controls) {
if (c.getOID().equals(OID_INTERNAL_OPERATION_REQUEST_CONTROL)) {
isInternalOp = true;
break;
}
}
// If this operation type is not allowed, then reject it.
if ((!isInternalOp) && (!config.getAllowedOperationTypes().contains(OperationType.EXTENDED))) {
return new LDAPMessage(messageID, new ExtendedResponseProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, null, ERR_MEM_HANDLER_EXTENDED_NOT_ALLOWED.get(), null, null, null));
}
// client is authenticated.
if ((authenticatedDN.isNullDN() && config.getAuthenticationRequiredOperationTypes().contains(OperationType.EXTENDED))) {
return new LDAPMessage(messageID, new ExtendedResponseProtocolOp(ResultCode.INSUFFICIENT_ACCESS_RIGHTS_INT_VALUE, null, ERR_MEM_HANDLER_EXTENDED_REQUIRES_AUTH.get(), null, null, null));
}
final String oid = request.getOID();
final InMemoryExtendedOperationHandler handler = extendedRequestHandlers.get(oid);
if (handler == null) {
return new LDAPMessage(messageID, new ExtendedResponseProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, null, ERR_MEM_HANDLER_EXTENDED_OP_NOT_SUPPORTED.get(oid), null, null, null));
}
try {
final Control[] controlArray = new Control[controls.size()];
controls.toArray(controlArray);
final ExtendedRequest extendedRequest = new ExtendedRequest(oid, request.getValue(), controlArray);
final ExtendedResult extendedResult = handler.processExtendedOperation(this, messageID, extendedRequest);
return new LDAPMessage(messageID, new ExtendedResponseProtocolOp(extendedResult.getResultCode().intValue(), extendedResult.getMatchedDN(), extendedResult.getDiagnosticMessage(), Arrays.asList(extendedResult.getReferralURLs()), extendedResult.getOID(), extendedResult.getValue()), extendedResult.getResponseControls());
} catch (final Exception e) {
Debug.debugException(e);
return new LDAPMessage(messageID, new ExtendedResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, ERR_MEM_HANDLER_EXTENDED_OP_FAILURE.get(StaticUtils.getExceptionMessage(e)), null, null, null));
}
}
}
Aggregations