2 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 #pragma ident "%Z%%M% %I% %E% SMI"
9 * The contents of this file are subject to the Netscape Public
10 * License Version 1.1 (the "License"); you may not use this file
11 * except in compliance with the License. You may obtain a copy of
12 * the License at http://www.mozilla.org/NPL/
14 * Software distributed under the License is distributed on an "AS
15 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
16 * implied. See the License for the specific language governing
17 * rights and limitations under the License.
19 * The Original Code is Mozilla Communicator client code, released
22 * The Initial Developer of the Original Code is Netscape
23 * Communications Corporation. Portions created by Netscape are
24 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
30 * setoption.c - ldap_set_option implementation
35 #include "solaris-priv.h"
38 extern int nsldapi_sasl_secprops(const char *in
,
39 sasl_security_properties_t
*secprops
);
41 #define LDAP_SETCLR_BITOPT(ld, bit, optdata) \
42 if (optdata != NULL) { \
43 (ld)->ld_options |= bit; \
45 (ld)->ld_options &= ~bit; \
51 ldap_set_option(LDAP
*ld
, int option
, const void *optdata
)
54 char *matched
, *errstr
;
56 if (!nsldapi_initialized
) {
57 nsldapi_initialize_defaults();
61 * process global options (not associated with an LDAP session handle)
63 if (option
== LDAP_OPT_MEMALLOC_FN_PTRS
) {
64 struct lber_memalloc_fns memalloc_fns
;
66 /* set libldap ones via a struct copy */
67 nsldapi_memalloc_fns
= *((struct ldap_memalloc_fns
*)optdata
);
69 /* also set liblber memory allocation callbacks */
70 memalloc_fns
.lbermem_malloc
=
71 nsldapi_memalloc_fns
.ldapmem_malloc
;
72 memalloc_fns
.lbermem_calloc
=
73 nsldapi_memalloc_fns
.ldapmem_calloc
;
74 memalloc_fns
.lbermem_realloc
=
75 nsldapi_memalloc_fns
.ldapmem_realloc
;
76 memalloc_fns
.lbermem_free
=
77 nsldapi_memalloc_fns
.ldapmem_free
;
78 if (ber_set_option(NULL
, LBER_OPT_MEMALLOC_FN_PTRS
,
79 &memalloc_fns
) != 0) {
86 * LDAP_OPT_DEBUG_LEVEL is global
88 if (LDAP_OPT_DEBUG_LEVEL
== option
) {
90 ldap_debug
= *((int *)optdata
);
96 * if ld is NULL, arrange to modify our default settings
99 ld
= &nsldapi_ld_defaults
;
107 * process options that are associated with an LDAP session handle
109 if (!NSLDAPI_VALID_LDAP_POINTER(ld
)) {
110 return (-1); /* punt */
114 if (ld
!= &nsldapi_ld_defaults
&&
115 option
!= LDAP_OPT_EXTRA_THREAD_FN_PTRS
&&
116 option
!= LDAP_OPT_THREAD_FN_PTRS
) {
117 LDAP_MUTEX_LOCK(ld
, LDAP_OPTION_LOCK
);
120 /* options that can be turned on and off */
123 LDAP_SETCLR_BITOPT(ld
, LDAP_BITOPT_DNS
, optdata
);
127 case LDAP_OPT_REFERRALS
:
128 LDAP_SETCLR_BITOPT(ld
, LDAP_BITOPT_REFERRALS
, optdata
);
131 #ifdef LDAP_SSLIO_HOOKS
133 LDAP_SETCLR_BITOPT(ld
, LDAP_BITOPT_SSL
, optdata
);
137 case LDAP_OPT_RESTART
:
138 LDAP_SETCLR_BITOPT(ld
, LDAP_BITOPT_RESTART
, optdata
);
141 case LDAP_OPT_RECONNECT
:
142 LDAP_SETCLR_BITOPT(ld
, LDAP_BITOPT_RECONNECT
, optdata
);
146 case LDAP_OPT_ASYNC_CONNECT
:
147 LDAP_SETCLR_BITOPT(ld
, LDAP_BITOPT_ASYNC
, optdata
);
149 #endif /* LDAP_ASYNC_IO */
151 /* fields in the LDAP structure */
153 ld
->ld_deref
= *((int *)optdata
);
155 case LDAP_OPT_SIZELIMIT
:
156 ld
->ld_sizelimit
= *((int *)optdata
);
158 case LDAP_OPT_TIMELIMIT
:
159 ld
->ld_timelimit
= *((int *)optdata
);
161 case LDAP_OPT_REFERRAL_HOP_LIMIT
:
162 ld
->ld_refhoplimit
= *((int *)optdata
);
164 case LDAP_OPT_PROTOCOL_VERSION
:
165 ld
->ld_version
= *((int *)optdata
);
166 if (ld
->ld_defconn
!= NULL
) { /* also set in default conn. */
167 ld
->ld_defconn
->lconn_version
= ld
->ld_version
;
170 case LDAP_OPT_SERVER_CONTROLS
:
171 /* nsldapi_dup_controls returns -1 and sets lderrno on error */
172 rc
= nsldapi_dup_controls(ld
, &ld
->ld_servercontrols
,
173 (LDAPControl
**)optdata
);
175 case LDAP_OPT_CLIENT_CONTROLS
:
176 /* nsldapi_dup_controls returns -1 and sets lderrno on error */
177 rc
= nsldapi_dup_controls(ld
, &ld
->ld_clientcontrols
,
178 (LDAPControl
**)optdata
);
182 case LDAP_OPT_REBIND_FN
:
183 ld
->ld_rebind_fn
= (LDAP_REBINDPROC_CALLBACK
*) optdata
;
185 case LDAP_OPT_REBIND_ARG
:
186 ld
->ld_rebind_arg
= (void *) optdata
;
189 #ifdef LDAP_SSLIO_HOOKS
190 /* i/o function pointers */
191 case LDAP_OPT_IO_FN_PTRS
:
192 if ((rc
= nsldapi_install_compat_io_fns(ld
,
193 (struct ldap_io_fns
*)optdata
)) != LDAP_SUCCESS
) {
194 LDAP_SET_LDERRNO(ld
, rc
, NULL
, NULL
);
199 /* extended i/o function pointers */
200 case LDAP_X_OPT_EXTIO_FN_PTRS
:
201 /* denotes use of old iofns struct (no writev) */
202 if (((struct ldap_x_ext_io_fns_rev0
*)optdata
)->lextiof_size
==
203 LDAP_X_EXTIO_FNS_SIZE_REV0
) {
204 ld
->ld_extio_size
= LDAP_X_EXTIO_FNS_SIZE
;
206 ((struct ldap_x_ext_io_fns_rev0
*)optdata
)->lextiof_close
;
207 ld
->ld_extconnect_fn
=
208 ((struct ldap_x_ext_io_fns_rev0
*)optdata
)->lextiof_connect
;
210 ((struct ldap_x_ext_io_fns_rev0
*)optdata
)->lextiof_read
;
212 ((struct ldap_x_ext_io_fns_rev0
*)optdata
)->lextiof_write
;
214 ((struct ldap_x_ext_io_fns_rev0
*)optdata
)->lextiof_poll
;
215 ld
->ld_extnewhandle_fn
=
216 ((struct ldap_x_ext_io_fns_rev0
*)optdata
)->lextiof_newhandle
;
217 ld
->ld_extdisposehandle_fn
=
218 ((struct ldap_x_ext_io_fns_rev0
*)optdata
)->
219 lextiof_disposehandle
;
220 ld
->ld_ext_session_arg
=
221 ((struct ldap_x_ext_io_fns_rev0
*)optdata
)->lextiof_session_arg
;
222 ld
->ld_extwritev_fn
= NULL
;
223 if (ber_sockbuf_set_option(ld
->ld_sbp
, LBER_SOCKBUF_OPT_EXT_IO_FNS
,
224 &(ld
->ld_ext_io_fns
)) != 0) {
225 return (LDAP_LOCAL_ERROR
);
229 ld
->ld_ext_io_fns
= *((struct ldap_x_ext_io_fns
*)optdata
);
231 if ((rc
= nsldapi_install_lber_extiofns(ld
, ld
->ld_sbp
))
233 LDAP_SET_LDERRNO(ld
, rc
, NULL
, NULL
);
239 /* thread function pointers */
240 case LDAP_OPT_THREAD_FN_PTRS
:
242 * It is only safe to set the thread function pointers
243 * when one thread is using the LDAP session handle.
245 /* free existing mutexes (some are allocated by ldap_init()) */
246 nsldapi_mutex_free_all(ld
);
249 ld
->ld_thread
= *((struct ldap_thread_fns
*)optdata
);
251 /* allocate new mutexes */
252 nsldapi_mutex_alloc_all(ld
);
254 /* LDAP_OPTION_LOCK was never locked... so just return */
257 /* extra thread function pointers */
258 case LDAP_OPT_EXTRA_THREAD_FN_PTRS
:
259 /* The extra thread funcs will only pick up the threadid */
260 ld
->ld_thread2
= *((struct ldap_extra_thread_fns
*)optdata
);
262 /* Reset the rest of the structure preserving the threadid fn */
263 ld
->ld_mutex_trylock_fn
= (LDAP_TF_MUTEX_TRYLOCK_CALLBACK
*)NULL
;
264 ld
->ld_sema_alloc_fn
= (LDAP_TF_SEMA_ALLOC_CALLBACK
*) NULL
;
265 ld
->ld_sema_free_fn
= (LDAP_TF_SEMA_FREE_CALLBACK
*) NULL
;
266 ld
->ld_sema_wait_fn
= (LDAP_TF_SEMA_WAIT_CALLBACK
*) NULL
;
267 ld
->ld_sema_post_fn
= (LDAP_TF_SEMA_POST_CALLBACK
*) NULL
;
269 /* We assume that only one thread is active when replacing */
270 /* the threadid function. We will now proceed and reset all */
271 /* of the threadid/refcounts */
272 for (i
= 0; i
< LDAP_MAX_LOCK
; i
++) {
273 ld
->ld_mutex_threadid
[i
] = (void *) -1;
274 ld
->ld_mutex_refcnt
[i
] = 0;
279 /* DNS function pointers */
280 case LDAP_OPT_DNS_FN_PTRS
:
282 ld
->ld_dnsfn
= *((struct ldap_dns_fns
*)optdata
);
285 /* cache function pointers */
286 case LDAP_OPT_CACHE_FN_PTRS
:
288 ld
->ld_cache
= *((struct ldap_cache_fns
*)optdata
);
290 case LDAP_OPT_CACHE_STRATEGY
:
291 ld
->ld_cache_strategy
= *((int *)optdata
);
293 case LDAP_OPT_CACHE_ENABLE
:
294 ld
->ld_cache_on
= *((int *)optdata
);
297 case LDAP_OPT_ERROR_NUMBER
:
298 LDAP_GET_LDERRNO(ld
, &matched
, &errstr
);
299 matched
= nsldapi_strdup(matched
);
300 errstr
= nsldapi_strdup(errstr
);
301 LDAP_SET_LDERRNO(ld
, *((int *)optdata
), matched
, errstr
);
304 case LDAP_OPT_ERROR_STRING
:
305 rc
= LDAP_GET_LDERRNO(ld
, &matched
, NULL
);
306 matched
= nsldapi_strdup(matched
);
307 LDAP_SET_LDERRNO(ld
, rc
, matched
,
308 nsldapi_strdup((char *)optdata
));
312 case LDAP_OPT_MATCHED_DN
:
313 rc
= LDAP_GET_LDERRNO(ld
, NULL
, &errstr
);
314 errstr
= nsldapi_strdup(errstr
);
315 LDAP_SET_LDERRNO(ld
, rc
,
316 nsldapi_strdup((char *)optdata
), errstr
);
320 case LDAP_OPT_PREFERRED_LANGUAGE
:
321 if (NULL
!= ld
->ld_preferred_language
) {
322 NSLDAPI_FREE(ld
->ld_preferred_language
);
324 ld
->ld_preferred_language
= nsldapi_strdup((char *)optdata
);
327 case LDAP_OPT_HOST_NAME
:
328 if (NULL
!= ld
->ld_defhost
) {
329 NSLDAPI_FREE(ld
->ld_defhost
);
331 ld
->ld_defhost
= nsldapi_strdup((char *)optdata
);
334 case LDAP_X_OPT_CONNECT_TIMEOUT
:
335 ld
->ld_connect_timeout
= *((int *)optdata
);
339 /* recursion prevention dns functions */
340 case LDAP_X_OPT_DNS_SKIPDB
:
341 rc
= prldap_x_install_dns_skipdb(ld
, (const char *)optdata
);
344 #ifdef LDAP_SASLIO_HOOKS
346 case LDAP_OPT_X_SASL_MECH
:
347 if (NULL
!= ld
->ld_def_sasl_mech
) {
349 NSLDAPI_FREE(ld
->ld_def_sasl_mech
);
351 ld
->ld_def_sasl_mech
= nsldapi_strdup((char *)optdata
);
353 case LDAP_OPT_X_SASL_REALM
:
354 if (NULL
!= ld
->ld_def_sasl_realm
) {
355 NSLDAPI_FREE(ld
->ld_def_sasl_realm
);
357 ld
->ld_def_sasl_realm
= nsldapi_strdup((char *)optdata
);
359 case LDAP_OPT_X_SASL_AUTHCID
:
360 if (NULL
!= ld
->ld_def_sasl_authcid
) {
361 NSLDAPI_FREE(ld
->ld_def_sasl_authcid
);
363 ld
->ld_def_sasl_authcid
= nsldapi_strdup((char *)optdata
);
365 case LDAP_OPT_X_SASL_AUTHZID
:
366 if (NULL
!= ld
->ld_def_sasl_authzid
) {
367 NSLDAPI_FREE(ld
->ld_def_sasl_authzid
);
369 ld
->ld_def_sasl_authzid
= nsldapi_strdup((char *)optdata
);
371 case LDAP_OPT_X_SASL_SSF_EXTERNAL
:
376 if (ld
->ld_defconn
== NULL
||
377 ld
->ld_defconn
->lconn_sb
== NULL
) {
380 ctx
= (sasl_conn_t
*)
381 (ld
->ld_defconn
->lconn_sb
->sb_sasl_ctx
);
385 memset(&extprops
, 0L, sizeof (extprops
));
386 extprops
= * ((sasl_ssf_t
*)optdata
);
387 sc
= sasl_setprop(ctx
, SASL_SSF_EXTERNAL
,
394 case LDAP_OPT_X_SASL_SECPROPS
:
397 sc
= nsldapi_sasl_secprops((char *)optdata
,
398 &ld
->ld_sasl_secprops
);
399 return (sc
== LDAP_SUCCESS
? 0 : -1);
401 case LDAP_OPT_X_SASL_SSF_MIN
:
402 ld
->ld_sasl_secprops
.min_ssf
= *((sasl_ssf_t
*)optdata
);
404 case LDAP_OPT_X_SASL_SSF_MAX
:
405 ld
->ld_sasl_secprops
.max_ssf
= *((sasl_ssf_t
*)optdata
);
407 case LDAP_OPT_X_SASL_MAXBUFSIZE
:
408 ld
->ld_sasl_secprops
.maxbufsize
= *((sasl_ssf_t
*)optdata
);
410 case LDAP_OPT_X_SASL_SSF
: /* read only */
411 LDAP_SET_LDERRNO(ld
, LDAP_PARAM_ERROR
, NULL
, NULL
);
417 LDAP_SET_LDERRNO(ld
, LDAP_PARAM_ERROR
, NULL
, NULL
);
421 if (ld
!= &nsldapi_ld_defaults
) {
422 LDAP_MUTEX_UNLOCK(ld
, LDAP_OPTION_LOCK
);