mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Chris Ridd
19.25.2012 475b62de777edb285f32607cd4501b9c9d551d63
Fix OPENDJ-502 DSML gateway not correctly forwarding modifications to userCertificate;binary attributes
2 files added
7 files modified
319 ■■■■ changed files
opends/build.xml 6 ●●●● patch | view | raw | blame | history
opends/resource/dsml/schema/bindings.xjb 94 ●●●●● patch | view | raw | blame | history
opends/src/dsml/org/opends/dsml/protocol/ByteStringUtility.java 95 ●●●●● patch | view | raw | blame | history
opends/src/dsml/org/opends/dsml/protocol/DSMLAddOperation.java 6 ●●●● patch | view | raw | blame | history
opends/src/dsml/org/opends/dsml/protocol/DSMLCompareOperation.java 3 ●●●● patch | view | raw | blame | history
opends/src/dsml/org/opends/dsml/protocol/DSMLExtendedOperation.java 30 ●●●●● patch | view | raw | blame | history
opends/src/dsml/org/opends/dsml/protocol/DSMLModifyOperation.java 6 ●●●● patch | view | raw | blame | history
opends/src/dsml/org/opends/dsml/protocol/DSMLSearchOperation.java 71 ●●●●● patch | view | raw | blame | history
opends/src/dsml/org/opends/dsml/protocol/DSMLServlet.java 8 ●●●●● patch | view | raw | blame | history
opends/build.xml
@@ -1313,7 +1313,11 @@
    <mkdir dir="${dsml.gen.dir}/org/opends/dsml/protocol" />
    <xjc target="${dsml.gen.dir}" schema="${dsml.dir}/schema/DSMLv2.xsd"
         removeOldOutput="yes" package="org.opends.dsml.protocol">
         removeOldOutput="yes" package="org.opends.dsml.protocol"
         binding="${dsml.dir}/schema/bindings.xjb">
      <!-- Don't generate package-info.java as it conflicts with
           the one in src/dsml -->
      <arg value="-npa"/>
      <produces dir="${dsml.gen.dir}/org/opends/dsml/protocol"
           includes="* impl/*" />
    </xjc>
opends/resource/dsml/schema/bindings.xjb
New file
@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
  ! 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
  ! trunk/opends/resource/legal-notices/OpenDS.LICENSE
  ! or https://OpenDS.dev.java.net/OpenDS.LICENSE.
  ! 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 2012 ForgeRock, AS.
  ! -->
<bindings xmlns="http://java.sun.com/xml/ns/jaxb" version="2.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" schemaLocation="DSMLv2.xsd" >
 <bindings
node="//xsd:complexType[@name='AttributeValueAssertion']/xsd:sequence/xsd:element[@name='value']">
  <property>
   <baseType name="java.lang.Object"/>
  </property>
 </bindings>
 <bindings
node="//xsd:complexType[@name='SubstringFilter']/xsd:sequence/xsd:element[@name='initial']">
  <property>
   <baseType name="java.lang.Object"/>
  </property>
 </bindings>
 <bindings
node="//xsd:complexType[@name='SubstringFilter']/xsd:sequence/xsd:element[@name='any']">
  <property>
   <baseType name="java.lang.Object"/>
  </property>
 </bindings>
 <bindings
node="//xsd:complexType[@name='SubstringFilter']/xsd:sequence/xsd:element[@name='final']">
  <property>
   <baseType name="java.lang.Object"/>
  </property>
 </bindings>
 <bindings
node="//xsd:complexType[@name='MatchingRuleAssertion']/xsd:sequence/xsd:element[@name='value']">
  <property>
   <baseType name="java.lang.Object"/>
  </property>
 </bindings>
 <bindings
node="//xsd:complexType[@name='DsmlAttr']/xsd:sequence/xsd:element[@name='value']">
  <property>
   <baseType name="java.lang.Object"/>
  </property>
 </bindings>
 <bindings
node="//xsd:complexType[@name='DsmlModification']/xsd:sequence/xsd:element[@name='value']">
  <property>
   <baseType name="java.lang.Object"/>
  </property>
 </bindings>
 <!--
 <bindings node="//xsd:complexType[@name='ResultCode']">
  <property>
   <baseType name="org.opends.dsml.protocol.SafeResultCode"/>
  </property>
 </bindings>
 <bindings node="//xsd:complexType[@name='LDAPResult']/xsd:complexContent/xsd:extension[@base='DsmlMessage']/xsd:sequence/xsd:element[@name='resultCode']">
  <property>
    <baseType name="org.opends.dsml.protocol.SafeResultCode"/>
  </property>
 </bindings>
 -->
 <bindings node="//xsd:complexType[@name='ExtendedRequest']/xsd:complexContent/xsd:extension[@base='DsmlMessage']/xsd:sequence/xsd:element[@name='requestValue']">
  <property>
   <baseType name="java.lang.Object"/>
  </property>
 </bindings>
 <bindings node="//xsd:complexType[@name='ExtendedResponse']/xsd:complexContent/xsd:extension[@base='LDAPResult']/xsd:sequence/xsd:element[@name='response']">
  <property>
   <baseType name="java.lang.Object"/>
  </property>
 </bindings>
</bindings>
opends/src/dsml/org/opends/dsml/protocol/ByteStringUtility.java
New file
@@ -0,0 +1,95 @@
/*
 * 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
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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 2012 ForgeRock AS.
 */
package org.opends.dsml.protocol;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import org.opends.server.types.ByteString;
import org.opends.server.types.ByteStringBuilder;
import org.w3c.dom.Element;
/**
 * A utility class to assist in converting DsmlValues (in Objects) into
 * the required ByteStrings.
 */
public class ByteStringUtility
{
  /**
   * Returns a ByteString from a DsmlValue Object.
   *
   * @param obj
   *           the DsmlValue object.
   * @return a new ByteString object with the value, or null if val was null,
   *         or if it could not be converted.
   * @throws IOException if any problems occurred retrieving an anyURI value.
   */
  public static ByteString convertValue(Object obj)
      throws IOException, MalformedURLException
  {
    ByteString bs = null;
    if (obj != null)
    {
      if (obj instanceof String)
      {
        bs = ByteString.valueOf((String)obj);
      }
      else if (obj instanceof byte [])
      {
        bs = ByteString.wrap((byte [])obj);
      }
      else if (obj instanceof URI)
      {
        // read raw content and return as a byte[].
        InputStream is = null;
        try
        {
          is = ((URI) obj).toURL().openStream();
          ByteStringBuilder bsb = new ByteStringBuilder();
          while (bsb.append(is, 2048) != -1)
          {
            // do nothing
          }
          bs = bsb.toByteString();
        }
        finally
        {
          is.close();
        }
      }
      else if (obj instanceof Element)
      {
        Element element = (Element) obj;
        bs = ByteString.valueOf(element.getTextContent());
      }
    }
    return bs;
  }
}
opends/src/dsml/org/opends/dsml/protocol/DSMLAddOperation.java
@@ -98,10 +98,10 @@
    for(DsmlAttr attr : addList)
    {
      ArrayList<ByteString> values = new ArrayList<ByteString>();
      List<String> vals = attr.getValue();
      for(String val : vals)
      List<Object> vals = attr.getValue();
      for(Object val : vals)
      {
        values.add(ByteString.valueOf(val));
        values.add(ByteStringUtility.convertValue(val));
      }
      LDAPAttribute ldapAttribute = new LDAPAttribute(attr.getName(), values);
      attributes.add(ldapAttribute);
opends/src/dsml/org/opends/dsml/protocol/DSMLCompareOperation.java
@@ -91,7 +91,8 @@
    // Read the attribute name and value for the compare request.
    AttributeValueAssertion attrValAssertion = compareRequest.getAssertion();
    String attrName = attrValAssertion.getName();
    ByteString attrValue = ByteString.valueOf(attrValAssertion.getValue());
    Object assertion = attrValAssertion.getValue();
    ByteString attrValue = ByteStringUtility.convertValue(assertion);
    ByteString dnStr = ByteString.valueOf(compareRequest.getDn());
    // Create and send the LDAP compare request to the server.
opends/src/dsml/org/opends/dsml/protocol/DSMLExtendedOperation.java
@@ -43,8 +43,6 @@
import org.opends.server.types.ByteString;
import org.opends.server.types.LDAPException;
import org.w3c.dom.Element;
/**
 * This class provides the functionality for the performing an
@@ -114,33 +112,7 @@
    String requestName = extendedRequest.getRequestName();
    Object value = extendedRequest.getRequestValue();
    ByteString asnValue = null;
    // value is optional in the request
    if (value != null)
    {
      /*
       * The processing of the value is tricky, because the schema defines
       * the requestValue with type="xsd:anyType".
       *
       * Consequently if we have:
       * <requestValue xsi:type="xsd:base64Binary">(base64)</requestValue>
       * then JAXB returns us a byte [] containing the decoded data.
       */
      if (value instanceof byte [])
      {
        asnValue = ByteString.wrap((byte [])value);
      }
      else
      {
        /*
         * On the other hand if we have:
         * <requestValue>arbitrary text</requestValue>
         * then we get an Element which we have to extract the text from.
         */
        Element content = (Element)value;
        asnValue = ByteString.valueOf(content.getTextContent());
      }
    }
    ByteString asnValue = ByteStringUtility.convertValue(value);
    // Create and send the LDAP request to the server.
    ProtocolOp op = new ExtendedRequestProtocolOp(requestName, asnValue);
opends/src/dsml/org/opends/dsml/protocol/DSMLModifyOperation.java
@@ -114,10 +114,10 @@
      String attrType = attr.getName();
      ArrayList<ByteString> values = new ArrayList<ByteString> ();
      List<String> vals = attr.getValue();
      for(String val : vals)
      List<Object> vals = attr.getValue();
      for(Object val : vals)
      {
        values.add(ByteString.valueOf(val));
        values.add(ByteStringUtility.convertValue(val));
      }
      LDAPAttribute ldapAttr = new LDAPAttribute(attrType, values);
opends/src/dsml/org/opends/dsml/protocol/DSMLSearchOperation.java
@@ -93,9 +93,10 @@
   * @throws LDAPException
   *           an LDAPException is thrown if the creation of a filter
   *           component fails.
   * @throws IOException if a value is an anyURI and cannot be fetched.
   */
  private static LDAPFilter createANDFilter(FilterSet filterSet)
      throws LDAPException
      throws LDAPException, IOException
  {
    List<JAXBElement<?>> list = filterSet.getFilterGroup();
    ArrayList<RawFilter> filters = new ArrayList<RawFilter>(list.size());
@@ -118,11 +119,13 @@
   *          filter.
   * @return a new Approximate search filter with the provided
   *         information.
   * @throws IOException if a value is an anyURI and cannot be fetched.
   */
  private static LDAPFilter createApproximateFilter(AttributeValueAssertion ava)
    throws IOException
  {
    return LDAPFilter.createApproximateFilter(ava.getName(), ByteString
        .valueOf(ava.getValue()));
    return LDAPFilter.createApproximateFilter(ava.getName(),
        ByteStringUtility.convertValue(ava.getValue()));
  }
@@ -135,11 +138,13 @@
   *          the attribute value assertion for this Equality filter.
   * @return a new Equality search filter with the provided
   *         information.
   * @throws IOException if a value is an anyURI and cannot be fetched.
   */
  private static LDAPFilter createEqualityFilter(AttributeValueAssertion ava)
    throws IOException
  {
    return LDAPFilter.createEqualityFilter(ava.getName(), ByteString
        .valueOf(ava.getValue()));
    return LDAPFilter.createEqualityFilter(ava.getName(),
        ByteStringUtility.convertValue(ava.getValue()));
  }
@@ -152,11 +157,14 @@
   *          the matching rule assertion for this Extensible filter.
   * @return a new Extensible search filter with the provided
   *         information.
   * @throws IOException if a value is an anyURI and cannot be fetched.
   */
  private static LDAPFilter createExtensibleFilter(MatchingRuleAssertion mra)
    throws IOException
  {
    return LDAPFilter.createExtensibleFilter(mra.getMatchingRule(), mra
        .getName(), ByteString.valueOf(mra.getValue()), mra.isDnAttributes());
        .getName(), ByteStringUtility.convertValue(mra.getValue()),
        mra.isDnAttributes());
  }
@@ -170,12 +178,14 @@
   *          filter.
   * @return a new GreaterOrEqual search filter with the provided
   *         information.
   * @throws IOException if a value is an anyURI and cannot be fetched.
   */
  private static LDAPFilter createGreaterOrEqualFilter(
      AttributeValueAssertion ava)
    throws IOException
  {
    return LDAPFilter.createGreaterOrEqualFilter(ava.getName(), ByteString
        .valueOf(ava.getValue()));
    return LDAPFilter.createGreaterOrEqualFilter(ava.getName(),
        ByteStringUtility.convertValue(ava.getValue()));
  }
@@ -189,11 +199,13 @@
   *          filter.
   * @return a new LessOrEqual search filter with the provided
   *         information.
   * @throws IOException if a value is an anyURI and cannot be fetched.
   */
  private static LDAPFilter createLessOrEqualFilter(AttributeValueAssertion ava)
    throws IOException
  {
    return LDAPFilter.createLessOrEqualFilter(ava.getName(), ByteString
        .valueOf(ava.getValue()));
    return LDAPFilter.createLessOrEqualFilter(ava.getName(),
        ByteStringUtility.convertValue(ava.getValue()));
  }
@@ -207,8 +219,10 @@
   * @throws LDAPException
   *           an LDAPException is thrown if the creation of the
   *           provided filter fails.
   * @throws IOException if a value is an anyURI and cannot be fetched.
   */
  private static LDAPFilter createNOTFilter(Filter filter) throws LDAPException
  private static LDAPFilter createNOTFilter(Filter filter)
    throws LDAPException, IOException
  {
    return LDAPFilter.createNOTFilter(createFilter(filter));
  }
@@ -226,9 +240,10 @@
   * @throws LDAPException
   *           an LDAPException is thrown if the creation of a filter
   *           component fails.
   * @throws IOException if a value is an anyURI and cannot be fetched.
   */
  private static LDAPFilter createORFilter(FilterSet filterSet)
      throws LDAPException
      throws LDAPException, IOException
  {
    List<JAXBElement<?>> list = filterSet.getFilterGroup();
    ArrayList<RawFilter> filters = new ArrayList<RawFilter>(list.size());
@@ -271,17 +286,19 @@
   *          the substring filter for this Substring filter.
   * @return a new Substring search filter with the provided
   *         information.
   * @throws LDAPException if the filter could not be decoded.
   * @throws IOException if a value is an anyURI and cannot be fetched.
   */
  private static LDAPFilter createSubstringFilter(SubstringFilter sf)
        throws LDAPException
        throws LDAPException, IOException
  {
    List<String> anys = sf.getAny();
    ArrayList<ByteString> subAnyElements = new ArrayList<ByteString>(anys
    List<Object> anyo = sf.getAny();
    ArrayList<ByteString> subAnyElements = new ArrayList<ByteString>(anyo
        .size());
    for (String s : anys)
    for (Object o : anyo)
    {
      subAnyElements.add(ByteString.valueOf(s));
      subAnyElements.add(ByteStringUtility.convertValue(o));
    }
    if(sf.getInitial() == null && subAnyElements.isEmpty()
            && sf.getFinal()==null)
@@ -289,9 +306,12 @@
      Message message = ERR_LDAP_FILTER_DECODE_NULL.get();
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, message);
    }
    return LDAPFilter.createSubstringFilter(sf.getName(), sf.getInitial()==null?
      null:ByteString.valueOf(sf.getInitial()), subAnyElements,
      sf.getFinal()==null?null:ByteString.valueOf(sf.getFinal()));
    return LDAPFilter.createSubstringFilter(sf.getName(),
        sf.getInitial() == null ? null : ByteStringUtility
            .convertValue(sf.getInitial()),
        subAnyElements,
        sf.getFinal() == null ? null : ByteStringUtility
            .convertValue(sf.getFinal()));
  }
@@ -310,9 +330,10 @@
   * @throws LDAPException
   *           an LDAPException is thrown if the creation of the
   *           targeted filter fails.
   * @throws IOException if a value is an anyURI and cannot be fetched.
   */
  private static LDAPFilter createFilter(JAXBElement<?> xmlElement)
      throws LDAPException
      throws LDAPException, IOException
  {
    LDAPFilter result = null;
@@ -395,8 +416,10 @@
   * @throws LDAPException
   *           an LDAPException is thrown if the creation of the
   *           targeted filter fails.
   * @throws IOException if a value is an anyURI and cannot be fetched.
   */
  private static LDAPFilter createFilter(Filter filter) throws LDAPException
  private static LDAPFilter createFilter(Filter filter)
    throws LDAPException, IOException
  {
    LDAPFilter result = null;
@@ -561,11 +584,11 @@
            DsmlAttr dsmlAttr = objFactory.createDsmlAttr();
            dsmlAttr.setName(nm);
            List<String> dsmlAttrVal = dsmlAttr.getValue();
            List<Object> dsmlAttrVal = dsmlAttr.getValue();
            ArrayList<ByteString> vals = attr.getValues();
            for (ByteString val : vals)
            {
              dsmlAttrVal.add(val.toString());
              dsmlAttrVal.add(val);
            }
            attrList.add(dsmlAttr);
          }
opends/src/dsml/org/opends/dsml/protocol/DSMLServlet.java
@@ -124,6 +124,7 @@
  private static final String AUTHENTICATION_FAILED = "authenticationFailed";
  private static final String COULD_NOT_CONNECT = "couldNotConnect";
  private static final String GATEWAY_INTERNAL_ERROR = "gatewayInternalError";
  private static final String UNRESOLVABLE_URI = "unresolvableURI";
  private static final String UNKNOWN_ERROR = "Unknown error";
@@ -199,11 +200,10 @@
       * and if the value's true then mark that OID (1.2.3.4.5) as one returning
       * a string value.
       */
      Enumeration<String> names = config.getServletContext()
          .getInitParameterNames();
      Enumeration names = config.getServletContext().getInitParameterNames();
      while (names.hasMoreElements())
      {
        String name = names.nextElement().toString();
        String name = (String) names.nextElement();
        if (name.startsWith(EXOPSTRINGPREFIX) &&
            Boolean.valueOf(config.getServletContext().getInitParameter(name)))
        {
@@ -650,6 +650,8 @@
      }
    } else if ( t instanceof LDAPConnectionException ) {
      errorResponse.setType(COULD_NOT_CONNECT);
    } else if ( t instanceof IOException ) {
      errorResponse.setType(UNRESOLVABLE_URI);
    } else {
      errorResponse.setType(GATEWAY_INTERNAL_ERROR);
    }