зеркало из https://github.com/mozilla/pjs.git
375 строки
14 KiB
Plaintext
375 строки
14 KiB
Plaintext
<!--
|
|
|
|
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
|
Portions copyright 1999 Netscape Communications Corporation. All
|
|
Rights Reserved.
|
|
|
|
The contents of this document are subject to the terms of the
|
|
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
|
version (the "License"). You may not use this document except in
|
|
compliance with the License.
|
|
|
|
See the License for the specific language governing
|
|
permissions and limitations under the License. You can obtain
|
|
a copy of the License at
|
|
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
|
|
|
-->
|
|
<chapter id="csdk-server-info"><title>Getting Server Information With &DirectorySDKForC;
|
|
</title>
|
|
<indexterm>
|
|
<primary>C SDK</primary>
|
|
<secondary>getting server information</secondary>
|
|
</indexterm><highlights>
|
|
<para>This chapter explains how to access and modify information about your
|
|
LDAP server over the LDAP protocol.</para>
|
|
<itemizedlist>
|
|
<para>This chapter covers the following topics:</para>
|
|
<listitem><para><olink targetptr="bdahu">Reading DSEs With Directory SDK for
|
|
C</olink></para></listitem>
|
|
<listitem><para><olink targetptr="bdahw">Determining LDAP v3 Support With
|
|
Directory SDK for C</olink></para></listitem>
|
|
<listitem><para><olink targetptr="bdahx">Getting Schema Information With Directory
|
|
SDK for C</olink></para></listitem>
|
|
</itemizedlist>
|
|
</highlights>
|
|
<sect1 id="bdahu"><title>Reading DSEs With &DirectorySDKForC;</title>
|
|
<indexterm>
|
|
<primary>C SDK</primary>
|
|
<secondary>getting server information</secondary>
|
|
<tertiary>DSE</tertiary>
|
|
</indexterm>
|
|
<para>A DSA-specific entry, <firstterm>DSE</firstterm>, contains information
|
|
specific to the server. In a directory tree, the root of the tree is the root
|
|
DSE. The root DSE is not part of any naming context. For example, the root
|
|
DSE is superior to <literal>dc=example,dc=com</literal> in the directory tree.</para>
|
|
<para>The root DSE is specified as part of LDAP v3. Note that LDAP v2 servers
|
|
do not necessarily have a root DSE.</para>
|
|
<itemizedlist>
|
|
<para>The root DSE can contain the following information:</para>
|
|
<listitem><para>The naming contexts of this server such as, <literal>dc=example,dc=com
|
|
</literal></para></listitem>
|
|
<listitem><para>URLs of alternate servers to contact if this server is unavailable
|
|
</para></listitem>
|
|
<listitem><para>The versions of LDAP supported by this server, version 2 or
|
|
version 3</para></listitem>
|
|
<listitem><para>The LDAP v3 controls supported by the server</para><para>See <olink targetptr="csdk-controls">Chapter 16, LDAP Controls With Directory SDK
|
|
for C</olink> for details.</para></listitem>
|
|
<listitem><para>The SASL mechanisms supported by the server</para><para>See <olink targetptr="csdk-sasl">Chapter 17, SASL Authentication With Directory
|
|
SDK for C</olink> for details.</para></listitem>
|
|
<listitem><para>The LDAP v3 extended operations supported by the server</para>
|
|
<para>See <olink targetptr="csdk-extop">Chapter 18, Extended Operations
|
|
With Directory SDK for C</olink> for details.</para></listitem>
|
|
</itemizedlist>
|
|
<para>The following lists root DSE attributes and explains the meaning of
|
|
their values.</para>
|
|
<table frame="topbot" pgwide="1" id="server-root-dse-info"><title>Root DSE
|
|
Attributes and Descriptions of Their Values</title>
|
|
<tgroup cols="2"><colspec colnum="1" colwidth="21.64*"><colspec colnum="2"
|
|
colwidth="78.36*">
|
|
<thead>
|
|
<row>
|
|
<entry>
|
|
<para>Attribute Name</para></entry>
|
|
<entry>
|
|
<para>Description of Values</para></entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>
|
|
<para><literal>namingContexts</literal></para></entry>
|
|
<entry>
|
|
<para>The naming contexts supported by this server, such <literal>dc=example,dc=com
|
|
</literal>.</para></entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<para><literal>altServer</literal></para></entry>
|
|
<entry>
|
|
<para>LDAP URLs that identify other servers to contact if this server is unavailable.
|
|
</para></entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<para><literal>supportedExtension</literal></para></entry>
|
|
<entry>
|
|
<para>The object identifiers (OIDs) of the LDAP v3 extended operations supported
|
|
by this server.</para>
|
|
<para>If this attribute is not in the root DSE, the server does not support
|
|
any extended operations.</para></entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<para><literal>supportedControl</literal></para></entry>
|
|
<entry>
|
|
<para>The OIDs of the LDAP v3 controls supported by this server.</para>
|
|
<para>If this attribute is not in the root DSE, the server does not support
|
|
any LDAP v3 controls.</para></entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<para><literal>supportedSASLMechanisms</literal></para></entry>
|
|
<entry>
|
|
<para>The names of the SASL mechanisms supported by the server.</para>
|
|
<para>If this attribute is not in the root DSE, the server does not support
|
|
any SASL mechanisms.</para></entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<para><literal>supportedLDAPVersion</literal></para></entry>
|
|
<entry>
|
|
<para>The value of this attribute is the version of LDAP supported by this
|
|
server, such as <literal>2</literal> or <literal>3</literal>.</para></entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<task id="bdahv"><title>To Get the Root DSE</title>
|
|
<procedure>
|
|
<step><para>Initialize an LDAP session by calling the <function>ldap_init</function> or <function>
|
|
prldap_init</function> function.</para></step>
|
|
<step><para>Turn off automatic referral handling by calling the <function>ldap_set_option
|
|
</function> function and setting the <literal>LDAP_OPT_REFERRALS</literal> option
|
|
to <literal>LDAP_OPT_OFF</literal>.</para></step>
|
|
<step><para>Search the directory with the following criteria:</para>
|
|
<substeps>
|
|
<step><para>Set the search scope to a <literal>base</literal> search.</para>
|
|
</step>
|
|
<step><para>Specify an empty string for the base DN.</para></step>
|
|
<step><para>Use the search filter <literal>(objectclass=*)</literal>.</para>
|
|
</step></substeps>
|
|
</step>
|
|
<step><para>Check the results of the search.</para><para>If the server returns
|
|
a result code, such as <errorcode>LDAP_OPERATIONS_ERROR</errorcode>, <errorcode>LDAP_PROTOCOL_ERROR
|
|
</errorcode>, <errorcode>LDAP_REFERRAL</errorcode>, or <errorcode>LDAP_NO_SUCH_OBJECT
|
|
</errorcode>, the LDAP server probably does not support LDAP v3.</para><para>The
|
|
following example gets the root DSE for a server and prints the values of
|
|
the root DSE attributes. The function assumes that you are passing in a valid
|
|
connection handle, an <structname>LDAP</structname> structure, you have created
|
|
by calling <function>ldap_init</function> or <function>prldap_init</function>.
|
|
The function returns <literal>0</literal> if successful or <literal>1</literal> if
|
|
an error occurred.</para></step>
|
|
</procedure>
|
|
<example id="server-dse-attr-example">
|
|
<title>Getting the Root DSE and Printing its Attribute Values</title>
|
|
<programlisting>int printdse( LDAP *ld )
|
|
{
|
|
int rc, i;
|
|
char *matched_msg = NULL, *error_msg = NULL;
|
|
LDAPMessage *result, *e;
|
|
BerElement *ber;
|
|
char *a;
|
|
char **vals;
|
|
char *attrs[3];
|
|
/* Verify that the connection handle is valid. */
|
|
if ( ld == NULL ) {
|
|
fprintf( stderr, "Invalid connection handle.\n" );
|
|
return( 1 );
|
|
}
|
|
/* Set automatic referral processing off. */
|
|
if ( ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF ) != 0 ) {
|
|
rc = ldap_get_lderrno( ld, NULL, NULL );
|
|
fprintf( stderr, "ldap_set_option: %s\n", ldap_err2string( rc ) );
|
|
return( 1 );
|
|
}
|
|
/* Search for the root DSE. */
|
|
attrs[0] = "supportedControl";
|
|
attrs[1] = "supportedExtension";
|
|
attrs[2] = NULL;
|
|
rc = ldap_search_ext_s( ld, "", LDAP_SCOPE_BASE, "(objectclass=*)",
|
|
attrs, 0, NULL, NULL, NULL, 0, &result );
|
|
/* Check the search results. */
|
|
switch( rc ) {
|
|
/* If successful, the root DSE was found. */
|
|
case LDAP_SUCCESS:
|
|
break;
|
|
/* If the root DSE was not found, the server does not comply
|
|
with the LDAPv3 protocol. */
|
|
case LDAP_PARTIAL_RESULTS:
|
|
case LDAP_NO_SUCH_OBJECT:
|
|
case LDAP_OPERATIONS_ERROR:
|
|
case LDAP_PROTOCOL_ERROR:
|
|
printf( "LDAP server returned result code %d (%s).\n"
|
|
"This server does not support the LDAPv3 protocol.\n",
|
|
rc, ldap_err2string( rc ) );
|
|
return( 1 );
|
|
/* If any other value is returned, an error must have occurred. */
|
|
default:
|
|
fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) );
|
|
return( 1 );
|
|
}
|
|
/* Since only one entry should have matched, get that entry. */
|
|
e = ldap_first_entry( ld, result );
|
|
if ( e == NULL ) {
|
|
fprintf( stderr, "ldap_search_ext_s: Unable to get root DSE.\n");
|
|
ldap_memfree( result );
|
|
return( 1 );
|
|
}
|
|
|
|
/* Iterate through each attribute in the entry. */
|
|
for ( a = ldap_first_attribute( ld, e, &ber );
|
|
a != NULL; a = ldap_next_attribute( ld, e, ber ) ) {
|
|
|
|
/* Print each value of the attribute. */
|
|
if ((vals = ldap_get_values( ld, e, a)) != NULL ) {
|
|
for ( i = 0; vals[i] != NULL; i++ ) {
|
|
printf( "%s: %s\n", a, vals[i] );
|
|
}
|
|
|
|
/* Free memory allocated by ldap_get_values(). */
|
|
ldap_value_free( vals );
|
|
}
|
|
|
|
/* Free memory allocated by ldap_first_attribute(). */
|
|
ldap_memfree( a );
|
|
}
|
|
|
|
/* Free memory allocated by ldap_first_attribute(). */
|
|
if ( ber != NULL ) {
|
|
ber_free( ber, 0 );
|
|
}
|
|
|
|
printf( "\n" );
|
|
/* Free memory allocated by ldap_search_ext_s(). */
|
|
ldap_msgfree( result );
|
|
ldap_unbind( ld );
|
|
return( 0 );
|
|
}</programlisting>
|
|
</example>
|
|
</task>
|
|
</sect1>
|
|
<sect1 id="bdahw"><title>Determining LDAP v3 Support With &DirectorySDKForC;</title>
|
|
<indexterm>
|
|
<primary>C SDK</primary>
|
|
<secondary>getting server information</secondary>
|
|
<tertiary>LDAP v3 support</tertiary>
|
|
</indexterm>
|
|
<para>You can determine what version an LDAP server supports by getting the <literal>
|
|
supportedLDAPVersion</literal> attribute from the root DSE. This attribute
|
|
could contain the value <literal>2</literal> or <literal>3</literal>.</para>
|
|
<para>You do not need to authenticate or bind before searching the directory.
|
|
Unlike LDAP v2, LDAP v3 states that clients do not need to bind to the server
|
|
before performing LDAP operations.</para>
|
|
<para>The following example connects to an LDAP server. The example code then
|
|
determines whether the server supports LDAP v3.</para>
|
|
<example id="server-ldapv3-support-example"><title>Determining the Supported
|
|
LDAP Version</title>
|
|
<programlisting>/* Function for determining if the LDAP server supports LDAPv3.
|
|
This function returns 1 if the server supports LDAPv3 or
|
|
0 if the server does not support LDAPv3.
|
|
*/
|
|
int
|
|
check_version( char *hostname, int portnum )
|
|
{
|
|
LDAP *ld;
|
|
int i, rc, v3supported = 0;
|
|
LDAPMessage *result, *e;
|
|
BerElement *ber;
|
|
LDAPControl **serverctrls = NULL, **clntctrls = NULL;
|
|
char *a, *dn;
|
|
char **vals;
|
|
char *attrs[2];
|
|
char *filter = "(objectClass=*)";
|
|
/* Check arguments */
|
|
if ( !hostname || !hostname[0] || !portnum ) {
|
|
printf( "Error: hostname or port number not specified\n" );
|
|
return( -1 );
|
|
}
|
|
/* Get a handle to an LDAP connection. Use prldap_init() for IPv6. */
|
|
if ( (ld = ldap_init( hostname, portnum )) == NULL ) {
|
|
perror( "ldap_init" );
|
|
return( -1 );
|
|
}
|
|
/* Set automatic referral processing off. */
|
|
if ( ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF) !=
|
|
LDAP_SUCCESS) {
|
|
ldap_perror( ld, "ldap_set_option" );
|
|
return( -1 );
|
|
}
|
|
/* Search for the root DSE and get the supportedLDAPVersion attribute. */
|
|
attrs[0] = "supportedLDAPVersion";
|
|
attrs[1] = NULL;
|
|
rc = ldap_search_ext_s( ld, "", LDAP_SCOPE_BASE, filter, attrs, 0,
|
|
serverctrls, clntctrls, NULL, 0, &result );
|
|
/* Check the search results. */
|
|
switch( rc ) {
|
|
/* If successful, the root DSE was found. */
|
|
case LDAP_SUCCESS:
|
|
break;
|
|
/* If the root DSE was not found, the server does not comply
|
|
with the LDAPv3 protocol. */
|
|
case LDAP_PARTIAL_RESULTS:
|
|
case LDAP_NO_SUCH_OBJECT:
|
|
case LDAP_OPERATIONS_ERROR:
|
|
case LDAP_PROTOCOL_ERROR:
|
|
ldap_perror( ld, "ldap_search_ext_s" );
|
|
return( 0 );
|
|
break;
|
|
/* If an different result code is returned, an error may have
|
|
occurred (for example, the server may be down. */
|
|
default:
|
|
ldap_perror( ld, "ldap_search_ext_s" );
|
|
return( -1 );
|
|
break;
|
|
}
|
|
/* Get the values of the supportedLDAPVersion attribute in the entry. */
|
|
if (( e = ldap_first_entry( ld, result )) != NULL &&
|
|
( a = ldap_first_attribute( ld, e, &ber )) != NULL &&
|
|
(vals = ldap_get_values( ld, e, a)) != NULL ) {
|
|
for ( i = 0; vals[i] != NULL; i++ ) {
|
|
if ( !strcmp( "3", vals[i] ) ) {
|
|
v3supported = 1;
|
|
break;
|
|
}
|
|
}
|
|
/* Free any memory allocated. */
|
|
ldap_value_free( vals );
|
|
ldap_memfree( a );
|
|
if ( ber != NULL ) {
|
|
ber_free( ber, 0 );
|
|
}
|
|
}
|
|
/* Free memory allocated by ldap_search_ext_s(). */
|
|
ldap_msgfree( result );
|
|
/* Free the ld structure. */
|
|
ldap_unbind_s( ld );
|
|
/* Return a value indicating whether or not LDAPv3 is supported. */
|
|
return( v3supported );
|
|
}
|
|
...</programlisting>
|
|
</example>
|
|
</sect1>
|
|
<sect1 id="bdahx"><title>Getting Schema Information With &DirectorySDKForC;</title>
|
|
<indexterm>
|
|
<primary>C SDK</primary>
|
|
<secondary>getting server information</secondary>
|
|
<tertiary>schema</tertiary>
|
|
</indexterm>
|
|
<para>In LDAP v3, an entry can specify the schema that defines the object
|
|
classes, attributes, and matching rules used by the directory. This entry
|
|
is called the <literal>subschema</literal> entry. To find the DN of the <literal>
|
|
subschema</literal> entry, get the <literal>subschemaSubentry</literal> operational
|
|
attribute from the root DSE or any entry.</para>
|
|
<itemizedlist>
|
|
<para>The <literal>subschema</literal> entry can have the following attributes:</para>
|
|
<listitem><para><literal>objectClasses</literal> specifies the object class
|
|
definitions in the schema. Each value of this attribute is an object class
|
|
that is known to the server.</para></listitem>
|
|
<listitem><para><literal>attributeTypes</literal> specifies the attribute
|
|
type definitions in the schema. Each value of this attribute is an attribute
|
|
type that is known to the server.</para></listitem>
|
|
<listitem><para><literal>matchingRules</literal> specifies the matching rule
|
|
definitions in the schema. Each value of this attribute is a matching rule
|
|
that is known to the server.</para></listitem>
|
|
<listitem><para><literal>matchingRuleUse</literal> specifies the use of a
|
|
matching rule in the schema. This rule specifies the attributes that can be
|
|
used with this extensible matching rule. Each value of this attribute is a
|
|
matching rule use description.</para></listitem>
|
|
</itemizedlist>
|
|
<para>For information about the format of the attribute values, see <ulink
|
|
url="http://www.ietf.org/rfc/rfc4517.txt" type="text_url"><?Pub Caret>RFC
|
|
4517</ulink>, <citetitle>Lightweight Directory Access Protocol (v3): Attribute
|
|
Syntax Definitions</citetitle>.</para></sect1>
|
|
</chapter>
|