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

  1. /* $OpenLDAP: pkg/ldap/libraries/libldap/init.c,v 1.33.2.9 2001/09/07 21:17:03 kurt Exp $ */
  2. /*
  3.  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  4.  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  5.  */
  6. #include "portable.h"
  7.  
  8. #include <stdio.h>
  9. #include <ac/stdlib.h>
  10.  
  11. #include <ac/socket.h>
  12. #include <ac/string.h>
  13. #include <ac/ctype.h>
  14. #include <ac/time.h>
  15.  
  16. #include <limits.h>
  17.  
  18. #include "ldap-int.h"
  19. #include "ldap_defaults.h"
  20.  
  21. struct ldapoptions ldap_int_global_options =
  22.     { LDAP_UNINITIALIZED, LDAP_DEBUG_NONE };  
  23.  
  24. #define ATTR_NONE    0
  25. #define ATTR_BOOL    1
  26. #define ATTR_INT    2
  27. #define ATTR_KV        3
  28. #define ATTR_STRING    4
  29. #define ATTR_OPTION    5
  30.  
  31. #define ATTR_SASL    6
  32. #define ATTR_TLS    7
  33.  
  34. struct ol_keyvalue {
  35.     const char *        key;
  36.     int            value;
  37. };
  38.  
  39. static const struct ol_keyvalue deref_kv[] = {
  40.     {"never", LDAP_DEREF_NEVER},
  41.     {"searching", LDAP_DEREF_SEARCHING},
  42.     {"finding", LDAP_DEREF_FINDING},
  43.     {"always", LDAP_DEREF_ALWAYS},
  44.     {NULL, 0}
  45. };
  46.  
  47. static const struct ol_attribute {
  48.     int            useronly;
  49.     int            type;
  50.     const char *    name;
  51.     const void *    data;
  52.     size_t        offset;
  53. } attrs[] = {
  54.     {0, ATTR_KV,        "DEREF",    deref_kv, /* or &deref_kv[0] */
  55.         offsetof(struct ldapoptions, ldo_deref)},
  56.     {0, ATTR_INT,        "SIZELIMIT",    NULL,
  57.         offsetof(struct ldapoptions, ldo_sizelimit)},
  58.     {0, ATTR_INT,        "TIMELIMIT",    NULL,
  59.         offsetof(struct ldapoptions, ldo_timelimit)},
  60.     {1, ATTR_STRING,    "BINDDN",        NULL,
  61.         offsetof(struct ldapoptions, ldo_defbinddn)},
  62.     {0, ATTR_STRING,    "BASE",            NULL,
  63.         offsetof(struct ldapoptions, ldo_defbase)},
  64.     {0, ATTR_INT,        "PORT",            NULL,        /* deprecated */
  65.         offsetof(struct ldapoptions, ldo_defport)},
  66.     {0, ATTR_OPTION,    "HOST",            NULL,    LDAP_OPT_HOST_NAME}, /* deprecated */
  67.     {0, ATTR_OPTION,    "URI",            NULL,    LDAP_OPT_URI}, /* replaces HOST/PORT */
  68.     {0, ATTR_BOOL,        "REFERRALS",    NULL,    LDAP_BOOL_REFERRALS},
  69.     {0, ATTR_BOOL,        "RESTART",        NULL,    LDAP_BOOL_RESTART},
  70.  
  71. #ifdef HAVE_CYRUS_SASL
  72.     {1, ATTR_STRING,    "SASL_MECH",        NULL,
  73.         offsetof(struct ldapoptions, ldo_def_sasl_mech)},
  74.     {1, ATTR_STRING,    "SASL_REALM",        NULL,
  75.         offsetof(struct ldapoptions, ldo_def_sasl_realm)},
  76.     {1, ATTR_STRING,    "SASL_AUTHCID",        NULL,
  77.         offsetof(struct ldapoptions, ldo_def_sasl_authcid)},
  78.     {1, ATTR_STRING,    "SASL_AUTHZID",        NULL,
  79.         offsetof(struct ldapoptions, ldo_def_sasl_authzid)},
  80.     {0, ATTR_SASL,        "SASL_SECPROPS",    NULL,    LDAP_OPT_X_SASL_SECPROPS},
  81. #endif
  82.  
  83. #ifdef HAVE_TLS
  84.       {0, ATTR_TLS,        "TLS",            NULL,    LDAP_OPT_X_TLS},
  85.     {1, ATTR_TLS,        "TLS_CERT",        NULL,    LDAP_OPT_X_TLS_CERTFILE},
  86.     {1, ATTR_TLS,        "TLS_KEY",        NULL,    LDAP_OPT_X_TLS_KEYFILE},
  87.       {0, ATTR_TLS,        "TLS_CACERT",    NULL,    LDAP_OPT_X_TLS_CACERTFILE},
  88.       {0, ATTR_TLS,        "TLS_CACERTDIR",NULL,    LDAP_OPT_X_TLS_CACERTDIR},
  89.       {0, ATTR_TLS,        "TLS_REQCERT",    NULL,    LDAP_OPT_X_TLS_REQUIRE_CERT},
  90.     {0, ATTR_TLS,        "TLS_RANDFILE",    NULL,    LDAP_OPT_X_TLS_RANDOM_FILE},
  91. #endif
  92.  
  93.     {0, ATTR_NONE,        NULL,        NULL,    0}
  94. };
  95.  
  96. #define MAX_LDAP_ATTR_LEN  sizeof("TLS_CACERTDIR")
  97. #define MAX_LDAP_ENV_PREFIX_LEN 8
  98.  
  99. static void openldap_ldap_init_w_conf(
  100.     const char *file, int userconf )
  101. {
  102.     char linebuf[128];
  103.     FILE *fp;
  104.     int i;
  105.     char *cmd, *opt;
  106.     char *start, *end;
  107.     struct ldapoptions *gopts;
  108.  
  109.     if ((gopts = LDAP_INT_GLOBAL_OPT()) == NULL) {
  110.         return;            /* Could not allocate mem for global options */
  111.     }
  112.  
  113.     if (file == NULL) {
  114.         /* no file name */
  115.         return;
  116.     }
  117.  
  118.     Debug(LDAP_DEBUG_TRACE, "ldap_init: trying %s\n", file, 0, 0);
  119.  
  120.     fp = fopen(file, "r");
  121.     if(fp == NULL) {
  122.         /* could not open file */
  123.         return;
  124.     }
  125.  
  126.     Debug(LDAP_DEBUG_TRACE, "ldap_init: using %s\n", file, 0, 0);
  127.  
  128.     while((start = fgets(linebuf, sizeof(linebuf), fp)) != NULL) {
  129.         /* skip lines starting with '#' */
  130.         if(*start == '#') continue;
  131.  
  132.         /* trim leading white space */
  133.         while((*start != '\0') && isspace((unsigned char) *start))
  134.             start++;
  135.  
  136.         /* anything left? */
  137.         if(*start == '\0') continue;
  138.  
  139.         /* trim trailing white space */
  140.         end = &start[strlen(start)-1];
  141.         while(isspace((unsigned char)*end)) end--;
  142.         end[1] = '\0';
  143.  
  144.         /* anything left? */
  145.         if(*start == '\0') continue;
  146.         
  147.  
  148.         /* parse the command */
  149.         cmd=start;
  150.         while((*start != '\0') && !isspace((unsigned char)*start)) {
  151.             start++;
  152.         }
  153.         if(*start == '\0') {
  154.             /* command has no argument */
  155.             continue;
  156.         } 
  157.  
  158.         *start++ = '\0';
  159.  
  160.         /* we must have some whitespace to skip */
  161.         while(isspace((unsigned char)*start)) start++;
  162.         opt = start;
  163.  
  164.         for(i=0; attrs[i].type != ATTR_NONE; i++) {
  165.             void *p;
  166.  
  167.             if( !userconf && attrs[i].useronly ) {
  168.                 continue;
  169.             }
  170.  
  171.             if(strcasecmp(cmd, attrs[i].name) != 0) {
  172.                 continue;
  173.             }
  174.  
  175.             switch(attrs[i].type) {
  176.             case ATTR_BOOL:
  177.                 if((strcasecmp(opt, "on") == 0) 
  178.                     || (strcasecmp(opt, "yes") == 0)
  179.                     || (strcasecmp(opt, "true") == 0))
  180.                 {
  181.                     LDAP_BOOL_SET(gopts, attrs[i].offset);
  182.  
  183.                 } else {
  184.                     LDAP_BOOL_CLR(gopts, attrs[i].offset);
  185.                 }
  186.  
  187.                 break;
  188.  
  189.             case ATTR_INT:
  190.                 p = &((char *) gopts)[attrs[i].offset];
  191.                 * (int*) p = atoi(opt);
  192.                 break;
  193.  
  194.             case ATTR_KV: {
  195.                     const struct ol_keyvalue *kv;
  196.  
  197.                     for(kv = attrs[i].data;
  198.                         kv->key != NULL;
  199.                         kv++) {
  200.  
  201.                         if(strcasecmp(opt, kv->key) == 0) {
  202.                             p = &((char *) gopts)[attrs[i].offset];
  203.                             * (int*) p = kv->value;
  204.                             break;
  205.                         }
  206.                     }
  207.                 } break;
  208.  
  209.             case ATTR_STRING:
  210.                 p = &((char *) gopts)[attrs[i].offset];
  211.                 if (* (char**) p != NULL) LDAP_FREE(* (char**) p);
  212.                 * (char**) p = LDAP_STRDUP(opt);
  213.                 break;
  214.             case ATTR_OPTION:
  215.                 ldap_set_option( NULL, attrs[i].offset, opt );
  216.                 break;
  217.             case ATTR_SASL:
  218. #ifdef HAVE_CYRUS_SASL
  219.                    ldap_int_sasl_config( gopts, attrs[i].offset, opt );
  220. #endif
  221.                 break;
  222.             case ATTR_TLS:
  223. #ifdef HAVE_TLS
  224.                    ldap_int_tls_config( NULL, attrs[i].offset, opt );
  225. #endif
  226.                 break;
  227.             }
  228.  
  229.             break;
  230.         }
  231.     }
  232.  
  233.     fclose(fp);
  234. }
  235.  
  236. static void openldap_ldap_init_w_sysconf(const char *file)
  237. {
  238.     openldap_ldap_init_w_conf( file, 0 );
  239. }
  240.  
  241. static void openldap_ldap_init_w_userconf(const char *file)
  242. {
  243.     char *home;
  244.     char *path = NULL;
  245.  
  246.     if (file == NULL) {
  247.         /* no file name */
  248.         return;
  249.     }
  250.  
  251.     home = getenv("HOME");
  252.  
  253.     if (home != NULL) {
  254.         Debug(LDAP_DEBUG_TRACE, "ldap_init: HOME env is %s\n",
  255.               home, 0, 0);
  256.         path = LDAP_MALLOC(strlen(home) + strlen(file) + 3);
  257.     } else {
  258.         Debug(LDAP_DEBUG_TRACE, "ldap_init: HOME env is NULL\n",
  259.               0, 0, 0);
  260.     }
  261.  
  262.     if(home != NULL && path != NULL) {
  263.         /* we assume UNIX path syntax is used... */
  264.  
  265.         /* try ~/file */
  266.         sprintf(path, "%s/%s", home, file);
  267.         openldap_ldap_init_w_conf(path, 1);
  268.  
  269.         /* try ~/.file */
  270.         sprintf(path, "%s/.%s", home, file);
  271.         openldap_ldap_init_w_conf(path, 1);
  272.     }
  273.  
  274.     if(path != NULL) {
  275.         LDAP_FREE(path);
  276.     }
  277.  
  278.     /* try file */
  279.     openldap_ldap_init_w_conf(file, 1);
  280. }
  281.  
  282. static void openldap_ldap_init_w_env(
  283.         struct ldapoptions *gopts,
  284.         const char *prefix)
  285. {
  286.     char buf[MAX_LDAP_ATTR_LEN+MAX_LDAP_ENV_PREFIX_LEN];
  287.     int len;
  288.     int i;
  289.     void *p;
  290.     char *value;
  291.  
  292.     if (prefix == NULL) {
  293.         prefix = LDAP_ENV_PREFIX;
  294.     }
  295.  
  296.     strncpy(buf, prefix, MAX_LDAP_ENV_PREFIX_LEN);
  297.     buf[MAX_LDAP_ENV_PREFIX_LEN] = '\0';
  298.     len = strlen(buf);
  299.  
  300.     for(i=0; attrs[i].type != ATTR_NONE; i++) {
  301.         strcpy(&buf[len], attrs[i].name);
  302.         value = getenv(buf);
  303.  
  304.         if(value == NULL) {
  305.             continue;
  306.         }
  307.  
  308.         switch(attrs[i].type) {
  309.         case ATTR_BOOL:
  310.             if((strcasecmp(value, "on") == 0) 
  311.                 || (strcasecmp(value, "yes") == 0)
  312.                 || (strcasecmp(value, "true") == 0))
  313.             {
  314.                 LDAP_BOOL_SET(gopts, attrs[i].offset);
  315.  
  316.             } else {
  317.                 LDAP_BOOL_CLR(gopts, attrs[i].offset);
  318.             }
  319.             break;
  320.  
  321.         case ATTR_INT:
  322.             p = &((char *) gopts)[attrs[i].offset];
  323.             * (int*) p = atoi(value);
  324.             break;
  325.  
  326.         case ATTR_KV: {
  327.                 const struct ol_keyvalue *kv;
  328.  
  329.                 for(kv = attrs[i].data;
  330.                     kv->key != NULL;
  331.                     kv++) {
  332.  
  333.                     if(strcasecmp(value, kv->key) == 0) {
  334.                         p = &((char *) gopts)[attrs[i].offset];
  335.                         * (int*) p = kv->value;
  336.                         break;
  337.                     }
  338.                 }
  339.             } break;
  340.  
  341.         case ATTR_STRING:
  342.             p = &((char *) gopts)[attrs[i].offset];
  343.             if (* (char**) p != NULL) LDAP_FREE(* (char**) p);
  344.             if (*value == '\0') {
  345.                 * (char**) p = NULL;
  346.             } else {
  347.                 * (char**) p = LDAP_STRDUP(value);
  348.             }
  349.             break;
  350.         case ATTR_OPTION:
  351.             ldap_set_option( NULL, attrs[i].offset, value );
  352.             break;
  353.         case ATTR_SASL:
  354. #ifdef HAVE_CYRUS_SASL
  355.                ldap_int_sasl_config( gopts, attrs[i].offset, value );
  356. #endif                 
  357.                break;
  358.         case ATTR_TLS:
  359. #ifdef HAVE_TLS
  360.                ldap_int_tls_config( NULL, attrs[i].offset, value );
  361. #endif                 
  362.                break;
  363.         }
  364.     }
  365. }
  366.  
  367. /* 
  368.  * Initialize the global options structure with default values.
  369.  */
  370. void ldap_int_initialize_global_options( struct ldapoptions *gopts, int *dbglvl )
  371. {
  372.     if (dbglvl)
  373.         gopts->ldo_debug = *dbglvl;
  374.     else
  375.         gopts->ldo_debug = 0;
  376.  
  377.     gopts->ldo_version   = LDAP_VERSION2;
  378.     gopts->ldo_deref     = LDAP_DEREF_NEVER;
  379.     gopts->ldo_timelimit = LDAP_NO_LIMIT;
  380.     gopts->ldo_sizelimit = LDAP_NO_LIMIT;
  381.  
  382.     gopts->ldo_tm_api = (struct timeval *)NULL;
  383.     gopts->ldo_tm_net = (struct timeval *)NULL;
  384.  
  385.     /* ldo_defludp is leaked, we should have an at_exit() handler
  386.      * to free this and whatever else needs to cleaned up. 
  387.      */
  388.     ldap_url_parselist(&gopts->ldo_defludp, "ldap://localhost/");
  389.     gopts->ldo_defport = LDAP_PORT;
  390.  
  391.     gopts->ldo_refhoplimit = LDAP_DEFAULT_REFHOPLIMIT;
  392.     gopts->ldo_rebindproc = NULL;
  393.  
  394.     LDAP_BOOL_ZERO(gopts);
  395.  
  396.     LDAP_BOOL_SET(gopts, LDAP_BOOL_REFERRALS);
  397.  
  398. #ifdef HAVE_CYRUS_SASL
  399.     gopts->ldo_def_sasl_mech = NULL;
  400.     gopts->ldo_def_sasl_realm = NULL;
  401.     gopts->ldo_def_sasl_authcid = NULL;
  402.     gopts->ldo_def_sasl_authzid = NULL;
  403.  
  404.     memset( &gopts->ldo_sasl_secprops,
  405.         '\0', sizeof(gopts->ldo_sasl_secprops) );
  406.  
  407.     gopts->ldo_sasl_secprops.max_ssf = INT_MAX;
  408.     gopts->ldo_sasl_secprops.maxbufsize = SASL_MAX_BUFF_SIZE;
  409.     gopts->ldo_sasl_secprops.security_flags =
  410.         SASL_SEC_NOPLAINTEXT | SASL_SEC_NOANONYMOUS;
  411. #endif
  412.  
  413.     gopts->ldo_valid = LDAP_INITIALIZED;
  414.        return;
  415. }
  416.  
  417. #if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) \
  418.     || defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
  419. char * ldap_int_hostname = NULL;
  420. #endif
  421.  
  422. void ldap_int_initialize( struct ldapoptions *gopts, int *dbglvl )
  423. {
  424.     if ( gopts->ldo_valid == LDAP_INITIALIZED ) {
  425.         return;
  426.     }
  427.  
  428. #if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) \
  429.     || defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
  430.     ldap_int_hostname = ldap_pvt_get_fqdn( ldap_int_hostname );
  431. #endif
  432.  
  433.     ldap_int_utils_init();
  434.  
  435.     if ( ldap_int_tblsize == 0 )
  436.         ldap_int_ip_init();
  437.  
  438.     ldap_int_initialize_global_options(gopts, NULL);
  439.  
  440.     if( getenv("LDAPNOINIT") != NULL ) {
  441.         return;
  442.     }
  443.  
  444. #ifdef HAVE_CYRUS_SASL
  445.     {
  446.         /* set authentication identity to current user name */
  447.         char *user = getenv("USER");
  448.  
  449.         if( user == NULL ) user = getenv("USERNAME");
  450.         if( user == NULL ) user = getenv("LOGNAME");
  451.  
  452.         if( user != NULL ) {
  453.             /* this value is leaked, need at_exit() handler */
  454.             gopts->ldo_def_sasl_authcid = LDAP_STRDUP( user );
  455.         }
  456.     }
  457. #endif
  458.  
  459.     openldap_ldap_init_w_sysconf(LDAP_CONF_FILE);
  460.     openldap_ldap_init_w_userconf(LDAP_USERRC_FILE);
  461.  
  462.     {
  463.         char *altfile = getenv(LDAP_ENV_PREFIX "CONF");
  464.  
  465.         if( altfile != NULL ) {
  466.             Debug(LDAP_DEBUG_TRACE, "ldap_init: %s env is %s\n",
  467.                   LDAP_ENV_PREFIX "CONF", altfile, 0);
  468.             openldap_ldap_init_w_sysconf( altfile );
  469.         }
  470.         else
  471.             Debug(LDAP_DEBUG_TRACE, "ldap_init: %s env is NULL\n",
  472.                   LDAP_ENV_PREFIX "CONF", 0, 0);
  473.     }
  474.  
  475.     {
  476.         char *altfile = getenv(LDAP_ENV_PREFIX "RC");
  477.  
  478.         if( altfile != NULL ) {
  479.             Debug(LDAP_DEBUG_TRACE, "ldap_init: %s env is %s\n",
  480.                   LDAP_ENV_PREFIX "RC", altfile, 0);
  481.             openldap_ldap_init_w_userconf( altfile );
  482.         }
  483.         else
  484.             Debug(LDAP_DEBUG_TRACE, "ldap_init: %s env is NULL\n",
  485.                   LDAP_ENV_PREFIX "RC", 0, 0);
  486.     }
  487.  
  488.     openldap_ldap_init_w_env(gopts, NULL);
  489.  
  490.     ldap_int_sasl_init();
  491. }
  492.