home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ldapsdk.zip / libraries / libldap / options.c < prev    next >
C/C++ Source or Header  |  2001-07-22  |  13KB  |  602 lines

  1. /* $OpenLDAP: pkg/ldap/libraries/libldap/options.c,v 1.36.2.7 2001/07/21 19:01:39 kurt Exp $ */
  2. /*
  3.  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  4.  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  5.  */
  6.  
  7. #include "portable.h"
  8.  
  9. #include <stdio.h>
  10.  
  11. #include <ac/stdlib.h>
  12.  
  13. #include <ac/socket.h>
  14. #include <ac/string.h>
  15. #include <ac/time.h>
  16.  
  17. #include "ldap-int.h"
  18.  
  19. #define LDAP_OPT_REBIND_PROC 0x4e814d
  20.  
  21. static const LDAPAPIFeatureInfo features[] = {
  22. #ifdef LDAP_API_FEATURE_X_OPENLDAP
  23.     {    /* OpenLDAP Extensions API Feature */
  24.         LDAP_FEATURE_INFO_VERSION,
  25.         "X_OPENLDAP",
  26.         LDAP_API_FEATURE_X_OPENLDAP
  27.     },
  28. #endif
  29.  
  30. #ifdef LDAP_API_FEATURE_THREAD_SAFE
  31.     {    /* Basic Thread Safe */
  32.         LDAP_FEATURE_INFO_VERSION,
  33.         "THREAD_SAFE",
  34.         LDAP_API_FEATURE_THREAD_SAFE
  35.     },
  36. #endif
  37. #ifdef LDAP_API_FEATURE_SESSION_THREAD_SAFE
  38.     {    /* Session Thread Safe */
  39.         LDAP_FEATURE_INFO_VERSION,
  40.         "SESSION_THREAD_SAFE",
  41.         LDAP_API_FEATURE_SESSION_THREAD_SAFE
  42.     },
  43. #endif
  44. #ifdef LDAP_API_FEATURE_OPERATION_THREAD_SAFE
  45.     {    /* Operation Thread Safe */
  46.         LDAP_FEATURE_INFO_VERSION,
  47.         "OPERATION_THREAD_SAFE",
  48.         LDAP_API_FEATURE_OPERATION_THREAD_SAFE
  49.     },
  50. #endif
  51. #ifdef LDAP_API_FEATURE_X_OPENLDAP_REENTRANT
  52.     {    /* OpenLDAP Reentrant */
  53.         LDAP_FEATURE_INFO_VERSION,
  54.         "X_OPENLDAP_REENTRANT",
  55.         LDAP_API_FEATURE_X_OPENLDAP_REENTRANT
  56.     },
  57. #endif
  58. #if defined( LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE ) && \
  59.     defined( LDAP_THREAD_SAFE )
  60.     {    /* OpenLDAP Thread Safe */
  61.         LDAP_FEATURE_INFO_VERSION,
  62.         "X_OPENLDAP_THREAD_SAFE",
  63.         LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE
  64.     },
  65. #endif
  66. #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
  67.     {    /* V2 Referrals */
  68.         LDAP_FEATURE_INFO_VERSION,
  69.         "X_OPENLDAP_V2_REFERRALS",
  70.         LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
  71.     },
  72. #endif
  73.     {0, NULL, 0}
  74. };
  75.  
  76. int
  77. ldap_get_option(
  78.     LDAP    *ld,
  79.     int        option,
  80.     void    *outvalue)
  81. {
  82.     struct ldapoptions *lo;
  83.  
  84.     /* Get pointer to global option structure */
  85.     lo = LDAP_INT_GLOBAL_OPT();   
  86.     if (NULL == lo)    {
  87.         return LDAP_NO_MEMORY;
  88.     }
  89.  
  90.     if( lo->ldo_valid != LDAP_INITIALIZED ) {
  91.         ldap_int_initialize(lo, NULL);
  92.     }
  93.  
  94.     if(ld != NULL) {
  95.         assert( LDAP_VALID( ld ) );
  96.  
  97.         if( !LDAP_VALID( ld ) ) {
  98.             return LDAP_OPT_ERROR;
  99.         }
  100.  
  101.         lo = &ld->ld_options;
  102.     }
  103.  
  104.     if(outvalue == NULL) {
  105.         /* no place to get to */
  106.         return LDAP_OPT_ERROR;
  107.     }
  108.  
  109.     switch(option) {
  110.     case LDAP_OPT_API_INFO: {
  111.             struct ldapapiinfo *info = (struct ldapapiinfo *) outvalue;
  112.  
  113.             if(info == NULL) {
  114.                 /* outvalue must point to an apiinfo structure */
  115.                 return LDAP_OPT_ERROR;
  116.             }
  117.  
  118.             if(info->ldapai_info_version != LDAP_API_INFO_VERSION) {
  119.                 /* api info version mismatch */
  120.                 info->ldapai_info_version = LDAP_API_INFO_VERSION;
  121.                 return LDAP_OPT_ERROR;
  122.             }
  123.  
  124.             info->ldapai_api_version = LDAP_API_VERSION;
  125.             info->ldapai_api_version = LDAP_API_VERSION;
  126.             info->ldapai_protocol_version = LDAP_VERSION_MAX;
  127.  
  128.             if(features[0].ldapaif_name == NULL) {
  129.                 info->ldapai_extensions = NULL;
  130.             } else {
  131.                 int i;
  132.                 info->ldapai_extensions = LDAP_MALLOC(sizeof(char *) *
  133.                     sizeof(features)/sizeof(LDAPAPIFeatureInfo));
  134.  
  135.                 for(i=0; features[i].ldapaif_name != NULL; i++) {
  136.                     info->ldapai_extensions[i] =
  137.                         LDAP_STRDUP(features[i].ldapaif_name);
  138.                 }
  139.  
  140.                 info->ldapai_extensions[i] = NULL;
  141.             }
  142.  
  143.             info->ldapai_vendor_name = LDAP_STRDUP(LDAP_VENDOR_NAME);
  144.             info->ldapai_vendor_version = LDAP_VENDOR_VERSION;
  145.  
  146.             return LDAP_OPT_SUCCESS;
  147.         } break;
  148.  
  149.     case LDAP_OPT_DESC:
  150.         if( ld == NULL || ld->ld_sb == NULL ) {
  151.             /* bad param */
  152.             break;
  153.         } 
  154.  
  155.         ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, outvalue );
  156.         return LDAP_OPT_SUCCESS;
  157.  
  158.     case LDAP_OPT_TIMEOUT:
  159.         /* the caller has to free outvalue ! */
  160.         if ( ldap_int_timeval_dup( outvalue, lo->ldo_tm_api) != 0 )
  161.         {
  162.             return LDAP_OPT_ERROR;
  163.         }
  164.         return LDAP_OPT_SUCCESS;
  165.         
  166.     case LDAP_OPT_NETWORK_TIMEOUT:
  167.         /* the caller has to free outvalue ! */
  168.         if ( ldap_int_timeval_dup( outvalue, lo->ldo_tm_net ) != 0 )
  169.         {
  170.             return LDAP_OPT_ERROR;
  171.         }
  172.         return LDAP_OPT_SUCCESS;
  173.  
  174.     case LDAP_OPT_DEREF:
  175.         * (int *) outvalue = lo->ldo_deref;
  176.         return LDAP_OPT_SUCCESS;
  177.  
  178.     case LDAP_OPT_SIZELIMIT:
  179.         * (int *) outvalue = lo->ldo_sizelimit;
  180.         return LDAP_OPT_SUCCESS;
  181.  
  182.     case LDAP_OPT_TIMELIMIT:
  183.         * (int *) outvalue = lo->ldo_timelimit;
  184.         return LDAP_OPT_SUCCESS;
  185.  
  186.     case LDAP_OPT_REFERRALS:
  187.         * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_REFERRALS);
  188.         return LDAP_OPT_SUCCESS;
  189.         
  190.     case LDAP_OPT_RESTART:
  191.         * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_RESTART);
  192.         return LDAP_OPT_SUCCESS;
  193.  
  194.     case LDAP_OPT_PROTOCOL_VERSION:
  195.         * (int *) outvalue = lo->ldo_version;
  196.         return LDAP_OPT_SUCCESS;
  197.  
  198.     case LDAP_OPT_SERVER_CONTROLS:
  199.         * (LDAPControl ***) outvalue =
  200.             ldap_controls_dup( lo->ldo_sctrls );
  201.  
  202.         return LDAP_OPT_SUCCESS;
  203.  
  204.     case LDAP_OPT_CLIENT_CONTROLS:
  205.         * (LDAPControl ***) outvalue =
  206.             ldap_controls_dup( lo->ldo_cctrls );
  207.  
  208.         return LDAP_OPT_SUCCESS;
  209.  
  210.     case LDAP_OPT_HOST_NAME:
  211.         * (char **) outvalue = ldap_url_list2hosts(lo->ldo_defludp);
  212.         return LDAP_OPT_SUCCESS;
  213.  
  214.     case LDAP_OPT_URI:
  215.         * (char **) outvalue = ldap_url_list2urls(lo->ldo_defludp);
  216.         return LDAP_OPT_SUCCESS;
  217.  
  218.     case LDAP_OPT_ERROR_NUMBER:
  219.         if(ld == NULL) {
  220.             /* bad param */
  221.             break;
  222.         } 
  223.         * (int *) outvalue = ld->ld_errno;
  224.         return LDAP_OPT_SUCCESS;
  225.  
  226.     case LDAP_OPT_ERROR_STRING:
  227.         if(ld == NULL) {
  228.             /* bad param */
  229.             break;
  230.         } 
  231.  
  232.         if( ld->ld_error == NULL ) {
  233.             * (char **) outvalue = NULL;
  234.         } else {
  235.             * (char **) outvalue = LDAP_STRDUP(ld->ld_error);
  236.         }
  237.  
  238.         return LDAP_OPT_SUCCESS;
  239.  
  240.     case LDAP_OPT_MATCHED_DN:
  241.         if(ld == NULL) {
  242.             /* bad param */
  243.             break;
  244.         } 
  245.  
  246.         if( ld->ld_matched == NULL ) {
  247.             * (char **) outvalue = NULL;
  248.         } else {
  249.             * (char **) outvalue = LDAP_STRDUP(ld->ld_matched);
  250.         }
  251.  
  252.         return LDAP_OPT_SUCCESS;
  253.  
  254.     case LDAP_OPT_API_FEATURE_INFO: {
  255.             LDAPAPIFeatureInfo *info = (LDAPAPIFeatureInfo *) outvalue;
  256.             int i;
  257.  
  258.             if(info == NULL) return LDAP_OPT_ERROR;
  259.  
  260.             if(info->ldapaif_info_version != LDAP_FEATURE_INFO_VERSION) {
  261.                 /* api info version mismatch */
  262.                 info->ldapaif_info_version = LDAP_FEATURE_INFO_VERSION;
  263.                 return LDAP_OPT_ERROR;
  264.             }
  265.  
  266.             if(info->ldapaif_name == NULL) return LDAP_OPT_ERROR;
  267.  
  268.             for(i=0; features[i].ldapaif_name != NULL; i++) {
  269.                 if(!strcmp(info->ldapaif_name, features[i].ldapaif_name)) {
  270.                     info->ldapaif_version =
  271.                         features[i].ldapaif_version;
  272.                     return LDAP_OPT_SUCCESS;
  273.                 }
  274.             }
  275.         }
  276.         break;
  277.  
  278.     case LDAP_OPT_DEBUG_LEVEL:
  279.         * (int *) outvalue = lo->ldo_debug;
  280.         return LDAP_OPT_SUCCESS;
  281.  
  282.     default:
  283. #ifdef HAVE_TLS
  284.         if ( ldap_pvt_tls_get_option( ld, option, outvalue ) == 0 ) {
  285.             return LDAP_OPT_SUCCESS;
  286.         }
  287. #endif
  288. #ifdef HAVE_CYRUS_SASL
  289.         if ( ldap_int_sasl_get_option( ld, option, outvalue ) == 0 ) {
  290.             return LDAP_OPT_SUCCESS;
  291.         }
  292. #endif
  293.         /* bad param */
  294.         break;
  295.     }
  296.  
  297.     return LDAP_OPT_ERROR;
  298. }
  299.  
  300. int
  301. ldap_set_option(
  302.     LDAP    *ld,
  303.     int        option,
  304.     LDAP_CONST void    *invalue)
  305. {
  306.     struct ldapoptions *lo;
  307.     int *dbglvl = NULL;
  308.  
  309.     /* Get pointer to global option structure */
  310.     lo = LDAP_INT_GLOBAL_OPT();
  311.     if (lo == NULL)    {
  312.         return LDAP_NO_MEMORY;
  313.     }
  314.  
  315.     /*
  316.      * The architecture to turn on debugging has a chicken and egg
  317.      * problem. Thus, we introduce a fix here.
  318.      */
  319.  
  320.     if (option == LDAP_OPT_DEBUG_LEVEL)
  321.         dbglvl = (int *) invalue;
  322.  
  323.     if( lo->ldo_valid != LDAP_INITIALIZED ) {
  324.         ldap_int_initialize(lo, dbglvl);
  325.     }
  326.  
  327.     if(ld != NULL) {
  328.         assert( LDAP_VALID( ld ) );
  329.  
  330.         if( !LDAP_VALID( ld ) ) {
  331.             return LDAP_OPT_ERROR;
  332.         }
  333.  
  334.         lo = &ld->ld_options;
  335.     }
  336.  
  337.     switch(option) {
  338.     case LDAP_OPT_REFERRALS:
  339.         if(invalue == LDAP_OPT_OFF) {
  340.             LDAP_BOOL_CLR(lo, LDAP_BOOL_REFERRALS);
  341.         } else {
  342.             LDAP_BOOL_SET(lo, LDAP_BOOL_REFERRALS);
  343.         }
  344.         return LDAP_OPT_SUCCESS;
  345.  
  346.     case LDAP_OPT_RESTART:
  347.         if(invalue == LDAP_OPT_OFF) {
  348.             LDAP_BOOL_CLR(lo, LDAP_BOOL_RESTART);
  349.         } else {
  350.             LDAP_BOOL_SET(lo, LDAP_BOOL_RESTART);
  351.         }
  352.         return LDAP_OPT_SUCCESS;
  353.     }
  354.  
  355.     /* options which can withstand invalue == NULL */
  356.     switch ( option ) {
  357.     case LDAP_OPT_SERVER_CONTROLS: {
  358.             LDAPControl *const *controls =
  359.                 (LDAPControl *const *) invalue;
  360.  
  361.             ldap_controls_free( lo->ldo_sctrls );
  362.  
  363.             if( controls == NULL || *controls == NULL ) {
  364.                 lo->ldo_sctrls = NULL;
  365.                 return LDAP_OPT_SUCCESS;
  366.             }
  367.                 
  368.             lo->ldo_sctrls = ldap_controls_dup( controls );
  369.  
  370.             if(lo->ldo_sctrls == NULL) {
  371.                 /* memory allocation error ? */
  372.                 break;
  373.             }
  374.         } return LDAP_OPT_SUCCESS;
  375.  
  376.     case LDAP_OPT_CLIENT_CONTROLS: {
  377.             LDAPControl *const *controls =
  378.                 (LDAPControl *const *) invalue;
  379.  
  380.             ldap_controls_free( lo->ldo_cctrls );
  381.  
  382.             if( controls == NULL || *controls == NULL ) {
  383.                 lo->ldo_cctrls = NULL;
  384.                 return LDAP_OPT_SUCCESS;
  385.             }
  386.                 
  387.             lo->ldo_cctrls = ldap_controls_dup( controls );
  388.  
  389.             if(lo->ldo_cctrls == NULL) {
  390.                 /* memory allocation error ? */
  391.                 break;
  392.             }
  393.         } return LDAP_OPT_SUCCESS;
  394.  
  395.     case LDAP_OPT_TIMEOUT: {
  396.             const struct timeval *tv = 
  397.                 (const struct timeval *) invalue;
  398.  
  399.             if ( lo->ldo_tm_api != NULL ) {
  400.                 LDAP_FREE( lo->ldo_tm_api );
  401.                 lo->ldo_tm_api = NULL;
  402.             }
  403.  
  404.             if ( ldap_int_timeval_dup( &lo->ldo_tm_api, tv ) != 0 ) {
  405.                 return LDAP_OPT_ERROR;
  406.             }
  407.         } return LDAP_OPT_SUCCESS;
  408.  
  409.     case LDAP_OPT_NETWORK_TIMEOUT: {
  410.             const struct timeval *tv = 
  411.                 (const struct timeval *) invalue;
  412.  
  413.             if ( lo->ldo_tm_net != NULL ) {
  414.                 LDAP_FREE( lo->ldo_tm_net );
  415.                 lo->ldo_tm_net = NULL;
  416.             }
  417.  
  418.             if ( ldap_int_timeval_dup( &lo->ldo_tm_net, tv ) != 0 ) {
  419.                 return LDAP_OPT_ERROR;
  420.             }
  421.         } return LDAP_OPT_SUCCESS;
  422.  
  423.     /* Only accessed from inside this function by ldap_set_rebind_proc() */
  424.     case LDAP_OPT_REBIND_PROC: {
  425.             lo->ldo_rebindproc = (LDAP_REBIND_PROC *)invalue;        
  426.         } return LDAP_OPT_SUCCESS;
  427.     }
  428.  
  429.     if(invalue == NULL) {
  430.         /* no place to set from */
  431.         return LDAP_OPT_ERROR;
  432.     }
  433.  
  434.     /* options which cannot withstand invalue == NULL */
  435.  
  436.     switch(option) {
  437.     case LDAP_OPT_API_INFO:
  438.     case LDAP_OPT_DESC:
  439.         /* READ ONLY */
  440.         break;
  441.  
  442.     case LDAP_OPT_DEREF:
  443.         lo->ldo_deref = * (const int *) invalue;
  444.         return LDAP_OPT_SUCCESS;
  445.  
  446.     case LDAP_OPT_SIZELIMIT:
  447.         lo->ldo_sizelimit = * (const int *) invalue;
  448.         return LDAP_OPT_SUCCESS;
  449.  
  450.     case LDAP_OPT_TIMELIMIT:
  451.         lo->ldo_timelimit = * (const int *) invalue;
  452.         return LDAP_OPT_SUCCESS;
  453.  
  454.     case LDAP_OPT_PROTOCOL_VERSION: {
  455.             int vers = * (const int *) invalue;
  456.             if (vers < LDAP_VERSION_MIN || vers > LDAP_VERSION_MAX) {
  457.                 /* not supported */
  458.                 break;
  459.             }
  460.             lo->ldo_version = vers;
  461.         } return LDAP_OPT_SUCCESS;
  462.  
  463.  
  464.     case LDAP_OPT_HOST_NAME: {
  465.             const char *host = (const char *) invalue;
  466.             LDAPURLDesc *ludlist = NULL;
  467.             int rc = LDAP_OPT_SUCCESS;
  468.  
  469.             if(host != NULL) {
  470.                 rc = ldap_url_parsehosts( &ludlist, host,
  471.                     lo->ldo_defport ? lo->ldo_defport : LDAP_PORT );
  472.  
  473.             } else if(ld == NULL) {
  474.                 /*
  475.                  * must want global default returned
  476.                  * to initial condition.
  477.                  */
  478.                 rc = ldap_url_parselist(&ludlist, "ldap://localhost/");
  479.  
  480.             } else {
  481.                 /*
  482.                  * must want the session default
  483.                  *   updated to the current global default
  484.                  */
  485.                 ludlist = ldap_url_duplist(
  486.                     ldap_int_global_options.ldo_defludp);
  487.                 if (ludlist == NULL)
  488.                     rc = LDAP_NO_MEMORY;
  489.             }
  490.  
  491.             if (rc == LDAP_OPT_SUCCESS) {
  492.                 if (lo->ldo_defludp != NULL)
  493.                     ldap_free_urllist(lo->ldo_defludp);
  494.                 lo->ldo_defludp = ludlist;
  495.             }
  496.             return rc;
  497.         }
  498.  
  499.     case LDAP_OPT_URI: {
  500.             const char *urls = (const char *) invalue;
  501.             LDAPURLDesc *ludlist = NULL;
  502.             int rc = LDAP_OPT_SUCCESS;
  503.  
  504.             if(urls != NULL) {
  505.                 rc = ldap_url_parselist(&ludlist, urls);
  506.  
  507.             } else if(ld == NULL) {
  508.                 /*
  509.                  * must want global default returned
  510.                  * to initial condition.
  511.                  */
  512.                 rc = ldap_url_parselist(&ludlist, "ldap://localhost/");
  513.  
  514.             } else {
  515.                 /*
  516.                  * must want the session default
  517.                  *   updated to the current global default
  518.                  */
  519.                 ludlist = ldap_url_duplist(
  520.                     ldap_int_global_options.ldo_defludp);
  521.                 if (ludlist == NULL)
  522.                     rc = LDAP_NO_MEMORY;
  523.             }
  524.  
  525.             if (rc == LDAP_OPT_SUCCESS) {
  526.                 if (lo->ldo_defludp != NULL)
  527.                     ldap_free_urllist(lo->ldo_defludp);
  528.                 lo->ldo_defludp = ludlist;
  529.             }
  530.             return rc;
  531.         }
  532.  
  533.     case LDAP_OPT_ERROR_NUMBER: {
  534.             int err = * (const int *) invalue;
  535.  
  536.             if(ld == NULL) {
  537.                 /* need a struct ldap */
  538.                 break;
  539.             }
  540.  
  541.             ld->ld_errno = err;
  542.         } return LDAP_OPT_SUCCESS;
  543.  
  544.     case LDAP_OPT_ERROR_STRING: {
  545.             const char *err = (const char *) invalue;
  546.  
  547.             if(ld == NULL) {
  548.                 /* need a struct ldap */
  549.                 break;
  550.             }
  551.  
  552.             if( ld->ld_error ) {
  553.                 LDAP_FREE(ld->ld_error);
  554.             }
  555.  
  556.             ld->ld_error = LDAP_STRDUP(err);
  557.         } return LDAP_OPT_SUCCESS;
  558.  
  559.     case LDAP_OPT_MATCHED_DN: {
  560.             const char *err = (const char *) invalue;
  561.  
  562.             if(ld == NULL) {
  563.                 /* need a struct ldap */
  564.                 break;
  565.             }
  566.  
  567.             if( ld->ld_matched ) {
  568.                 LDAP_FREE(ld->ld_matched);
  569.             }
  570.  
  571.             ld->ld_matched = LDAP_STRDUP(err);
  572.         } return LDAP_OPT_SUCCESS;
  573.  
  574.     case LDAP_OPT_API_FEATURE_INFO:
  575.         /* read-only */
  576.         break;
  577.  
  578.     case LDAP_OPT_DEBUG_LEVEL:
  579.         lo->ldo_debug = * (const int *) invalue;
  580.         return LDAP_OPT_SUCCESS;
  581.  
  582.     default:
  583. #ifdef HAVE_TLS
  584.         if ( ldap_pvt_tls_set_option( ld, option, (void *)invalue ) == 0 )
  585.              return LDAP_OPT_SUCCESS;
  586. #endif
  587. #ifdef HAVE_CYRUS_SASL
  588.         if ( ldap_int_sasl_set_option( ld, option, (void *)invalue ) == 0 )
  589.             return LDAP_OPT_SUCCESS;
  590. #endif
  591.         /* bad param */
  592.         break;
  593.     }
  594.     return LDAP_OPT_ERROR;
  595. }
  596.  
  597. int
  598. ldap_set_rebind_proc( LDAP *ld, LDAP_REBIND_PROC *rebind_proc)
  599. {
  600.     return( ldap_set_option( ld, LDAP_OPT_REBIND_PROC, (void *)rebind_proc));
  601. }
  602.