use of com.unboundid.ldap.protocol.LDAPMessage in project ldapsdk by pingidentity.
the class LDAPListenerClientConnection method sendSearchResultReference.
/**
* Sends a search result reference message to the client with the provided
* information.
*
* @param messageID The message ID for the LDAP message to send to the
* client. It must match the message ID of the associated
* search request.
* @param protocolOp The search result reference protocol op to include in
* the LDAP message to send to the client.
* @param controls The set of controls to include in the response message.
* It may be empty or {@code null} if no controls should
* be included.
*
* @throws LDAPException If a problem occurs while attempting to send the
* provided response message. If an exception is
* thrown, then the client connection will have been
* terminated.
*/
public void sendSearchResultReference(final int messageID, @NotNull final SearchResultReferenceProtocolOp protocolOp, @Nullable final Control... controls) throws LDAPException {
if (searchReferenceTransformers.isEmpty()) {
sendMessage(new LDAPMessage(messageID, protocolOp, controls));
} else {
Control[] c;
SearchResultReferenceProtocolOp op = protocolOp;
if (controls == null) {
c = EMPTY_CONTROL_ARRAY;
} else {
c = controls;
}
for (final SearchReferenceTransformer t : searchReferenceTransformers) {
try {
final ObjectPair<SearchResultReferenceProtocolOp, Control[]> p = t.transformReference(messageID, op, c);
if (p == null) {
return;
}
op = p.getFirst();
c = p.getSecond();
} catch (final Exception e) {
Debug.debugException(e);
sendMessage(new LDAPMessage(messageID, protocolOp, c));
throw new LDAPException(ResultCode.LOCAL_ERROR, ERR_CONN_SEARCH_REFERENCE_TRANSFORMER_EXCEPTION.get(t.getClass().getName(), String.valueOf(op), StaticUtils.getExceptionMessage(e)), e);
}
}
sendMessage(new LDAPMessage(messageID, op, c));
}
}
use of com.unboundid.ldap.protocol.LDAPMessage in project ldapsdk by pingidentity.
the class LDAPListenerClientConnection method sendSearchResultEntry.
/**
* Sends a search result entry message to the client with the provided
* information.
*
* @param messageID The message ID for the LDAP message to send to the
* client. It must match the message ID of the associated
* search request.
* @param protocolOp The search result entry protocol op to include in the
* LDAP message to send to the client. It must not be
* {@code null}.
* @param controls The set of controls to include in the response message.
* It may be empty or {@code null} if no controls should
* be included.
*
* @throws LDAPException If a problem occurs while attempting to send the
* provided response message. If an exception is
* thrown, then the client connection will have been
* terminated.
*/
public void sendSearchResultEntry(final int messageID, @NotNull final SearchResultEntryProtocolOp protocolOp, @Nullable final Control... controls) throws LDAPException {
if (searchEntryTransformers.isEmpty()) {
sendMessage(new LDAPMessage(messageID, protocolOp, controls));
} else {
Control[] c;
SearchResultEntryProtocolOp op = protocolOp;
if (controls == null) {
c = EMPTY_CONTROL_ARRAY;
} else {
c = controls;
}
for (final SearchEntryTransformer t : searchEntryTransformers) {
try {
final ObjectPair<SearchResultEntryProtocolOp, Control[]> p = t.transformEntry(messageID, op, c);
if (p == null) {
return;
}
op = p.getFirst();
c = p.getSecond();
} catch (final Exception e) {
Debug.debugException(e);
sendMessage(new LDAPMessage(messageID, protocolOp, c));
throw new LDAPException(ResultCode.LOCAL_ERROR, ERR_CONN_SEARCH_ENTRY_TRANSFORMER_EXCEPTION.get(t.getClass().getName(), String.valueOf(op), StaticUtils.getExceptionMessage(e)), e);
}
}
sendMessage(new LDAPMessage(messageID, op, c));
}
}
use of com.unboundid.ldap.protocol.LDAPMessage in project ldapsdk by pingidentity.
the class InMemoryRequestHandler method delete.
/**
* Processes the provided delete request.
* <BR><BR>
* This method may be used regardless of whether the server is listening for
* client connections, and regardless of whether delete operations are
* allowed in the server.
*
* @param deleteRequest The delete request to be processed. It must not be
* {@code null}.
*
* @return The result of processing the delete operation.
*
* @throws LDAPException If the server rejects the delete request, or if a
* problem is encountered while sending the request or
* reading the response.
*/
@NotNull()
public LDAPResult delete(@NotNull final DeleteRequest deleteRequest) throws LDAPException {
final ArrayList<Control> requestControlList = new ArrayList<>(deleteRequest.getControlList());
requestControlList.add(new Control(OID_INTERNAL_OPERATION_REQUEST_CONTROL, false));
final LDAPMessage responseMessage = processDeleteRequest(1, new DeleteRequestProtocolOp(deleteRequest.getDN()), requestControlList);
final DeleteResponseProtocolOp deleteResponse = responseMessage.getDeleteResponseProtocolOp();
final LDAPResult ldapResult = new LDAPResult(responseMessage.getMessageID(), ResultCode.valueOf(deleteResponse.getResultCode()), deleteResponse.getDiagnosticMessage(), deleteResponse.getMatchedDN(), deleteResponse.getReferralURLs(), responseMessage.getControls());
switch(deleteResponse.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 processModifyRequest.
/**
* Attempts to process the provided modify 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 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 does not exist.</LI>
* <LI>Any of the modifications cannot be applied to the entry.</LI>
* <LI>If a schema was provided, and the entry violates any of the
* constraints of that schema.</LI>
* </UL>
*
* @param messageID The message ID of the LDAP message containing the modify
* request.
* @param request The modify 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 ModifyResponseProtocolOp}.
*/
@Override()
@NotNull()
public LDAPMessage processModifyRequest(final int messageID, @NotNull final ModifyRequestProtocolOp 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_REQUEST, controls);
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new ModifyResponseProtocolOp(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))) {
return new LDAPMessage(messageID, new ModifyResponseProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, null, ERR_MEM_HANDLER_MODIFY_NOT_ALLOWED.get(), null));
}
// client is authenticated.
if ((authenticatedDN.isNullDN() && config.getAuthenticationRequiredOperationTypes().contains(OperationType.MODIFY))) {
return new LDAPMessage(messageID, new ModifyResponseProtocolOp(ResultCode.INSUFFICIENT_ACCESS_RIGHTS_INT_VALUE, null, ERR_MEM_HANDLER_MODIFY_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 ModifyResponseProtocolOp(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 ModifyResponseProtocolOp(le.getResultCode().intValue(), le.getMatchedDN(), le.getDiagnosticMessage(), StaticUtils.toList(le.getReferralURLs())), le.getResponseControls());
}
// Get the parsed target DN.
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 ModifyResponseProtocolOp(ResultCode.INVALID_DN_SYNTAX_INT_VALUE, null, ERR_MEM_HANDLER_MOD_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 ModifyResponseProtocolOp(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 ModifyResponseProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, null, ERR_MEM_HANDLER_MOD_ROOT_DSE.get(), null));
} else if (dn.equals(subschemaSubentryDN)) {
try {
validateSchemaMods(request);
} catch (final LDAPException le) {
return new LDAPMessage(messageID, new ModifyResponseProtocolOp(le.getResultCode().intValue(), le.getMatchedDN(), le.getMessage(), null));
}
} else if (dn.isDescendantOf(changeLogBaseDN, true)) {
return new LDAPMessage(messageID, new ModifyResponseProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, null, ERR_MEM_HANDLER_MOD_CHANGELOG.get(request.getDN()), null));
}
// Get the target entry. If it does not exist, then fail.
Entry entry = entryMap.get(dn);
if (entry == null) {
if (dn.equals(subschemaSubentryDN)) {
entry = subschemaSubentryRef.get().duplicate();
} else {
return new LDAPMessage(messageID, new ModifyResponseProtocolOp(ResultCode.NO_SUCH_OBJECT_INT_VALUE, getMatchedDNString(dn), ERR_MEM_HANDLER_MOD_NO_SUCH_ENTRY.get(request.getDN()), null));
}
}
// If any of the modifications target password attributes, then make sure
// they are properly encoded.
final ReadOnlyEntry readOnlyEntry = new ReadOnlyEntry(entry);
final List<Modification> unencodedMods = request.getModifications();
final ArrayList<Modification> modifications = new ArrayList<>(unencodedMods.size());
for (final Modification m : unencodedMods) {
try {
modifications.add(encodeModificationPasswords(m, readOnlyEntry, unencodedMods));
} catch (final LDAPException le) {
Debug.debugException(le);
if (le.getResultCode().isClientSideResultCode()) {
return new LDAPMessage(messageID, new ModifyResponseProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, le.getMatchedDN(), le.getMessage(), null));
} else {
return new LDAPMessage(messageID, new ModifyResponseProtocolOp(le.getResultCode().intValue(), le.getMatchedDN(), le.getMessage(), null));
}
}
}
// Attempt to apply the modifications to the entry. If successful, then a
// copy of the entry will be returned with the modifications applied.
final Entry modifiedEntry;
try {
modifiedEntry = Entry.applyModifications(entry, controlMap.containsKey(PermissiveModifyRequestControl.PERMISSIVE_MODIFY_REQUEST_OID), modifications);
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new ModifyResponseProtocolOp(le.getResultCode().intValue(), null, ERR_MEM_HANDLER_MOD_FAILED.get(request.getDN(), le.getMessage()), null));
}
// If a schema was provided, use it to validate the resulting entry.
// Also, ensure that no NO-USER-MODIFICATION attributes were targeted.
final EntryValidator entryValidator = entryValidatorRef.get();
if (entryValidator != null) {
final ArrayList<String> invalidReasons = new ArrayList<>(1);
if (!entryValidator.entryIsValid(modifiedEntry, invalidReasons)) {
return new LDAPMessage(messageID, new ModifyResponseProtocolOp(ResultCode.OBJECT_CLASS_VIOLATION_INT_VALUE, null, ERR_MEM_HANDLER_MOD_VIOLATES_SCHEMA.get(request.getDN(), StaticUtils.concatenateStrings(invalidReasons)), null));
}
for (final Modification m : modifications) {
final Attribute a = m.getAttribute();
final String baseName = a.getBaseName();
final AttributeTypeDefinition at = schema.getAttributeType(baseName);
if ((!isInternalOp) && (at != null) && at.isNoUserModification()) {
return new LDAPMessage(messageID, new ModifyResponseProtocolOp(ResultCode.CONSTRAINT_VIOLATION_INT_VALUE, null, ERR_MEM_HANDLER_MOD_NO_USER_MOD.get(request.getDN(), a.getName()), null));
}
}
}
// Perform the appropriate processing for the assertion and proxied
// authorization controls.
// Perform the appropriate processing for the assertion, pre-read,
// post-read, and proxied authorization controls.
final DN authzDN;
try {
handleAssertionRequestControl(controlMap, entry);
authzDN = handleProxiedAuthControl(controlMap);
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new ModifyResponseProtocolOp(le.getResultCode().intValue(), null, le.getMessage(), null));
}
// Update modifiersName and modifyTimestamp.
if (generateOperationalAttributes) {
modifiedEntry.setAttribute(new Attribute("modifiersName", DistinguishedNameMatchingRule.getInstance(), authzDN.toString()));
modifiedEntry.setAttribute(new Attribute("modifyTimestamp", GeneralizedTimeMatchingRule.getInstance(), StaticUtils.encodeGeneralizedTime(new Date())));
}
// Perform the appropriate processing for the pre-read and post-read
// controls.
final PreReadResponseControl preReadResponse = handlePreReadControl(controlMap, entry);
if (preReadResponse != null) {
responseControls.add(preReadResponse);
}
final PostReadResponseControl postReadResponse = handlePostReadControl(controlMap, modifiedEntry);
if (postReadResponse != null) {
responseControls.add(postReadResponse);
}
// Replace the entry in the map and return a success result.
if (dn.equals(subschemaSubentryDN)) {
final Schema newSchema = new Schema(modifiedEntry);
subschemaSubentryRef.set(new ReadOnlyEntry(modifiedEntry));
schemaRef.set(newSchema);
entryValidatorRef.set(new EntryValidator(newSchema));
} else {
entryMap.put(dn, new ReadOnlyEntry(modifiedEntry));
indexDelete(entry);
indexAdd(modifiedEntry);
}
addChangeLogEntry(request, authzDN);
return new LDAPMessage(messageID, new ModifyResponseProtocolOp(ResultCode.SUCCESS_INT_VALUE, null, null, null), responseControls);
}
}
use of com.unboundid.ldap.protocol.LDAPMessage in project ldapsdk by pingidentity.
the class InMemoryRequestHandler method processCompareRequest.
/**
* Attempts to process the provided compare 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 compare request contains a malformed target DN.</LI>
* <LI>The target entry does not exist.</LI>
* </UL>
*
* @param messageID The message ID of the LDAP message containing the
* compare request.
* @param request The compare 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 CompareResponseProtocolOp}.
*/
@Override()
@NotNull()
public LDAPMessage processCompareRequest(final int messageID, @NotNull final CompareRequestProtocolOp 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_COMPARE_REQUEST, controls);
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new CompareResponseProtocolOp(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.COMPARE))) {
return new LDAPMessage(messageID, new CompareResponseProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, null, ERR_MEM_HANDLER_COMPARE_NOT_ALLOWED.get(), null));
}
// client is authenticated.
if ((authenticatedDN.isNullDN() && config.getAuthenticationRequiredOperationTypes().contains(OperationType.COMPARE))) {
return new LDAPMessage(messageID, new CompareResponseProtocolOp(ResultCode.INSUFFICIENT_ACCESS_RIGHTS_INT_VALUE, null, ERR_MEM_HANDLER_COMPARE_REQUIRES_AUTH.get(), null));
}
// 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 CompareResponseProtocolOp(ResultCode.INVALID_DN_SYNTAX_INT_VALUE, null, ERR_MEM_HANDLER_COMPARE_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 CompareResponseProtocolOp(ResultCode.REFERRAL_INT_VALUE, referralEntry.getDN(), INFO_MEM_HANDLER_REFERRAL_ENCOUNTERED.get(), getReferralURLs(dn, referralEntry)));
}
}
// Get the target entry (optionally checking for the root DSE or subschema
// subentry). If it does not exist, then fail.
final Entry entry;
if (dn.isNullDN()) {
entry = generateRootDSE();
} else if (dn.equals(subschemaSubentryDN)) {
entry = subschemaSubentryRef.get();
} else {
entry = entryMap.get(dn);
}
if (entry == null) {
return new LDAPMessage(messageID, new CompareResponseProtocolOp(ResultCode.NO_SUCH_OBJECT_INT_VALUE, getMatchedDNString(dn), ERR_MEM_HANDLER_COMPARE_NO_SUCH_ENTRY.get(request.getDN()), null));
}
// then perform the appropriate processing.
try {
handleAssertionRequestControl(controlMap, entry);
handleProxiedAuthControl(controlMap);
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new CompareResponseProtocolOp(le.getResultCode().intValue(), null, le.getMessage(), null));
}
// See if the entry contains the assertion value.
final int resultCode;
if (entry.hasAttributeValue(request.getAttributeName(), request.getAssertionValue().getValue())) {
resultCode = ResultCode.COMPARE_TRUE_INT_VALUE;
} else {
resultCode = ResultCode.COMPARE_FALSE_INT_VALUE;
}
return new LDAPMessage(messageID, new CompareResponseProtocolOp(resultCode, null, null, null), responseControls);
}
}
Aggregations