home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ldapsdk.zip / libraries / libldap / open.c < prev    next >
C/C++ Source or Header  |  2001-08-31  |  8KB  |  360 lines

  1. /* $OpenLDAP: pkg/ldap/libraries/libldap/open.c,v 1.30.2.18 2001/08/30 22:14:55 kurt Exp $ */
  2. /*
  3.  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  4.  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  5.  */
  6. /*  Portions
  7.  *  Copyright (c) 1995 Regents of the University of Michigan.
  8.  *  All rights reserved.
  9.  *
  10.  *  open.c
  11.  */
  12.  
  13. #include "portable.h"
  14.  
  15. #include <stdio.h>
  16. #include <limits.h>
  17.  
  18. #include <ac/stdlib.h>
  19.  
  20. #include <ac/param.h>
  21. #include <ac/socket.h>
  22. #include <ac/string.h>
  23. #include <ac/time.h>
  24.  
  25. #include "ldap-int.h"
  26.  
  27. int ldap_open_defconn( LDAP *ld )
  28. {
  29.     ld->ld_defconn = ldap_new_connection( ld,
  30.         ld->ld_options.ldo_defludp, 1, 1, NULL );
  31.  
  32.     if( ld->ld_defconn == NULL ) {
  33.         ld->ld_errno = LDAP_SERVER_DOWN;
  34.         return -1;
  35.     }
  36.  
  37.     ++ld->ld_defconn->lconn_refcnt;    /* so it never gets closed/freed */
  38.     return 0;
  39. }
  40.  
  41. /*
  42.  * ldap_open - initialize and connect to an ldap server.  A magic cookie to
  43.  * be used for future communication is returned on success, NULL on failure.
  44.  * "host" may be a space-separated list of hosts or IP addresses
  45.  *
  46.  * Example:
  47.  *    LDAP    *ld;
  48.  *    ld = ldap_open( hostname, port );
  49.  */
  50.  
  51. LDAP *
  52. ldap_open( LDAP_CONST char *host, int port )
  53. {
  54.     int rc;
  55.     LDAP        *ld;
  56.  
  57.     Debug( LDAP_DEBUG_TRACE, "ldap_open(%s, %d)\n",
  58.         host, port, 0 );
  59.  
  60.     ld = ldap_init( host, port );
  61.     if ( ld == NULL ) {
  62.         return( NULL );
  63.     }
  64.  
  65.     rc = ldap_open_defconn( ld );
  66.  
  67.     if( rc < 0 ) {
  68.         ldap_ld_free( ld, 0, NULL, NULL );
  69.         ld = NULL;
  70.     }
  71.  
  72.     Debug( LDAP_DEBUG_TRACE, "ldap_open: %s\n",
  73.         ld == NULL ? "succeeded" : "failed", 0, 0 );
  74.  
  75.     return ld;
  76. }
  77.  
  78.  
  79.  
  80. int
  81. ldap_create( LDAP **ldp )
  82. {
  83.     LDAP            *ld;
  84.     struct ldapoptions    *gopts;
  85.  
  86.     *ldp = NULL;
  87.     /* Get pointer to global option structure */
  88.     if ( (gopts = LDAP_INT_GLOBAL_OPT()) == NULL) {
  89.         return LDAP_NO_MEMORY;
  90.     }
  91.  
  92.     /* Initialize the global options, if not already done. */
  93.     if( gopts->ldo_valid != LDAP_INITIALIZED ) {
  94.         ldap_int_initialize(gopts, NULL);
  95.     }
  96.  
  97.     Debug( LDAP_DEBUG_TRACE, "ldap_create\n", 0, 0, 0 );
  98.  
  99. #ifdef HAVE_WINSOCK2
  100. {    WORD wVersionRequested;
  101.     WSADATA wsaData;
  102.  
  103.     wVersionRequested = MAKEWORD( 2, 0 );
  104.     if ( WSAStartup( wVersionRequested, &wsaData ) != 0 ) {
  105.         /* Tell the user that we couldn't find a usable */
  106.         /* WinSock DLL.                                  */
  107.         return LDAP_LOCAL_ERROR;
  108.     }
  109.  
  110.     /* Confirm that the WinSock DLL supports 2.0.*/
  111.     /* Note that if the DLL supports versions greater    */
  112.     /* than 2.0 in addition to 2.0, it will still return */
  113.     /* 2.0 in wVersion since that is the version we      */
  114.     /* requested.                                        */
  115.  
  116.     if ( LOBYTE( wsaData.wVersion ) != 2 ||
  117.         HIBYTE( wsaData.wVersion ) != 0 )
  118.     {
  119.         /* Tell the user that we couldn't find a usable */
  120.         /* WinSock DLL.                                  */
  121.         WSACleanup( );
  122.         return LDAP_LOCAL_ERROR; 
  123.     }
  124. }    /* The WinSock DLL is acceptable. Proceed. */
  125.  
  126. #elif HAVE_WINSOCK
  127. {    WSADATA wsaData;
  128.     if ( WSAStartup( 0x0101, &wsaData ) != 0 ) {
  129.         return LDAP_LOCAL_ERROR;
  130.     }
  131. }
  132. #endif
  133.  
  134.     if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) {
  135.         WSACleanup( );
  136.         return( LDAP_NO_MEMORY );
  137.     }
  138.    
  139.     /* copy the global options */
  140.     AC_MEMCPY(&ld->ld_options, gopts, sizeof(ld->ld_options));
  141.  
  142.     ld->ld_valid = LDAP_VALID_SESSION;
  143.  
  144.     /* but not pointers to malloc'ed items */
  145.     ld->ld_options.ldo_sctrls = NULL;
  146.     ld->ld_options.ldo_cctrls = NULL;
  147.  
  148. #ifdef HAVE_CYRUS_SASL
  149.     ld->ld_options.ldo_def_sasl_mech = gopts->ldo_def_sasl_mech
  150.         ? LDAP_STRDUP( gopts->ldo_def_sasl_mech ) : NULL;
  151.     ld->ld_options.ldo_def_sasl_realm = gopts->ldo_def_sasl_realm
  152.         ? LDAP_STRDUP( gopts->ldo_def_sasl_realm ) : NULL;
  153.     ld->ld_options.ldo_def_sasl_authcid = gopts->ldo_def_sasl_authcid
  154.         ? LDAP_STRDUP( gopts->ldo_def_sasl_authcid ) : NULL;
  155.     ld->ld_options.ldo_def_sasl_authzid = gopts->ldo_def_sasl_authzid
  156.         ? LDAP_STRDUP( gopts->ldo_def_sasl_authzid ) : NULL;
  157. #endif
  158.  
  159.     ld->ld_options.ldo_defludp = ldap_url_duplist(gopts->ldo_defludp);
  160.  
  161.     if ( ld->ld_options.ldo_defludp == NULL ) {
  162.         LDAP_FREE( (char*)ld );
  163.         WSACleanup( );
  164.         return LDAP_NO_MEMORY;
  165.     }
  166.  
  167.     if (( ld->ld_selectinfo = ldap_new_select_info()) == NULL ) {
  168.         ldap_free_urllist( ld->ld_options.ldo_defludp );
  169.         LDAP_FREE( (char*) ld );
  170.         WSACleanup( );
  171.         return LDAP_NO_MEMORY;
  172.     }
  173.  
  174.     ld->ld_lberoptions = LBER_USE_DER;
  175.  
  176.     ld->ld_sb = ber_sockbuf_alloc( );
  177.     if ( ld->ld_sb == NULL ) {
  178.         ldap_free_urllist( ld->ld_options.ldo_defludp );
  179.         LDAP_FREE( (char*) ld );
  180.         WSACleanup( );
  181.         return LDAP_NO_MEMORY;
  182.     }
  183.  
  184.     *ldp = ld;
  185.     return LDAP_SUCCESS;
  186. }
  187.  
  188. /*
  189.  * ldap_init - initialize the LDAP library.  A magic cookie to be used for
  190.  * future communication is returned on success, NULL on failure.
  191.  * "host" may be a space-separated list of hosts or IP addresses
  192.  *
  193.  * Example:
  194.  *    LDAP    *ld;
  195.  *    ld = ldap_init( host, port );
  196.  */
  197. LDAP *
  198. ldap_init( LDAP_CONST char *defhost, int defport )
  199. {
  200.     LDAP *ld;
  201.     int rc;
  202.  
  203.     rc = ldap_create(&ld);
  204.     if ( rc != LDAP_SUCCESS )
  205.         return NULL;
  206.  
  207.     if (defport != 0)
  208.         ld->ld_options.ldo_defport = defport;
  209.  
  210.     if (defhost != NULL) {
  211.         rc = ldap_set_option(ld, LDAP_OPT_HOST_NAME, defhost);
  212.         if ( rc != LDAP_SUCCESS ) {
  213.             ldap_ld_free(ld, 1, NULL, NULL);
  214.             return NULL;
  215.         }
  216.     }
  217.  
  218.     return( ld );
  219. }
  220.  
  221.  
  222. int
  223. ldap_initialize( LDAP **ldp, LDAP_CONST char *url )
  224. {
  225.     int rc;
  226.     LDAP *ld;
  227.  
  228.     *ldp = NULL;
  229.     rc = ldap_create(&ld);
  230.     if ( rc != LDAP_SUCCESS )
  231.         return rc;
  232.  
  233.     if (url != NULL) {
  234.         rc = ldap_set_option(ld, LDAP_OPT_URI, url);
  235.         if ( rc != LDAP_SUCCESS ) {
  236.             ldap_ld_free(ld, 1, NULL, NULL);
  237.             return rc;
  238.         }
  239.     }
  240.  
  241.     *ldp = ld;
  242.     return LDAP_SUCCESS;
  243. }
  244.  
  245. int
  246. ldap_int_open_connection(
  247.     LDAP *ld,
  248.     LDAPConn *conn,
  249.     LDAPURLDesc *srv,
  250.     int async )
  251. {
  252.     int rc = -1;
  253. #ifdef HAVE_CYRUS_SASL
  254.     char *sasl_host = NULL;
  255.     int sasl_ssf = 0;
  256. #endif
  257.     char *host;
  258.     int port;
  259.     long addr;
  260.  
  261.     Debug( LDAP_DEBUG_TRACE, "ldap_int_open_connection\n", 0, 0, 0 );
  262.  
  263.     switch ( ldap_pvt_url_scheme2proto( srv->lud_scheme ) ) {
  264.         case LDAP_PROTO_TCP:
  265.             port = htons( (short) srv->lud_port );
  266.  
  267.             addr = 0;
  268.             if ( srv->lud_host == NULL || *srv->lud_host == 0 ) {
  269.                 host = NULL;
  270.                 addr = htonl( INADDR_LOOPBACK );
  271.             } else {
  272.                 host = srv->lud_host;
  273.             }
  274.  
  275.             rc = ldap_connect_to_host( ld, conn->lconn_sb, 0,
  276.                 host, addr, port, async );
  277.  
  278.             if ( rc == -1 ) return rc;
  279.  
  280. #ifdef LDAP_DEBUG
  281.             ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
  282.                 LBER_SBIOD_LEVEL_PROVIDER, (void *)"tcp_" );
  283. #endif
  284.             ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_tcp,
  285.                 LBER_SBIOD_LEVEL_PROVIDER, NULL );
  286.  
  287. #ifdef HAVE_CYRUS_SASL
  288.             sasl_host = ldap_host_connected_to( conn->lconn_sb );
  289. #endif
  290.             break;
  291.         case LDAP_PROTO_IPC:
  292. #ifdef LDAP_PF_LOCAL
  293.             /* only IPC mechanism supported is PF_LOCAL (PF_UNIX) */
  294.             rc = ldap_connect_to_path( ld, conn->lconn_sb,
  295.                 srv->lud_host, async );
  296.             if ( rc == -1 ) return rc;
  297.  
  298. #ifdef LDAP_DEBUG
  299.             ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
  300.                 LBER_SBIOD_LEVEL_PROVIDER, (void *)"ipc_" );
  301. #endif
  302.             ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_fd,
  303.                 LBER_SBIOD_LEVEL_PROVIDER, NULL );
  304.  
  305. #ifdef HAVE_CYRUS_SASL
  306.             sasl_host = ldap_host_connected_to( conn->lconn_sb );
  307.             sasl_ssf = LDAP_PVT_SASL_LOCAL_SSF;
  308. #endif
  309.             break;
  310. #endif /* LDAP_PF_LOCAL */
  311.         default:
  312.             return -1;
  313.             break;
  314.     }
  315.  
  316.     ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_readahead,
  317.         LBER_SBIOD_LEVEL_PROVIDER, NULL );
  318.  
  319. #ifdef LDAP_DEBUG
  320.     ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
  321.         INT_MAX, (void *)"ldap_" );
  322. #endif
  323.  
  324. #ifdef HAVE_CYRUS_SASL
  325.     if( sasl_host != NULL ) {
  326.         ldap_int_sasl_open( ld, conn, sasl_host, sasl_ssf );
  327.     }
  328. #endif
  329.  
  330. #ifdef HAVE_TLS
  331.     if (ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD ||
  332.         strcmp( srv->lud_scheme, "ldaps" ) == 0 )
  333.     {
  334.         ++conn->lconn_refcnt;    /* avoid premature free */
  335.  
  336.         rc = ldap_int_tls_start( ld, conn, srv );
  337.  
  338.         --conn->lconn_refcnt;
  339.  
  340.         if (rc != LDAP_SUCCESS) {
  341.             return -1;
  342.         }
  343.     }
  344. #endif
  345.  
  346. #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
  347.     if ( conn->lconn_krbinstance == NULL ) {
  348.         char *c;
  349.         conn->lconn_krbinstance = ldap_host_connected_to( conn->lconn_sb );
  350.  
  351.         if( conn->lconn_krbinstance != NULL && 
  352.             ( c = strchr( conn->lconn_krbinstance, '.' )) != NULL ) {
  353.             *c = '\0';
  354.         }
  355.     }
  356. #endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
  357.  
  358.     return( 0 );
  359. }
  360.