LocalBackendSearchOperation.java revision a395dd575518d9e5280fc5d5d5ef47c61b174647
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
* add the following below this CDDL HEADER, with the fields enclosed
* by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2008 Sun Microsystems, Inc.
*/
/**
* This class defines an operation used to search for entries in a local backend
* of the Directory Server.
*/
public class LocalBackendSearchOperation
extends SearchOperationWrapper
implements PreOperationSearchOperation, PostOperationSearchOperation,
{
/**
* The tracer object for the debug logger.
*/
// The backend in which the search is to be performed.
// Indicates whether we should actually process the search. This should
// only be false if it's a persistent search with changesOnly=true.
private boolean processSearch;
// Indicates whether to skip post-operation plugin processing.
private boolean skipPostOperation;
// The client connection for the search operation.
private ClientConnection clientConnection;
// The base DN for the search.
// The persistent search request, if applicable.
private PersistentSearch persistentSearch;
// The filter for the search.
private SearchFilter filter;
/**
* Creates a new operation that may be used to search for entries in a local
* backend of the Directory Server.
*
* @param search The operation to process.
*/
{
super(search);
}
/**
* Process this search operation against a local backend.
*
* @param backend The backend in which the search operation should be
* performed.
*/
{
// Get the plugin config manager that will be used for invoking plugins.
skipPostOperation = false;
processSearch = true;
// Create a labeled block of code that we can break out of if a problem is
// detected.
{
// Process the search base and filter to convert them from their raw forms
// as provided by the client to the forms required for the rest of the
// search processing.
break searchProcessing;
}
// Check to see if there are any controls in the request. If so, then
// see if there is any special processing required.
try
{
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
break searchProcessing;
}
// Check to see if the client has permission to perform the
// search.
// FIXME: for now assume that this will check all permission
// pertinent to the operation. This includes proxy authorization
// and any other controls specified.
isAllowed(this))
{
skipPostOperation = true;
break searchProcessing;
}
// Check for a request to cancel this operation.
if (cancelIfRequested())
{
return;
}
// Invoke the pre-operation search plugins.
if (preOpResult.connectionTerminated())
{
// There's no point in continuing with anything. Log the request and
// result and return.
return;
}
else if (preOpResult.sendResponseImmediately())
{
skipPostOperation = true;
break searchProcessing;
}
else if (preOpResult.skipCoreProcessing())
{
skipPostOperation = false;
break searchProcessing;
}
// Check for a request to cancel this operation.
if (cancelIfRequested())
{
return;
}
// Get the backend that should hold the search base. If there is none,
// then fail.
{
break searchProcessing;
}
// We'll set the result code to "success". If a problem occurs, then it
// will be overwritten.
// If there's a persistent search, then register it with the server.
if (persistentSearch != null)
{
setSendResponse(false);
}
// Process the search in the backend and all its subordinates.
try
{
if (processSearch)
{
}
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
if (persistentSearch != null)
{
setSendResponse(true);
}
break searchProcessing;
}
catch (CancelledOperationException coe)
{
if (debugEnabled())
{
}
{
}
if (persistentSearch != null)
{
setSendResponse(true);
}
skipPostOperation = true;
break searchProcessing;
}
catch (Exception e)
{
if (debugEnabled())
{
}
getExceptionMessage(e)));
if (persistentSearch != null)
{
setSendResponse(true);
}
skipPostOperation = true;
break searchProcessing;
}
}
// Check for a request to cancel this operation.
if (cancelIfRequested())
{
return;
}
// Invoke the post-operation search plugins.
if (! skipPostOperation)
{
{
return;
}
}
}
/**
* Checks to determine whether there has been a request to cancel this
* operation. If so, then set the cancel result and processing stop time.
*
* @return {@code true} if there was a cancel request, or {@code false} if
* not.
*/
private boolean cancelIfRequested()
{
if (getCancelRequest() == null)
{
return false;
}
return true;
}
/**
* Handles any controls contained in the request.
*
* @throws DirectoryException If there is a problem with any of the request
* controls.
*/
private void handleRequestControls()
throws DirectoryException
{
{
{
if (! AccessControlConfigManager.getInstance().
{
skipPostOperation = true;
}
{
if (c instanceof LDAPAssertionRequestControl)
{
}
else
{
try
{
}
catch (LDAPException le)
{
if (debugEnabled())
{
}
throw new DirectoryException(
}
}
try
{
// FIXME -- We need to determine whether the current user has
// permission to make this determination.
try
{
}
catch (DirectoryException de)
{
if (debugEnabled())
{
}
de.getMessageObject()));
}
{
}
{
}
}
catch (DirectoryException de)
{
{
throw de;
}
if (debugEnabled())
{
}
}
}
{
// The requester must have the PROXIED_AUTH privilige in order to be
// able to use this control.
{
}
if (c instanceof ProxiedAuthV1Control)
{
proxyControl = (ProxiedAuthV1Control) c;
}
else
{
try
{
}
catch (LDAPException le)
{
if (debugEnabled())
{
}
throw new DirectoryException(
}
}
if (authorizationEntry == null)
{
}
else
{
}
}
{
// The requester must have the PROXIED_AUTH privilige in order to be
// able to use this control.
{
}
if (c instanceof ProxiedAuthV2Control)
{
proxyControl = (ProxiedAuthV2Control) c;
}
else
{
try
{
}
catch (LDAPException le)
{
if (debugEnabled())
{
}
throw new DirectoryException(
}
}
if (authorizationEntry == null)
{
}
else
{
}
}
{
if (c instanceof PersistentSearchControl)
{
}
else
{
try
{
}
catch (LDAPException le)
{
if (debugEnabled())
{
}
throw new DirectoryException(
}
}
persistentSearch = new PersistentSearch(this,
// If we're only interested in changes, then we don't actually want
// to process the search now.
if (psearchControl.getChangesOnly())
{
processSearch = false;
}
}
{
setReturnLDAPSubentries(true);
}
{
if (c instanceof MatchedValuesControl)
{
}
else
{
try
{
}
catch (LDAPException le)
{
if (debugEnabled())
{
}
throw new DirectoryException(
}
}
}
{
setIncludeUsableControl(true);
}
{
setRealAttributesOnly(true);
}
{
setVirtualAttributesOnly(true);
}
{
// Do nothing here and let AciHandler deal with it.
}
// NYI -- Add support for additional controls.
else if (c.isCritical())
{
{
throw new DirectoryException(
}
}
}
}
}
}