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