1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved.
3*0Sstevel@tonic-gate * Use is subject to license terms.
4*0Sstevel@tonic-gate */
5*0Sstevel@tonic-gate
6*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
7*0Sstevel@tonic-gate
8*0Sstevel@tonic-gate /*
9*0Sstevel@tonic-gate * The contents of this file are subject to the Netscape Public
10*0Sstevel@tonic-gate * License Version 1.1 (the "License"); you may not use this file
11*0Sstevel@tonic-gate * except in compliance with the License. You may obtain a copy of
12*0Sstevel@tonic-gate * the License at http://www.mozilla.org/NPL/
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * Software distributed under the License is distributed on an "AS
15*0Sstevel@tonic-gate * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
16*0Sstevel@tonic-gate * implied. See the License for the specific language governing
17*0Sstevel@tonic-gate * rights and limitations under the License.
18*0Sstevel@tonic-gate *
19*0Sstevel@tonic-gate * The Original Code is Mozilla Communicator client code, released
20*0Sstevel@tonic-gate * March 31, 1998.
21*0Sstevel@tonic-gate *
22*0Sstevel@tonic-gate * The Initial Developer of the Original Code is Netscape
23*0Sstevel@tonic-gate * Communications Corporation. Portions created by Netscape are
24*0Sstevel@tonic-gate * Copyright (C) 1998-1999 Netscape Communications Corporation. All
25*0Sstevel@tonic-gate * Rights Reserved.
26*0Sstevel@tonic-gate *
27*0Sstevel@tonic-gate * Contributor(s):
28*0Sstevel@tonic-gate */
29*0Sstevel@tonic-gate #include "ldap-int.h"
30*0Sstevel@tonic-gate
31*0Sstevel@tonic-gate #define LDAP_GET_BITOPT( ld, bit ) \
32*0Sstevel@tonic-gate ((ld)->ld_options & bit ) != 0 ? 1 : 0
33*0Sstevel@tonic-gate
34*0Sstevel@tonic-gate static int nsldapi_get_api_info( LDAPAPIInfo *aip );
35*0Sstevel@tonic-gate static int nsldapi_get_feature_info( LDAPAPIFeatureInfo *fip );
36*0Sstevel@tonic-gate
37*0Sstevel@tonic-gate
38*0Sstevel@tonic-gate int
39*0Sstevel@tonic-gate LDAP_CALL
ldap_get_option(LDAP * ld,int option,void * optdata)40*0Sstevel@tonic-gate ldap_get_option( LDAP *ld, int option, void *optdata )
41*0Sstevel@tonic-gate {
42*0Sstevel@tonic-gate int rc = 0;
43*0Sstevel@tonic-gate
44*0Sstevel@tonic-gate if ( !nsldapi_initialized ) {
45*0Sstevel@tonic-gate nsldapi_initialize_defaults();
46*0Sstevel@tonic-gate }
47*0Sstevel@tonic-gate
48*0Sstevel@tonic-gate /*
49*0Sstevel@tonic-gate * optdata MUST be a valid pointer...
50*0Sstevel@tonic-gate */
51*0Sstevel@tonic-gate if (NULL == optdata)
52*0Sstevel@tonic-gate {
53*0Sstevel@tonic-gate return(LDAP_PARAM_ERROR);
54*0Sstevel@tonic-gate }
55*0Sstevel@tonic-gate /*
56*0Sstevel@tonic-gate * process global options (not associated with an LDAP session handle)
57*0Sstevel@tonic-gate */
58*0Sstevel@tonic-gate if ( option == LDAP_OPT_MEMALLOC_FN_PTRS ) {
59*0Sstevel@tonic-gate /* struct copy */
60*0Sstevel@tonic-gate *((struct ldap_memalloc_fns *)optdata) = nsldapi_memalloc_fns;
61*0Sstevel@tonic-gate return( 0 );
62*0Sstevel@tonic-gate }
63*0Sstevel@tonic-gate
64*0Sstevel@tonic-gate if ( option == LDAP_OPT_API_INFO ) {
65*0Sstevel@tonic-gate rc = nsldapi_get_api_info( (LDAPAPIInfo *)optdata );
66*0Sstevel@tonic-gate if ( rc != LDAP_SUCCESS ) {
67*0Sstevel@tonic-gate if ( ld != NULL ) {
68*0Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
69*0Sstevel@tonic-gate }
70*0Sstevel@tonic-gate return( -1 );
71*0Sstevel@tonic-gate }
72*0Sstevel@tonic-gate return( 0 );
73*0Sstevel@tonic-gate }
74*0Sstevel@tonic-gate /*
75*0Sstevel@tonic-gate * LDAP_OPT_DEBUG_LEVEL is global
76*0Sstevel@tonic-gate */
77*0Sstevel@tonic-gate if (LDAP_OPT_DEBUG_LEVEL == option)
78*0Sstevel@tonic-gate {
79*0Sstevel@tonic-gate #ifdef LDAP_DEBUG
80*0Sstevel@tonic-gate *((int *) optdata) = ldap_debug;
81*0Sstevel@tonic-gate #endif /* LDAP_DEBUG */
82*0Sstevel@tonic-gate return ( 0 );
83*0Sstevel@tonic-gate }
84*0Sstevel@tonic-gate
85*0Sstevel@tonic-gate /*
86*0Sstevel@tonic-gate * if ld is NULL, arrange to return options from our default settings
87*0Sstevel@tonic-gate */
88*0Sstevel@tonic-gate if ( ld == NULL ) {
89*0Sstevel@tonic-gate ld = &nsldapi_ld_defaults;
90*0Sstevel@tonic-gate }
91*0Sstevel@tonic-gate
92*0Sstevel@tonic-gate if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
93*0Sstevel@tonic-gate return( -1 ); /* punt */
94*0Sstevel@tonic-gate }
95*0Sstevel@tonic-gate
96*0Sstevel@tonic-gate
97*0Sstevel@tonic-gate if (ld != &nsldapi_ld_defaults)
98*0Sstevel@tonic-gate LDAP_MUTEX_LOCK( ld, LDAP_OPTION_LOCK );
99*0Sstevel@tonic-gate switch( option ) {
100*0Sstevel@tonic-gate #ifdef LDAP_DNS
101*0Sstevel@tonic-gate case LDAP_OPT_DNS:
102*0Sstevel@tonic-gate *((int *) optdata) = LDAP_GET_BITOPT( ld, LDAP_BITOPT_DNS );
103*0Sstevel@tonic-gate break;
104*0Sstevel@tonic-gate #endif
105*0Sstevel@tonic-gate
106*0Sstevel@tonic-gate case LDAP_OPT_REFERRALS:
107*0Sstevel@tonic-gate *((int *) optdata) =
108*0Sstevel@tonic-gate LDAP_GET_BITOPT( ld, LDAP_BITOPT_REFERRALS );
109*0Sstevel@tonic-gate break;
110*0Sstevel@tonic-gate
111*0Sstevel@tonic-gate #ifdef LDAP_SSLIO_HOOKS
112*0Sstevel@tonic-gate case LDAP_OPT_SSL:
113*0Sstevel@tonic-gate *((int *) optdata) = LDAP_GET_BITOPT( ld, LDAP_BITOPT_SSL );
114*0Sstevel@tonic-gate break;
115*0Sstevel@tonic-gate #endif
116*0Sstevel@tonic-gate case LDAP_OPT_RESTART:
117*0Sstevel@tonic-gate *((int *) optdata) = LDAP_GET_BITOPT( ld, LDAP_BITOPT_RESTART );
118*0Sstevel@tonic-gate break;
119*0Sstevel@tonic-gate
120*0Sstevel@tonic-gate case LDAP_OPT_RECONNECT:
121*0Sstevel@tonic-gate *((int *) optdata) =
122*0Sstevel@tonic-gate LDAP_GET_BITOPT( ld, LDAP_BITOPT_RECONNECT );
123*0Sstevel@tonic-gate break;
124*0Sstevel@tonic-gate
125*0Sstevel@tonic-gate #ifdef LDAP_ASYNC_IO
126*0Sstevel@tonic-gate case LDAP_OPT_ASYNC_CONNECT:
127*0Sstevel@tonic-gate *((int *) optdata) =
128*0Sstevel@tonic-gate LDAP_GET_BITOPT( ld, LDAP_BITOPT_ASYNC );
129*0Sstevel@tonic-gate break;
130*0Sstevel@tonic-gate #endif /* LDAP_ASYNC_IO */
131*0Sstevel@tonic-gate
132*0Sstevel@tonic-gate /* stuff in the sockbuf */
133*0Sstevel@tonic-gate case LDAP_X_OPT_SOCKBUF:
134*0Sstevel@tonic-gate *((Sockbuf **) optdata) = ld->ld_sbp;
135*0Sstevel@tonic-gate break;
136*0Sstevel@tonic-gate case LDAP_OPT_DESC:
137*0Sstevel@tonic-gate if ( ber_sockbuf_get_option( ld->ld_sbp,
138*0Sstevel@tonic-gate LBER_SOCKBUF_OPT_DESC, optdata ) != 0 ) {
139*0Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, LDAP_LOCAL_ERROR, NULL, NULL );
140*0Sstevel@tonic-gate rc = -1;
141*0Sstevel@tonic-gate }
142*0Sstevel@tonic-gate break;
143*0Sstevel@tonic-gate
144*0Sstevel@tonic-gate /* fields in the LDAP structure */
145*0Sstevel@tonic-gate case LDAP_OPT_DEREF:
146*0Sstevel@tonic-gate *((int *) optdata) = ld->ld_deref;
147*0Sstevel@tonic-gate break;
148*0Sstevel@tonic-gate case LDAP_OPT_SIZELIMIT:
149*0Sstevel@tonic-gate *((int *) optdata) = ld->ld_sizelimit;
150*0Sstevel@tonic-gate break;
151*0Sstevel@tonic-gate case LDAP_OPT_TIMELIMIT:
152*0Sstevel@tonic-gate *((int *) optdata) = ld->ld_timelimit;
153*0Sstevel@tonic-gate break;
154*0Sstevel@tonic-gate case LDAP_OPT_REFERRAL_HOP_LIMIT:
155*0Sstevel@tonic-gate *((int *) optdata) = ld->ld_refhoplimit;
156*0Sstevel@tonic-gate break;
157*0Sstevel@tonic-gate case LDAP_OPT_PROTOCOL_VERSION:
158*0Sstevel@tonic-gate *((int *) optdata) = ld->ld_version;
159*0Sstevel@tonic-gate break;
160*0Sstevel@tonic-gate case LDAP_OPT_SERVER_CONTROLS:
161*0Sstevel@tonic-gate /* fall through */
162*0Sstevel@tonic-gate case LDAP_OPT_CLIENT_CONTROLS:
163*0Sstevel@tonic-gate *((LDAPControl ***)optdata) = NULL;
164*0Sstevel@tonic-gate /* nsldapi_dup_controls returns -1 and sets lderrno on error */
165*0Sstevel@tonic-gate rc = nsldapi_dup_controls( ld, (LDAPControl ***)optdata,
166*0Sstevel@tonic-gate ( option == LDAP_OPT_SERVER_CONTROLS ) ?
167*0Sstevel@tonic-gate ld->ld_servercontrols : ld->ld_clientcontrols );
168*0Sstevel@tonic-gate break;
169*0Sstevel@tonic-gate
170*0Sstevel@tonic-gate /* rebind proc */
171*0Sstevel@tonic-gate case LDAP_OPT_REBIND_FN:
172*0Sstevel@tonic-gate *((LDAP_REBINDPROC_CALLBACK **) optdata) = ld->ld_rebind_fn;
173*0Sstevel@tonic-gate break;
174*0Sstevel@tonic-gate case LDAP_OPT_REBIND_ARG:
175*0Sstevel@tonic-gate *((void **) optdata) = ld->ld_rebind_arg;
176*0Sstevel@tonic-gate break;
177*0Sstevel@tonic-gate
178*0Sstevel@tonic-gate #ifdef LDAP_SSLIO_HOOKS
179*0Sstevel@tonic-gate /* i/o function pointers */
180*0Sstevel@tonic-gate case LDAP_OPT_IO_FN_PTRS:
181*0Sstevel@tonic-gate if ( ld->ld_io_fns_ptr == NULL ) {
182*0Sstevel@tonic-gate memset( optdata, 0, sizeof( struct ldap_io_fns ));
183*0Sstevel@tonic-gate } else {
184*0Sstevel@tonic-gate /* struct copy */
185*0Sstevel@tonic-gate *((struct ldap_io_fns *)optdata) = *(ld->ld_io_fns_ptr);
186*0Sstevel@tonic-gate }
187*0Sstevel@tonic-gate break;
188*0Sstevel@tonic-gate
189*0Sstevel@tonic-gate /* extended i/o function pointers */
190*0Sstevel@tonic-gate case LDAP_X_OPT_EXTIO_FN_PTRS:
191*0Sstevel@tonic-gate if ( ((struct ldap_x_ext_io_fns *) optdata)->lextiof_size == LDAP_X_EXTIO_FNS_SIZE_REV0) {
192*0Sstevel@tonic-gate ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_close = ld->ld_extclose_fn;
193*0Sstevel@tonic-gate ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_connect = ld->ld_extconnect_fn;
194*0Sstevel@tonic-gate ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_read = ld->ld_extread_fn;
195*0Sstevel@tonic-gate ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_write = ld->ld_extwrite_fn;
196*0Sstevel@tonic-gate ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_poll = ld->ld_extpoll_fn;
197*0Sstevel@tonic-gate ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_newhandle = ld->ld_extnewhandle_fn;
198*0Sstevel@tonic-gate ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_disposehandle = ld->ld_extdisposehandle_fn;
199*0Sstevel@tonic-gate ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_session_arg = ld->ld_ext_session_arg;
200*0Sstevel@tonic-gate } else if ( ((struct ldap_x_ext_io_fns *) optdata)->lextiof_size ==
201*0Sstevel@tonic-gate LDAP_X_EXTIO_FNS_SIZE ) {
202*0Sstevel@tonic-gate /* struct copy */
203*0Sstevel@tonic-gate *((struct ldap_x_ext_io_fns *) optdata) = ld->ld_ext_io_fns;
204*0Sstevel@tonic-gate } else {
205*0Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
206*0Sstevel@tonic-gate rc = -1;
207*0Sstevel@tonic-gate }
208*0Sstevel@tonic-gate break;
209*0Sstevel@tonic-gate #endif /* LDAP_SSLIO_HOOKS */
210*0Sstevel@tonic-gate
211*0Sstevel@tonic-gate /* thread function pointers */
212*0Sstevel@tonic-gate case LDAP_OPT_THREAD_FN_PTRS:
213*0Sstevel@tonic-gate /* struct copy */
214*0Sstevel@tonic-gate *((struct ldap_thread_fns *) optdata) = ld->ld_thread;
215*0Sstevel@tonic-gate break;
216*0Sstevel@tonic-gate
217*0Sstevel@tonic-gate /* DNS function pointers */
218*0Sstevel@tonic-gate case LDAP_OPT_DNS_FN_PTRS:
219*0Sstevel@tonic-gate /* struct copy */
220*0Sstevel@tonic-gate *((struct ldap_dns_fns *) optdata) = ld->ld_dnsfn;
221*0Sstevel@tonic-gate break;
222*0Sstevel@tonic-gate
223*0Sstevel@tonic-gate /* cache function pointers */
224*0Sstevel@tonic-gate case LDAP_OPT_CACHE_FN_PTRS:
225*0Sstevel@tonic-gate /* struct copy */
226*0Sstevel@tonic-gate *((struct ldap_cache_fns *) optdata) = ld->ld_cache;
227*0Sstevel@tonic-gate break;
228*0Sstevel@tonic-gate case LDAP_OPT_CACHE_STRATEGY:
229*0Sstevel@tonic-gate *((int *) optdata) = ld->ld_cache_strategy;
230*0Sstevel@tonic-gate break;
231*0Sstevel@tonic-gate case LDAP_OPT_CACHE_ENABLE:
232*0Sstevel@tonic-gate *((int *) optdata) = ld->ld_cache_on;
233*0Sstevel@tonic-gate break;
234*0Sstevel@tonic-gate
235*0Sstevel@tonic-gate case LDAP_OPT_ERROR_NUMBER:
236*0Sstevel@tonic-gate *((int *) optdata) = LDAP_GET_LDERRNO( ld, NULL, NULL );
237*0Sstevel@tonic-gate break;
238*0Sstevel@tonic-gate
239*0Sstevel@tonic-gate case LDAP_OPT_ERROR_STRING:
240*0Sstevel@tonic-gate (void)LDAP_GET_LDERRNO( ld, NULL, (char **)optdata );
241*0Sstevel@tonic-gate *((char **) optdata) = nsldapi_strdup( *((char **) optdata ));
242*0Sstevel@tonic-gate break;
243*0Sstevel@tonic-gate
244*0Sstevel@tonic-gate case LDAP_OPT_MATCHED_DN:
245*0Sstevel@tonic-gate (void)LDAP_GET_LDERRNO( ld, (char **)optdata, NULL );
246*0Sstevel@tonic-gate *((char **) optdata) = nsldapi_strdup( *((char **) optdata ));
247*0Sstevel@tonic-gate break;
248*0Sstevel@tonic-gate
249*0Sstevel@tonic-gate case LDAP_OPT_PREFERRED_LANGUAGE:
250*0Sstevel@tonic-gate if ( NULL != ld->ld_preferred_language ) {
251*0Sstevel@tonic-gate *((char **) optdata) =
252*0Sstevel@tonic-gate nsldapi_strdup(ld->ld_preferred_language);
253*0Sstevel@tonic-gate } else {
254*0Sstevel@tonic-gate *((char **) optdata) = NULL;
255*0Sstevel@tonic-gate }
256*0Sstevel@tonic-gate break;
257*0Sstevel@tonic-gate
258*0Sstevel@tonic-gate case LDAP_OPT_API_FEATURE_INFO:
259*0Sstevel@tonic-gate rc = nsldapi_get_feature_info( (LDAPAPIFeatureInfo *)optdata );
260*0Sstevel@tonic-gate if ( rc != LDAP_SUCCESS ) {
261*0Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
262*0Sstevel@tonic-gate rc = -1;
263*0Sstevel@tonic-gate }
264*0Sstevel@tonic-gate break;
265*0Sstevel@tonic-gate
266*0Sstevel@tonic-gate case LDAP_OPT_HOST_NAME:
267*0Sstevel@tonic-gate *((char **) optdata) = nsldapi_strdup( ld->ld_defhost );
268*0Sstevel@tonic-gate break;
269*0Sstevel@tonic-gate
270*0Sstevel@tonic-gate case LDAP_X_OPT_CONNECT_TIMEOUT:
271*0Sstevel@tonic-gate *((int *) optdata) = ld->ld_connect_timeout;
272*0Sstevel@tonic-gate break;
273*0Sstevel@tonic-gate
274*0Sstevel@tonic-gate #ifdef LDAP_SASLIO_HOOKS
275*0Sstevel@tonic-gate /* SASL options */
276*0Sstevel@tonic-gate case LDAP_OPT_X_SASL_MECH:
277*0Sstevel@tonic-gate *((char **) optdata) = nsldapi_strdup(ld->ld_def_sasl_mech);
278*0Sstevel@tonic-gate break;
279*0Sstevel@tonic-gate case LDAP_OPT_X_SASL_REALM:
280*0Sstevel@tonic-gate *((char **) optdata) = nsldapi_strdup(ld->ld_def_sasl_realm);
281*0Sstevel@tonic-gate break;
282*0Sstevel@tonic-gate case LDAP_OPT_X_SASL_AUTHCID:
283*0Sstevel@tonic-gate *((char **) optdata) = nsldapi_strdup(ld->ld_def_sasl_authcid);
284*0Sstevel@tonic-gate break;
285*0Sstevel@tonic-gate case LDAP_OPT_X_SASL_AUTHZID:
286*0Sstevel@tonic-gate *((char **) optdata) = nsldapi_strdup(ld->ld_def_sasl_authzid);
287*0Sstevel@tonic-gate break;
288*0Sstevel@tonic-gate case LDAP_OPT_X_SASL_SSF:
289*0Sstevel@tonic-gate {
290*0Sstevel@tonic-gate int sc;
291*0Sstevel@tonic-gate sasl_ssf_t *ssf;
292*0Sstevel@tonic-gate sasl_conn_t *ctx;
293*0Sstevel@tonic-gate if( ld->ld_defconn == NULL ||
294*0Sstevel@tonic-gate ld->ld_defconn->lconn_sb == NULL ) {
295*0Sstevel@tonic-gate return -1;
296*0Sstevel@tonic-gate }
297*0Sstevel@tonic-gate ctx = (sasl_conn_t *)(ld->ld_defconn->lconn_sb->sb_sasl_ctx);
298*0Sstevel@tonic-gate if ( ctx == NULL ) {
299*0Sstevel@tonic-gate return -1;
300*0Sstevel@tonic-gate }
301*0Sstevel@tonic-gate sc = sasl_getprop( ctx, SASL_SSF, (const void **) &ssf );
302*0Sstevel@tonic-gate if ( sc != SASL_OK ) {
303*0Sstevel@tonic-gate return -1;
304*0Sstevel@tonic-gate }
305*0Sstevel@tonic-gate *((sasl_ssf_t *) optdata) = *ssf;
306*0Sstevel@tonic-gate }
307*0Sstevel@tonic-gate break;
308*0Sstevel@tonic-gate case LDAP_OPT_X_SASL_SSF_MIN:
309*0Sstevel@tonic-gate *((sasl_ssf_t *) optdata) = ld->ld_sasl_secprops.min_ssf;
310*0Sstevel@tonic-gate break;
311*0Sstevel@tonic-gate case LDAP_OPT_X_SASL_SSF_MAX:
312*0Sstevel@tonic-gate *((sasl_ssf_t *) optdata) = ld->ld_sasl_secprops.max_ssf;
313*0Sstevel@tonic-gate break;
314*0Sstevel@tonic-gate case LDAP_OPT_X_SASL_MAXBUFSIZE:
315*0Sstevel@tonic-gate *((sasl_ssf_t *) optdata) = ld->ld_sasl_secprops.maxbufsize;
316*0Sstevel@tonic-gate break;
317*0Sstevel@tonic-gate case LDAP_OPT_X_SASL_SSF_EXTERNAL:
318*0Sstevel@tonic-gate case LDAP_OPT_X_SASL_SECPROPS:
319*0Sstevel@tonic-gate /*
320*0Sstevel@tonic-gate * These options are write only. Making these options
321*0Sstevel@tonic-gate * read/write would expose semi-private interfaces of libsasl
322*0Sstevel@tonic-gate * for which there are no cross platform/standardized
323*0Sstevel@tonic-gate * definitions.
324*0Sstevel@tonic-gate */
325*0Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
326*0Sstevel@tonic-gate rc = -1;
327*0Sstevel@tonic-gate break;
328*0Sstevel@tonic-gate #endif
329*0Sstevel@tonic-gate
330*0Sstevel@tonic-gate default:
331*0Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
332*0Sstevel@tonic-gate rc = -1;
333*0Sstevel@tonic-gate }
334*0Sstevel@tonic-gate if (ld != &nsldapi_ld_defaults)
335*0Sstevel@tonic-gate LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK );
336*0Sstevel@tonic-gate return( rc );
337*0Sstevel@tonic-gate }
338*0Sstevel@tonic-gate
339*0Sstevel@tonic-gate
340*0Sstevel@tonic-gate /*
341*0Sstevel@tonic-gate * Table of extended API features we support.
342*0Sstevel@tonic-gate * The first field is the version of the info. strcuture itself; we do not
343*0Sstevel@tonic-gate * use the ones from this table so it is okay to leave as zero.
344*0Sstevel@tonic-gate */
345*0Sstevel@tonic-gate static LDAPAPIFeatureInfo nsldapi_extensions[] = {
346*0Sstevel@tonic-gate { 0, "SERVER_SIDE_SORT", LDAP_API_FEATURE_SERVER_SIDE_SORT },
347*0Sstevel@tonic-gate { 0, "VIRTUAL_LIST_VIEW", LDAP_API_FEATURE_VIRTUAL_LIST_VIEW },
348*0Sstevel@tonic-gate { 0, "PERSISTENT_SEARCH", LDAP_API_FEATURE_PERSISTENT_SEARCH },
349*0Sstevel@tonic-gate { 0, "PROXY_AUTHORIZATION", LDAP_API_FEATURE_PROXY_AUTHORIZATION },
350*0Sstevel@tonic-gate { 0, "X_LDERRNO", LDAP_API_FEATURE_X_LDERRNO },
351*0Sstevel@tonic-gate { 0, "X_MEMCACHE", LDAP_API_FEATURE_X_MEMCACHE },
352*0Sstevel@tonic-gate { 0, "X_IO_FUNCTIONS", LDAP_API_FEATURE_X_IO_FUNCTIONS },
353*0Sstevel@tonic-gate { 0, "X_EXTIO_FUNCTIONS", LDAP_API_FEATURE_X_EXTIO_FUNCTIONS },
354*0Sstevel@tonic-gate { 0, "X_DNS_FUNCTIONS", LDAP_API_FEATURE_X_DNS_FUNCTIONS },
355*0Sstevel@tonic-gate { 0, "X_MEMALLOC_FUNCTIONS", LDAP_API_FEATURE_X_MEMALLOC_FUNCTIONS },
356*0Sstevel@tonic-gate { 0, "X_THREAD_FUNCTIONS", LDAP_API_FEATURE_X_THREAD_FUNCTIONS },
357*0Sstevel@tonic-gate { 0, "X_EXTHREAD_FUNCTIONS", LDAP_API_FEATURE_X_EXTHREAD_FUNCTIONS },
358*0Sstevel@tonic-gate { 0, "X_GETLANGVALUES", LDAP_API_FEATURE_X_GETLANGVALUES },
359*0Sstevel@tonic-gate { 0, "X_CLIENT_SIDE_SORT", LDAP_API_FEATURE_X_CLIENT_SIDE_SORT },
360*0Sstevel@tonic-gate { 0, "X_URL_FUNCTIONS", LDAP_API_FEATURE_X_URL_FUNCTIONS },
361*0Sstevel@tonic-gate { 0, "X_FILTER_FUNCTIONS", LDAP_API_FEATURE_X_FILTER_FUNCTIONS },
362*0Sstevel@tonic-gate };
363*0Sstevel@tonic-gate
364*0Sstevel@tonic-gate #define NSLDAPI_EXTENSIONS_COUNT \
365*0Sstevel@tonic-gate (sizeof(nsldapi_extensions)/sizeof(LDAPAPIFeatureInfo))
366*0Sstevel@tonic-gate
367*0Sstevel@tonic-gate /*
368*0Sstevel@tonic-gate * Retrieve information about this implementation of the LDAP API.
369*0Sstevel@tonic-gate * Returns an LDAP error code.
370*0Sstevel@tonic-gate */
371*0Sstevel@tonic-gate static int
nsldapi_get_api_info(LDAPAPIInfo * aip)372*0Sstevel@tonic-gate nsldapi_get_api_info( LDAPAPIInfo *aip )
373*0Sstevel@tonic-gate {
374*0Sstevel@tonic-gate int i;
375*0Sstevel@tonic-gate
376*0Sstevel@tonic-gate if ( aip == NULL ) {
377*0Sstevel@tonic-gate return( LDAP_PARAM_ERROR );
378*0Sstevel@tonic-gate }
379*0Sstevel@tonic-gate
380*0Sstevel@tonic-gate aip->ldapai_api_version = LDAP_API_VERSION;
381*0Sstevel@tonic-gate
382*0Sstevel@tonic-gate if ( aip->ldapai_info_version != LDAP_API_INFO_VERSION ) {
383*0Sstevel@tonic-gate aip->ldapai_info_version = LDAP_API_INFO_VERSION;
384*0Sstevel@tonic-gate return( LDAP_PARAM_ERROR );
385*0Sstevel@tonic-gate }
386*0Sstevel@tonic-gate
387*0Sstevel@tonic-gate aip->ldapai_protocol_version = LDAP_VERSION_MAX;
388*0Sstevel@tonic-gate aip->ldapai_vendor_version = LDAP_VENDOR_VERSION;
389*0Sstevel@tonic-gate
390*0Sstevel@tonic-gate if (( aip->ldapai_vendor_name = nsldapi_strdup( LDAP_VENDOR_NAME ))
391*0Sstevel@tonic-gate == NULL ) {
392*0Sstevel@tonic-gate return( LDAP_NO_MEMORY );
393*0Sstevel@tonic-gate }
394*0Sstevel@tonic-gate
395*0Sstevel@tonic-gate if ( NSLDAPI_EXTENSIONS_COUNT < 1 ) {
396*0Sstevel@tonic-gate aip->ldapai_extensions = NULL;
397*0Sstevel@tonic-gate } else {
398*0Sstevel@tonic-gate if (( aip->ldapai_extensions = NSLDAPI_CALLOC(
399*0Sstevel@tonic-gate NSLDAPI_EXTENSIONS_COUNT + 1, sizeof(char *))) == NULL ) {
400*0Sstevel@tonic-gate NSLDAPI_FREE( aip->ldapai_vendor_name );
401*0Sstevel@tonic-gate aip->ldapai_vendor_name = NULL;
402*0Sstevel@tonic-gate return( LDAP_NO_MEMORY );
403*0Sstevel@tonic-gate }
404*0Sstevel@tonic-gate
405*0Sstevel@tonic-gate for ( i = 0; i < NSLDAPI_EXTENSIONS_COUNT; ++i ) {
406*0Sstevel@tonic-gate if (( aip->ldapai_extensions[i] = nsldapi_strdup(
407*0Sstevel@tonic-gate nsldapi_extensions[i].ldapaif_name )) == NULL ) {
408*0Sstevel@tonic-gate ldap_value_free( aip->ldapai_extensions );
409*0Sstevel@tonic-gate NSLDAPI_FREE( aip->ldapai_vendor_name );
410*0Sstevel@tonic-gate aip->ldapai_extensions = NULL;
411*0Sstevel@tonic-gate aip->ldapai_vendor_name = NULL;
412*0Sstevel@tonic-gate return( LDAP_NO_MEMORY );
413*0Sstevel@tonic-gate }
414*0Sstevel@tonic-gate }
415*0Sstevel@tonic-gate }
416*0Sstevel@tonic-gate
417*0Sstevel@tonic-gate return( LDAP_SUCCESS );
418*0Sstevel@tonic-gate }
419*0Sstevel@tonic-gate
420*0Sstevel@tonic-gate
421*0Sstevel@tonic-gate /*
422*0Sstevel@tonic-gate * Retrieves information about a specific extended feature of the LDAP API/
423*0Sstevel@tonic-gate * Returns an LDAP error code.
424*0Sstevel@tonic-gate */
425*0Sstevel@tonic-gate static int
nsldapi_get_feature_info(LDAPAPIFeatureInfo * fip)426*0Sstevel@tonic-gate nsldapi_get_feature_info( LDAPAPIFeatureInfo *fip )
427*0Sstevel@tonic-gate {
428*0Sstevel@tonic-gate int i;
429*0Sstevel@tonic-gate
430*0Sstevel@tonic-gate if ( fip == NULL || fip->ldapaif_name == NULL ) {
431*0Sstevel@tonic-gate return( LDAP_PARAM_ERROR );
432*0Sstevel@tonic-gate }
433*0Sstevel@tonic-gate
434*0Sstevel@tonic-gate if ( fip->ldapaif_info_version != LDAP_FEATURE_INFO_VERSION ) {
435*0Sstevel@tonic-gate fip->ldapaif_info_version = LDAP_FEATURE_INFO_VERSION;
436*0Sstevel@tonic-gate return( LDAP_PARAM_ERROR );
437*0Sstevel@tonic-gate }
438*0Sstevel@tonic-gate
439*0Sstevel@tonic-gate for ( i = 0; i < NSLDAPI_EXTENSIONS_COUNT; ++i ) {
440*0Sstevel@tonic-gate if ( strcmp( fip->ldapaif_name,
441*0Sstevel@tonic-gate nsldapi_extensions[i].ldapaif_name ) == 0 ) {
442*0Sstevel@tonic-gate fip->ldapaif_version =
443*0Sstevel@tonic-gate nsldapi_extensions[i].ldapaif_version;
444*0Sstevel@tonic-gate break;
445*0Sstevel@tonic-gate }
446*0Sstevel@tonic-gate }
447*0Sstevel@tonic-gate
448*0Sstevel@tonic-gate return(( i < NSLDAPI_EXTENSIONS_COUNT ) ? LDAP_SUCCESS
449*0Sstevel@tonic-gate : LDAP_PARAM_ERROR );
450*0Sstevel@tonic-gate }
451