]> git.sur5r.net Git - openldap/blob - libraries/libldap/open.c
50641603c79ee26974d6560ad26f68959978a65c
[openldap] / libraries / libldap / open.c
1 /*
2  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
3  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
4  */
5 /*  Portions
6  *  Copyright (c) 1995 Regents of the University of Michigan.
7  *  All rights reserved.
8  *
9  *  open.c
10  */
11
12 #include "portable.h"
13
14 #include <stdio.h>
15 #include <stdlib.h>
16
17 #include <ac/socket.h>
18 #include <ac/string.h>
19 #include <ac/time.h>
20
21 #ifdef HAVE_SYS_PARAM_H
22 #include <sys/param.h>
23 #endif
24
25 #include "ldap-int.h"
26
27
28 /*
29  * ldap_open - initialize and connect to an ldap server.  A magic cookie to
30  * be used for future communication is returned on success, NULL on failure.
31  * "host" may be a space-separated list of hosts or IP addresses
32  *
33  * Example:
34  *      LDAP    *ld;
35  *      ld = ldap_open( hostname, port );
36  */
37
38 LDAP *
39 ldap_open( LDAP_CONST char *host, int port )
40 {
41         LDAP            *ld;
42         LDAPServer      *srv;
43
44         Debug( LDAP_DEBUG_TRACE, "ldap_open\n", 0, 0, 0 );
45
46         if (( ld = ldap_init( host, port )) == NULL ) {
47                 return( NULL );
48         }
49
50         if (( srv = (LDAPServer *)LDAP_CALLOC( 1, sizeof( LDAPServer ))) ==
51             NULL || ( ld->ld_defhost != NULL && ( srv->lsrv_host =
52             LDAP_STRDUP( ld->ld_defhost )) == NULL )) {
53                 if(srv != NULL) LDAP_FREE( (char*) srv );
54                 ldap_ld_free( ld, 0, NULL, NULL );
55                 return( NULL );
56         }
57         srv->lsrv_port = ld->ld_defport;
58
59         if (( ld->ld_defconn = ldap_new_connection( ld, &srv, 1,1,0 )) == NULL ) {
60                 if ( ld->ld_defhost != NULL ) LDAP_FREE( srv->lsrv_host );
61                 LDAP_FREE( (char *)srv );
62                 ldap_ld_free( ld, 0, NULL, NULL );
63                 return( NULL );
64         }
65         ++ld->ld_defconn->lconn_refcnt; /* so it never gets closed/freed */
66
67         Debug( LDAP_DEBUG_TRACE, "ldap_open successful, ld_host is %s\n",
68                 ( ld->ld_host == NULL ) ? "(null)" : ld->ld_host, 0, 0 );
69
70         return( ld );
71 }
72
73
74 /*
75  * ldap_init - initialize the LDAP library.  A magic cookie to be used for
76  * future communication is returned on success, NULL on failure.
77  * "host" may be a space-separated list of hosts or IP addresses
78  *
79  * Example:
80  *      LDAP    *ld;
81  *      ld = ldap_open( host, port );
82  */
83 LDAP *
84 ldap_init( LDAP_CONST char *defhost, int defport )
85 {
86         LDAP                    *ld;
87
88         if( ldap_int_global_options.ldo_valid != LDAP_INITIALIZED ) {
89                 ldap_int_initialize();
90         }
91
92         Debug( LDAP_DEBUG_TRACE, "ldap_init\n", 0, 0, 0 );
93
94 #ifdef HAVE_WINSOCK2
95 {       WORD wVersionRequested;
96         WSADATA wsaData;
97         int err;
98  
99         wVersionRequested = MAKEWORD( 2, 0 );
100  
101         err = WSAStartup( wVersionRequested, &wsaData );
102         if ( err != 0 ) {
103                 /* Tell the user that we couldn't find a usable */
104                 /* WinSock DLL.                                  */
105                 return NULL;
106         }
107  
108         /* Confirm that the WinSock DLL supports 2.0.*/
109         /* Note that if the DLL supports versions greater    */
110         /* than 2.0 in addition to 2.0, it will still return */
111         /* 2.0 in wVersion since that is the version we      */
112         /* requested.                                        */
113  
114         if ( LOBYTE( wsaData.wVersion ) != 2 ||
115                 HIBYTE( wsaData.wVersion ) != 0 )
116         {
117             /* Tell the user that we couldn't find a usable */
118             /* WinSock DLL.                                  */
119             WSACleanup( );
120             return NULL; 
121         }
122 }       /* The WinSock DLL is acceptable. Proceed. */
123
124 #elif HAVE_WINSOCK
125 {       WSADATA wsaData;
126         if ( WSAStartup( 0x0101, &wsaData ) != 0 ) {
127             return( NULL );
128         }
129 }
130 #endif
131
132         if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) {
133             WSACleanup( );
134                 return( NULL );
135         }
136    
137         /* copy the global options */
138         memcpy(&ld->ld_options, &ldap_int_global_options,
139                 sizeof(ld->ld_options));
140
141         ld->ld_valid = LDAP_VALID_SESSION;
142
143         /* but not pointers to malloc'ed items */
144         ld->ld_options.ldo_defbase = NULL;
145         ld->ld_options.ldo_defhost = NULL;
146         ld->ld_options.ldo_sctrls = NULL;
147         ld->ld_options.ldo_cctrls = NULL;
148
149         if ( defhost != NULL ) {
150                 ld->ld_options.ldo_defhost = LDAP_STRDUP( defhost );
151         } else {
152                 ld->ld_options.ldo_defhost = LDAP_STRDUP(
153                         ldap_int_global_options.ldo_defhost);
154         }
155
156         if ( ld->ld_options.ldo_defhost == NULL ) {
157                 LDAP_FREE( (char*)ld );
158             WSACleanup( );
159                 return( NULL );
160         }
161
162         if ( ldap_int_global_options.ldo_defbase != NULL ) {
163                 ld->ld_options.ldo_defbase = LDAP_STRDUP(
164                         ldap_int_global_options.ldo_defbase);
165         }
166
167         if (( ld->ld_selectinfo = ldap_new_select_info()) == NULL ) {
168                 LDAP_FREE( (char*) ld->ld_options.ldo_defhost );
169                 if ( ld->ld_options.ldo_defbase == NULL ) {
170                         LDAP_FREE( (char*) ld->ld_options.ldo_defbase );
171                 }
172                 LDAP_FREE( (char*) ld );
173             WSACleanup( );
174                 return( NULL );
175         }
176
177         if(defport != 0) {
178                 ld->ld_defport = defport;
179         }
180
181         ld->ld_lberoptions = LBER_USE_DER;
182
183 #if defined( STR_TRANSLATION ) && defined( LDAP_DEFAULT_CHARSET )
184         ld->ld_lberoptions |= LBER_TRANSLATE_STRINGS;
185 #if LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET
186         ldap_set_string_translators( ld, ldap_8859_to_t61, ldap_t61_to_8859 );
187 #endif /* LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET */
188 #endif /* STR_TRANSLATION && LDAP_DEFAULT_CHARSET */
189
190         /* we'll assume we're talking version 2 for now */
191         ld->ld_version = LDAP_VERSION2;
192
193         ber_pvt_sb_init( &(ld->ld_sb) );
194
195         return( ld );
196 }
197
198
199 int
200 open_ldap_connection( LDAP *ld, Sockbuf *sb, const char *host, int defport,
201         char **krbinstancep, int async )
202 {
203         int                     rc = -1;
204         int                             port;
205         const char              *p, *q;
206         char                    *r, *curhost, hostname[ 2*MAXHOSTNAMELEN ];
207
208         Debug( LDAP_DEBUG_TRACE, "open_ldap_connection\n", 0, 0, 0 );
209
210         defport = htons( (short) defport );
211
212         if ( host != NULL ) {
213                 for ( p = host; p != NULL && *p != '\0'; p = q ) {
214                         if (( q = strchr( p, ' ' )) != NULL ) {
215                                 strncpy( hostname, p, q - p );
216                                 hostname[ q - p ] = '\0';
217                                 curhost = hostname;
218                                 while ( *q == ' ' ) {
219                                     ++q;
220                                 }
221                         } else {
222                                 curhost = (char *) p;   /* avoid copy if possible */
223                                 q = NULL;
224                         }
225
226                         if (( r = strchr( curhost, ':' )) != NULL ) {
227                             if ( curhost != hostname ) {
228                                 strcpy( hostname, curhost );    /* now copy */
229                                 r = hostname + ( r - curhost );
230                                 curhost = hostname;
231                             }
232                             *r++ = '\0';
233                             port = htons( (short) atoi( r ) );
234                         } else {
235                             port = defport;   
236                         }
237
238                         if (( rc = ldap_connect_to_host( sb, curhost, 0L,
239                             port, async )) != -1 ) {
240                                 break;
241                         }
242                 }
243         } else {
244                 rc = ldap_connect_to_host( sb, NULL, htonl( INADDR_LOOPBACK ),
245                     defport, async );
246         }
247
248         if ( rc == -1 ) {
249                 return( rc );
250         }
251    
252         ber_pvt_sb_set_io( sb, &ber_pvt_sb_io_tcp, NULL );
253
254         if ( krbinstancep != NULL ) {
255 #ifdef HAVE_KERBEROS
256                 char *c;
257                 if (( *krbinstancep = ldap_host_connected_to( sb )) != NULL &&
258                     ( c = strchr( *krbinstancep, '.' )) != NULL ) {
259                         *c = '\0';
260                 }
261 #else /* HAVE_KERBEROS */
262                 krbinstancep = NULL;
263 #endif /* HAVE_KERBEROS */
264         }
265
266         return( 0 );
267 }