--- rlm_ldap.c 2008-01-05 18:51:50.000000000 +0000 +++ rlm_ldap_mozilla.c 2008-01-23 16:27:55.000000000 +0000 @@ -102,6 +102,10 @@ #endif +#ifndef LDAP_OPT_SUCCESS +#define LDAP_OPT_SUCCESS LDAP_SUCCESS +#endif + /* linked list of mappings between RADIUS attributes and LDAP attributes */ struct TLDAP_RADIUS { char* attr; @@ -406,11 +410,13 @@ inst->timeout.tv_usec = 0; inst->net_timeout.tv_usec = 0; +#ifdef LDAP_OPT_X_TLS_HARD /* workaround for servers which support LDAPS but not START TLS */ if(inst->port == LDAPS_PORT || inst->tls_mode) inst->tls_mode = LDAP_OPT_X_TLS_HARD; else inst->tls_mode = 0; +#endif inst->reply_item_map = NULL; inst->check_item_map = NULL; inst->conns = NULL; @@ -2153,7 +2159,12 @@ int msgid, rc, ldap_version; int ldap_errno = 0; LDAPMessage *res; - +#ifdef LDAP_X_OPT_CONNECT_TIMEOUT + int ctimeout; +#endif +#ifdef HAVE_LDAPSSL_ADVCLIENTAUTH_INIT + int sslstrength; +#endif if (inst->is_url){ #ifdef HAVE_LDAP_INITIALIZE DEBUG("rlm_ldap: (re)connect to %s, authentication %d", inst->server, auth); @@ -2164,27 +2175,50 @@ } #endif } else { +#ifdef HAVE_LDAPSSL_ADVCLIENTAUTH_INIT + if(inst->port != LDAPS_PORT && !inst->tls_mode) { + DEBUG("rlm_ldap: (re)connect to %s:%d, authentication %d", inst->server, inst->port, auth); + if ((ld = ldap_init(inst->server, inst->port)) == NULL) { + radlog(L_ERR, "rlm_ldap: ldap_init() failed"); + *result = RLM_MODULE_FAIL; + return (NULL); + } + } +#else DEBUG("rlm_ldap: (re)connect to %s:%d, authentication %d", inst->server, inst->port, auth); if ((ld = ldap_init(inst->server, inst->port)) == NULL) { radlog(L_ERR, "rlm_ldap: ldap_init() failed"); *result = RLM_MODULE_FAIL; return (NULL); } +#endif } + +#ifdef LDAP_X_OPT_CONNECT_TIMEOUT + ctimeout=inst->net_timeout.tv_sec*1000; + if (ldap_set_option(ld, LDAP_X_OPT_CONNECT_TIMEOUT, + (void *) &ctimeout) != LDAP_OPT_SUCCESS) { + radlog(L_ERR, "rlm_ldap: Could not set LDAP_OPT_NETWORK_TIMEOUT %ld", ctimeout); + } +#endif + +#ifdef LDAP_OPT_NETWORK_TIMEOUT if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, (void *) &(inst->net_timeout)) != LDAP_OPT_SUCCESS) { radlog(L_ERR, "rlm_ldap: Could not set LDAP_OPT_NETWORK_TIMEOUT %ld.%ld", inst->net_timeout.tv_sec, inst->net_timeout.tv_usec); } - +#endif +#ifdef LDAP_OPT_TIMELIMIT if (ldap_set_option(ld, LDAP_OPT_TIMELIMIT, (void *) &(inst->timelimit)) != LDAP_OPT_SUCCESS) { radlog(L_ERR, "rlm_ldap: Could not set LDAP_OPT_TIMELIMIT %d", inst->timelimit); } - +#endif +#ifdef LDAP_OPT_DEBUG_LEVEL if (inst->ldap_debug && ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &(inst->ldap_debug)) != LDAP_OPT_SUCCESS) { radlog(L_ERR, "rlm_ldap: Could not set LDAP_OPT_DEBUG_LEVEL %d", inst->ldap_debug); } - +#endif ldap_version = LDAP_VERSION3; if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ldap_version) != LDAP_OPT_SUCCESS) { @@ -2292,6 +2326,56 @@ } #endif /* HAVE_LDAP_START_TLS */ +#ifdef HAVE_LDAPSSL_ADVCLIENTAUTH_INIT + if (inst->tls_cacertdir != NULL) { + DEBUG("rlm_ldap: setting TLS CACert Directory to %s", inst->tls_cacertdir); + } +/* + * allow => + * LDAPSSL_AUTH_WEAK indicates that you accept the server's certificate without checking + * the CA who issued the certificate. + * demand => + * LDAPSSL_AUTH_CERT indicates that you accept the server's certificate only if you trust + * the CA who issued the certificate. + * strict => + * LDAPSSL_AUTH_CNCHECK indicates that you accept the server's certificate only if you trust + * the CA who issued the certificate and if the value of the cn attribute + * is the DNS hostname of the server. + * try,never => invalid + */ + sslstrength = LDAPSSL_AUTH_WEAK; + if (strcmp(TLS_DEFAULT_VERIFY, inst->tls_require_cert ) != 0 ) { + DEBUG("rlm_ldap: setting TLS Require Cert to %s", + inst->tls_require_cert); + if (strcmp(inst->tls_require_cert,"demand") == 0) + sslstrength=LDAPSSL_AUTH_CERT; + else if (strcmp(inst->tls_require_cert,"strict") == 0) + sslstrength=LDAPSSL_AUTH_CNCHECK; + else + DEBUG("rlm_ldap: invalid TLS Require Cert value %s", + inst->tls_require_cert); + } + if(inst->port == LDAPS_PORT || inst->tls_mode) { + DEBUG("rlm_ldap: starting SSL"); + rc = ldapssl_advclientauth_init( inst->tls_cacertdir, NULL , 0 , NULL, NULL, 0, NULL, sslstrength); + if (rc != LDAP_SUCCESS) { + DEBUG("rlm_ldap: ldapssl_advclientauth_init()"); + ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, + &ldap_errno); + radlog(L_ERR, "rlm_ldap: could not start SSL %s", + ldap_err2string(ldap_errno)); + *result = RLM_MODULE_FAIL; + return (NULL); + } + DEBUG("rlm_ldap: (re)connect to %s:%d, authentication %d", inst->server, inst->port, auth); + if ((ld = ldapssl_init(inst->server, inst->port, 1)) == NULL) { + radlog(L_ERR, "rlm_ldap: ldap_init() failed"); + *result = RLM_MODULE_FAIL; + return (NULL); + } + } +#endif /* HAVE_LDAPSSL_ADVCLIENTAUTH_INIT */ + if (inst->is_url){ DEBUG("rlm_ldap: bind as %s/%s to %s", dn, password, inst->server);