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 2010 Sun Microsystems, Inc.
015 * Portions Copyright 2011-2015 ForgeRock AS.
016 */
017package org.opends.server.extensions;
018
019import org.forgerock.i18n.LocalizableMessage;
020import org.forgerock.i18n.slf4j.LocalizedLogger;
021import org.forgerock.opendj.ldap.ResultCode;
022import org.opends.server.admin.std.server.
023        PasswordPolicySubentryVirtualAttributeCfg;
024import org.opends.server.api.AuthenticationPolicy;
025import org.opends.server.api.VirtualAttributeProvider;
026import org.opends.server.core.SearchOperation;
027import org.opends.server.types.*;
028import static org.opends.messages.ExtensionMessages.*;
029
030/**
031 * This class implements a virtual attribute provider to serve
032 * the pwdPolicySubentry operational attribute as described in
033 * Password Policy for LDAP Directories Internet-Draft.
034 */
035public class PasswordPolicySubentryVirtualAttributeProvider
036        extends VirtualAttributeProvider<
037        PasswordPolicySubentryVirtualAttributeCfg>
038{
039  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
040
041  /**
042   * Creates a new instance of this pwdPolicySubentry
043   * virtual attribute provider.
044   */
045  public PasswordPolicySubentryVirtualAttributeProvider()
046  {
047    super();
048
049    // All initialization should be performed in the
050    // initializeVirtualAttributeProvider method.
051  }
052
053  /** {@inheritDoc} */
054  @Override
055  public boolean isMultiValued()
056  {
057    return false;
058  }
059
060  /** {@inheritDoc} */
061  @Override
062  public Attribute getValues(Entry entry, VirtualAttributeRule rule)
063  {
064    if (!entry.isSubentry() && !entry.isLDAPSubentry())
065    {
066      AuthenticationPolicy policy = null;
067
068      try
069      {
070        policy = AuthenticationPolicy.forUser(entry, false);
071      }
072      catch (DirectoryException de)
073      {
074        // Something went wrong while trying to
075        // retrieve password policy, log this.
076        logger.error(de.getMessageObject());
077
078        logger.traceException(de, "Failed to retrieve password policy for user %s",
079            entry.getName());
080      }
081
082      if (policy == null)
083      {
084        // No authentication policy: debug log this as an error since all
085        // entries should have at least the default password policy.
086        logger.trace("No applicable password policy for user %s", entry.getName());
087      }
088      else if (policy.isPasswordPolicy())
089      {
090        return Attributes.create(rule.getAttributeType(),
091            policy.getDN().toString());
092      }
093      else
094      {
095        // Not a password policy, could be PTA, etc.
096        if (logger.isTraceEnabled())
097        {
098          logger.trace("Authentication policy %s found for user %s is "
099              + "not a password policy", policy.getDN(), entry.getName());
100        }
101      }
102    }
103
104    return Attributes.empty(rule.getAttributeType());
105  }
106
107  /** {@inheritDoc} */
108  @Override
109  public boolean isSearchable(VirtualAttributeRule rule,
110                              SearchOperation searchOperation,
111                              boolean isPreIndexed)
112  {
113    return false;
114  }
115
116  /** {@inheritDoc} */
117  @Override
118  public void processSearch(VirtualAttributeRule rule,
119                            SearchOperation searchOperation)
120  {
121    searchOperation.setResultCode(ResultCode.UNWILLING_TO_PERFORM);
122
123    LocalizableMessage message =
124            ERR_PASSWORDPOLICYSUBENTRY_VATTR_NOT_SEARCHABLE.get(
125            rule.getAttributeType().getNameOrOID());
126    searchOperation.appendErrorMessage(message);
127  }
128}