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