001/*
002 * Copyright 2008-2024 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2008-2024 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-2024 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.NotNull;
046import com.unboundid.util.Nullable;
047import com.unboundid.util.StaticUtils;
048import com.unboundid.util.ThreadSafety;
049import com.unboundid.util.ThreadSafetyLevel;
050
051import static com.unboundid.ldap.matchingrules.MatchingRuleMessages.*;
052
053
054
055/**
056 * This class provides an implementation of a matching rule that performs
057 * equality comparisons against values that should be distinguished names.
058 * Substring and ordering matching are not supported.
059 */
060@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
061public final class DistinguishedNameMatchingRule
062       extends MatchingRule
063{
064  /**
065   * The singleton instance that will be returned from the {@code getInstance}
066   * method.
067   */
068  @NotNull private static final DistinguishedNameMatchingRule INSTANCE =
069       new DistinguishedNameMatchingRule();
070
071
072
073  /**
074   * The name for the distinguishedNameMatch equality matching rule.
075   */
076  @NotNull public static final String EQUALITY_RULE_NAME =
077       "distinguishedNameMatch";
078
079
080
081  /**
082   * The name for the distinguishedNameMatch equality matching rule, formatted
083   * in all lowercase characters.
084   */
085  @NotNull static final String LOWER_EQUALITY_RULE_NAME =
086       StaticUtils.toLowerCase(EQUALITY_RULE_NAME);
087
088
089
090  /**
091   * The OID for the distinguishedNameMatch equality matching rule.
092   */
093  @NotNull public static final String EQUALITY_RULE_OID = "2.5.13.1";
094
095
096
097  /**
098   * The serial version UID for this serializable class.
099   */
100  private static final long serialVersionUID = -2617356571703597868L;
101
102
103
104  /**
105   * Creates a new instance of this distinguished name matching rule.
106   */
107  public DistinguishedNameMatchingRule()
108  {
109    // No implementation is required.
110  }
111
112
113
114  /**
115   * Retrieves a singleton instance of this matching rule.
116   *
117   * @return  A singleton instance of this matching rule.
118   */
119  @NotNull()
120  public static DistinguishedNameMatchingRule getInstance()
121  {
122    return INSTANCE;
123  }
124
125
126
127  /**
128   * {@inheritDoc}
129   */
130  @Override()
131  @NotNull()
132  public String getEqualityMatchingRuleName()
133  {
134    return EQUALITY_RULE_NAME;
135  }
136
137
138
139  /**
140   * {@inheritDoc}
141   */
142  @Override()
143  @NotNull()
144  public String getEqualityMatchingRuleOID()
145  {
146    return EQUALITY_RULE_OID;
147  }
148
149
150
151  /**
152   * {@inheritDoc}
153   */
154  @Override()
155  @Nullable()
156  public String getOrderingMatchingRuleName()
157  {
158    return null;
159  }
160
161
162
163  /**
164   * {@inheritDoc}
165   */
166  @Override()
167  @Nullable()
168  public String getOrderingMatchingRuleOID()
169  {
170    return null;
171  }
172
173
174
175  /**
176   * {@inheritDoc}
177   */
178  @Override()
179  @Nullable()
180  public String getSubstringMatchingRuleName()
181  {
182    return null;
183  }
184
185
186
187  /**
188   * {@inheritDoc}
189   */
190  @Override()
191  @Nullable()
192  public String getSubstringMatchingRuleOID()
193  {
194    return null;
195  }
196
197
198
199  /**
200   * {@inheritDoc}
201   */
202  @Override()
203  public boolean valuesMatch(@NotNull final ASN1OctetString value1,
204                             @NotNull final ASN1OctetString value2)
205         throws LDAPException
206  {
207    final DN dn1;
208    try
209    {
210      dn1 = new DN(value1.stringValue());
211    }
212    catch (final LDAPException le)
213    {
214      Debug.debugException(le);
215      throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
216                              le.getMessage(), le);
217    }
218
219    final DN dn2;
220    try
221    {
222      dn2 = new DN(value2.stringValue());
223    }
224    catch (final LDAPException le)
225    {
226      Debug.debugException(le);
227      throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
228                              le.getMessage(), le);
229    }
230
231    return dn1.equals(dn2);
232  }
233
234
235
236  /**
237   * {@inheritDoc}
238   */
239  @Override()
240  public boolean matchesAnyValue(@NotNull final ASN1OctetString assertionValue,
241                      @NotNull final ASN1OctetString[] attributeValues)
242         throws LDAPException
243  {
244    if ((assertionValue == null) || (attributeValues == null) ||
245        (attributeValues.length == 0))
246    {
247      return false;
248    }
249
250    final DN assertionValueDN;
251    try
252    {
253      assertionValueDN = new DN(assertionValue.stringValue());
254    }
255    catch (final LDAPException le)
256    {
257      Debug.debugException(le);
258      throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
259           le.getMessage(), le);
260    }
261
262    for (final ASN1OctetString attributeValue : attributeValues)
263    {
264      try
265      {
266        if (assertionValueDN.equals(new DN(attributeValue.stringValue())))
267        {
268          return true;
269        }
270      }
271      catch (final Exception e)
272      {
273        Debug.debugException(e);
274      }
275    }
276
277    return false;
278  }
279
280
281
282  /**
283   * {@inheritDoc}
284   */
285  @Override()
286  public boolean matchesSubstring(@NotNull final ASN1OctetString value,
287                                  @Nullable final ASN1OctetString subInitial,
288                                  @Nullable final ASN1OctetString[] subAny,
289                                  @Nullable final ASN1OctetString subFinal)
290         throws LDAPException
291  {
292    throw new LDAPException(ResultCode.INAPPROPRIATE_MATCHING,
293                            ERR_DN_SUBSTRING_MATCHING_NOT_SUPPORTED.get());
294  }
295
296
297
298  /**
299   * {@inheritDoc}
300   */
301  @Override()
302  public int compareValues(@NotNull final ASN1OctetString value1,
303                           @NotNull final ASN1OctetString value2)
304         throws LDAPException
305  {
306    throw new LDAPException(ResultCode.INAPPROPRIATE_MATCHING,
307                            ERR_DN_ORDERING_MATCHING_NOT_SUPPORTED.get());
308  }
309
310
311
312  /**
313   * {@inheritDoc}
314   */
315  @Override()
316  @NotNull()
317  public ASN1OctetString normalize(@NotNull final ASN1OctetString value)
318         throws LDAPException
319  {
320    try
321    {
322      final DN dn = new DN(value.stringValue());
323      return new ASN1OctetString(dn.toNormalizedString());
324    }
325    catch (final LDAPException le)
326    {
327      Debug.debugException(le);
328      throw new LDAPException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
329                              le.getMessage(), le);
330    }
331  }
332
333
334
335  /**
336   * {@inheritDoc}
337   */
338  @Override()
339  @NotNull()
340  public ASN1OctetString normalizeSubstring(
341                              @NotNull final ASN1OctetString value,
342                              final byte substringType)
343         throws LDAPException
344  {
345    throw new LDAPException(ResultCode.INAPPROPRIATE_MATCHING,
346                            ERR_DN_SUBSTRING_MATCHING_NOT_SUPPORTED.get());
347  }
348}