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