#include <unistd.h>
#include <pthread.h>
+#include "libradius.h"
#include "radiusd.h"
#include "conffile.h"
#include "modules.h"
#define LDAP_VALID_SESSION 0x2
#define LDAP_VALID(ld) ( (ld)->ld_valid == LDAP_VALID_SESSION )
-static char *make_filter(char *, char *);
#ifdef FIELDCPY
static void fieldcpy(char *, char **);
#endif
static int
perform_search(void *instance, char *search_basedn, int scope, char *filter, char **attrs, LDAPMessage ** result)
{
- int msgid;
int res = RLM_MODULE_OK;
- int rc;
+ int ldap_errno = 0;
ldap_instance *inst = instance;
if (!inst->bound) {
inst->bound = 1;
}
DEBUG2("rlm_ldap: performing search in %s, with filter %s", search_basedn, filter);
- msgid = ldap_search(inst->ld, search_basedn, scope, filter, attrs, 0);
- if (msgid == -1) {
- radlog(L_ERR, "rlm_ldap: ldap_search() failed\n");
- inst->bound = 0;
- return (RLM_MODULE_FAIL);
- }
- rc = ldap_result(inst->ld, msgid, 1, timeout, result);
-
- if (rc < 1) {
- ldap_perror(inst->ld, "rlm_ldap: ldap_result()");
- radlog(L_ERR, "rlm_ldap: ldap_result() failed - %s\n", strerror(errno));
- ldap_msgfree(*result);
- inst->bound = 0;
- return (RLM_MODULE_FAIL);
- }
- switch (ldap_result2error(inst->ld, *result, 0)) {
+ switch (ldap_search_st(inst->ld, search_basedn, scope, filter, attrs, 0, timeout, result)) {
case LDAP_SUCCESS:
break;
- case LDAP_TIMELIMIT_EXCEEDED:
- radlog(L_ERR, "rlm_ldap: Warning timelimit exceeded, using partial results\n");
- break;
-
default:
- DEBUG("rlm_ldap: ldap_search() failed");
- ldap_msgfree(*result);
+ ldap_get_option(inst->ld, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
+ radlog(L_ERR, "rlm_ldap: ldap_search() failed: %s", ldap_err2string(ldap_errno));
+/*
+ if(*result != NULL)
+ ldap_msgfree(*result);
+*/
inst->bound = 0;
return (RLM_MODULE_FAIL);
}
{
LDAPMessage *result, *msg, *gr_result;
ldap_instance *inst = instance;
- char *filter, *name, *user_dn;
+ char *user_dn;
char *attrs[] = {"*", NULL};
+ static char filter[MAX_AUTH_QUERY_LEN];
+ static char *filt_patt = "(| (& (objectClass=GroupOfNames) (member=%{Ldap-UserDn})) (& (objectClass=GroupOfUniqueNames) (uniquemember=%{Ldap-UserDn})))";
VALUE_PAIR *check_tmp;
VALUE_PAIR *reply_tmp;
int res;
check_pairs = &request->config_items;
reply_pairs = &request->reply->vps;
- name = request->username->strvalue;
/*
* Check for valid input, zero length names not permitted
*/
- if (name[0] == 0) {
+ if (request->username->strvalue == 0) {
radlog(L_ERR, "rlm_ldap: zero length username not permitted\n");
return RLM_MODULE_INVALID;
}
- DEBUG("rlm_ldap: performing user authorization for %s", name);
+ DEBUG("rlm_ldap: performing user authorization for %s",
+ request->username->strvalue);
- filter = make_filter(inst->filter, name);
+ if(!radius_xlat(filter, MAX_AUTH_QUERY_LEN, inst->filter,
+ request, NULL))
+ radlog (L_ERR, "rlm_ldap: unable to create filter.\n");
if ((res = perform_search(instance, inst->basedn, LDAP_SCOPE_SUBTREE, filter, attrs, &result)) != RLM_MODULE_OK) {
DEBUG("rlm_ldap: search failed");
ldap_msgfree(result);
return RLM_MODULE_FAIL;
}
+ /*
+ * Adding new attribute containing DN for LDAP object associated with
+ * given username
+ */
+ pairadd(&request->packet->vps, pairmake("Ldap-UserDn", user_dn, T_OP_EQ));
/* Remote access is controled by attribute of the user object */
if (inst->access_attr) {
if ((vals = ldap_get_values(inst->ld, msg, inst->access_attr)) != NULL) {
- DEBUG("rlm_ldap: checking if remote access for %s is allowed by %s", name, inst->access_attr);
+ DEBUG("rlm_ldap: checking if remote access for %s is allowed by %s", request->username->strvalue, inst->access_attr);
if (!strncmp(vals[0], "FALSE", 5)) {
DEBUG("rlm_ldap: dialup access disabled");
ldap_msgfree(result);
* since we have objectclass groupOfNames and
* groupOfUniqueNames
*/
- filter = make_filter("(| (& (objectClass=GroupOfNames) (member=%u)) (& (objectClass=GroupOfUniqueNames) (uniquemember=%u)))", user_dn);
+ if(!radius_xlat(filter, MAX_AUTH_QUERY_LEN, filt_patt,
+ request, NULL))
+ radlog (L_ERR, "rlm_ldap: unable to create filter.\n");
+
res = perform_search(instance, inst->access_group, LDAP_SCOPE_BASE, filter, NULL, &gr_result);
ldap_msgfree(gr_result);
if (pairfind(*check_pairs, PW_AUTHTYPE) == NULL)
pairadd(check_pairs, pairmake("Auth-Type", "LDAP", T_OP_CMP_EQ));
- /*
- * Adding new attribute containing DN for LDAP object associated with
- * given username
- */
- pairadd(&request->packet->vps, pairmake("Ldap-UserDn", user_dn, T_OP_EQ));
DEBUG("rlm_ldap: looking for reply items in directory...");
if ((reply_tmp = ldap_pairget(inst->ld, msg, inst->reply_item_map)) != NULL)
pairadd(reply_pairs, reply_tmp);
- DEBUG("rlm_ldap: user %s authorized to use remote access", name);
+ DEBUG("rlm_ldap: user %s authorized to use remote access",
+ request->username->strvalue);
ldap_msgfree(result);
return RLM_MODULE_OK;
}
LDAP *ld_user;
LDAPMessage *result, *msg;
ldap_instance *inst = instance;
- char *filter, *passwd, *user_dn, *name, *attrs[] = {"uid", NULL};
+ char *user_dn, *attrs[] = {"uid", NULL};
+ static char filter[MAX_AUTH_QUERY_LEN];
int res;
VALUE_PAIR *vp_user_dn;
return RLM_MODULE_INVALID;
}
- name = request->username->strvalue;
- passwd = request->password->strvalue;
-
- if (strlen(passwd) == 0) {
+ if (request->password->strvalue == 0) {
radlog(L_ERR, "rlm_ldap: empty password supplied");
return RLM_MODULE_INVALID;
}
- DEBUG("rlm_ldap: login attempt by \"%s\" with password \"%s\"", name, passwd);
- filter = make_filter(inst->filter, name);
+ DEBUG("rlm_ldap: login attempt by \"%s\" with password \"%s\"",
+ request->username->strvalue, request->password->strvalue);
+ if(!radius_xlat(filter, MAX_AUTH_QUERY_LEN, inst->filter,
+ request, NULL))
+ radlog (L_ERR, "rlm_ldap: unable to create filter.\n");
if ((vp_user_dn = pairfind(request->packet->vps, LDAP_USERDN)) == NULL) {
if ((res = perform_search(instance, inst->basedn, LDAP_SCOPE_SUBTREE, filter, attrs, &result)) != RLM_MODULE_OK) {
- DEBUG("rlm_ldap: search did not return ok value");
return (res);
}
if ((msg = ldap_first_entry(inst->ld, result)) == NULL) {
DEBUG("rlm_ldap: user DN: %s", user_dn);
- ld_user = ldap_connect(instance, user_dn, passwd, 1, &res);
+ ld_user = ldap_connect(instance, user_dn, request->password->strvalue,
+ 1, &res);
if (ld_user == NULL)
return (res);
- DEBUG("rlm_ldap: user %s authenticated succesfully", name);
+ DEBUG("rlm_ldap: user %s authenticated succesfully",
+ request->username->strvalue);
ldap_unbind_s(ld_user);
return RLM_MODULE_OK;
}
ldap_instance *inst = instance;
LDAP *ld;
int msgid, rc;
+ int ldap_errno = 0;
LDAPMessage *res;
DEBUG("rlm_ldap: (re)connect to %s:%d, authentication %d", inst->server, inst->port, auth);
}
#endif
- DEBUG("rlm_ldap: connect as %s/%s", dn, password);
+ DEBUG("rlm_ldap: bind as %s/%s", dn, password);
msgid = ldap_bind(ld, dn, password, LDAP_AUTH_SIMPLE);
if (msgid == -1) {
- ldap_perror(ld, "rlm_ldap: ldap_connect()");
+ DEBUG("rlm_ldap: ldap_bind()");
+ ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
+ radlog(L_ERR, "rlm_ldap: %s bind failed: %s", dn, ldap_err2string(ldap_errno));
*result = RLM_MODULE_FAIL;
ldap_unbind_s(ld);
return (NULL);
}
- DEBUG("rlm_ldap: ldap_connect() waiting for bind result ...");
+ DEBUG("rlm_ldap: waiting for bind result ...");
if (inst->timeout.tv_sec < 0)
rc = ldap_result(ld, msgid, 1, NULL, &res);
else
rc = ldap_result(ld, msgid, 1, &(inst->timeout), &res);
- if (rc < 1) {
- ldap_perror(ld, "rlm_ldap: ldap_result()");
+ ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
+ if(rc < 1) {
+ DEBUG("rlm_ldap: ldap_result()");
+ radlog(L_ERR, "rlm_ldap: %s bind failed: %s", dn, (rc == 0) ? "timeout" : ldap_err2string(ldap_errno));
*result = RLM_MODULE_FAIL;
ldap_unbind_s(ld);
return (NULL);
}
- DEBUG("rlm_ldap: ldap_connect() bind finished");
- switch (ldap_result2error(ld, res, 1)) {
+ ldap_errno = ldap_result2error(ld, res, 1);
+ switch (ldap_errno) {
case LDAP_SUCCESS:
*result = RLM_MODULE_OK;
break;
case LDAP_INVALID_CREDENTIALS:
- if (auth) {
+ if (auth)
*result = RLM_MODULE_REJECT;
- break;
- }
+ else {
+ radlog(L_ERR, "rlm_ldap: LDAP login failed: check login, password settings in ldap section of radiusd.conf");
+ *result = RLM_MODULE_FAIL;
+ }
+ break;
+
default:
- DEBUG("rlm_ldap: LDAP FAILURE");
+ radlog(L_ERR,"rlm_ldap: %s bind failed %s", dn, ldap_err2string(ldap_errno));
*result = RLM_MODULE_FAIL;
}
+
if (*result != RLM_MODULE_OK) {
ldap_unbind_s(ld);
ld = NULL;
return 0;
}
-/*****************************************************************************
- * Replace %<whatever> in a string.
- *
- * %u User name
- *
- *****************************************************************************/
-static char *
-make_filter(char *str, char *name)
-{
- static char buf[MAX_AUTH_QUERY_LEN];
- int i = 0, c;
- char *p;
-
- for (p = str; *p; p++) {
- c = *p;
- if (c != '%' && c != '\\') {
- buf[i++] = *p;
- continue;
- }
- if (*++p == 0)
- break;
- if (c == '%')
- switch (*p) {
- case '%':
- buf[i++] = *p;
- break;
- case 'u': /* User name */
- if (name != NULL)
- strcpy(buf + i, name);
- else
- strcpy(buf + i, " ");
- i += strlen(buf + i);
- break;
- default:
- buf[i++] = '%';
- buf[i++] = *p;
- break;
- }
- if (c == '\\')
- switch (*p) {
- case 'n':
- buf[i++] = '\n';
- break;
- case 'r':
- buf[i++] = '\r';
- break;
- case 't':
- buf[i++] = '\t';
- break;
- default:
- buf[i++] = '\\';
- buf[i++] = *p;
- break;
- }
- }
- if (i >= MAX_AUTH_QUERY_LEN)
- i = MAX_AUTH_QUERY_LEN - 1;
- buf[i++] = 0;
- return buf;
-}
-
#ifdef FIELDCPY
static void
fieldcpy(char *string, char **uptr)