001    /*
002     * Copyright 2007-2015 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2008-2015 UnboundID Corp.
007     *
008     * This program is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU General Public License (GPLv2 only)
010     * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011     * as published by the Free Software Foundation.
012     *
013     * This program is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016     * GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with this program; if not, see <http://www.gnu.org/licenses>.
020     */
021    package com.unboundid.ldap.sdk;
022    
023    
024    
025    
026    import static com.unboundid.util.Debug.*;
027    
028    
029    
030    /**
031     * This class provides a data structure for representing the directory server
032     * root DSE.  This entry provides information about the capabilities of the
033     * directory server, server vendor and version information, and published naming
034     * contexts.
035     * <BR><BR>
036     * Note a root DSE object instance represents a read-only version of an entry,
037     * so all read operations allowed for an entry will succeed, but all write
038     * attempts will be rejected.
039     * <BR><BR>
040     * <H2>Example</H2>
041     * The following example demonstrates the process for retrieving the root DSE
042     * of a directory server and using it to determine whether it supports the
043     * {@code com.unboundid.ldap.sdk.controls.ServerSideSortRequestControl}:
044     * <PRE>
045     * RootDSE rootDSE = connection.getRootDSE();
046     * if (rootDSE.supportsControl(
047     *      ServerSideSortRequestControl.SERVER_SIDE_SORT_REQUEST_OID))
048     * {
049     *   // The directory server does support the server-side sort control.
050     * }
051     * else
052     * {
053     *   // The directory server does not support the server-side sort control.
054     * }
055     * </PRE>
056     */
057    public class RootDSE
058           extends ReadOnlyEntry
059    {
060      /**
061       * The name of the attribute that includes a set of URIs (likely in the form
062       * of LDAP URLs) of other servers that may be contacted if the target server
063       * is unavailable, as defined in RFC 4512 section 5.1.
064       */
065      public static final String ATTR_ALT_SERVER = "altServer";
066    
067    
068    
069      /**
070       * The name of the attribute that specifies the DN that is the base of the
071       * LDAP changelog data, if available, as defined in draft-good-ldap-changelog.
072       */
073      public static final String ATTR_CHANGELOG_DN = "changelog";
074    
075    
076    
077      /**
078       * The name of the attribute that may contain the change number for the first
079       * entry in the LDAP changelog.  This is not defined in any public
080       * specification, but is provided by a number of servers which implement
081       * draft-good-ldap-changelog.
082       */
083      public static final String ATTR_FIRST_CHANGE_NUMBER = "firstChangeNumber";
084    
085    
086    
087      /**
088       * The name of the attribute that may contain the change number for the last
089       * entry in the LDAP changelog, if available.  This is not defined in any
090       * public specification, but is provided by a number of servers which
091       * implement draft-good-ldap-changelog.
092       */
093      public static final String ATTR_LAST_CHANGE_NUMBER = "lastChangeNumber";
094    
095    
096    
097      /**
098       * The name of the attribute that may contain the change number for the last
099       * entry purged from the LDAP changelog, if available.  This is not defined in
100       * any public specification, but is provided by a number of servers which
101       * implement draft-good-ldap-changelog.
102       */
103      public static final String ATTR_LAST_PURGED_CHANGE_NUMBER =
104           "lastPurgedChangeNumber";
105    
106    
107    
108      /**
109       * The name of the attribute that includes the DNs of the public naming
110       * contexts defined in the server, as defined in RFC 4512 section 5.1.
111       */
112      public static final String ATTR_NAMING_CONTEXT = "namingContexts";
113    
114    
115    
116      /**
117       * The name of the attribute that specifies the DN of the subschema subentry
118       * that serves the server root DSE, as defined in RFC 4512 section 4.2.
119       */
120      public static final String ATTR_SUBSCHEMA_SUBENTRY = "subschemaSubentry";
121    
122    
123    
124      /**
125       * The name of the attribute that includes the names of the supported
126       * authentication password storage schemes, as defined in RFC 3112.
127       */
128      public static final String ATTR_SUPPORTED_AUTH_PASSWORD_STORAGE_SCHEME =
129           "supportedAuthPasswordSchemes";
130    
131    
132    
133      /**
134       * The name of the attribute that includes the OIDs of the request controls
135       * supported by the server, as defined in RFC 4512 section 5.1.
136       */
137      public static final String ATTR_SUPPORTED_CONTROL = "supportedControl";
138    
139    
140    
141      /**
142       * The name of the attribute that includes the OIDs of the extended operations
143       * supported by the server, as defined in RFC 4512 section 5.1.
144       */
145      public static final String ATTR_SUPPORTED_EXTENDED_OPERATION =
146           "supportedExtension";
147    
148    
149    
150      /**
151       * The name of the attribute that includes the OIDs of the features supported
152       * by the server, as defined in RFC 4512 section 5.1.
153       */
154      public static final String ATTR_SUPPORTED_FEATURE =
155           "supportedFeatures";
156    
157    
158    
159      /**
160       * The name of the attribute that includes the OIDs of the LDAP protocol
161       * versions supported by the server, as defined in RFC 4512 section 5.1.
162       */
163      public static final String ATTR_SUPPORTED_LDAP_VERSION =
164           "supportedLDAPVersion";
165    
166    
167    
168      /**
169       * The name of the attribute that includes the names of the SASL mechanisms
170       * supported by the server, as defined in RFC 4512 section 5.1.
171       */
172      public static final String ATTR_SUPPORTED_SASL_MECHANISM =
173           "supportedSASLMechanisms";
174    
175    
176    
177      /**
178       * The name of the attribute that includes the name of the server vendor,
179       * as defined in RFC 3045.
180       */
181      public static final String ATTR_VENDOR_NAME = "vendorName";
182    
183    
184    
185      /**
186       * The name of the attribute that includes the server version, as defined in
187       * RFC 3045.
188       */
189      public static final String ATTR_VENDOR_VERSION = "vendorVersion";
190    
191    
192    
193      /**
194       * The set of request attributes to use when attempting to retrieve the server
195       * root DSE.  It will attempt to retrieve all operational attributes if the
196       * server supports that capability, but will also attempt to retrieve specific
197       * attributes by name in case it does not.
198       */
199      protected static final String[] REQUEST_ATTRS =
200      {
201        "*",
202        "+",
203        ATTR_ALT_SERVER,
204        ATTR_CHANGELOG_DN,
205        ATTR_FIRST_CHANGE_NUMBER,
206        ATTR_LAST_CHANGE_NUMBER,
207        ATTR_LAST_PURGED_CHANGE_NUMBER,
208        ATTR_NAMING_CONTEXT,
209        ATTR_SUBSCHEMA_SUBENTRY,
210        ATTR_SUPPORTED_AUTH_PASSWORD_STORAGE_SCHEME,
211        ATTR_SUPPORTED_CONTROL,
212        ATTR_SUPPORTED_EXTENDED_OPERATION,
213        ATTR_SUPPORTED_FEATURE,
214        ATTR_SUPPORTED_LDAP_VERSION,
215        ATTR_SUPPORTED_SASL_MECHANISM,
216        ATTR_VENDOR_NAME,
217        ATTR_VENDOR_VERSION,
218      };
219    
220    
221    
222      /**
223       * The serial version UID for this serializable class.
224       */
225      private static final long serialVersionUID = -1678182563511570981L;
226    
227    
228    
229      /**
230       * Creates a new root DSE object from the information in the provided entry.
231       *
232       * @param  rootDSEEntry  The entry to use to create this root DSE object.  It
233       *                       must not be {@code null}.
234       */
235      public RootDSE(final Entry rootDSEEntry)
236      {
237        super(rootDSEEntry);
238      }
239    
240    
241    
242      /**
243       * Retrieves the directory server root DSE using the provided connection.
244       *
245       * @param  connection  The connection to use to retrieve the server root DSE.
246       *
247       * @return  The directory server root DSE, or {@code null} if it is not
248       *          available (e.g., the client does not have permission to read the
249       *          entry).
250       *
251       * @throws  LDAPException  If a problem occurs while attempting to retrieve
252       *                         the server root DSE.
253       */
254      public static RootDSE getRootDSE(final LDAPInterface connection)
255             throws LDAPException
256      {
257        final Entry rootDSEEntry = connection.getEntry("", REQUEST_ATTRS);
258        if (rootDSEEntry == null)
259        {
260          return null;
261        }
262    
263        return new RootDSE(rootDSEEntry);
264      }
265    
266    
267    
268      /**
269       * Retrieves a set of URIs for alternate servers that may be contacted if
270       * the current server becomes unavailable.
271       *
272       * @return  A set of URIs for alternate servers that may be contacted if the
273       *          current server becomes available, or {@code null} if the server
274       *          does not publish that information.
275       */
276      public final String[] getAltServerURIs()
277      {
278        return getAttributeValues(ATTR_ALT_SERVER);
279      }
280    
281    
282    
283      /**
284       * Retrieves the DN of the base entry for the directory server changelog
285       * information, if available.
286       *
287       * @return  The DN of the base entry for the directory server changelog
288       *          information, or {@code null} if the server does not publish that
289       *          information or no changelog is available.
290       */
291      public final String getChangelogDN()
292      {
293        return getAttributeValue(ATTR_CHANGELOG_DN);
294      }
295    
296    
297    
298      /**
299       * Retrieves the change number for the first entry contained in the LDAP
300       * changelog, if available.
301       *
302       * @return  The change number for the first entry contained in the LDAP
303       *          changelog, if available.
304       */
305      public final Long getFirstChangeNumber()
306      {
307        return getAttributeValueAsLong(ATTR_FIRST_CHANGE_NUMBER);
308      }
309    
310    
311    
312      /**
313       * Retrieves the change number for the last entry contained in the LDAP
314       * changelog, if available.
315       *
316       * @return  The change number for the last entry contained in the LDAP
317       *          changelog, if available.
318       */
319      public final Long getLastChangeNumber()
320      {
321        return getAttributeValueAsLong(ATTR_LAST_CHANGE_NUMBER);
322      }
323    
324    
325    
326      /**
327       * Retrieves the change number for the last entry purged from the LDAP
328       * changelog, if available.
329       *
330       * @return  The change number for the last entry purged from the LDAP
331       *          changelog, if available.
332       */
333      public final Long getLastPurgedChangeNumber()
334      {
335        return getAttributeValueAsLong(ATTR_LAST_PURGED_CHANGE_NUMBER);
336      }
337    
338    
339    
340      /**
341       * Retrieves the DNs of the naming contexts provided by the directory server.
342       *
343       * @return  The DNs of the naming contexts provided by the directory server,
344       *          or {@code null} if the server does not publish that information.
345       */
346      public final String[] getNamingContextDNs()
347      {
348        return getAttributeValues(ATTR_NAMING_CONTEXT);
349      }
350    
351    
352    
353      /**
354       * Retrieves the DN of the subschema subentry that serves the directory server
355       * root DSE.
356       *
357       * @return  The DN of the subschema subentry that serves the directory server
358       *          root DSE, or {@code null} if the server does not publish that
359       *          information.
360       */
361      public final String getSubschemaSubentryDN()
362      {
363        return getAttributeValue(ATTR_SUBSCHEMA_SUBENTRY);
364      }
365    
366    
367    
368      /**
369       * Retrieves the names of the authentication password storage schemes
370       * supported by the server.
371       *
372       * @return  The names of the authentication password storage schemes supported
373       *          by the server, or {@code null} if the server does not publish
374       *          that information.
375       */
376      public final String[] getSupportedAuthPasswordSchemeNames()
377      {
378        return getAttributeValues(ATTR_SUPPORTED_AUTH_PASSWORD_STORAGE_SCHEME);
379      }
380    
381    
382    
383      /**
384       * Indicates whether the directory server indicates that it supports the
385       * specified authentication password storage scheme.
386       *
387       * @param  scheme  The name of the authentication password storage scheme for
388       *                 which to make the determination.  It must not be
389       *                 {@code null}.
390       *
391       * @return  {@code true} if the directory server indicates that it supports
392       *          the specified authentication password storage scheme, or
393       *          {@code false} if it does not.
394       */
395      public final boolean supportsAuthPasswordScheme(final String scheme)
396      {
397        return hasAttributeValue(ATTR_SUPPORTED_AUTH_PASSWORD_STORAGE_SCHEME,
398                                 scheme);
399      }
400    
401    
402    
403      /**
404       * Retrieves the OIDs of the supported request controls advertised by the
405       * server root DSE.
406       *
407       * @return  The OIDs of the supported request controls advertised by the
408       *          server root DSE, or {@code null} if the server does not publish
409       *          that information.
410       */
411      public final String[] getSupportedControlOIDs()
412      {
413        return getAttributeValues(ATTR_SUPPORTED_CONTROL);
414      }
415    
416    
417    
418      /**
419       * Indicates whether the directory server indicates that it supports the
420       * request control with the provided OID.
421       *
422       * @param  controlOID  The OID of the control for which to make the
423       *                     determination.  It must not be {@code null}.
424       *
425       * @return  {@code true} if the server indicates that it supports the request
426       *          control with the specified OID, or {@code false} if it does not.
427       */
428      public final boolean supportsControl(final String controlOID)
429      {
430        return hasAttributeValue(ATTR_SUPPORTED_CONTROL, controlOID);
431      }
432    
433    
434    
435      /**
436       * Retrieves the OIDs of the supported extended operations advertised by the
437       * server root DSE.
438       *
439       * @return  The OIDs of the supported extended operations advertised by the
440       *          server root DSE, or {@code null} if the server does not publish
441       *          that information.
442       */
443      public final String[] getSupportedExtendedOperationOIDs()
444      {
445        return getAttributeValues(ATTR_SUPPORTED_EXTENDED_OPERATION);
446      }
447    
448    
449    
450      /**
451       * Indicates whether the directory server indicates that it supports the
452       * extended operation with the provided OID.
453       *
454       * @param  extendedOperationOID  The OID of the extended operation for which
455       *                               to make the determination.  It must not be
456       *                               {@code null}.
457       *
458       * @return  {@code true} if the server indicates that it supports the extended
459       *          operation with the specified OID, or {@code false} if it does not.
460       */
461      public final boolean supportsExtendedOperation(
462                                final String extendedOperationOID)
463      {
464        return hasAttributeValue(ATTR_SUPPORTED_EXTENDED_OPERATION,
465                                 extendedOperationOID);
466      }
467    
468    
469    
470      /**
471       * Retrieves the OIDs of the supported features advertised by the server root
472       * DSE.
473       *
474       * @return  The OIDs of the supported features advertised by the server root
475       *          DSE, or {@code null} if the server does not publish that
476       *          information.
477       */
478      public final String[] getSupportedFeatureOIDs()
479      {
480        return getAttributeValues(ATTR_SUPPORTED_FEATURE);
481      }
482    
483    
484    
485      /**
486       * Indicates whether the directory server indicates that it supports the
487       * extended operation with the provided OID.
488       *
489       * @param  featureOID  The OID of the feature for which to make the
490       *                     determination.  It must not be {@code null}.
491       *
492       * @return  {@code true} if the server indicates that it supports the feature
493       *          with the specified OID, or {@code false} if it does not.
494       */
495      public final boolean supportsFeature(final String featureOID)
496      {
497        return hasAttributeValue(ATTR_SUPPORTED_FEATURE, featureOID);
498      }
499    
500    
501    
502      /**
503       * Retrieves the supported LDAP protocol versions advertised by the server
504       * root DSE.
505       *
506       * @return  The supported LDAP protocol versions advertised by the server
507       *          root DSE, or {@code null} if the server does not publish that
508       *          information.
509       */
510      public final int[] getSupportedLDAPVersions()
511      {
512        final String[] versionStrs =
513             getAttributeValues(ATTR_SUPPORTED_LDAP_VERSION);
514        if (versionStrs == null)
515        {
516          return null;
517        }
518    
519        final int[] versions = new int[versionStrs.length];
520        for (int i=0; i < versionStrs.length; i++)
521        {
522          try
523          {
524            versions[i] = Integer.parseInt(versionStrs[i]);
525          }
526          catch (final Exception e)
527          {
528            debugException(e);
529            // We couldn't parse the value as an integer.
530            return null;
531          }
532        }
533    
534        return versions;
535      }
536    
537    
538    
539      /**
540       * Indicates whether the directory server indicates that it supports the
541       * provided LDAP protocol version.
542       *
543       * @param  ldapVersion  The LDAP protocol version for which to make the
544       *                      determination.
545       *
546       * @return  {@code true} if the server indicates that it supports the
547       *          specified LDAP protocol version, or {@code false} if it does not.
548       */
549      public final boolean supportsLDAPVersion(final int ldapVersion)
550      {
551        return hasAttributeValue(ATTR_SUPPORTED_LDAP_VERSION,
552                                 String.valueOf(ldapVersion));
553      }
554    
555    
556    
557      /**
558       * Retrieves the names of the supported SASL mechanisms advertised by the
559       * server root DSE.
560       *
561       * @return  The names of the supported SASL mechanisms advertised by the
562       *          server root DSE, or {@code null} if the server does not publish
563       *          that information.
564       */
565      public final String[] getSupportedSASLMechanismNames()
566      {
567        return getAttributeValues(ATTR_SUPPORTED_SASL_MECHANISM);
568      }
569    
570    
571    
572      /**
573       * Indicates whether the directory server indicates that it supports the
574       * specified SASL mechanism.
575       *
576       * @param  mechanismName  The name of the SASL mechanism for which to make the
577       *                        determination.  It must not be {@code null}.
578       *
579       * @return  {@code true} if the server indicates that it supports the
580       *          specified SASL mechanism, or {@code false} if it does not.
581       */
582      public final boolean supportsSASLMechanism(final String mechanismName)
583      {
584        return hasAttributeValue(ATTR_SUPPORTED_SASL_MECHANISM, mechanismName);
585      }
586    
587    
588    
589      /**
590       * Retrieves the name of the directory server vendor, if available.
591       *
592       * @return  The name of the directory server vendor, or {@code null} if the
593       *          server does not publish that information.
594       */
595      public final String getVendorName()
596      {
597        return getAttributeValue(ATTR_VENDOR_NAME);
598      }
599    
600    
601    
602      /**
603       * Retrieves the directory server version string, if available.
604       *
605       * @return  The directory server version string, or {@code null} if the server
606       *          does not publish that information.
607       */
608      public final String getVendorVersion()
609      {
610        return getAttributeValue(ATTR_VENDOR_VERSION);
611      }
612    }