001 /*
002 * Copyright 2007-2016 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2008-2016 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 }