1 /*
2 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 #pragma ident "%Z%%M% %I% %E% SMI"
7
8
9 /*
10 * The contents of this file are subject to the Netscape Public
11 * License Version 1.1 (the "License"); you may not use this file
12 * except in compliance with the License. You may obtain a copy of
13 * the License at http://www.mozilla.org/NPL/
14 *
15 * Software distributed under the License is distributed on an "AS
16 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
17 * implied. See the License for the specific language governing
18 * rights and limitations under the License.
19 *
20 * The Original Code is Mozilla Communicator client code, released
21 * March 31, 1998.
22 *
23 * The Initial Developer of the Original Code is Netscape
24 * Communications Corporation. Portions created by Netscape are
25 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
26 * Rights Reserved.
27 *
28 * Contributor(s):
29 */
30
31 /*
32 * Public interface for libprldap -- use NSPR (Netscape Portable Runtime)
33 * I/O, threads, etc. with libldap.
34 *
35 */
36
37 #include "ldappr-int.h"
38
39
40 /*
41 * Function: prldap_init().
42 *
43 * Create a new LDAP session handle, but with NSPR I/O, threading, and DNS
44 * functions installed.
45 *
46 * Pass a non-zero value for the 'shared' parameter if you plan to use
47 * this LDAP * handle from more than one thread.
48 *
49 * prldap_init() returns an LDAP session handle (or NULL if an error occurs).
50 */
51 LDAP * LDAP_CALL
prldap_init(const char * defhost,int defport,int shared)52 prldap_init( const char *defhost, int defport, int shared )
53 {
54 LDAP *ld;
55
56 if (( ld = ldap_init( defhost, defport )) != NULL ) {
57 if ( prldap_install_routines( ld, shared ) != LDAP_SUCCESS ) {
58 prldap_set_system_errno( EINVAL ); /* XXXmcs: just a guess! */
59 ldap_unbind( ld );
60 ld = NULL;
61 }
62 }
63
64 return( ld );
65 }
66
67
68 /*
69 * Function: prldap_install_routines().
70 *
71 * Install NSPR I/O, threading, and DNS functions so they will be used by
72 * 'ld'.
73 *
74 * If 'ld' is NULL, the functions are installed as the default functions
75 * for all new LDAP * handles).
76 *
77 * Pass a non-zero value for the 'shared' parameter if you plan to use
78 * this LDAP * handle from more than one thread.
79 *
80 * prldap_install_routines() returns an LDAP API error code (LDAP_SUCCESS
81 * if all goes well).
82 */
83 int LDAP_CALL
prldap_install_routines(LDAP * ld,int shared)84 prldap_install_routines( LDAP *ld, int shared )
85 {
86
87 if ( prldap_install_io_functions( ld, shared ) != 0
88 || prldap_install_thread_functions( ld, shared ) != 0
89 || prldap_install_dns_functions( ld ) != 0 ) {
90 return( ldap_get_lderrno( ld, NULL, NULL ));
91 }
92
93 return( LDAP_SUCCESS );
94 }
95
96
97 /*
98 * Function: prldap_set_session_option().
99 *
100 * Given an LDAP session handle or a session argument such is passed to
101 * SOCKET, POLL, NEWHANDLE, or DISPOSEHANDLE extended I/O callbacks, set
102 * an option that affects the prldap layer.
103 *
104 * If 'ld' and 'session" are both NULL, the option is set as the default
105 * for all new prldap sessions.
106 *
107 * Returns an LDAP API error code (LDAP_SUCCESS if all goes well).
108 */
109 int LDAP_CALL
prldap_set_session_option(LDAP * ld,void * sessionarg,int option,...)110 prldap_set_session_option( LDAP *ld, void *sessionarg, int option, ... )
111 {
112 int rc = LDAP_SUCCESS; /* optimistic */
113 PRLDAPIOSessionArg *prsessp = NULL;
114 va_list ap;
115
116 if ( NULL != ld ) {
117 if ( LDAP_SUCCESS !=
118 ( rc = prldap_session_arg_from_ld( ld, &prsessp ))) {
119 return( rc );
120 }
121 } else if ( NULL != sessionarg ) {
122 prsessp = (PRLDAPIOSessionArg *)sessionarg;
123 }
124
125 va_start( ap, option );
126 switch ( option ) {
127 case PRLDAP_OPT_IO_MAX_TIMEOUT:
128 rc = prldap_set_io_max_timeout( prsessp, va_arg( ap, int ));
129 break;
130 default:
131 rc = LDAP_PARAM_ERROR;
132 }
133 va_end( ap );
134
135 return( rc );
136 }
137
138
139 /*
140 * Function: prldap_get_session_option().
141 *
142 * Given an LDAP session handle or a session argument such is passed to
143 * SOCKET, POLL, NEWHANDLE, or DISPOSEHANDLE extended I/O callbacks, retrieve
144 * the setting for an option that affects the prldap layer.
145 *
146 * If 'ld' and 'session" are both NULL, the default option value for all new
147 * new prldap sessions is retrieved.
148 *
149 * Returns an LDAP API error code (LDAP_SUCCESS if all goes well).
150 */
prldap_get_session_option(LDAP * ld,void * sessionarg,int option,...)151 int LDAP_CALL prldap_get_session_option( LDAP *ld, void *sessionarg,
152 int option, ... )
153 {
154 int rc = LDAP_SUCCESS; /* optimistic */
155 PRLDAPIOSessionArg *prsessp = NULL;
156 va_list ap;
157
158 if ( NULL != ld ) {
159 if ( LDAP_SUCCESS !=
160 ( rc = prldap_session_arg_from_ld( ld, &prsessp ))) {
161 return( rc );
162 }
163 } else if ( NULL != sessionarg ) {
164 prsessp = (PRLDAPIOSessionArg *)sessionarg;
165 }
166
167 va_start( ap, option );
168 switch ( option ) {
169 case PRLDAP_OPT_IO_MAX_TIMEOUT:
170 rc = prldap_get_io_max_timeout( prsessp, va_arg( ap, int * ));
171 break;
172 default:
173 rc = LDAP_PARAM_ERROR;
174 }
175 va_end( ap );
176
177 return( rc );
178 }
179
180
181 /*
182 * Function: prldap_set_session_info().
183 *
184 * Given an LDAP session handle, set some application-specific data.
185 *
186 * Returns an LDAP API error code (LDAP_SUCCESS if all goes well).
187 */
188 int LDAP_CALL
prldap_set_session_info(LDAP * ld,void * sessionarg,PRLDAPSessionInfo * seip)189 prldap_set_session_info( LDAP *ld, void *sessionarg, PRLDAPSessionInfo *seip )
190 {
191 int rc;
192 PRLDAPIOSessionArg *prsessp;
193
194 if ( seip == NULL || PRLDAP_SESSIONINFO_SIZE != seip->seinfo_size ) {
195 ldap_set_lderrno( ld, LDAP_PARAM_ERROR, NULL, NULL );
196 return( LDAP_PARAM_ERROR );
197 }
198
199 if ( NULL != ld ) {
200 if ( LDAP_SUCCESS !=
201 ( rc = prldap_session_arg_from_ld( ld, &prsessp ))) {
202 return( rc );
203 }
204 } else if ( NULL != sessionarg ) {
205 prsessp = (PRLDAPIOSessionArg *)sessionarg;
206 } else {
207 ldap_set_lderrno( ld, LDAP_PARAM_ERROR, NULL, NULL );
208 return( LDAP_PARAM_ERROR );
209 }
210
211 prsessp->prsess_appdata = seip->seinfo_appdata;
212 return( LDAP_SUCCESS );
213 }
214
215
216 /*
217 * Function: prldap_get_session_info().
218 *
219 * Given an LDAP session handle, retrieve some application-specific data.
220 *
221 * Returns an LDAP API error code (LDAP_SUCCESS if all goes well, in
222 * which case the fields in the structure that seip points to are filled in).
223 */
224 int LDAP_CALL
prldap_get_session_info(LDAP * ld,void * sessionarg,PRLDAPSessionInfo * seip)225 prldap_get_session_info( LDAP *ld, void *sessionarg, PRLDAPSessionInfo *seip )
226 {
227 int rc;
228 PRLDAPIOSessionArg *prsessp;
229
230 if ( seip == NULL || PRLDAP_SESSIONINFO_SIZE != seip->seinfo_size ) {
231 ldap_set_lderrno( ld, LDAP_PARAM_ERROR, NULL, NULL );
232 return( LDAP_PARAM_ERROR );
233 }
234
235 if ( NULL != ld ) {
236 if ( LDAP_SUCCESS !=
237 ( rc = prldap_session_arg_from_ld( ld, &prsessp ))) {
238 return( rc );
239 }
240 } else if ( NULL != sessionarg ) {
241 prsessp = (PRLDAPIOSessionArg *)sessionarg;
242 } else {
243 ldap_set_lderrno( ld, LDAP_PARAM_ERROR, NULL, NULL );
244 return( LDAP_PARAM_ERROR );
245 }
246
247 seip->seinfo_appdata = prsessp->prsess_appdata;
248 return( LDAP_SUCCESS );
249 }
250
251
252 /*
253 * Function: prldap_set_socket_info().
254 *
255 * Given an integer fd and a void * argument such as those passed to the
256 * extended I/O callback functions, set socket specific information.
257 *
258 * Returns an LDAP API error code (LDAP_SUCCESS if all goes well).
259 *
260 * Note: it is only safe to change soinfo_prfd from within the SOCKET
261 * extended I/O callback function.
262 */
263 int LDAP_CALL
prldap_set_socket_info(int fd,void * socketarg,PRLDAPSocketInfo * soip)264 prldap_set_socket_info( int fd, void *socketarg, PRLDAPSocketInfo *soip )
265 {
266 PRLDAPIOSocketArg *prsockp;
267
268 if ( NULL == socketarg || NULL == soip ||
269 PRLDAP_SOCKETINFO_SIZE != soip->soinfo_size ) {
270 return( LDAP_PARAM_ERROR );
271 }
272
273 prsockp = (PRLDAPIOSocketArg *)socketarg;
274 prsockp->prsock_prfd = soip->soinfo_prfd;
275 prsockp->prsock_appdata = soip->soinfo_appdata;
276
277 return( LDAP_SUCCESS );
278 }
279
280
281 /*
282 * Function: prldap_get_socket_info().
283 *
284 * Given an integer fd and a void * argument such as those passed to the
285 * extended I/O callback functions, retrieve socket specific information.
286 *
287 * Returns an LDAP API error code (LDAP_SUCCESS if all goes well, in
288 * which case the fields in the structure that soip points to are filled in).
289 */
290 int LDAP_CALL
prldap_get_socket_info(int fd,void * socketarg,PRLDAPSocketInfo * soip)291 prldap_get_socket_info( int fd, void *socketarg, PRLDAPSocketInfo *soip )
292 {
293 PRLDAPIOSocketArg *prsockp;
294
295 if ( NULL == socketarg || NULL == soip ||
296 PRLDAP_SOCKETINFO_SIZE != soip->soinfo_size ) {
297 return( LDAP_PARAM_ERROR );
298 }
299
300 prsockp = (PRLDAPIOSocketArg *)socketarg;
301 soip->soinfo_prfd = prsockp->prsock_prfd;
302 soip->soinfo_appdata = prsockp->prsock_appdata;
303
304 return( LDAP_SUCCESS );
305 }
306
307 /*
308 * Function: prldap_get_default_socket_info().
309 *
310 * Given an LDAP session handle, retrieve socket specific information.
311 * If ld is NULL, LDAP_PARAM_ERROR is returned.
312 *
313 * Returns an LDAP API error code (LDAP_SUCCESS if all goes well, in
314 * which case the fields in the structure that soip points to are filled in).
315 */
316 int LDAP_CALL
prldap_get_default_socket_info(LDAP * ld,PRLDAPSocketInfo * soip)317 prldap_get_default_socket_info( LDAP *ld, PRLDAPSocketInfo *soip )
318 {
319 int rc;
320 PRLDAPIOSocketArg *prsockp;
321
322
323 if ( NULL == soip || PRLDAP_SOCKETINFO_SIZE != soip->soinfo_size ) {
324 ldap_set_lderrno( ld, LDAP_PARAM_ERROR, NULL, NULL );
325 return( LDAP_PARAM_ERROR );
326 }
327
328 if ( NULL != ld ) {
329 if ( LDAP_SUCCESS !=
330 ( rc = prldap_socket_arg_from_ld( ld, &prsockp ))) {
331 return( rc );
332 }
333 } else {
334 ldap_set_lderrno( ld, LDAP_PARAM_ERROR, NULL, NULL );
335 return( LDAP_PARAM_ERROR );
336 }
337
338 soip->soinfo_prfd = prsockp->prsock_prfd;
339 soip->soinfo_appdata = prsockp->prsock_appdata;
340
341 return( LDAP_SUCCESS );
342 }
343
344
345 /*
346 * Function: prldap_set_default_socket_info().
347 *
348 * Given an LDAP session handle, set socket specific information.
349 * If ld is NULL, LDAP_PARAM_ERROR is returned.
350 *
351 * Returns an LDAP API error code (LDAP_SUCCESS if all goes well, in
352 * which case the fields in the structure that soip points to are filled in).
353 */
354 int LDAP_CALL
prldap_set_default_socket_info(LDAP * ld,PRLDAPSocketInfo * soip)355 prldap_set_default_socket_info( LDAP *ld, PRLDAPSocketInfo *soip )
356 {
357 int rc;
358 PRLDAPIOSocketArg *prsockp;
359
360
361 if ( NULL == soip || PRLDAP_SOCKETINFO_SIZE != soip->soinfo_size ) {
362 ldap_set_lderrno( ld, LDAP_PARAM_ERROR, NULL, NULL );
363 return( LDAP_PARAM_ERROR );
364 }
365
366 if ( NULL != ld ) {
367 if ( LDAP_SUCCESS !=
368 ( rc = prldap_socket_arg_from_ld( ld, &prsockp ))) {
369 return( rc );
370 }
371 } else {
372 ldap_set_lderrno( ld, LDAP_PARAM_ERROR, NULL, NULL );
373 return( LDAP_PARAM_ERROR );
374 }
375
376 prsockp->prsock_prfd = soip->soinfo_prfd;
377 prsockp->prsock_appdata = soip->soinfo_appdata;
378
379 return( LDAP_SUCCESS );
380 }
381