ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

init.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.