001/*
002 * Copyright 2015-2024 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2015-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) 2015-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.sdk.unboundidds;
037
038
039
040import com.unboundid.ldap.sdk.Entry;
041import com.unboundid.ldap.sdk.LDAPException;
042import com.unboundid.ldap.sdk.LDAPInterface;
043import com.unboundid.ldap.sdk.RootDSE;
044import com.unboundid.util.NotMutable;
045import com.unboundid.util.NotNull;
046import com.unboundid.util.Nullable;
047import com.unboundid.util.ThreadSafety;
048import com.unboundid.util.ThreadSafetyLevel;
049
050
051
052/**
053 * This class provides an enhanced implementation of the {@link RootDSE} class
054 * that provides access to additional attributes that may be included in the
055 * root DSE of a Ping Identity, UnboundID, or Nokia/Alcatel-Lucent 8661 server.
056 * <BR>
057 * <BLOCKQUOTE>
058 *   <B>NOTE:</B>  This class, and other classes within the
059 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
060 *   supported for use against Ping Identity, UnboundID, and
061 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
062 *   for proprietary functionality or for external specifications that are not
063 *   considered stable or mature enough to be guaranteed to work in an
064 *   interoperable way with other types of LDAP servers.
065 * </BLOCKQUOTE>
066 */
067@NotMutable()
068@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
069public final class UnboundIDRootDSE
070       extends RootDSE
071{
072  /**
073   * The name of the attribute that provides a digest of the base configuration
074   * for the software version the server is currently running.
075   */
076  @NotNull public static final String ATTR_BASELINE_CONFIG_DIGEST =
077       "baselineConfigurationDigest";
078
079
080
081  /**
082   * The name of the attribute that provides a digest of the configuration model
083   * for the software version the server is currently running.
084   */
085  @NotNull public static final String ATTR_CONFIG_MODEL_DIGEST =
086       "configurationModelDigest";
087
088
089
090  /**
091   * The name of the attribute that provides a the unique instance name for the
092   * server instance.
093   */
094  @NotNull public static final String ATTR_INSTANCE_NAME = "ds-instance-name";
095
096
097
098  /**
099   * The name of the attribute that includes the DNs of the private naming
100   * contexts defined in the server.  These are base DNs that provide some
101   * content in the UnboundID server, but do not house user-provided data that
102   * is expected to be accessed by normal clients.
103   */
104  @NotNull public static final String ATTR_PRIVATE_NAMING_CONTEXTS =
105       "ds-private-naming-contexts";
106
107
108
109  /**
110   * The name of the attribute that includes unique identifier generated at
111   * server startup, and can be used to determine whether an instance has been
112   * restarted.
113   */
114  @NotNull public static final String ATTR_STARTUP_UUID = "startupUUID";
115
116
117
118  /**
119   * The name of the attribute that includes the one-time password delivery
120   * mechanisms supported for use in the server.
121   */
122  @NotNull public static final String ATTR_SUPPORTED_OTP_DELIVERY_MECHANISM =
123       "ds-supported-otp-delivery-mechanism";
124
125
126
127  /**
128   * The set of request attributes to use when attempting to retrieve the server
129   * root DSE.  It will attempt to retrieve all operational attributes if the
130   * server supports that capability, but will also attempt to retrieve specific
131   * attributes by name in case it does not.
132   */
133  @NotNull private static final String[] REQUEST_ATTRS;
134  static
135  {
136    final String[] superAttrs = RootDSE.REQUEST_ATTRS;
137    REQUEST_ATTRS = new String[superAttrs.length + 6];
138    System.arraycopy(superAttrs, 0, REQUEST_ATTRS, 0, superAttrs.length);
139
140    int i = superAttrs.length;
141    REQUEST_ATTRS[i++] = ATTR_BASELINE_CONFIG_DIGEST;
142    REQUEST_ATTRS[i++] = ATTR_CONFIG_MODEL_DIGEST;
143    REQUEST_ATTRS[i++] = ATTR_INSTANCE_NAME;
144    REQUEST_ATTRS[i++] = ATTR_PRIVATE_NAMING_CONTEXTS;
145    REQUEST_ATTRS[i++] = ATTR_STARTUP_UUID;
146    REQUEST_ATTRS[i++] = ATTR_SUPPORTED_OTP_DELIVERY_MECHANISM;
147  }
148
149
150
151  /**
152   * The serial version UID for this serializable class.
153   */
154  private static final long serialVersionUID = 2555047334281707615L;
155
156
157
158  /**
159   * Creates a new UnboundID root DSE object from the information in the
160   * provided entry.
161   *
162   * @param  rootDSEEntry  The entry to use to create this UnboundID root DSE
163   *                       object.  It must not be {@code null}.
164   */
165  public UnboundIDRootDSE(@NotNull final Entry rootDSEEntry)
166  {
167    super(rootDSEEntry);
168  }
169
170
171
172  /**
173   * Retrieves the root DSE from an UnboundID server using the provided
174   * connection.
175   *
176   * @param  connection  The connection to use to retrieve the server root DSE.
177   *
178   * @return The UnboundID server root DSE, or {@code null} if it is not
179   *          available (e.g., the client does not have permission to read the
180   *          entry).
181   *
182   * @throws LDAPException  If a problem occurs while attempting to retrieve
183   *                         the server root DSE.
184   */
185  @Nullable()
186  public static UnboundIDRootDSE getRootDSE(
187                     @NotNull final LDAPInterface connection)
188       throws LDAPException
189  {
190    final Entry rootDSEEntry = connection.getEntry("", REQUEST_ATTRS);
191    if (rootDSEEntry == null)
192    {
193      return null;
194    }
195
196    return new UnboundIDRootDSE(rootDSEEntry);
197  }
198
199
200
201  /**
202   * Retrieves a digest of the baseline configuration for the software version
203   * the server is currently running.
204   *
205   * @return The server's baseline configuration digest, or {@code null} if
206   *          that information is not available.
207   */
208  @Nullable()
209  public String getBaselineConfigurationDigest()
210  {
211    return getAttributeValue(ATTR_BASELINE_CONFIG_DIGEST);
212  }
213
214
215
216  /**
217   * Retrieves a digest of the configuration model for the software version the
218   * server is currently running.
219   *
220   * @return The server's configuration model digest, or {@code null} if that
221   *          information is not available.
222   */
223  @Nullable()
224  public String getConfigurationModelDigest()
225  {
226    return getAttributeValue(ATTR_CONFIG_MODEL_DIGEST);
227  }
228
229
230
231  /**
232   * Retrieves the unique name assigned to the server instance.
233   *
234   * @return The unique name assigned to the server instance, or {@code null}
235   *          if that information is not available.
236   */
237  @Nullable()
238  public String getInstanceName()
239  {
240    return getAttributeValue(ATTR_INSTANCE_NAME);
241  }
242
243
244
245  /**
246   * Retrieves the DNs of the private naming contexts, which identify base DNs
247   * for content in the server that is not intended to be accessed by normal
248   * clients but instead provides some alternate function like administration
249   * or monitoring.
250   *
251   * @return The DNs of the private naming contexts, or {@code null} if that
252   *          information is not available.
253   */
254  @Nullable()
255  public String[] getPrivateNamingContexts()
256  {
257    return getAttributeValues(ATTR_PRIVATE_NAMING_CONTEXTS);
258  }
259
260
261
262  /**
263   * Retrieves a unique identifier that the server generated at startup and can
264   * be used to determine whether a server has been restarted.
265   *
266   * @return The server's startup UUID, or {@code null} if that information is
267   *          not available.
268   */
269  @Nullable()
270  public String getStartupUUID()
271  {
272    return getAttributeValue(ATTR_STARTUP_UUID);
273  }
274
275
276
277  /**
278   * Retrieves the names of the supported one-time password delivery mechanisms.
279   *
280   * @return The names of the supported one-time password delivery mechanisms,
281   *          or {@code null} if that information is not available.
282   */
283  @Nullable()
284  public String[] getSupportedOTPDeliveryMechanisms()
285  {
286    return getAttributeValues(ATTR_SUPPORTED_OTP_DELIVERY_MECHANISM);
287  }
288
289
290
291  /**
292   * Indicates whether the directory server indicates that it supports the
293   * specified one-time password delivery mechanism.
294   *
295   * @param  mechanismName  The name of the delivery mechanism for which to make
296   *                        the determination.  It must not be {@code null}.
297   *
298   * @return  {@code true} if the server indicates that it supports the
299   *          specified one-time password delivery mechanism, or {@code false}
300   *          if it does not.
301   */
302  public boolean supportsOTPDeliveryMechanism(
303              @NotNull final String mechanismName)
304  {
305    return hasAttributeValue(ATTR_SUPPORTED_OTP_DELIVERY_MECHANISM,
306         mechanismName);
307  }
308}