Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeninit.c
Go to the documentation of this file.
00001 /* 00002 * WLDAP32 - LDAP support for Wine 00003 * 00004 * Copyright 2005 Hans Leidekker 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include "config.h" 00022 00023 #include "wine/port.h" 00024 #include "wine/debug.h" 00025 00026 #include <stdio.h> 00027 #include <stdarg.h> 00028 00029 #include "windef.h" 00030 #include "winbase.h" 00031 #include "winnls.h" 00032 00033 #ifdef HAVE_LDAP_H 00034 #include <ldap.h> 00035 #endif 00036 00037 #include "winldap_private.h" 00038 #include "wldap32.h" 00039 00040 #ifdef HAVE_LDAP 00041 /* Should eventually be determined by the algorithm documented on MSDN. */ 00042 static const WCHAR defaulthost[] = { 'l','o','c','a','l','h','o','s','t',0 }; 00043 00044 /* Split a space separated string of hostnames into a string array */ 00045 static char **split_hostnames( const char *hostnames ) 00046 { 00047 char **res, *str, *p, *q; 00048 unsigned int i = 0; 00049 00050 str = strdupU( hostnames ); 00051 if (!str) return NULL; 00052 00053 p = str; 00054 while (isspace( *p )) p++; 00055 if (*p) i++; 00056 00057 while (*p) 00058 { 00059 if (isspace( *p )) 00060 { 00061 while (isspace( *p )) p++; 00062 if (*p) i++; 00063 } 00064 p++; 00065 } 00066 00067 res = HeapAlloc( GetProcessHeap(), 0, (i + 1) * sizeof(char *) ); 00068 if (!res) 00069 { 00070 HeapFree( GetProcessHeap(), 0, str ); 00071 return NULL; 00072 } 00073 00074 p = str; 00075 while (isspace( *p )) p++; 00076 00077 q = p; 00078 i = 0; 00079 00080 while (*p) 00081 { 00082 if (p[1] != '\0') 00083 { 00084 if (isspace( *p )) 00085 { 00086 *p = '\0'; p++; 00087 res[i] = strdupU( q ); 00088 if (!res[i]) goto oom; 00089 i++; 00090 00091 while (isspace( *p )) p++; 00092 q = p; 00093 } 00094 } 00095 else 00096 { 00097 res[i] = strdupU( q ); 00098 if (!res[i]) goto oom; 00099 i++; 00100 } 00101 p++; 00102 } 00103 res[i] = NULL; 00104 00105 HeapFree( GetProcessHeap(), 0, str ); 00106 return res; 00107 00108 oom: 00109 while (i > 0) strfreeU( res[--i] ); 00110 00111 HeapFree( GetProcessHeap(), 0, res ); 00112 HeapFree( GetProcessHeap(), 0, str ); 00113 00114 return NULL; 00115 } 00116 00117 /* Determine if a URL starts with a known LDAP scheme */ 00118 static int has_ldap_scheme( char *url ) 00119 { 00120 if (!strncasecmp( url, "ldap://", 7 ) || 00121 !strncasecmp( url, "ldaps://", 8 ) || 00122 !strncasecmp( url, "ldapi://", 8 ) || 00123 !strncasecmp( url, "cldap://", 8 )) return 1; 00124 return 0; 00125 } 00126 00127 /* Flatten an array of hostnames into a space separated string of URLs. 00128 * Prepend a given scheme and append a given portnumber to each hostname 00129 * if necessary. 00130 */ 00131 static char *join_hostnames( const char *scheme, char **hostnames, ULONG portnumber ) 00132 { 00133 char *res, *p, *q, **v; 00134 unsigned int i = 0, size = 0; 00135 static const char sep[] = " ", fmt[] = ":%d"; 00136 char port[7]; 00137 00138 sprintf( port, fmt, portnumber ); 00139 00140 for (v = hostnames; *v; v++) 00141 { 00142 if (!has_ldap_scheme( *v )) 00143 { 00144 size += strlen( scheme ); 00145 q = *v; 00146 } 00147 else 00148 /* skip past colon in scheme prefix */ 00149 q = strchr( *v, '/' ); 00150 00151 size += strlen( *v ); 00152 00153 if (!strchr( q, ':' )) 00154 size += strlen( port ); 00155 00156 i++; 00157 } 00158 00159 size += (i - 1) * strlen( sep ); 00160 00161 res = HeapAlloc( GetProcessHeap(), 0, size + 1 ); 00162 if (!res) return NULL; 00163 00164 p = res; 00165 for (v = hostnames; *v; v++) 00166 { 00167 if (v != hostnames) 00168 { 00169 strcpy( p, sep ); 00170 p += strlen( sep ); 00171 } 00172 00173 if (!has_ldap_scheme( *v )) 00174 { 00175 strcpy( p, scheme ); 00176 p += strlen( scheme ); 00177 q = *v; 00178 } 00179 else 00180 /* skip past colon in scheme prefix */ 00181 q = strchr( *v, '/' ); 00182 00183 strcpy( p, *v ); 00184 p += strlen( *v ); 00185 00186 if (!strchr( q, ':' )) 00187 { 00188 strcpy( p, port ); 00189 p += strlen( port ); 00190 } 00191 } 00192 return res; 00193 } 00194 00195 static char *urlify_hostnames( const char *scheme, char *hostnames, ULONG port ) 00196 { 00197 char *url = NULL, **strarray; 00198 00199 strarray = split_hostnames( hostnames ); 00200 if (strarray) 00201 url = join_hostnames( scheme, strarray, port ); 00202 else 00203 return NULL; 00204 00205 strarrayfreeU( strarray ); 00206 return url; 00207 } 00208 #endif 00209 00210 WINE_DEFAULT_DEBUG_CHANNEL(wldap32); 00211 00212 /*********************************************************************** 00213 * cldap_openA (WLDAP32.@) 00214 * 00215 * See cldap_openW. 00216 */ 00217 WLDAP32_LDAP * CDECL cldap_openA( PCHAR hostname, ULONG portnumber ) 00218 { 00219 #ifdef HAVE_LDAP 00220 WLDAP32_LDAP *ld = NULL; 00221 WCHAR *hostnameW = NULL; 00222 00223 TRACE( "(%s, %d)\n", debugstr_a(hostname), portnumber ); 00224 00225 if (hostname) { 00226 hostnameW = strAtoW( hostname ); 00227 if (!hostnameW) goto exit; 00228 } 00229 00230 ld = cldap_openW( hostnameW, portnumber ); 00231 00232 exit: 00233 strfreeW( hostnameW ); 00234 return ld; 00235 00236 #else 00237 return NULL; 00238 #endif 00239 } 00240 00241 /*********************************************************************** 00242 * cldap_openW (WLDAP32.@) 00243 * 00244 * Initialize an LDAP context and create a UDP connection. 00245 * 00246 * PARAMS 00247 * hostname [I] Name of the host to connect to. 00248 * portnumber [I] Portnumber to use. 00249 * 00250 * RETURNS 00251 * Success: Pointer to an LDAP context. 00252 * Failure: NULL 00253 * 00254 * NOTES 00255 * The hostname string can be a space separated string of hostnames, 00256 * in which case the LDAP runtime will try to connect to the hosts 00257 * in order, until a connection can be made. A hostname may have a 00258 * trailing portnumber (separated from the hostname by a ':'), which 00259 * will take precedence over the portnumber supplied as a parameter 00260 * to this function. 00261 */ 00262 WLDAP32_LDAP * CDECL cldap_openW( PWCHAR hostname, ULONG portnumber ) 00263 { 00264 #ifdef HAVE_LDAP 00265 LDAP *ld = NULL; 00266 char *hostnameU = NULL, *url = NULL; 00267 00268 TRACE( "(%s, %d)\n", debugstr_w(hostname), portnumber ); 00269 00270 if (hostname) { 00271 hostnameU = strWtoU( hostname ); 00272 if (!hostnameU) goto exit; 00273 } 00274 else { 00275 hostnameU = strWtoU( defaulthost ); 00276 if (!hostnameU) goto exit; 00277 } 00278 00279 url = urlify_hostnames( "cldap://", hostnameU, portnumber ); 00280 if (!url) goto exit; 00281 00282 ldap_initialize( &ld, url ); 00283 00284 exit: 00285 strfreeU( hostnameU ); 00286 strfreeU( url ); 00287 return ld; 00288 00289 #else 00290 return NULL; 00291 #endif 00292 } 00293 00294 /*********************************************************************** 00295 * ldap_connect (WLDAP32.@) 00296 * 00297 * Connect to an LDAP server. 00298 * 00299 * PARAMS 00300 * ld [I] Pointer to an LDAP context. 00301 * timeout [I] Pointer to an l_timeval structure specifying the 00302 * timeout in seconds. 00303 * 00304 * RETURNS 00305 * Success: LDAP_SUCCESS 00306 * Failure: An LDAP error code. 00307 * 00308 * NOTES 00309 * The timeout parameter may be NULL in which case a default timeout 00310 * value will be used. 00311 */ 00312 ULONG CDECL ldap_connect( WLDAP32_LDAP *ld, struct l_timeval *timeout ) 00313 { 00314 TRACE( "(%p, %p)\n", ld, timeout ); 00315 00316 if (!ld) return WLDAP32_LDAP_PARAM_ERROR; 00317 return WLDAP32_LDAP_SUCCESS; /* FIXME: do something, e.g. ping the host */ 00318 } 00319 00320 /*********************************************************************** 00321 * ldap_initA (WLDAP32.@) 00322 * 00323 * See ldap_initW. 00324 */ 00325 WLDAP32_LDAP * CDECL ldap_initA( PCHAR hostname, ULONG portnumber ) 00326 { 00327 #ifdef HAVE_LDAP 00328 WLDAP32_LDAP *ld = NULL; 00329 WCHAR *hostnameW = NULL; 00330 00331 TRACE( "(%s, %d)\n", debugstr_a(hostname), portnumber ); 00332 00333 if (hostname) { 00334 hostnameW = strAtoW( hostname ); 00335 if (!hostnameW) goto exit; 00336 } 00337 00338 ld = ldap_initW( hostnameW, portnumber ); 00339 00340 exit: 00341 strfreeW( hostnameW ); 00342 return ld; 00343 00344 #else 00345 return NULL; 00346 #endif 00347 } 00348 00349 /*********************************************************************** 00350 * ldap_initW (WLDAP32.@) 00351 * 00352 * Initialize an LDAP context and create a TCP connection. 00353 * 00354 * PARAMS 00355 * hostname [I] Name of the host to connect to. 00356 * portnumber [I] Portnumber to use. 00357 * 00358 * RETURNS 00359 * Success: Pointer to an LDAP context. 00360 * Failure: NULL 00361 * 00362 * NOTES 00363 * The hostname string can be a space separated string of hostnames, 00364 * in which case the LDAP runtime will try to connect to the hosts 00365 * in order, until a connection can be made. A hostname may have a 00366 * trailing portnumber (separated from the hostname by a ':'), which 00367 * will take precedence over the portnumber supplied as a parameter 00368 * to this function. The connection will not be made until the first 00369 * LDAP function that needs it is called. 00370 */ 00371 WLDAP32_LDAP * CDECL ldap_initW( PWCHAR hostname, ULONG portnumber ) 00372 { 00373 #ifdef HAVE_LDAP 00374 LDAP *ld = NULL; 00375 char *hostnameU = NULL, *url = NULL; 00376 00377 TRACE( "(%s, %d)\n", debugstr_w(hostname), portnumber ); 00378 00379 if (hostname) { 00380 hostnameU = strWtoU( hostname ); 00381 if (!hostnameU) goto exit; 00382 } 00383 else { 00384 hostnameU = strWtoU( defaulthost ); 00385 if (!hostnameU) goto exit; 00386 } 00387 00388 url = urlify_hostnames( "ldap://", hostnameU, portnumber ); 00389 if (!url) goto exit; 00390 00391 ldap_initialize( &ld, url ); 00392 00393 exit: 00394 strfreeU( hostnameU ); 00395 strfreeU( url ); 00396 return ld; 00397 00398 #else 00399 return NULL; 00400 #endif 00401 } 00402 00403 /*********************************************************************** 00404 * ldap_openA (WLDAP32.@) 00405 * 00406 * See ldap_openW. 00407 */ 00408 WLDAP32_LDAP * CDECL ldap_openA( PCHAR hostname, ULONG portnumber ) 00409 { 00410 #ifdef HAVE_LDAP 00411 WLDAP32_LDAP *ld = NULL; 00412 WCHAR *hostnameW = NULL; 00413 00414 TRACE( "(%s, %d)\n", debugstr_a(hostname), portnumber ); 00415 00416 if (hostname) { 00417 hostnameW = strAtoW( hostname ); 00418 if (!hostnameW) goto exit; 00419 } 00420 00421 ld = ldap_openW( hostnameW, portnumber ); 00422 00423 exit: 00424 strfreeW( hostnameW ); 00425 return ld; 00426 00427 #else 00428 return NULL; 00429 #endif 00430 } 00431 00432 /*********************************************************************** 00433 * ldap_openW (WLDAP32.@) 00434 * 00435 * Initialize an LDAP context and create a TCP connection. 00436 * 00437 * PARAMS 00438 * hostname [I] Name of the host to connect to. 00439 * portnumber [I] Portnumber to use. 00440 * 00441 * RETURNS 00442 * Success: Pointer to an LDAP context. 00443 * Failure: NULL 00444 * 00445 * NOTES 00446 * The hostname string can be a space separated string of hostnames, 00447 * in which case the LDAP runtime will try to connect to the hosts 00448 * in order, until a connection can be made. A hostname may have a 00449 * trailing portnumber (separated from the hostname by a ':'), which 00450 * will take precedence over the portnumber supplied as a parameter 00451 * to this function. 00452 */ 00453 WLDAP32_LDAP * CDECL ldap_openW( PWCHAR hostname, ULONG portnumber ) 00454 { 00455 #ifdef HAVE_LDAP 00456 LDAP *ld = NULL; 00457 char *hostnameU = NULL, *url = NULL; 00458 00459 TRACE( "(%s, %d)\n", debugstr_w(hostname), portnumber ); 00460 00461 if (hostname) { 00462 hostnameU = strWtoU( hostname ); 00463 if (!hostnameU) goto exit; 00464 } 00465 else { 00466 hostnameU = strWtoU( defaulthost ); 00467 if (!hostnameU) goto exit; 00468 } 00469 00470 url = urlify_hostnames( "ldap://", hostnameU, portnumber ); 00471 if (!url) goto exit; 00472 00473 ldap_initialize( &ld, url ); 00474 00475 exit: 00476 strfreeU( hostnameU ); 00477 strfreeU( url ); 00478 return ld; 00479 00480 #else 00481 return NULL; 00482 #endif 00483 } 00484 00485 /*********************************************************************** 00486 * ldap_sslinitA (WLDAP32.@) 00487 * 00488 * See ldap_sslinitW. 00489 */ 00490 WLDAP32_LDAP * CDECL ldap_sslinitA( PCHAR hostname, ULONG portnumber, int secure ) 00491 { 00492 #ifdef HAVE_LDAP 00493 WLDAP32_LDAP *ld; 00494 WCHAR *hostnameW = NULL; 00495 00496 TRACE( "(%s, %d, 0x%08x)\n", debugstr_a(hostname), portnumber, secure ); 00497 00498 if (hostname) { 00499 hostnameW = strAtoW( hostname ); 00500 if (!hostnameW) return NULL; 00501 } 00502 00503 ld = ldap_sslinitW( hostnameW, portnumber, secure ); 00504 00505 strfreeW( hostnameW ); 00506 return ld; 00507 00508 #else 00509 return NULL; 00510 #endif 00511 } 00512 00513 /*********************************************************************** 00514 * ldap_sslinitW (WLDAP32.@) 00515 * 00516 * Initialize an LDAP context and create a secure TCP connection. 00517 * 00518 * PARAMS 00519 * hostname [I] Name of the host to connect to. 00520 * portnumber [I] Portnumber to use. 00521 * secure [I] Ask the server to create an SSL connection. 00522 * 00523 * RETURNS 00524 * Success: Pointer to an LDAP context. 00525 * Failure: NULL 00526 * 00527 * NOTES 00528 * The hostname string can be a space separated string of hostnames, 00529 * in which case the LDAP runtime will try to connect to the hosts 00530 * in order, until a connection can be made. A hostname may have a 00531 * trailing portnumber (separated from the hostname by a ':'), which 00532 * will take precedence over the portnumber supplied as a parameter 00533 * to this function. The connection will not be made until the first 00534 * LDAP function that needs it is called. 00535 */ 00536 WLDAP32_LDAP * CDECL ldap_sslinitW( PWCHAR hostname, ULONG portnumber, int secure ) 00537 { 00538 #ifdef HAVE_LDAP 00539 WLDAP32_LDAP *ld = NULL; 00540 char *hostnameU = NULL, *url = NULL; 00541 00542 TRACE( "(%s, %d, 0x%08x)\n", debugstr_w(hostname), portnumber, secure ); 00543 00544 if (hostname) { 00545 hostnameU = strWtoU( hostname ); 00546 if (!hostnameU) goto exit; 00547 } 00548 else { 00549 hostnameU = strWtoU( defaulthost ); 00550 if (!hostnameU) goto exit; 00551 } 00552 00553 if (secure) 00554 url = urlify_hostnames( "ldaps://", hostnameU, portnumber ); 00555 else 00556 url = urlify_hostnames( "ldap://", hostnameU, portnumber ); 00557 00558 if (!url) goto exit; 00559 ldap_initialize( &ld, url ); 00560 00561 exit: 00562 strfreeU( hostnameU ); 00563 strfreeU( url ); 00564 return ld; 00565 00566 #else 00567 return NULL; 00568 #endif 00569 } 00570 00571 /*********************************************************************** 00572 * ldap_start_tls_sA (WLDAP32.@) 00573 * 00574 * See ldap_start_tls_sW. 00575 */ 00576 ULONG CDECL ldap_start_tls_sA( WLDAP32_LDAP *ld, PULONG retval, WLDAP32_LDAPMessage **result, 00577 PLDAPControlA *serverctrls, PLDAPControlA *clientctrls ) 00578 { 00579 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 00580 #ifdef HAVE_LDAP 00581 LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL; 00582 00583 ret = WLDAP32_LDAP_NO_MEMORY; 00584 00585 TRACE( "(%p, %p, %p, %p, %p)\n", ld, retval, result, serverctrls, clientctrls ); 00586 00587 if (!ld) return ~0u; 00588 00589 if (serverctrls) { 00590 serverctrlsW = controlarrayAtoW( serverctrls ); 00591 if (!serverctrlsW) goto exit; 00592 } 00593 if (clientctrls) { 00594 clientctrlsW = controlarrayAtoW( clientctrls ); 00595 if (!clientctrlsW) goto exit; 00596 } 00597 00598 ret = ldap_start_tls_sW( ld, retval, result, serverctrlsW, clientctrlsW ); 00599 00600 exit: 00601 controlarrayfreeW( serverctrlsW ); 00602 controlarrayfreeW( clientctrlsW ); 00603 00604 #endif 00605 return ret; 00606 } 00607 00608 /*********************************************************************** 00609 * ldap_start_tls_s (WLDAP32.@) 00610 * 00611 * Start TLS encryption on an LDAP connection. 00612 * 00613 * PARAMS 00614 * ld [I] Pointer to an LDAP context. 00615 * retval [I] Return value from the server. 00616 * result [I] Response message from the server. 00617 * serverctrls [I] Array of LDAP server controls. 00618 * clientctrls [I] Array of LDAP client controls. 00619 * 00620 * RETURNS 00621 * Success: LDAP_SUCCESS 00622 * Failure: An LDAP error code. 00623 * 00624 * NOTES 00625 * LDAP function that needs it is called. 00626 */ 00627 ULONG CDECL ldap_start_tls_sW( WLDAP32_LDAP *ld, PULONG retval, WLDAP32_LDAPMessage **result, 00628 PLDAPControlW *serverctrls, PLDAPControlW *clientctrls ) 00629 { 00630 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 00631 #ifdef HAVE_LDAP 00632 LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL; 00633 00634 ret = WLDAP32_LDAP_NO_MEMORY; 00635 00636 TRACE( "(%p, %p, %p, %p, %p)\n", ld, retval, result, serverctrls, clientctrls ); 00637 00638 if (!ld) return ~0u; 00639 00640 if (serverctrls) { 00641 serverctrlsU = controlarrayWtoU( serverctrls ); 00642 if (!serverctrlsU) goto exit; 00643 } 00644 if (clientctrls) { 00645 clientctrlsU = controlarrayWtoU( clientctrls ); 00646 if (!clientctrlsU) goto exit; 00647 } 00648 00649 ret = map_error( ldap_start_tls_s( ld, serverctrlsU, clientctrlsU )); 00650 00651 exit: 00652 controlarrayfreeU( serverctrlsU ); 00653 controlarrayfreeU( clientctrlsU ); 00654 00655 #endif 00656 return ret; 00657 } 00658 00659 /*********************************************************************** 00660 * ldap_startup (WLDAP32.@) 00661 */ 00662 ULONG CDECL ldap_startup( PLDAP_VERSION_INFO version, HANDLE *instance ) 00663 { 00664 TRACE( "(%p, %p)\n", version, instance ); 00665 return WLDAP32_LDAP_SUCCESS; 00666 } 00667 00668 /*********************************************************************** 00669 * ldap_stop_tls_s (WLDAP32.@) 00670 * 00671 * Stop TLS encryption on an LDAP connection. 00672 * 00673 * PARAMS 00674 * ld [I] Pointer to an LDAP context. 00675 * 00676 * RETURNS 00677 * Success: TRUE 00678 * Failure: FALSE 00679 */ 00680 BOOLEAN CDECL ldap_stop_tls_s( WLDAP32_LDAP *ld ) 00681 { 00682 TRACE( "(%p)\n", ld ); 00683 return TRUE; /* FIXME: find a way to stop tls on a connection */ 00684 } Generated on Sun May 27 2012 04:23:31 for ReactOS by
1.7.6.1
|