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