001/*
002 * Copyright 2008-2020 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2008-2020 Ping Identity Corporation
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *    http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020/*
021 * Copyright (C) 2008-2020 Ping Identity Corporation
022 *
023 * This program is free software; you can redistribute it and/or modify
024 * it under the terms of the GNU General Public License (GPLv2 only)
025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
026 * as published by the Free Software Foundation.
027 *
028 * This program is distributed in the hope that it will be useful,
029 * but WITHOUT ANY WARRANTY; without even the implied warranty of
030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
031 * GNU General Public License for more details.
032 *
033 * You should have received a copy of the GNU General Public License
034 * along with this program; if not, see <http://www.gnu.org/licenses>.
035 */
036package com.unboundid.ldap.matchingrules;
037
038
039
040import com.unboundid.asn1.ASN1OctetString;
041import com.unboundid.ldap.sdk.DN;
042import com.unboundid.ldap.sdk.LDAPException;
043import com.unboundid.ldap.sdk.ResultCode;
044import com.unboundid.util.Debug;
045import com.unboundid.util.StaticUtils;
046import com.unboundid.util.ThreadSafety;
047import com.unboundid.util.ThreadSafetyLevel;
048
049import static com.unboundid.ldap.matchingrules.MatchingRuleMessages.*;
050
051
052
053/**
054 * This class provides an implementation of a matching rule that performs
055 * equality comparisons against values that should be distinguished names.
056 * Substring and ordering matching are not supported.
057 */
058@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
059public final class DistinguishedNameMatchingRule
060       extends MatchingRule
061{
062  /**
063   * The singleton instance that will be returned from the {@code getInstance}
064   * method.
065   */
066  private static final DistinguishedNameMatchingRule INSTANCE =
067       new DistinguishedNameMatchingRule();
068
069
070
071  /**
072   * The name for the distinguishedNameMatch equality matching rule.
073   */
074  public static final String EQUALITY_RULE_NAME = "distinguishedNameMatch";
075
076
077
078  /**
079   * The name for the distinguishedNameMatch equality matching rule, formatted
080   * in all lowercase characters.
081   */
082  static final String LOWER_EQUALITY_RULE_NAME =
083       StaticUtils.toLowerCase(EQUALITY_RULE_NAME);
084
085
086
087  /**
088   * The OID for the distinguishedNameMatch equality matching rule.
089   */
090  public static final String EQUALITY_RULE_OID = "2.5.13.1";
091
092
093
094  /**
095   * The serial version UID for this serializable class.
096   */
097  private static final long serialVersionUID = -2617356571703597868L;
098
099
100
101  /**
102   * Creates a new instance of this distinguished name matching rule.
103   */
104  public DistinguishedNameMatchingRule()
105  {
106    // No implementation is required.
107  }
108
109
110
111  /**
112   * Retrieves a singleton instance of this matching rule.
113   *
114   * @return  A singleton instance of this matching rule.
115   */
116  public static DistinguishedNameMatchingRule getInstance()
117  {
118    return INSTANCE;
119  }
120
121
122
123  /**
124   * {@inheritDoc}
125   */
126  @Override()
127  public String getEqualityMatchingRuleName()
128  {
129    return EQUALITY_RULE_NAME;
130  }
131
132
133
134  /**
135   * {@inheritDoc}
136   */
137  @Override()
138  public String getEqualityMatchingRuleOID()
139  {
140    return EQUALITY_RULE_OID;
141  }
142
143
144
145  /**
146   * {@inheritDoc}
147   */
148  @Override()
149  public String getOrderingMatchingRuleName()
150  {
151    return null;
152  }
153
154
155
156  /**
157   * {@inheritDoc}
158   */
159  @Override()
160  public String getOrderingMatchingRuleOID()
161  {
162    return null;
163  }
164
165
166
167  /**
168   * {@inheritDoc}
169   */
170  @Override()
171  public String getSubstringMatchingRuleName()
172  {
173    return null;
174  }
175
176
177
178  /**
179   * {@inheritDoc}
180   */
181  @Override()
182  public String getSubstringMatchingRuleOID()
183  {
184    return null;
185  }
186
187
188
189  /**
190   * {@inheritDoc}
191   */
192  @Override()
193  public boolean valuesMatch(final ASN1OctetString value1,
194                             final ASN1OctetString value2)
195         throws LDAPException
196  {
197    final DN dn1;
198    try
199    {
200      dn1 = new DN(value1.stringValue());
201    }
202    catch (final LDAPException le)
203    {
204      Debug.debugException(le);
205      throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
206                              le.getMessage(), le);
207    }
208
209    final DN dn2;
210    try
211    {
212      dn2 = new DN(value2.stringValue());
213    }
214    catch (final LDAPException le)
215    {
216      Debug.debugException(le);
217      throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
218                              le.getMessage(), le);
219    }
220
221    return dn1.equals(dn2);
222  }
223
224
225
226  /**
227   * {@inheritDoc}
228   */
229  @Override()
230  public boolean matchesAnyValue(final ASN1OctetString assertionValue,
231                                 final ASN1OctetString[] attributeValues)
232         throws LDAPException
233  {
234    if ((assertionValue == null) || (attributeValues == null) ||
235        (attributeValues.length == 0))
236    {
237      return false;
238    }
239
240    final DN assertionValueDN;
241    try
242    {
243      assertionValueDN = new DN(assertionValue.stringValue());
244    }
245    catch (final LDAPException le)
246    {
247      Debug.debugException(le);
248      throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
249           le.getMessage(), le);
250    }
251
252    for (final ASN1OctetString attributeValue : attributeValues)
253    {
254      try
255      {
256        if (assertionValueDN.equals(new DN(attributeValue.stringValue())))
257        {
258          return true;
259        }
260      }
261      catch (final Exception e)
262      {
263        Debug.debugException(e);
264      }
265    }
266
267    return false;
268  }
269
270
271
272  /**
273   * {@inheritDoc}
274   */
275  @Override()
276  public boolean matchesSubstring(final ASN1OctetString value,
277                                  final ASN1OctetString subInitial,
278                                  final ASN1OctetString[] subAny,
279                                  final ASN1OctetString subFinal)
280         throws LDAPException
281  {
282    throw new LDAPException(ResultCode.INAPPROPRIATE_MATCHING,
283                            ERR_DN_SUBSTRING_MATCHING_NOT_SUPPORTED.get());
284  }
285
286
287
288  /**
289   * {@inheritDoc}
290   */
291  @Override()
292  public int compareValues(final ASN1OctetString value1,
293                           final ASN1OctetString value2)
294         throws LDAPException
295  {
296    throw new LDAPException(ResultCode.INAPPROPRIATE_MATCHING,
297                            ERR_DN_ORDERING_MATCHING_NOT_SUPPORTED.get());
298  }
299
300
301
302  /**
303   * {@inheritDoc}
304   */
305  @Override()
306  public ASN1OctetString normalize(final ASN1OctetString value)
307         throws LDAPException
308  {
309    try
310    {
311      final DN dn = new DN(value.stringValue());
312      return new ASN1OctetString(dn.toNormalizedString());
313    }
314    catch (final LDAPException le)
315    {
316      Debug.debugException(le);
317      throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
318                              le.getMessage(), le);
319    }
320  }
321
322
323
324  /**
325   * {@inheritDoc}
326   */
327  @Override()
328  public ASN1OctetString normalizeSubstring(final ASN1OctetString value,
329                                            final byte substringType)
330         throws LDAPException
331  {
332    throw new LDAPException(ResultCode.INAPPROPRIATE_MATCHING,
333                            ERR_DN_SUBSTRING_MATCHING_NOT_SUPPORTED.get());
334  }
335}