001 /*
002 * Copyright 2007-2014 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2008-2014 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 final 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 private 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 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 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 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 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 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 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 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 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 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 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 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 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 boolean supportsExtendedOperation(final String extendedOperationOID)
462 {
463 return hasAttributeValue(ATTR_SUPPORTED_EXTENDED_OPERATION,
464 extendedOperationOID);
465 }
466
467
468
469 /**
470 * Retrieves the OIDs of the supported features advertised by the server root
471 * DSE.
472 *
473 * @return The OIDs of the supported features advertised by the server root
474 * DSE, or {@code null} if the server does not publish that
475 * information.
476 */
477 public String[] getSupportedFeatureOIDs()
478 {
479 return getAttributeValues(ATTR_SUPPORTED_FEATURE);
480 }
481
482
483
484 /**
485 * Indicates whether the directory server indicates that it supports the
486 * extended operation with the provided OID.
487 *
488 * @param featureOID The OID of the feature for which to make the
489 * determination. It must not be {@code null}.
490 *
491 * @return {@code true} if the server indicates that it supports the feature
492 * with the specified OID, or {@code false} if it does not.
493 */
494 public boolean supportsFeature(final String featureOID)
495 {
496 return hasAttributeValue(ATTR_SUPPORTED_FEATURE, featureOID);
497 }
498
499
500
501 /**
502 * Retrieves the supported LDAP protocol versions advertised by the server
503 * root DSE.
504 *
505 * @return The supported LDAP protocol versions advertised by the server
506 * root DSE, or {@code null} if the server does not publish that
507 * information.
508 */
509 public int[] getSupportedLDAPVersions()
510 {
511 final String[] versionStrs =
512 getAttributeValues(ATTR_SUPPORTED_LDAP_VERSION);
513 if (versionStrs == null)
514 {
515 return null;
516 }
517
518 final int[] versions = new int[versionStrs.length];
519 for (int i=0; i < versionStrs.length; i++)
520 {
521 try
522 {
523 versions[i] = Integer.parseInt(versionStrs[i]);
524 }
525 catch (final Exception e)
526 {
527 debugException(e);
528 // We couldn't parse the value as an integer.
529 return null;
530 }
531 }
532
533 return versions;
534 }
535
536
537
538 /**
539 * Indicates whether the directory server indicates that it supports the
540 * provided LDAP protocol version.
541 *
542 * @param ldapVersion The LDAP protocol version for which to make the
543 * determination.
544 *
545 * @return {@code true} if the server indicates that it supports the
546 * specified LDAP protocol version, or {@code false} if it does not.
547 */
548 public boolean supportsLDAPVersion(final int ldapVersion)
549 {
550 return hasAttributeValue(ATTR_SUPPORTED_LDAP_VERSION,
551 String.valueOf(ldapVersion));
552 }
553
554
555
556 /**
557 * Retrieves the names of the supported SASL mechanisms advertised by the
558 * server root DSE.
559 *
560 * @return The names of the supported SASL mechanisms advertised by the
561 * server root DSE, or {@code null} if the server does not publish
562 * that information.
563 */
564 public String[] getSupportedSASLMechanismNames()
565 {
566 return getAttributeValues(ATTR_SUPPORTED_SASL_MECHANISM);
567 }
568
569
570
571 /**
572 * Indicates whether the directory server indicates that it supports the
573 * specified SASL mechanism.
574 *
575 * @param mechanismName The name of the SASL mechanism for which to make the
576 * determination. It must not be {@code null}.
577 *
578 * @return {@code true} if the server indicates that it supports the
579 * specified SASL mechanism, or {@code false} if it does not.
580 */
581 public boolean supportsSASLMechanism(final String mechanismName)
582 {
583 return hasAttributeValue(ATTR_SUPPORTED_SASL_MECHANISM, mechanismName);
584 }
585
586
587
588 /**
589 * Retrieves the name of the directory server vendor, if available.
590 *
591 * @return The name of the directory server vendor, or {@code null} if the
592 * server does not publish that information.
593 */
594 public String getVendorName()
595 {
596 return getAttributeValue(ATTR_VENDOR_NAME);
597 }
598
599
600
601 /**
602 * Retrieves the directory server version string, if available.
603 *
604 * @return The directory server version string, or {@code null} if the server
605 * does not publish that information.
606 */
607 public String getVendorVersion()
608 {
609 return getAttributeValue(ATTR_VENDOR_VERSION);
610 }
611 }