xref: /reactos/dll/win32/wldap32/init.c (revision 6b9bd93f)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * WLDAP32 - LDAP support for Wine
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * Copyright 2005 Hans Leidekker
5c2c66affSColin Finck  *
6c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
7c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
8c2c66affSColin Finck  * License as published by the Free Software Foundation; either
9c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
10c2c66affSColin Finck  *
11c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
12c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14c2c66affSColin Finck  * Lesser General Public License for more details.
15c2c66affSColin Finck  *
16c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
17c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
18c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19c2c66affSColin Finck  */
20c2c66affSColin Finck 
21e6368408SAmine Khaldi #include "config.h"
22e6368408SAmine Khaldi #include "wine/port.h"
23e6368408SAmine Khaldi 
24e6368408SAmine Khaldi #include <stdio.h>
25e6368408SAmine Khaldi #include <stdarg.h>
26e6368408SAmine Khaldi #ifdef HAVE_LDAP_H
27e6368408SAmine Khaldi #include <ldap.h>
28e6368408SAmine Khaldi #endif
29e6368408SAmine Khaldi 
30e6368408SAmine Khaldi #include "windef.h"
31e6368408SAmine Khaldi #include "winbase.h"
32e6368408SAmine Khaldi #include "winnls.h"
33*6b9bd93fSAmine Khaldi #include "wine/winternl.h"
34e6368408SAmine Khaldi 
35c2c66affSColin Finck #include "winldap_private.h"
36e6368408SAmine Khaldi #include "wldap32.h"
37e6368408SAmine Khaldi #include "wine/debug.h"
38c2c66affSColin Finck 
39c2c66affSColin Finck #ifdef HAVE_LDAP
40c2c66affSColin Finck /* Should eventually be determined by the algorithm documented on MSDN. */
41c2c66affSColin Finck static const WCHAR defaulthost[] = { 'l','o','c','a','l','h','o','s','t',0 };
42c2c66affSColin Finck 
43c2c66affSColin Finck /* Split a space separated string of hostnames into a string array */
split_hostnames(const char * hostnames)44c2c66affSColin Finck static char **split_hostnames( const char *hostnames )
45c2c66affSColin Finck {
46c2c66affSColin Finck     char **res, *str, *p, *q;
47c2c66affSColin Finck     unsigned int i = 0;
48c2c66affSColin Finck 
49c2c66affSColin Finck     str = strdupU( hostnames );
50c2c66affSColin Finck     if (!str) return NULL;
51c2c66affSColin Finck 
52c2c66affSColin Finck     p = str;
53c2c66affSColin Finck     while (isspace( *p )) p++;
54c2c66affSColin Finck     if (*p) i++;
55c2c66affSColin Finck 
56c2c66affSColin Finck     while (*p)
57c2c66affSColin Finck     {
58c2c66affSColin Finck         if (isspace( *p ))
59c2c66affSColin Finck         {
60c2c66affSColin Finck             while (isspace( *p )) p++;
61c2c66affSColin Finck             if (*p) i++;
62c2c66affSColin Finck         }
63c2c66affSColin Finck         p++;
64c2c66affSColin Finck     }
65c2c66affSColin Finck 
66e6368408SAmine Khaldi     if (!(res = heap_alloc( (i + 1) * sizeof(char *) )))
67c2c66affSColin Finck     {
68e6368408SAmine Khaldi         heap_free( str );
69c2c66affSColin Finck         return NULL;
70c2c66affSColin Finck     }
71c2c66affSColin Finck 
72c2c66affSColin Finck     p = str;
73c2c66affSColin Finck     while (isspace( *p )) p++;
74c2c66affSColin Finck 
75c2c66affSColin Finck     q = p;
76c2c66affSColin Finck     i = 0;
77c2c66affSColin Finck 
78c2c66affSColin Finck     while (*p)
79c2c66affSColin Finck     {
80c2c66affSColin Finck         if (p[1] != '\0')
81c2c66affSColin Finck         {
82c2c66affSColin Finck             if (isspace( *p ))
83c2c66affSColin Finck             {
84c2c66affSColin Finck                 *p = '\0'; p++;
85c2c66affSColin Finck                 res[i] = strdupU( q );
86c2c66affSColin Finck                 if (!res[i]) goto oom;
87c2c66affSColin Finck                 i++;
88c2c66affSColin Finck 
89c2c66affSColin Finck                 while (isspace( *p )) p++;
90c2c66affSColin Finck                 q = p;
91c2c66affSColin Finck             }
92c2c66affSColin Finck         }
93c2c66affSColin Finck         else
94c2c66affSColin Finck         {
95c2c66affSColin Finck             res[i] = strdupU( q );
96c2c66affSColin Finck             if (!res[i]) goto oom;
97c2c66affSColin Finck             i++;
98c2c66affSColin Finck         }
99c2c66affSColin Finck         p++;
100c2c66affSColin Finck     }
101c2c66affSColin Finck     res[i] = NULL;
102c2c66affSColin Finck 
103e6368408SAmine Khaldi     heap_free( str );
104c2c66affSColin Finck     return res;
105c2c66affSColin Finck 
106c2c66affSColin Finck oom:
107c2c66affSColin Finck     while (i > 0) strfreeU( res[--i] );
108c2c66affSColin Finck 
109e6368408SAmine Khaldi     heap_free( res );
110e6368408SAmine Khaldi     heap_free( str );
111c2c66affSColin Finck 
112c2c66affSColin Finck     return NULL;
113c2c66affSColin Finck }
114c2c66affSColin Finck 
115c2c66affSColin Finck /* Determine if a URL starts with a known LDAP scheme */
has_ldap_scheme(char * url)116c2c66affSColin Finck static BOOL has_ldap_scheme( char *url )
117c2c66affSColin Finck {
118*6b9bd93fSAmine Khaldi     return !_strnicmp( url, "ldap://", 7 )  ||
119*6b9bd93fSAmine Khaldi            !_strnicmp( url, "ldaps://", 8 ) ||
120*6b9bd93fSAmine Khaldi            !_strnicmp( url, "ldapi://", 8 ) ||
121*6b9bd93fSAmine Khaldi            !_strnicmp( url, "cldap://", 8 );
122c2c66affSColin Finck }
123c2c66affSColin Finck 
124c2c66affSColin Finck /* Flatten an array of hostnames into a space separated string of URLs.
125c2c66affSColin Finck  * Prepend a given scheme and append a given port number to each hostname
126c2c66affSColin Finck  * if necessary.
127c2c66affSColin Finck  */
join_hostnames(const char * scheme,char ** hostnames,ULONG portnumber)128c2c66affSColin Finck static char *join_hostnames( const char *scheme, char **hostnames, ULONG portnumber )
129c2c66affSColin Finck {
130c2c66affSColin Finck     char *res, *p, *q, **v;
131c2c66affSColin Finck     unsigned int i = 0, size = 0;
132c2c66affSColin Finck     static const char sep[] = " ", fmt[] = ":%d";
133c2c66affSColin Finck     char port[7];
134c2c66affSColin Finck 
135c2c66affSColin Finck     sprintf( port, fmt, portnumber );
136c2c66affSColin Finck 
137c2c66affSColin Finck     for (v = hostnames; *v; v++)
138c2c66affSColin Finck     {
139c2c66affSColin Finck         if (!has_ldap_scheme( *v ))
140c2c66affSColin Finck         {
141c2c66affSColin Finck             size += strlen( scheme );
142c2c66affSColin Finck             q = *v;
143c2c66affSColin Finck         }
144c2c66affSColin Finck         else
145c2c66affSColin Finck             /* skip past colon in scheme prefix */
146c2c66affSColin Finck             q = strchr( *v, '/' );
147c2c66affSColin Finck 
148c2c66affSColin Finck         size += strlen( *v );
149c2c66affSColin Finck 
150c2c66affSColin Finck         if (!strchr( q, ':' ))
151c2c66affSColin Finck             size += strlen( port );
152c2c66affSColin Finck 
153c2c66affSColin Finck         i++;
154c2c66affSColin Finck     }
155c2c66affSColin Finck 
156c2c66affSColin Finck     size += (i - 1) * strlen( sep );
157e6368408SAmine Khaldi     if (!(res = heap_alloc( size + 1 ))) return NULL;
158c2c66affSColin Finck 
159c2c66affSColin Finck     p = res;
160c2c66affSColin Finck     for (v = hostnames; *v; v++)
161c2c66affSColin Finck     {
162c2c66affSColin Finck         if (v != hostnames)
163c2c66affSColin Finck         {
164c2c66affSColin Finck             strcpy( p, sep );
165c2c66affSColin Finck             p += strlen( sep );
166c2c66affSColin Finck         }
167c2c66affSColin Finck 
168c2c66affSColin Finck         if (!has_ldap_scheme( *v ))
169c2c66affSColin Finck         {
170c2c66affSColin Finck             strcpy( p, scheme );
171c2c66affSColin Finck             p += strlen( scheme );
172c2c66affSColin Finck             q = *v;
173c2c66affSColin Finck         }
174c2c66affSColin Finck         else
175c2c66affSColin Finck             /* skip past colon in scheme prefix */
176c2c66affSColin Finck             q = strchr( *v, '/' );
177c2c66affSColin Finck 
178c2c66affSColin Finck         strcpy( p, *v );
179c2c66affSColin Finck         p += strlen( *v );
180c2c66affSColin Finck 
181c2c66affSColin Finck         if (!strchr( q, ':' ))
182c2c66affSColin Finck         {
183c2c66affSColin Finck             strcpy( p, port );
184c2c66affSColin Finck             p += strlen( port );
185c2c66affSColin Finck         }
186c2c66affSColin Finck     }
187c2c66affSColin Finck     return res;
188c2c66affSColin Finck }
189c2c66affSColin Finck 
urlify_hostnames(const char * scheme,char * hostnames,ULONG port)190c2c66affSColin Finck static char *urlify_hostnames( const char *scheme, char *hostnames, ULONG port )
191c2c66affSColin Finck {
192c2c66affSColin Finck     char *url = NULL, **strarray;
193c2c66affSColin Finck 
194c2c66affSColin Finck     strarray = split_hostnames( hostnames );
195c2c66affSColin Finck     if (strarray)
196c2c66affSColin Finck         url = join_hostnames( scheme, strarray, port );
197c2c66affSColin Finck     else
198c2c66affSColin Finck         return NULL;
199c2c66affSColin Finck 
200c2c66affSColin Finck     strarrayfreeU( strarray );
201c2c66affSColin Finck     return url;
202c2c66affSColin Finck }
203c2c66affSColin Finck #endif
204c2c66affSColin Finck 
205e6368408SAmine Khaldi WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
206e6368408SAmine Khaldi 
20787c506baSAmine Khaldi #ifdef HAVE_LDAP
create_context(const char * url)20887c506baSAmine Khaldi static LDAP *create_context( const char *url )
20987c506baSAmine Khaldi {
21087c506baSAmine Khaldi     LDAP *ld;
21187c506baSAmine Khaldi     int version = LDAP_VERSION3;
21287c506baSAmine Khaldi     if (ldap_initialize( &ld, url ) != LDAP_SUCCESS) return NULL;
21387c506baSAmine Khaldi     ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
21487c506baSAmine Khaldi     return ld;
21587c506baSAmine Khaldi }
21687c506baSAmine Khaldi #endif
21787c506baSAmine Khaldi 
218c2c66affSColin Finck /***********************************************************************
219c2c66affSColin Finck  *      cldap_openA     (WLDAP32.@)
220c2c66affSColin Finck  *
221c2c66affSColin Finck  * See cldap_openW.
222c2c66affSColin Finck  */
cldap_openA(PCHAR hostname,ULONG portnumber)223c2c66affSColin Finck WLDAP32_LDAP * CDECL cldap_openA( PCHAR hostname, ULONG portnumber )
224c2c66affSColin Finck {
225c2c66affSColin Finck #ifdef HAVE_LDAP
226c2c66affSColin Finck     WLDAP32_LDAP *ld = NULL;
227c2c66affSColin Finck     WCHAR *hostnameW = NULL;
228c2c66affSColin Finck 
229c2c66affSColin Finck     TRACE( "(%s, %d)\n", debugstr_a(hostname), portnumber );
230c2c66affSColin Finck 
231c2c66affSColin Finck     if (hostname) {
232c2c66affSColin Finck         hostnameW = strAtoW( hostname );
233c2c66affSColin Finck         if (!hostnameW) goto exit;
234c2c66affSColin Finck     }
235c2c66affSColin Finck 
236c2c66affSColin Finck     ld = cldap_openW( hostnameW, portnumber );
237c2c66affSColin Finck 
238c2c66affSColin Finck exit:
239c2c66affSColin Finck     strfreeW( hostnameW );
240c2c66affSColin Finck     return ld;
241c2c66affSColin Finck 
242c2c66affSColin Finck #else
243c2c66affSColin Finck     return NULL;
244c2c66affSColin Finck #endif
245c2c66affSColin Finck }
246c2c66affSColin Finck 
247c2c66affSColin Finck /***********************************************************************
248c2c66affSColin Finck  *      cldap_openW     (WLDAP32.@)
249c2c66affSColin Finck  *
250c2c66affSColin Finck  * Initialize an LDAP context and create a UDP connection.
251c2c66affSColin Finck  *
252c2c66affSColin Finck  * PARAMS
253c2c66affSColin Finck  *  hostname   [I] Name of the host to connect to.
254c2c66affSColin Finck  *  portnumber [I] Port number to use.
255c2c66affSColin Finck  *
256c2c66affSColin Finck  * RETURNS
257c2c66affSColin Finck  *  Success: Pointer to an LDAP context.
258c2c66affSColin Finck  *  Failure: NULL
259c2c66affSColin Finck  *
260c2c66affSColin Finck  * NOTES
261c2c66affSColin Finck  *  The hostname string can be a space separated string of hostnames,
262c2c66affSColin Finck  *  in which case the LDAP runtime will try to connect to the hosts
263c2c66affSColin Finck  *  in order, until a connection can be made. A hostname may have a
264c2c66affSColin Finck  *  trailing port number (separated from the hostname by a ':'), which
265c2c66affSColin Finck  *  will take precedence over the port number supplied as a parameter
266c2c66affSColin Finck  *  to this function.
267c2c66affSColin Finck  */
cldap_openW(PWCHAR hostname,ULONG portnumber)268c2c66affSColin Finck WLDAP32_LDAP * CDECL cldap_openW( PWCHAR hostname, ULONG portnumber )
269c2c66affSColin Finck {
270c2c66affSColin Finck #ifdef HAVE_LDAP
271c2c66affSColin Finck     LDAP *ld = NULL;
272c2c66affSColin Finck     char *hostnameU = NULL, *url = NULL;
273c2c66affSColin Finck 
274c2c66affSColin Finck     TRACE( "(%s, %d)\n", debugstr_w(hostname), portnumber );
275c2c66affSColin Finck 
276c2c66affSColin Finck     if (hostname) {
277c2c66affSColin Finck         hostnameU = strWtoU( hostname );
278c2c66affSColin Finck         if (!hostnameU) goto exit;
279c2c66affSColin Finck     }
280c2c66affSColin Finck     else {
281c2c66affSColin Finck         hostnameU = strWtoU( defaulthost );
282c2c66affSColin Finck         if (!hostnameU) goto exit;
283c2c66affSColin Finck     }
284c2c66affSColin Finck 
285c2c66affSColin Finck     url = urlify_hostnames( "cldap://", hostnameU, portnumber );
286c2c66affSColin Finck     if (!url) goto exit;
287c2c66affSColin Finck 
28887c506baSAmine Khaldi     ld = create_context( url );
289c2c66affSColin Finck 
290c2c66affSColin Finck exit:
291c2c66affSColin Finck     strfreeU( hostnameU );
292c2c66affSColin Finck     strfreeU( url );
293c2c66affSColin Finck     return ld;
294c2c66affSColin Finck 
295c2c66affSColin Finck #else
296c2c66affSColin Finck     return NULL;
297c2c66affSColin Finck #endif
298c2c66affSColin Finck }
299c2c66affSColin Finck 
300c2c66affSColin Finck /***********************************************************************
301c2c66affSColin Finck  *      ldap_connect     (WLDAP32.@)
302c2c66affSColin Finck  *
303c2c66affSColin Finck  * Connect to an LDAP server.
304c2c66affSColin Finck  *
305c2c66affSColin Finck  * PARAMS
306c2c66affSColin Finck  *  ld      [I] Pointer to an LDAP context.
307c2c66affSColin Finck  *  timeout [I] Pointer to an l_timeval structure specifying the
308c2c66affSColin Finck  *              timeout in seconds.
309c2c66affSColin Finck  *
310c2c66affSColin Finck  * RETURNS
311c2c66affSColin Finck  *  Success: LDAP_SUCCESS
312c2c66affSColin Finck  *  Failure: An LDAP error code.
313c2c66affSColin Finck  *
314c2c66affSColin Finck  * NOTES
315c2c66affSColin Finck  *  The timeout parameter may be NULL in which case a default timeout
316c2c66affSColin Finck  *  value will be used.
317c2c66affSColin Finck  */
ldap_connect(WLDAP32_LDAP * ld,struct l_timeval * timeout)318c2c66affSColin Finck ULONG CDECL ldap_connect( WLDAP32_LDAP *ld, struct l_timeval *timeout )
319c2c66affSColin Finck {
320c2c66affSColin Finck     TRACE( "(%p, %p)\n", ld, timeout );
321c2c66affSColin Finck 
322c2c66affSColin Finck     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
323c2c66affSColin Finck     return WLDAP32_LDAP_SUCCESS; /* FIXME: do something, e.g. ping the host */
324c2c66affSColin Finck }
325c2c66affSColin Finck 
326c2c66affSColin Finck /***********************************************************************
327c2c66affSColin Finck  *      ldap_initA     (WLDAP32.@)
328c2c66affSColin Finck  *
329c2c66affSColin Finck  * See ldap_initW.
330c2c66affSColin Finck  */
ldap_initA(const PCHAR hostname,ULONG portnumber)331c2c66affSColin Finck WLDAP32_LDAP *  CDECL ldap_initA( const PCHAR hostname, ULONG portnumber )
332c2c66affSColin Finck {
333c2c66affSColin Finck #ifdef HAVE_LDAP
334c2c66affSColin Finck     WLDAP32_LDAP *ld = NULL;
335c2c66affSColin Finck     WCHAR *hostnameW = NULL;
336c2c66affSColin Finck 
337c2c66affSColin Finck     TRACE( "(%s, %d)\n", debugstr_a(hostname), portnumber );
338c2c66affSColin Finck 
339c2c66affSColin Finck     if (hostname) {
340c2c66affSColin Finck         hostnameW = strAtoW( hostname );
341c2c66affSColin Finck         if (!hostnameW) goto exit;
342c2c66affSColin Finck     }
343c2c66affSColin Finck 
344c2c66affSColin Finck     ld = ldap_initW( hostnameW, portnumber );
345c2c66affSColin Finck 
346c2c66affSColin Finck exit:
347c2c66affSColin Finck     strfreeW( hostnameW );
348c2c66affSColin Finck     return ld;
349c2c66affSColin Finck 
350c2c66affSColin Finck #else
351c2c66affSColin Finck     return NULL;
352c2c66affSColin Finck #endif
353c2c66affSColin Finck }
354c2c66affSColin Finck 
355c2c66affSColin Finck /***********************************************************************
356c2c66affSColin Finck  *      ldap_initW     (WLDAP32.@)
357c2c66affSColin Finck  *
358c2c66affSColin Finck  * Initialize an LDAP context and create a TCP connection.
359c2c66affSColin Finck  *
360c2c66affSColin Finck  * PARAMS
361c2c66affSColin Finck  *  hostname   [I] Name of the host to connect to.
362c2c66affSColin Finck  *  portnumber [I] Port number to use.
363c2c66affSColin Finck  *
364c2c66affSColin Finck  * RETURNS
365c2c66affSColin Finck  *  Success: Pointer to an LDAP context.
366c2c66affSColin Finck  *  Failure: NULL
367c2c66affSColin Finck  *
368c2c66affSColin Finck  * NOTES
369c2c66affSColin Finck  *  The hostname string can be a space separated string of hostnames,
370c2c66affSColin Finck  *  in which case the LDAP runtime will try to connect to the hosts
371c2c66affSColin Finck  *  in order, until a connection can be made. A hostname may have a
372c2c66affSColin Finck  *  trailing port number (separated from the hostname by a ':'), which
373c2c66affSColin Finck  *  will take precedence over the port number supplied as a parameter
374c2c66affSColin Finck  *  to this function. The connection will not be made until the first
375c2c66affSColin Finck  *  LDAP function that needs it is called.
376c2c66affSColin Finck  */
ldap_initW(const PWCHAR hostname,ULONG portnumber)377c2c66affSColin Finck WLDAP32_LDAP * CDECL ldap_initW( const PWCHAR hostname, ULONG portnumber )
378c2c66affSColin Finck {
379c2c66affSColin Finck #ifdef HAVE_LDAP
380c2c66affSColin Finck     LDAP *ld = NULL;
381c2c66affSColin Finck     char *hostnameU = NULL, *url = NULL;
382c2c66affSColin Finck 
383c2c66affSColin Finck     TRACE( "(%s, %d)\n", debugstr_w(hostname), portnumber );
384c2c66affSColin Finck 
385c2c66affSColin Finck     if (hostname) {
386c2c66affSColin Finck         hostnameU = strWtoU( hostname );
387c2c66affSColin Finck         if (!hostnameU) goto exit;
388c2c66affSColin Finck     }
389c2c66affSColin Finck     else {
390c2c66affSColin Finck         hostnameU = strWtoU( defaulthost );
391c2c66affSColin Finck         if (!hostnameU) goto exit;
392c2c66affSColin Finck     }
393c2c66affSColin Finck 
394c2c66affSColin Finck     url = urlify_hostnames( "ldap://", hostnameU, portnumber );
395c2c66affSColin Finck     if (!url) goto exit;
396c2c66affSColin Finck 
39787c506baSAmine Khaldi     ld = create_context( url );
398c2c66affSColin Finck 
399c2c66affSColin Finck exit:
400c2c66affSColin Finck     strfreeU( hostnameU );
401c2c66affSColin Finck     strfreeU( url );
402c2c66affSColin Finck     return ld;
403c2c66affSColin Finck 
404c2c66affSColin Finck #else
405c2c66affSColin Finck     return NULL;
406c2c66affSColin Finck #endif
407c2c66affSColin Finck }
408c2c66affSColin Finck 
409c2c66affSColin Finck /***********************************************************************
410c2c66affSColin Finck  *      ldap_openA     (WLDAP32.@)
411c2c66affSColin Finck  *
412c2c66affSColin Finck  * See ldap_openW.
413c2c66affSColin Finck  */
ldap_openA(PCHAR hostname,ULONG portnumber)414c2c66affSColin Finck WLDAP32_LDAP * CDECL ldap_openA( PCHAR hostname, ULONG portnumber )
415c2c66affSColin Finck {
416c2c66affSColin Finck #ifdef HAVE_LDAP
417c2c66affSColin Finck     WLDAP32_LDAP *ld = NULL;
418c2c66affSColin Finck     WCHAR *hostnameW = NULL;
419c2c66affSColin Finck 
420c2c66affSColin Finck     TRACE( "(%s, %d)\n", debugstr_a(hostname), portnumber );
421c2c66affSColin Finck 
422c2c66affSColin Finck     if (hostname) {
423c2c66affSColin Finck         hostnameW = strAtoW( hostname );
424c2c66affSColin Finck         if (!hostnameW) goto exit;
425c2c66affSColin Finck     }
426c2c66affSColin Finck 
427c2c66affSColin Finck     ld = ldap_openW( hostnameW, portnumber );
428c2c66affSColin Finck 
429c2c66affSColin Finck exit:
430c2c66affSColin Finck     strfreeW( hostnameW );
431c2c66affSColin Finck     return ld;
432c2c66affSColin Finck 
433c2c66affSColin Finck #else
434c2c66affSColin Finck     return NULL;
435c2c66affSColin Finck #endif
436c2c66affSColin Finck }
437c2c66affSColin Finck 
438c2c66affSColin Finck /***********************************************************************
439c2c66affSColin Finck  *      ldap_openW     (WLDAP32.@)
440c2c66affSColin Finck  *
441c2c66affSColin Finck  * Initialize an LDAP context and create a TCP connection.
442c2c66affSColin Finck  *
443c2c66affSColin Finck  * PARAMS
444c2c66affSColin Finck  *  hostname   [I] Name of the host to connect to.
445c2c66affSColin Finck  *  portnumber [I] Port number to use.
446c2c66affSColin Finck  *
447c2c66affSColin Finck  * RETURNS
448c2c66affSColin Finck  *  Success: Pointer to an LDAP context.
449c2c66affSColin Finck  *  Failure: NULL
450c2c66affSColin Finck  *
451c2c66affSColin Finck  * NOTES
452c2c66affSColin Finck  *  The hostname string can be a space separated string of hostnames,
453c2c66affSColin Finck  *  in which case the LDAP runtime will try to connect to the hosts
454c2c66affSColin Finck  *  in order, until a connection can be made. A hostname may have a
455c2c66affSColin Finck  *  trailing port number (separated from the hostname by a ':'), which
456c2c66affSColin Finck  *  will take precedence over the port number supplied as a parameter
457c2c66affSColin Finck  *  to this function.
458c2c66affSColin Finck  */
ldap_openW(PWCHAR hostname,ULONG portnumber)459c2c66affSColin Finck WLDAP32_LDAP * CDECL ldap_openW( PWCHAR hostname, ULONG portnumber )
460c2c66affSColin Finck {
461c2c66affSColin Finck #ifdef HAVE_LDAP
462c2c66affSColin Finck     LDAP *ld = NULL;
463c2c66affSColin Finck     char *hostnameU = NULL, *url = NULL;
464c2c66affSColin Finck 
465c2c66affSColin Finck     TRACE( "(%s, %d)\n", debugstr_w(hostname), portnumber );
466c2c66affSColin Finck 
467c2c66affSColin Finck     if (hostname) {
468c2c66affSColin Finck         hostnameU = strWtoU( hostname );
469c2c66affSColin Finck         if (!hostnameU) goto exit;
470c2c66affSColin Finck     }
471c2c66affSColin Finck     else {
472c2c66affSColin Finck         hostnameU = strWtoU( defaulthost );
473c2c66affSColin Finck         if (!hostnameU) goto exit;
474c2c66affSColin Finck     }
475c2c66affSColin Finck 
476c2c66affSColin Finck     url = urlify_hostnames( "ldap://", hostnameU, portnumber );
477c2c66affSColin Finck     if (!url) goto exit;
478c2c66affSColin Finck 
47987c506baSAmine Khaldi     ld = create_context( url );
480c2c66affSColin Finck 
481c2c66affSColin Finck exit:
482c2c66affSColin Finck     strfreeU( hostnameU );
483c2c66affSColin Finck     strfreeU( url );
484c2c66affSColin Finck     return ld;
485c2c66affSColin Finck 
486c2c66affSColin Finck #else
487c2c66affSColin Finck     return NULL;
488c2c66affSColin Finck #endif
489c2c66affSColin Finck }
490c2c66affSColin Finck 
491c2c66affSColin Finck /***********************************************************************
492c2c66affSColin Finck  *      ldap_sslinitA     (WLDAP32.@)
493c2c66affSColin Finck  *
494c2c66affSColin Finck  * See ldap_sslinitW.
495c2c66affSColin Finck  */
ldap_sslinitA(PCHAR hostname,ULONG portnumber,int secure)496c2c66affSColin Finck WLDAP32_LDAP * CDECL ldap_sslinitA( PCHAR hostname, ULONG portnumber, int secure )
497c2c66affSColin Finck {
498c2c66affSColin Finck #ifdef HAVE_LDAP
499c2c66affSColin Finck     WLDAP32_LDAP *ld;
500c2c66affSColin Finck     WCHAR *hostnameW = NULL;
501c2c66affSColin Finck 
502c2c66affSColin Finck     TRACE( "(%s, %d, 0x%08x)\n", debugstr_a(hostname), portnumber, secure );
503c2c66affSColin Finck 
504c2c66affSColin Finck     if (hostname) {
505c2c66affSColin Finck         hostnameW = strAtoW( hostname );
506c2c66affSColin Finck         if (!hostnameW) return NULL;
507c2c66affSColin Finck     }
508c2c66affSColin Finck 
509c2c66affSColin Finck     ld  = ldap_sslinitW( hostnameW, portnumber, secure );
510c2c66affSColin Finck 
511c2c66affSColin Finck     strfreeW( hostnameW );
512c2c66affSColin Finck     return ld;
513c2c66affSColin Finck 
514c2c66affSColin Finck #else
515c2c66affSColin Finck     return NULL;
516c2c66affSColin Finck #endif
517c2c66affSColin Finck }
518c2c66affSColin Finck 
519c2c66affSColin Finck /***********************************************************************
520c2c66affSColin Finck  *      ldap_sslinitW     (WLDAP32.@)
521c2c66affSColin Finck  *
522c2c66affSColin Finck  * Initialize an LDAP context and create a secure TCP connection.
523c2c66affSColin Finck  *
524c2c66affSColin Finck  * PARAMS
525c2c66affSColin Finck  *  hostname   [I] Name of the host to connect to.
526c2c66affSColin Finck  *  portnumber [I] Port number to use.
527c2c66affSColin Finck  *  secure     [I] Ask the server to create an SSL connection.
528c2c66affSColin Finck  *
529c2c66affSColin Finck  * RETURNS
530c2c66affSColin Finck  *  Success: Pointer to an LDAP context.
531c2c66affSColin Finck  *  Failure: NULL
532c2c66affSColin Finck  *
533c2c66affSColin Finck  * NOTES
534c2c66affSColin Finck  *  The hostname string can be a space separated string of hostnames,
535c2c66affSColin Finck  *  in which case the LDAP runtime will try to connect to the hosts
536c2c66affSColin Finck  *  in order, until a connection can be made. A hostname may have a
537c2c66affSColin Finck  *  trailing port number (separated from the hostname by a ':'), which
538c2c66affSColin Finck  *  will take precedence over the port number supplied as a parameter
539c2c66affSColin Finck  *  to this function. The connection will not be made until the first
540c2c66affSColin Finck  *  LDAP function that needs it is called.
541c2c66affSColin Finck  */
ldap_sslinitW(PWCHAR hostname,ULONG portnumber,int secure)542c2c66affSColin Finck WLDAP32_LDAP * CDECL ldap_sslinitW( PWCHAR hostname, ULONG portnumber, int secure )
543c2c66affSColin Finck {
544c2c66affSColin Finck #ifdef HAVE_LDAP
545c2c66affSColin Finck     WLDAP32_LDAP *ld = NULL;
546c2c66affSColin Finck     char *hostnameU = NULL, *url = NULL;
547c2c66affSColin Finck 
548c2c66affSColin Finck     TRACE( "(%s, %d, 0x%08x)\n", debugstr_w(hostname), portnumber, secure );
549c2c66affSColin Finck 
550c2c66affSColin Finck     if (hostname) {
551c2c66affSColin Finck         hostnameU = strWtoU( hostname );
552c2c66affSColin Finck         if (!hostnameU) goto exit;
553c2c66affSColin Finck     }
554c2c66affSColin Finck     else {
555c2c66affSColin Finck         hostnameU = strWtoU( defaulthost );
556c2c66affSColin Finck         if (!hostnameU) goto exit;
557c2c66affSColin Finck     }
558c2c66affSColin Finck 
559c2c66affSColin Finck     if (secure)
560c2c66affSColin Finck         url = urlify_hostnames( "ldaps://", hostnameU, portnumber );
561c2c66affSColin Finck     else
562c2c66affSColin Finck         url = urlify_hostnames( "ldap://", hostnameU, portnumber );
563c2c66affSColin Finck 
564c2c66affSColin Finck     if (!url) goto exit;
565c2c66affSColin Finck     ldap_initialize( &ld, url );
566c2c66affSColin Finck 
567c2c66affSColin Finck exit:
568c2c66affSColin Finck     strfreeU( hostnameU );
569c2c66affSColin Finck     strfreeU( url );
570c2c66affSColin Finck     return ld;
571c2c66affSColin Finck 
572c2c66affSColin Finck #else
573c2c66affSColin Finck     return NULL;
574c2c66affSColin Finck #endif
575c2c66affSColin Finck }
576c2c66affSColin Finck 
577c2c66affSColin Finck /***********************************************************************
578c2c66affSColin Finck  *      ldap_start_tls_sA     (WLDAP32.@)
579c2c66affSColin Finck  *
580c2c66affSColin Finck  * See ldap_start_tls_sW.
581c2c66affSColin Finck  */
ldap_start_tls_sA(WLDAP32_LDAP * ld,PULONG retval,WLDAP32_LDAPMessage ** result,PLDAPControlA * serverctrls,PLDAPControlA * clientctrls)582c2c66affSColin Finck ULONG CDECL ldap_start_tls_sA( WLDAP32_LDAP *ld, PULONG retval, WLDAP32_LDAPMessage **result,
583c2c66affSColin Finck     PLDAPControlA *serverctrls, PLDAPControlA *clientctrls )
584c2c66affSColin Finck {
585c2c66affSColin Finck     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
586c2c66affSColin Finck #ifdef HAVE_LDAP
587c2c66affSColin Finck     LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
588c2c66affSColin Finck 
589c2c66affSColin Finck     ret = WLDAP32_LDAP_NO_MEMORY;
590c2c66affSColin Finck 
591c2c66affSColin Finck     TRACE( "(%p, %p, %p, %p, %p)\n", ld, retval, result, serverctrls, clientctrls );
592c2c66affSColin Finck 
593c2c66affSColin Finck     if (!ld) return ~0u;
594c2c66affSColin Finck 
595c2c66affSColin Finck     if (serverctrls) {
596c2c66affSColin Finck         serverctrlsW = controlarrayAtoW( serverctrls );
597c2c66affSColin Finck         if (!serverctrlsW) goto exit;
598c2c66affSColin Finck     }
599c2c66affSColin Finck     if (clientctrls) {
600c2c66affSColin Finck         clientctrlsW = controlarrayAtoW( clientctrls );
601c2c66affSColin Finck         if (!clientctrlsW) goto exit;
602c2c66affSColin Finck     }
603c2c66affSColin Finck 
604c2c66affSColin Finck     ret = ldap_start_tls_sW( ld, retval, result, serverctrlsW, clientctrlsW );
605c2c66affSColin Finck 
606c2c66affSColin Finck exit:
607c2c66affSColin Finck     controlarrayfreeW( serverctrlsW );
608c2c66affSColin Finck     controlarrayfreeW( clientctrlsW );
609c2c66affSColin Finck 
610c2c66affSColin Finck #endif
611c2c66affSColin Finck     return ret;
612c2c66affSColin Finck }
613c2c66affSColin Finck 
614c2c66affSColin Finck /***********************************************************************
615c2c66affSColin Finck  *      ldap_start_tls_s     (WLDAP32.@)
616c2c66affSColin Finck  *
617c2c66affSColin Finck  * Start TLS encryption on an LDAP connection.
618c2c66affSColin Finck  *
619c2c66affSColin Finck  * PARAMS
620c2c66affSColin Finck  *  ld          [I] Pointer to an LDAP context.
621c2c66affSColin Finck  *  retval      [I] Return value from the server.
622c2c66affSColin Finck  *  result      [I] Response message from the server.
623c2c66affSColin Finck  *  serverctrls [I] Array of LDAP server controls.
624c2c66affSColin Finck  *  clientctrls [I] Array of LDAP client controls.
625c2c66affSColin Finck  *
626c2c66affSColin Finck  * RETURNS
627c2c66affSColin Finck  *  Success: LDAP_SUCCESS
628c2c66affSColin Finck  *  Failure: An LDAP error code.
629c2c66affSColin Finck  *
630c2c66affSColin Finck  * NOTES
631c2c66affSColin Finck  *  LDAP function that needs it is called.
632c2c66affSColin Finck  */
ldap_start_tls_sW(WLDAP32_LDAP * ld,PULONG retval,WLDAP32_LDAPMessage ** result,PLDAPControlW * serverctrls,PLDAPControlW * clientctrls)633c2c66affSColin Finck ULONG CDECL ldap_start_tls_sW( WLDAP32_LDAP *ld, PULONG retval, WLDAP32_LDAPMessage **result,
634c2c66affSColin Finck     PLDAPControlW *serverctrls, PLDAPControlW *clientctrls )
635c2c66affSColin Finck {
636c2c66affSColin Finck     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
637c2c66affSColin Finck #ifdef HAVE_LDAP
638c2c66affSColin Finck     LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
639c2c66affSColin Finck 
640c2c66affSColin Finck     ret = WLDAP32_LDAP_NO_MEMORY;
641c2c66affSColin Finck 
642c2c66affSColin Finck     TRACE( "(%p, %p, %p, %p, %p)\n", ld, retval, result, serverctrls, clientctrls );
643c2c66affSColin Finck 
644c2c66affSColin Finck     if (!ld) return ~0u;
645c2c66affSColin Finck 
646c2c66affSColin Finck     if (serverctrls) {
647c2c66affSColin Finck         serverctrlsU = controlarrayWtoU( serverctrls );
648c2c66affSColin Finck         if (!serverctrlsU) goto exit;
649c2c66affSColin Finck     }
650c2c66affSColin Finck     if (clientctrls) {
651c2c66affSColin Finck         clientctrlsU = controlarrayWtoU( clientctrls );
652c2c66affSColin Finck         if (!clientctrlsU) goto exit;
653c2c66affSColin Finck     }
654c2c66affSColin Finck 
655c2c66affSColin Finck     ret = map_error( ldap_start_tls_s( ld, serverctrlsU, clientctrlsU ));
656c2c66affSColin Finck 
657c2c66affSColin Finck exit:
658c2c66affSColin Finck     controlarrayfreeU( serverctrlsU );
659c2c66affSColin Finck     controlarrayfreeU( clientctrlsU );
660c2c66affSColin Finck 
661c2c66affSColin Finck #endif
662c2c66affSColin Finck     return ret;
663c2c66affSColin Finck }
664c2c66affSColin Finck 
665c2c66affSColin Finck /***********************************************************************
666c2c66affSColin Finck  *      ldap_startup     (WLDAP32.@)
667c2c66affSColin Finck  */
ldap_startup(PLDAP_VERSION_INFO version,HANDLE * instance)668c2c66affSColin Finck ULONG CDECL ldap_startup( PLDAP_VERSION_INFO version, HANDLE *instance )
669c2c66affSColin Finck {
670c2c66affSColin Finck     TRACE( "(%p, %p)\n", version, instance );
671c2c66affSColin Finck     return WLDAP32_LDAP_SUCCESS;
672c2c66affSColin Finck }
673c2c66affSColin Finck 
674c2c66affSColin Finck /***********************************************************************
675c2c66affSColin Finck  *      ldap_stop_tls_s     (WLDAP32.@)
676c2c66affSColin Finck  *
677c2c66affSColin Finck  * Stop TLS encryption on an LDAP connection.
678c2c66affSColin Finck  *
679c2c66affSColin Finck  * PARAMS
680c2c66affSColin Finck  *  ld [I] Pointer to an LDAP context.
681c2c66affSColin Finck  *
682c2c66affSColin Finck  * RETURNS
683c2c66affSColin Finck  *  Success: TRUE
684c2c66affSColin Finck  *  Failure: FALSE
685c2c66affSColin Finck  */
ldap_stop_tls_s(WLDAP32_LDAP * ld)686c2c66affSColin Finck BOOLEAN CDECL ldap_stop_tls_s( WLDAP32_LDAP *ld )
687c2c66affSColin Finck {
688c2c66affSColin Finck     TRACE( "(%p)\n", ld );
689c2c66affSColin Finck     return TRUE; /* FIXME: find a way to stop tls on a connection */
690c2c66affSColin Finck }
691