|
|
@ -9,20 +9,22 @@ |
|
|
|
|
|
|
|
|
|
|
|
#include "config.h" |
|
|
|
#include "config.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
enum { bufsize = 1024 }; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** shared connection, used for searching users and
|
|
|
|
|
|
|
|
* comparing their passwords if mode set to 'compare' |
|
|
|
|
|
|
|
* @returns 0 on success, 1 on error |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
LDAP *ld = NULL; |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
int |
|
|
|
check_against_ldap(oal_config_t * const config, |
|
|
|
oal_connect(oal_config_t * const config) |
|
|
|
const char * const username, |
|
|
|
|
|
|
|
const char * const password) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
enum { bufsize = 1024 }; |
|
|
|
const short int ldapver = LDAP_VERSION3; |
|
|
|
|
|
|
|
const short int sizelimit = 5; |
|
|
|
struct timeval tv = { 30, 0 }; |
|
|
|
struct timeval tv = { 30, 0 }; |
|
|
|
short int tmp; |
|
|
|
|
|
|
|
LDAP *ld = NULL; |
|
|
|
|
|
|
|
LDAPMessage *res = NULL; |
|
|
|
|
|
|
|
LDAPMessage *entry = NULL; |
|
|
|
|
|
|
|
char err[bufsize]; |
|
|
|
char err[bufsize]; |
|
|
|
char *searchattr[] = { (char *) LDAP_NO_ATTRS, NULL }; |
|
|
|
int rc = 0; |
|
|
|
int rc; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((rc = ldap_initialize(&ld, config->bindurls)) != LDAP_SUCCESS) { |
|
|
|
if ((rc = ldap_initialize(&ld, config->bindurls)) != LDAP_SUCCESS) { |
|
|
|
snprintf(err, bufsize, "can't connnect to ldap server(s): %s", strerror(errno)); |
|
|
|
snprintf(err, bufsize, "can't connnect to ldap server(s): %s", strerror(errno)); |
|
|
@ -33,62 +35,91 @@ check_against_ldap(oal_config_t * const config, |
|
|
|
tv.tv_sec = config->bindtimeout; |
|
|
|
tv.tv_sec = config->bindtimeout; |
|
|
|
|
|
|
|
|
|
|
|
/* hardcoded options */ |
|
|
|
/* hardcoded options */ |
|
|
|
tmp = LDAP_VERSION3; |
|
|
|
if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ldapver) != LDAP_OPT_SUCCESS) { |
|
|
|
if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &tmp) != LDAP_OPT_SUCCESS) { |
|
|
|
|
|
|
|
snprintf(err, bufsize, "can't set ldap protocol version"); |
|
|
|
snprintf(err, bufsize, "can't set ldap protocol version"); |
|
|
|
goto error_opts; |
|
|
|
goto error; |
|
|
|
} |
|
|
|
} |
|
|
|
tmp = 5; |
|
|
|
if (ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &sizelimit) != LDAP_OPT_SUCCESS) { |
|
|
|
if (ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &tmp) != LDAP_OPT_SUCCESS) { |
|
|
|
|
|
|
|
snprintf(err, bufsize, "can't set max results limit"); |
|
|
|
snprintf(err, bufsize, "can't set max results limit"); |
|
|
|
goto error_opts; |
|
|
|
goto error; |
|
|
|
} |
|
|
|
} |
|
|
|
/* timeouts */ |
|
|
|
/* timeouts */ |
|
|
|
if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &tv) != LDAP_OPT_SUCCESS) { |
|
|
|
if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &tv) != LDAP_OPT_SUCCESS) { |
|
|
|
snprintf(err, bufsize, "can't set network timeout: %d", config->bindtimeout); |
|
|
|
snprintf(err, bufsize, "can't set network timeout: %d", config->bindtimeout); |
|
|
|
goto error_opts; |
|
|
|
goto error; |
|
|
|
} |
|
|
|
} |
|
|
|
if (ldap_set_option(ld, LDAP_OPT_TIMEOUT, &tv) != LDAP_OPT_SUCCESS) { |
|
|
|
if (ldap_set_option(ld, LDAP_OPT_TIMEOUT, &tv) != LDAP_OPT_SUCCESS) { |
|
|
|
snprintf(err, bufsize, "can't set search timeout: %d", config->bindtimeout); |
|
|
|
snprintf(err, bufsize, "can't set search timeout: %d", config->bindtimeout); |
|
|
|
goto error_opts; |
|
|
|
goto error; |
|
|
|
} |
|
|
|
} |
|
|
|
/* TODO: hardcoded */ |
|
|
|
/* TODO: hardcoded */ |
|
|
|
if (ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF) != LDAP_OPT_SUCCESS) { |
|
|
|
if (ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF) != LDAP_OPT_SUCCESS) { |
|
|
|
snprintf(err, bufsize, "can't set follow referrals to 'off'"); |
|
|
|
snprintf(err, bufsize, "can't set follow referrals to 'off'"); |
|
|
|
goto error_opts; |
|
|
|
goto error; |
|
|
|
} |
|
|
|
} |
|
|
|
/* required */ |
|
|
|
/* required */ |
|
|
|
if (ldap_set_option(ld, LDAP_OPT_DEFBASE, config->basedn) != LDAP_OPT_SUCCESS) { |
|
|
|
if (ldap_set_option(ld, LDAP_OPT_DEFBASE, config->basedn) != LDAP_OPT_SUCCESS) { |
|
|
|
snprintf(err, bufsize, "can't set searchbase: %s", config->basedn); |
|
|
|
snprintf(err, bufsize, "can't set searchbase: %s", config->basedn); |
|
|
|
goto error_opts; |
|
|
|
goto error; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if((rc = ldap_simple_bind_s(ld, config->binddn, config->bindpass)) != LDAP_SUCCESS) { |
|
|
|
if((rc = ldap_simple_bind_s(ld, config->binddn, config->bindpass)) != LDAP_SUCCESS) { |
|
|
|
snprintf(err, bufsize, "can't bind to ldap server: %s", ldap_err2string(rc)); |
|
|
|
snprintf(err, bufsize, "can't bind to ldap server: %s", ldap_err2string(rc)); |
|
|
|
goto error_opts; |
|
|
|
goto error; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0; /* success */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
error: |
|
|
|
|
|
|
|
config->error = strndup(err, bufsize); |
|
|
|
|
|
|
|
return 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @returns 1 if user pass the check, 0 on password mismatch and -1 on error |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
int |
|
|
|
|
|
|
|
oal_check_cred(oal_config_t * const config, |
|
|
|
|
|
|
|
const char * const username, |
|
|
|
|
|
|
|
const char * const password) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LDAPMessage *res = NULL; /* whole search result */ |
|
|
|
|
|
|
|
LDAPMessage *msg = NULL; /* first message from search result */ |
|
|
|
|
|
|
|
char *searchattr[] = { (char *) LDAP_NO_ATTRS, NULL }; |
|
|
|
|
|
|
|
char *udn = NULL; /* DN of found user */ |
|
|
|
|
|
|
|
char err[bufsize]; |
|
|
|
|
|
|
|
int rc = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!ld && !oal_connect(config)) |
|
|
|
|
|
|
|
return -1; /* error text already set inside oal_connect() */ |
|
|
|
|
|
|
|
|
|
|
|
rc = ldap_search_s(ld, config->basedn, LDAP_SCOPE_SUBTREE, config->userfilter, searchattr, 1, &res); |
|
|
|
rc = ldap_search_s(ld, config->basedn, LDAP_SCOPE_SUBTREE, config->userfilter, searchattr, 1, &res); |
|
|
|
if (rc != LDAP_SUCCESS) { |
|
|
|
if (rc != LDAP_SUCCESS) { |
|
|
|
; |
|
|
|
snprintf(err, bufsize, "ldap search failed: %s", ldap_err2string(rc)); |
|
|
|
|
|
|
|
goto error; /* TODO */ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
while (1) { |
|
|
|
if (ldap_count_messages(ld, res) <= 0) { |
|
|
|
if ((ldap_simple_bind_s(ld, NULL, password)) != LDAP_SUCCESS) { |
|
|
|
ldap_msgfree(res); |
|
|
|
} |
|
|
|
return 0; /* no such user or error */ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (res) { |
|
|
|
if ((msg = ldap_first_message(ld, res)) == NULL) { |
|
|
|
ldap_msgfree(res); |
|
|
|
snprintf(err, bufsize, "ldap search found something, but can't get result"); |
|
|
|
res = NULL; |
|
|
|
goto error; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (ld) |
|
|
|
if ((udn = ldap_get_dn(ld, msg)) == NULL) { |
|
|
|
ldap_unbind(ld); |
|
|
|
snprintf(err, bufsize, "can't get DN of found user"); |
|
|
|
|
|
|
|
goto error; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
return 1; |
|
|
|
|
|
|
|
|
|
|
|
error_opts: |
|
|
|
error: |
|
|
|
|
|
|
|
if (res) ldap_msgfree(res); |
|
|
|
|
|
|
|
if (msg) ldap_msgfree(msg); |
|
|
|
|
|
|
|
if (udn) ldap_memfree(udn); |
|
|
|
config->error = strndup(err, bufsize); |
|
|
|
config->error = strndup(err, bufsize); |
|
|
|
return 1; |
|
|
|
return -1; |
|
|
|
} |
|
|
|
} |
|
|
|