001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2006-2009 Sun Microsystems, Inc.
015 * Portions Copyright 2011-2016 ForgeRock AS.
016 */
017package org.opends.server.api;
018
019import java.util.List;
020
021import org.forgerock.i18n.LocalizableMessage;
022import org.forgerock.opendj.server.config.server.AccessControlHandlerCfg;
023import org.forgerock.opendj.config.server.ConfigException;
024import org.forgerock.opendj.ldap.DN;
025import org.opends.server.core.*;
026import org.opends.server.types.*;
027import org.opends.server.workflowelement.localbackend.LocalBackendAddOperation;
028import org.opends.server.workflowelement.localbackend.LocalBackendCompareOperation;
029import org.opends.server.workflowelement.localbackend.LocalBackendDeleteOperation;
030import org.opends.server.workflowelement.localbackend.LocalBackendModifyOperation;
031
032/**
033 * This class defines the set of methods and structures that must be
034 * implemented by a Directory Server access control handler. All
035 * methods in this class should take the entire request into account
036 * when making the determination, including any request controls that
037 * might have been provided.
038 *
039 * @param <T>
040 *          The type of access control configuration handled by this
041 *          access control provider implementation.
042 */
043@org.opends.server.types.PublicAPI(
044     stability=org.opends.server.types.StabilityLevel.VOLATILE,
045     mayInstantiate=false,
046     mayExtend=true,
047     mayInvoke=false)
048public abstract class AccessControlHandler
049                      <T extends AccessControlHandlerCfg>
050{
051
052  /**
053   * Initializes the access control handler implementation based on
054   * the information in the provided configuration entry.
055   *
056   * @param configuration
057   *          The configuration object that contains the information
058   *          to use to initialize this access control handler.
059   * @throws ConfigException
060   *           If an unrecoverable problem arises in the process of
061   *           performing the initialization.
062   * @throws InitializationException
063   *           If a problem occurs during initialization that is not
064   *           related to the server configuration.
065   */
066  public abstract void initializeAccessControlHandler(T configuration)
067  throws ConfigException, InitializationException;
068
069
070
071  /**
072   * Indicates whether the provided configuration is acceptable for
073   * this access control handler. It should be possible to call this
074   * method on an uninitialized access control handler instance in
075   * order to determine whether the handler would be able to use the
076   * provided configuration. <BR>
077   * <BR>
078   * Note that implementations which use a subclass of the provided
079   * configuration class will likely need to cast the configuration to
080   * the appropriate subclass type.
081   *
082   * @param configuration
083   *          The access control handler configuration for which to
084   *          make the determination.
085   * @param unacceptableReasons
086   *          A list that may be used to hold the reasons that the
087   *          provided configuration is not acceptable.
088   * @return {@code true} if the provided configuration is acceptable
089   *         for this access control handler, or {@code false} if not.
090   */
091  public boolean isConfigurationAcceptable(
092      AccessControlHandlerCfg configuration,
093      List<LocalizableMessage> unacceptableReasons)
094  {
095    // This default implementation does not perform any special
096    // validation. It should be overridden by access control handler
097    // implementations that wish to perform more detailed validation.
098    return true;
099  }
100
101
102
103  /**
104   * Performs any necessary finalization for the access control
105   * handler implementation. This will be called just after the
106   * handler has been deregistered with the server but before it has
107   * been unloaded.
108   */
109  public abstract void finalizeAccessControlHandler();
110
111
112  /**
113   * Checks whether the ACIs prevent sending information about the provided
114   * entry, or entryDN if entry is null.
115   *
116   * @param entry
117   *          the entry for which to check if ACIs prevent information
118   *          disclosure, if null, then a fake entry will be created from the
119   *          entryDN parameter
120   * @param entryDN
121   *          the entry dn for which to check if ACIs prevent information
122   *          disclosure. Only used if entry is null.
123   * @param operation
124   *          the operation for which to check if ACIs prevent information
125   *          disclosure
126   * @return true if the information for this entry can be disclosed, false
127   *         otherwise.
128   * @throws DirectoryException
129   *           If an error occurred while performing the access control check.
130   */
131  public boolean canDiscloseInformation(Entry entry, DN entryDN,
132      Operation operation) throws DirectoryException
133  {
134    if (entry == null)
135    {
136      entry = DirectoryServer.getEntry(entryDN);
137    }
138    if (entry == null)
139    {
140      // no such entry exist, only disclose underlying information if it is an
141      // internal (broad meaning) operation, otherwise let's be safe and forbid
142      // any info disclosure for external operations.
143      // This will avoid breaking conflicts resolution in replication
144      return operation.isInternalOperation()
145          || operation.isSynchronizationOperation()
146          || operation.isInnerOperation();
147    }
148    return maySend(operation, new SearchResultEntry(entry, operation
149        .getResponseControls()));
150  }
151
152  /**
153   * Indicates whether the provided add operation is allowed based on
154   * the access control configuration. This method should not alter
155   * the provided add operation in any way.
156   *
157   * @param addOperation
158   *          The operation for which to make the determination.
159   * @return {@code true} if the operation should be allowed by the
160   *         access control configuration, or {@code false} if not.
161   * @throws DirectoryException
162   *           If an error occurred while performing the access
163   *           control check. For example, if an attribute could not
164   *           be decoded. Care must be taken not to expose any
165   *           potentially sensitive information in the exception.
166   */
167  public abstract boolean isAllowed(
168      LocalBackendAddOperation addOperation)
169    throws DirectoryException;
170
171
172
173  /**
174   * Indicates whether the provided control is allowed based on the
175   * access control configuration and the specified operation. This
176   * method should not alter the provided operation in any way.
177   *
178   * @param dn
179   *          A DN that can be used in the access determination.
180   * @param op
181   *          The operation to use in the determination.
182   * @param control
183   *          The control for which to make the determination.
184   * @return {@code true} if the control should be allowed by the
185   *         access control configuration, or {@code false} if not.
186   * @throws DirectoryException
187   *           If an error occurred while performing the access
188   *           control check. For example, if an attribute could not
189   *           be decoded. Care must be taken not to expose any
190   *           potentially sensitive information in the exception.
191   */
192  public abstract boolean isAllowed(
193      DN dn,
194      Operation op,
195      Control control)
196    throws DirectoryException;
197
198
199
200  /**
201   * Indicates whether the provided bind operation is allowed based on
202   * the access control configuration. This method should not alter
203   * the provided bind operation in any way.
204   *
205   * @param bindOperation
206   *          The operation for which to make the determination.
207   * @return {@code true} if the operation should be allowed by the
208   *         access control configuration, or {@code false} if not.
209   * @throws DirectoryException
210   *           If an error occurred while performing the access
211   *           control check. For example, if an attribute could not
212   *           be decoded. Care must be taken not to expose any
213   *           potentially sensitive information in the exception.
214   */
215  public abstract boolean isAllowed(BindOperation bindOperation)
216    throws DirectoryException;
217
218
219
220  /**
221   * Indicates whether the provided compare operation is allowed based
222   * on the access control configuration. This method should not alter
223   * the provided compare operation in any way.
224   *
225   * @param compareOperation
226   *          The operation for which to make the determination.
227   * @return {@code true} if the operation should be allowed by the
228   *         access control configuration, or {@code false} if not.
229   * @throws DirectoryException
230   *           If an error occurred while performing the access
231   *           control check. For example, if an attribute could not
232   *           be decoded. Care must be taken not to expose any
233   *           potentially sensitive information in the exception.
234   */
235  public abstract boolean isAllowed(
236      LocalBackendCompareOperation compareOperation)
237    throws DirectoryException;
238
239
240
241  /**
242   * Indicates whether the provided delete operation is allowed based
243   * on the access control configuration. This method should not alter
244   * the provided delete operation in any way.
245   *
246   * @param deleteOperation
247   *          The operation for which to make the determination.
248   * @return {@code true} if the operation should be allowed by the
249   *         access control configuration, or {@code false} if not.
250   * @throws DirectoryException
251   *           If an error occurred while performing the access
252   *           control check. For example, if an attribute could not
253   *           be decoded. Care must be taken not to expose any
254   *           potentially sensitive information in the exception.
255   */
256  public abstract boolean isAllowed(
257      LocalBackendDeleteOperation deleteOperation)
258    throws DirectoryException;
259
260
261
262  /**
263   * Indicates whether the provided extended operation is allowed
264   * based on the access control configuration. This method should not
265   * alter the provided extended operation in any way.
266   *
267   * @param extendedOperation
268   *          The operation for which to make the determination.
269   * @return {@code true} if the operation should be allowed by the
270   *         access control configuration, or {@code false} if not.
271   * @throws DirectoryException
272   *           If an error occurred while performing the access
273   *           control check. For example, if an attribute could not
274   *           be decoded. Care must be taken not to expose any
275   *           potentially sensitive information in the exception.
276   */
277  public abstract boolean isAllowed(ExtendedOperation extendedOperation)
278    throws DirectoryException;
279
280
281
282  /**
283   * Indicates whether the provided modify operation is allowed based
284   * on the access control configuration. This method should not alter
285   * the provided modify operation in any way.
286   *
287   * @param modifyOperation
288   *          The operation for which to make the determination.
289   * @return {@code true} if the operation should be allowed by the
290   *         access control configuration, or {@code false} if not.
291   * @throws DirectoryException
292   *           If an error occurred while performing the access
293   *           control check. For example, if an attribute could not
294   *           be decoded. Care must be taken not to expose any
295   *           potentially sensitive information in the exception.
296   */
297  public abstract boolean isAllowed(
298      LocalBackendModifyOperation modifyOperation)
299    throws DirectoryException;
300
301
302
303  /**
304   * Indicates whether the provided modify DN operation is allowed
305   * based on the access control configuration. This method should not
306   * alter the provided modify DN operation in any way.
307   *
308   * @param modifyDNOperation
309   *          The operation for which to make the determination.
310   * @return {@code true} if the operation should be allowed by the
311   *         access control configuration, or {@code false} if not.
312   * @throws DirectoryException
313   *           If an error occurred while performing the access
314   *           control check. For example, if an attribute could not
315   *           be decoded. Care must be taken not to expose any
316   *           potentially sensitive information in the exception.
317   */
318  public abstract boolean isAllowed(ModifyDNOperation modifyDNOperation)
319    throws DirectoryException;
320
321
322
323  /**
324   * Indicates whether the provided search operation is allowed based
325   * on the access control configuration. This method may only alter
326   * the provided search operation in order to add an opaque block of
327   * data to it that will be made available for use in determining
328   * whether matching search result entries or search result
329   * references may be allowed.
330   *
331   * @param searchOperation
332   *          The operation for which to make the determination.
333   * @return {@code true} if the operation should be allowed by the
334   *         access control configuration, or {@code false} if not.
335   * @throws DirectoryException
336   *           If an error occurred while performing the access
337   *           control check. For example, if an attribute could not
338   *           be decoded. Care must be taken not to expose any
339   *           potentially sensitive information in the exception.
340   */
341  public abstract boolean isAllowed(SearchOperation searchOperation)
342    throws DirectoryException;
343
344
345
346  /**
347   * Indicates whether the provided operation search filter is allowed
348   * based on the access control configuration. This method should not
349   * alter the provided operation in any way.
350   *
351   * @param operation
352   *          The operation for which to make the determination.
353   * @param entry
354   *          The entry for which to make the determination.
355   * @param filter
356   *          The filter to check access on.
357   * @return {@code true} if the operation should be allowed by the
358   *         access control configuration, or {@code false} if not.
359   * @throws DirectoryException
360   *           If an error occurred while performing the access
361   *           control check. For example, if an attribute could not
362   *           be decoded. Care must be taken not to expose any
363   *           potentially sensitive information in the exception.
364   */
365  public abstract boolean isAllowed(Operation operation, Entry entry,
366    SearchFilter filter) throws DirectoryException;
367
368
369
370  /**
371   * Indicates whether the provided search result entry may be sent to
372   * the client. Implementations <b>must not under any
373   * circumstances</b> modify the search entry in any way.
374   *
375   * @param operation
376   *          The operation currently being processed (this will
377   *          usually be a search, but may be other types of operation
378   *          when pre/post read controls are used).
379   * @param unfilteredEntry
380   *          The result entry before any attribute filtering.
381   * @return {@code true} if the access control configuration allows
382   *         the entry to be returned to the client, or {@code false}
383   *         if not.
384   */
385  public abstract boolean maySend(Operation operation,
386      SearchResultEntry unfilteredEntry);
387
388
389
390  /**
391   * Filter the contents of the provided entry such that it no longer
392   * contains any attributes or values that the client is not
393   * permitted to access.
394   *
395   * @param operation
396   *          The operation currently being processed (this will
397   *          usually be a search, but may be other types of operation
398   *          when pre/post read controls are used).
399   * @param unfilteredEntry
400   *          The result entry before any attribute filtering.
401   * @param filteredEntry
402   *          The partially filtered result entry being returned to
403   *          the client.
404   */
405  public abstract void filterEntry(Operation operation,
406      SearchResultEntry unfilteredEntry,
407      SearchResultEntry filteredEntry);
408
409
410
411  /**
412   * Indicates whether the provided search result reference may be
413   * sent to the client based on the access control configuration.
414   *
415   * @param dn
416   *          A DN that can be used in the access determination.
417   * @param operation
418   *          The operation with which the provided reference
419   *          is associated.
420   * @param searchReference
421   *          The search result reference for which to make the
422   *          determination.
423   * @return {@code true} if the access control configuration allows
424   *         the reference to be returned to the client, or {@code
425   *         false} if not.
426   */
427  public abstract boolean maySend(DN dn, Operation operation,
428      SearchResultReference searchReference);
429
430
431
432  /**
433   * Indicates if the specified proxy user entry can proxy, or act on
434   * the behalf of the specified proxied user entry. The operation
435   * parameter is used in the evaluation.
436   *
437   * @param proxyUser
438   *          The entry to use as the proxy user.
439   * @param proxiedUser
440   *          The entry to be proxied by the proxy user.
441   * @param operation
442   *          The operation to use in the evaluation.
443   * @return {@code true} if the access control configuration allows
444   *         the proxy user to proxy the proxied user, or {@code
445   *         false} if not.
446   */
447  public abstract boolean mayProxy(Entry proxyUser, Entry proxiedUser,
448      Operation operation);
449
450}