- add support in rlm_ldap for reading clients from ldap

- fix TLS parameter controling if a cert which fails to validate will be
    accepted (i.e. self-signed), rlm_ldap config parameter=tls_require_cert
    ldap LDAP_OPT_X_TLS_REQUIRE_CERT parameter was being passed to
    ldap_set_option() when it should have been ldap_int_tls_config()
This commit is contained in:
John Dennis 2007-11-16 13:34:48 +00:00
parent 05ae0f7aec
commit ca4745ed4d
2 changed files with 308 additions and 14 deletions

View File

@ -1,4 +1,4 @@
diff -r -u freeradius-1.1.7/src/modules/rlm_ldap/configure.in work/src/modules/rlm_ldap/configure.in diff -u -r freeradius-1.1.7/src/modules/rlm_ldap/configure.in work/src/modules/rlm_ldap/configure.in
--- freeradius-1.1.7/src/modules/rlm_ldap/configure.in 2007-06-26 03:34:58.000000000 -0400 --- freeradius-1.1.7/src/modules/rlm_ldap/configure.in 2007-06-26 03:34:58.000000000 -0400
+++ work/src/modules/rlm_ldap/configure.in 2007-11-03 14:49:46.000000000 -0400 +++ work/src/modules/rlm_ldap/configure.in 2007-11-03 14:49:46.000000000 -0400
@@ -70,6 +70,75 @@ @@ -70,6 +70,75 @@
@ -128,9 +128,9 @@ diff -r -u freeradius-1.1.7/src/modules/rlm_ldap/configure.in work/src/modules/r
AC_SUBST(targetname) AC_SUBST(targetname)
+AC_CONFIG_HEADER(config.h) +AC_CONFIG_HEADER(config.h)
AC_OUTPUT(Makefile) AC_OUTPUT(Makefile)
diff -r -u freeradius-1.1.7/src/modules/rlm_ldap/rlm_ldap.c work/src/modules/rlm_ldap/rlm_ldap.c diff -u -r freeradius-1.1.7/src/modules/rlm_ldap/rlm_ldap.c work/src/modules/rlm_ldap/rlm_ldap.c
--- freeradius-1.1.7/src/modules/rlm_ldap/rlm_ldap.c 2007-11-01 13:16:18.000000000 -0400 --- freeradius-1.1.7/src/modules/rlm_ldap/rlm_ldap.c 2007-11-01 13:16:18.000000000 -0400
+++ work/src/modules/rlm_ldap/rlm_ldap.c 2007-11-02 13:12:30.000000000 -0400 +++ work/src/modules/rlm_ldap/rlm_ldap.c 2007-11-09 16:52:36.000000000 -0500
@@ -1,3 +1,4 @@ @@ -1,3 +1,4 @@
+// -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; -*- +// -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; -*-
/* /*
@ -138,7 +138,7 @@ diff -r -u freeradius-1.1.7/src/modules/rlm_ldap/rlm_ldap.c work/src/modules/rlm
* *
@@ -159,7 +160,9 @@ @@ -159,7 +160,9 @@
*/ */
static const char rcsid[] = "$Id: freeradius-1.1.7-ipa.patch,v 1.1 2007/11/10 05:13:58 jdennis Exp $"; static const char rcsid[] = "$Id: freeradius-1.1.7-ipa.patch,v 1.2 2007/11/16 13:34:48 jdennis Exp $";
+#define _GNU_SOURCE +#define _GNU_SOURCE
#include "autoconf.h" #include "autoconf.h"
@ -181,7 +181,7 @@ diff -r -u freeradius-1.1.7/src/modules/rlm_ldap/rlm_ldap.c work/src/modules/rlm
typedef struct { typedef struct {
char *server; char *server;
int port; int port;
@@ -322,6 +346,15 @@ @@ -322,6 +346,17 @@
int edir_account_policy_check; int edir_account_policy_check;
#endif #endif
int set_auth_type; int set_auth_type;
@ -194,10 +194,12 @@ diff -r -u freeradius-1.1.7/src/modules/rlm_ldap/rlm_ldap.c work/src/modules/rlm
+ char *krb_principal; + char *krb_principal;
+ krb_session krb; + krb_session krb;
+#endif +#endif
+ char *clients_basedn;
+ char *clients_filter;
} ldap_instance; } ldap_instance;
/* The default setting for TLS Certificate Verification */ /* The default setting for TLS Certificate Verification */
@@ -370,6 +403,14 @@ @@ -370,6 +405,16 @@
#endif #endif
{"set_auth_type", PW_TYPE_BOOLEAN, offsetof(ldap_instance,set_auth_type), NULL, "yes"}, {"set_auth_type", PW_TYPE_BOOLEAN, offsetof(ldap_instance,set_auth_type), NULL, "yes"},
@ -209,10 +211,12 @@ diff -r -u freeradius-1.1.7/src/modules/rlm_ldap/rlm_ldap.c work/src/modules/rlm
+ {"krb_keytab", PW_TYPE_STRING_PTR, offsetof(ldap_instance,krb_keytab), NULL, "${confdir}/krb5.keytab"}, + {"krb_keytab", PW_TYPE_STRING_PTR, offsetof(ldap_instance,krb_keytab), NULL, "${confdir}/krb5.keytab"},
+ {"krb_principal", PW_TYPE_STRING_PTR, offsetof(ldap_instance,krb_principal), NULL, NULL}, + {"krb_principal", PW_TYPE_STRING_PTR, offsetof(ldap_instance,krb_principal), NULL, NULL},
+#endif +#endif
+ {"clients_basedn", PW_TYPE_STRING_PTR, offsetof(ldap_instance,clients_basedn), NULL, NULL},
+ {"clients_filter", PW_TYPE_STRING_PTR, offsetof(ldap_instance,clients_filter), NULL, "(objectclass=radiusClientProfile)"},
{NULL, -1, 0, NULL, NULL} {NULL, -1, 0, NULL, NULL}
}; };
@@ -380,6 +421,214 @@ @@ -380,11 +425,220 @@
#ifdef FIELDCPY #ifdef FIELDCPY
static void fieldcpy(char *, char **); static void fieldcpy(char *, char **);
#endif #endif
@ -427,7 +431,13 @@ diff -r -u freeradius-1.1.7/src/modules/rlm_ldap/rlm_ldap.c work/src/modules/rlm
static VALUE_PAIR *ldap_pairget(LDAP *, LDAPMessage *, TLDAP_RADIUS *,VALUE_PAIR **,char); static VALUE_PAIR *ldap_pairget(LDAP *, LDAPMessage *, TLDAP_RADIUS *,VALUE_PAIR **,char);
static int ldap_groupcmp(void *, REQUEST *, VALUE_PAIR *, VALUE_PAIR *, VALUE_PAIR *, VALUE_PAIR **); static int ldap_groupcmp(void *, REQUEST *, VALUE_PAIR *, VALUE_PAIR *, VALUE_PAIR *, VALUE_PAIR **);
static int ldap_xlat(void *, REQUEST *, char *, char *, size_t, RADIUS_ESCAPE_STRING); static int ldap_xlat(void *, REQUEST *, char *, char *, size_t, RADIUS_ESCAPE_STRING);
@@ -662,6 +911,11 @@ static LDAP *ldap_connect(void *instance, const char *, const char *, int, int *, char **);
static int read_mappings(ldap_instance* inst);
+static int generate_ldap_clients(ldap_instance* inst);
static inline int ldap_get_conn(LDAP_CONN *conns,LDAP_CONN **ret,void *instance)
{
@@ -662,6 +916,15 @@
DEBUG("conns: %p",inst->conns); DEBUG("conns: %p",inst->conns);
@ -436,10 +446,276 @@ diff -r -u freeradius-1.1.7/src/modules/rlm_ldap/rlm_ldap.c work/src/modules/rlm
+ radlog(L_ERR, "rlm_ldap: Failed to init kerberos session"); + radlog(L_ERR, "rlm_ldap: Failed to init kerberos session");
+ } + }
+#endif +#endif
+ if (generate_ldap_clients(inst)) {
+ radlog(L_ERR, "rlm_ldap: Failed to read client list from ldap");
+ }
+
*instance = inst; *instance = inst;
@@ -2167,6 +2421,12 @@ @@ -770,7 +1033,7 @@
static int
perform_search(void *instance, LDAP_CONN *conn, char *search_basedn, int scope, char *filter,
- char **attrs, LDAPMessage ** result)
+ char **attrs, int single, LDAPMessage ** result)
{
int res = RLM_MODULE_OK;
int ldap_errno = 0;
@@ -854,11 +1117,13 @@
return (RLM_MODULE_FAIL);
}
- if ((ldap_count_entries(conn->ld, *result)) != 1) {
+
+ if (single && (ldap_count_entries(conn->ld, *result)) != 1) {
DEBUG("rlm_ldap: object not found or got ambiguous search result");
res = RLM_MODULE_NOTFOUND;
ldap_msgfree(*result);
}
+
return res;
}
@@ -914,6 +1179,156 @@
}
/*
+ * generate_ldap_clients(). read clients from ldap, append to client list
+ */
+
+static int generate_ldap_clients(ldap_instance* inst)
+{
+ LDAP_CONN *conn;
+ int conn_id = -1;
+ int res;
+ LDAPMessage *result, *entry;
+ int client_idx;
+
+ if (!inst->clients_basedn) {
+ DEBUG("rlm_ldap: generate_ldap_clients, client basedn not set, skipping...");
+ return 0;
+ }
+ DEBUG("rlm_ldap: generate_ldap_clients, client_basedn=%s", inst->clients_basedn);
+
+
+ if ((conn_id = ldap_get_conn(inst->conns,&conn,inst)) == -1){
+ radlog(L_ERR, "rlm_ldap: All ldap connections are in use");
+ return 1;
+ }
+ if ((res = perform_search(inst, conn, inst->clients_basedn, LDAP_SCOPE_SUBTREE,
+ inst->clients_filter, NULL, FALSE, &result)) != RLM_MODULE_OK){
+ DEBUG("rlm_ldap::generate_ldap_clients: search failed");
+ ldap_release_conn(conn_id,inst->conns);
+ return 1;
+ }
+
+ for (entry = ldap_first_entry(conn->ld, result), client_idx = 0;
+ entry != NULL;
+ entry = ldap_next_entry(conn->ld, entry), client_idx++) {
+ char *val, **vals;
+ RADCLIENT client, *p_client;
+ char *netmask;
+ char ip_buf[64];
+
+ memset(&client, 0, sizeof(client));
+
+ if ((vals = ldap_get_values(conn->ld, entry, "radiusClientNASIpAddress")) != NULL) {
+ val = vals[0];
+ if (strlen(val) >= sizeof(client.longname)) {
+ radlog(L_ERR, "rlm_ldap, retrieving clients: address (%s) length %d exceeds %d maximum",
+ val, strlen(val), sizeof(client.longname)-1);
+ ldap_value_free(vals);
+ continue;
+ } else {
+ strcpy(client.longname, val);
+ ldap_value_free(vals);
+ }
+ }
+
+
+ if ((vals = ldap_get_values(conn->ld, entry, "radiusClientSecret")) != NULL) {
+ val = vals[0];
+ if (strlen(val) >= sizeof(client.secret)) {
+ radlog(L_ERR, "rlm_ldap, retrieving clients: secret length %d exceeds %d maximum",
+ strlen(val), sizeof(client.secret)-1);
+ ldap_value_free(vals);
+ continue;
+ } else {
+ strcpy(client.secret, val);
+ ldap_value_free(vals);
+ }
+ }
+
+
+ if ((vals = ldap_get_values(conn->ld, entry, "radiusClientNASType")) != NULL) {
+ val = vals[0];
+ if (strlen(val) >= sizeof(client.nastype)) {
+ radlog(L_ERR, "rlm_ldap, retrieving clients:NAS Type (%s) length %d exceeds %d maximum",
+ val, strlen(val), sizeof(client.nastype)-1);
+ ldap_value_free(vals);
+ continue;
+ } else {
+ strcpy(client.nastype, val);
+ ldap_value_free(vals);
+ }
+ }
+
+
+ if ((vals = ldap_get_values(conn->ld, entry, "radiusClientShortName")) != NULL) {
+ val = vals[0];
+ if (strlen(val) >= sizeof(client.shortname)) {
+ radlog(L_ERR, "rlm_ldap, retrieving clients: address (%s) length %d exceeds %d maximum",
+ val, strlen(val), sizeof(client.shortname)-1);
+ ldap_value_free(vals);
+ continue;
+ } else {
+ strcpy(client.shortname, val);
+ ldap_value_free(vals);
+ }
+ }
+
+
+ /* Look for a mask in the hostname */
+ netmask = strchr(client.longname, '/');
+ client.netmask = ~0;
+ if (netmask) {
+ int mask_length;
+
+ *netmask = '\0';
+ netmask++;
+
+ mask_length = atoi(netmask);
+ if ((mask_length < 0) || (mask_length > 32)) {
+ radlog(L_ERR, "rlm_ldap: Invalid value '%s' for IP network mask.for %s", netmask, client.longname);
+ continue;
+ }
+
+ if (mask_length == 0) {
+ client.netmask = 0;
+ } else {
+ client.netmask = ~0 << (32 - mask_length);
+ }
+ }
+
+ client.ipaddr = ip_getaddr(client.longname);
+ if (client.ipaddr == INADDR_NONE) {
+ radlog(L_ERR, "rlm_ldap: Failed to look up hostname %s", client.longname);
+ continue;
+ }
+ client.netmask = htonl(client.netmask);
+ client.ipaddr &= client.netmask; /* addr & mask are in network order */
+ if (netmask) *netmask = '/';
+
+
+ DEBUG("rlm_ldap: client[%2d] client=%s ip=%s mask=0x%x shortname=%s nastype=%s",
+ client_idx, client.longname, ip_ntoa(ip_buf, client.ipaddr), client.netmask, client.shortname, client.nastype);
+
+
+ if ((p_client = rad_malloc(sizeof(RADCLIENT))) == NULL) {
+ radlog(L_ERR, "rlm_ldap: Out of memory!");
+ ldap_msgfree(result);
+ ldap_release_conn(conn_id,inst->conns);
+ return 1;
+ }
+ memcpy(p_client, &client, sizeof(client));
+ p_client->next = mainconfig.clients;
+ mainconfig.clients = p_client;
+
+ }
+
+ ldap_msgfree(result);
+ ldap_release_conn(conn_id,inst->conns);
+ // client_walk(); /* uncomment for debugging */
+ return 0;
+}
+
+/*
* ldap_groupcmp(). Implement the Ldap-Group == "group" filter
*/
@@ -967,7 +1382,7 @@
return 1;
}
if ((res = perform_search(inst, conn, basedn, LDAP_SCOPE_SUBTREE,
- filter, attrs, &result)) != RLM_MODULE_OK){
+ filter, attrs, TRUE, &result)) != RLM_MODULE_OK){
DEBUG("rlm_ldap::ldap_groupcmp: search failed");
ldap_release_conn(conn_id,inst->conns);
return 1;
@@ -1012,7 +1427,7 @@
}
if ((res = perform_search(inst, conn, basedn, LDAP_SCOPE_SUBTREE,
- filter, attrs, &result)) == RLM_MODULE_OK){
+ filter, attrs, TRUE, &result)) == RLM_MODULE_OK){
DEBUG("rlm_ldap::ldap_groupcmp: User found in group %s",
(char *)check->strvalue);
ldap_msgfree(result);
@@ -1042,7 +1457,7 @@
return 1;
}
if ((res = perform_search(inst, conn, (char *)vp_user_dn->strvalue, LDAP_SCOPE_BASE,
- filter, group_attrs,&result)) != RLM_MODULE_OK){
+ filter, group_attrs, TRUE, &result)) != RLM_MODULE_OK){
DEBUG("rlm_ldap::ldap_groupcmp: Search returned error");
ldap_release_conn(conn_id, inst->conns);
return 1;
@@ -1066,7 +1481,7 @@
(char *)check->strvalue);
if ((res = perform_search(inst, conn, vals[i],
LDAP_SCOPE_BASE, filter,
- attrs, &gr_result)) != RLM_MODULE_OK){
+ attrs, TRUE, &gr_result)) != RLM_MODULE_OK){
if (res != RLM_MODULE_NOTFOUND){
DEBUG("rlm_ldap::ldap_groupcmp: \
Search returned error");
@@ -1161,7 +1576,7 @@
ldap_free_urldesc(ldap_url);
return 0;
}
- if ((res = perform_search(inst, conn, ldap_url->lud_dn, ldap_url->lud_scope, ldap_url->lud_filter, ldap_url->lud_attrs, &result)) != RLM_MODULE_OK){
+ if ((res = perform_search(inst, conn, ldap_url->lud_dn, ldap_url->lud_scope, ldap_url->lud_filter, ldap_url->lud_attrs, TRUE, &result)) != RLM_MODULE_OK){
if (res == RLM_MODULE_NOTFOUND){
DEBUG("rlm_ldap: Search returned not found");
ldap_free_urldesc(ldap_url);
@@ -1275,7 +1690,7 @@
radlog(L_ERR, "rlm_ldap: All ldap connections are in use");
return RLM_MODULE_FAIL;
}
- if ((res = perform_search(instance, conn, basedn, LDAP_SCOPE_SUBTREE, filter, inst->atts, &result)) != RLM_MODULE_OK) {
+ if ((res = perform_search(instance, conn, basedn, LDAP_SCOPE_SUBTREE, filter, inst->atts, TRUE, &result)) != RLM_MODULE_OK) {
DEBUG("rlm_ldap: search failed");
if (res == RLM_MODULE_NOTFOUND){
snprintf(module_fmsg,sizeof(module_fmsg),"rlm_ldap: User not found");
@@ -1360,7 +1775,7 @@
if (profile && strlen(profile)){
if ((res = perform_search(instance, conn,
profile, LDAP_SCOPE_BASE,
- filter, inst->atts, &def_result)) == RLM_MODULE_OK){
+ filter, inst->atts, TRUE, &def_result)) == RLM_MODULE_OK){
if ((def_msg = ldap_first_entry(conn->ld,def_result))){
if ((check_tmp = ldap_pairget(conn->ld,def_msg,inst->check_item_map,check_pairs,1))) {
if (inst->do_xlat){
@@ -1399,7 +1814,7 @@
while(vals[i] != NULL && strlen(vals[i])){
if ((res = perform_search(instance, conn,
vals[i], LDAP_SCOPE_BASE,
- filter, inst->atts, &def_attr_result)) == RLM_MODULE_OK){
+ filter, inst->atts, TRUE, &def_attr_result)) == RLM_MODULE_OK){
if ((def_attr_msg = ldap_first_entry(conn->ld,def_attr_result))){
if ((check_tmp = ldap_pairget(conn->ld,def_attr_msg,inst->check_item_map,check_pairs,1))) {
if (inst->do_xlat){
@@ -1778,7 +2193,7 @@
radlog(L_ERR, "rlm_ldap: All ldap connections are in use");
return RLM_MODULE_FAIL;
}
- if ((res = perform_search(instance, conn, basedn, LDAP_SCOPE_SUBTREE, filter, attrs, &result)) != RLM_MODULE_OK) {
+ if ((res = perform_search(instance, conn, basedn, LDAP_SCOPE_SUBTREE, filter, attrs, TRUE, &result)) != RLM_MODULE_OK) {
if (res == RLM_MODULE_NOTFOUND){
snprintf(module_fmsg,sizeof(module_fmsg),"rlm_ldap: User not found");
module_fmsg_vp = pairmake("Module-Failure-Message", module_fmsg, T_OP_EQ);
@@ -2167,6 +2582,12 @@
ldap_version = LDAP_VERSION3; ldap_version = LDAP_VERSION3;
if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ldap_version) != LDAP_OPT_SUCCESS) { if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ldap_version) != LDAP_OPT_SUCCESS) {
radlog(L_ERR, "rlm_ldap: Could not set LDAP version to V3"); radlog(L_ERR, "rlm_ldap: Could not set LDAP version to V3");
@ -452,7 +728,16 @@ diff -r -u freeradius-1.1.7/src/modules/rlm_ldap/rlm_ldap.c work/src/modules/rlm
} }
#ifdef HAVE_LDAP_START_TLS #ifdef HAVE_LDAP_START_TLS
if(inst->tls_mode) { if(inst->tls_mode) {
@@ -2273,6 +2533,25 @@ @@ -2208,7 +2629,7 @@
#ifdef HAVE_LDAP_INT_TLS_CONFIG
- if ( ldap_set_option( NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
+ if ( ldap_int_tls_config( NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
(inst->tls_require_cert) )
!= LDAP_OPT_SUCCESS) {
radlog(L_ERR, "rlm_ldap: could not set "
@@ -2273,6 +2694,25 @@
else{ else{
DEBUG("rlm_ldap: bind as %s/%s to %s:%d", dn, password, inst->server, inst->port); DEBUG("rlm_ldap: bind as %s/%s to %s:%d", dn, password, inst->server, inst->port);
} }
@ -478,7 +763,7 @@ diff -r -u freeradius-1.1.7/src/modules/rlm_ldap/rlm_ldap.c work/src/modules/rlm
msgid = ldap_bind(ld, dn, password,LDAP_AUTH_SIMPLE); msgid = ldap_bind(ld, dn, password,LDAP_AUTH_SIMPLE);
if (msgid == -1) { if (msgid == -1) {
ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ldap_errno); ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
@@ -2314,6 +2593,9 @@ @@ -2314,6 +2754,9 @@
return (NULL); return (NULL);
} }
ldap_errno = ldap_result2error(ld, res, 1); ldap_errno = ldap_result2error(ld, res, 1);
@ -488,7 +773,7 @@ diff -r -u freeradius-1.1.7/src/modules/rlm_ldap/rlm_ldap.c work/src/modules/rlm
switch (ldap_errno) { switch (ldap_errno) {
case LDAP_SUCCESS: case LDAP_SUCCESS:
DEBUG("rlm_ldap: Bind was successful"); DEBUG("rlm_ldap: Bind was successful");
@@ -2406,6 +2688,18 @@ @@ -2406,6 +2849,18 @@
free(inst->conns); free(inst->conns);
} }

View File

@ -1,7 +1,7 @@
Summary: High-performance and highly configurable free RADIUS server Summary: High-performance and highly configurable free RADIUS server
Name: freeradius Name: freeradius
Version: 1.1.7 Version: 1.1.7
Release: 3.2.ipa%{?dist} Release: 3.3.ipa%{?dist}
License: GPLv2+ and LGPLv2+ License: GPLv2+ and LGPLv2+
Group: System Environment/Daemons Group: System Environment/Daemons
URL: http://www.freeradius.org/ URL: http://www.freeradius.org/
@ -103,6 +103,7 @@ export LDFLAGS="-L${RPM_BUILD_ROOT}%{_libdir}"
cp %{SOURCE1} . cp %{SOURCE1} .
./freeradius-autogen.sh ./freeradius-autogen.sh
%configure \ %configure \
--with-gnu-ld \ --with-gnu-ld \
--with-threads \ --with-threads \
@ -309,7 +310,15 @@ fi
%changelog %changelog
* Sat Nov 10 2007 <jdennis@redhat.com> - 1.1.7-3.2.ipa * Sat Nov 10 2007 <jdennis@redhat.com> - 1.1.7-3.3.ipa
- add support in rlm_ldap for reading clients from ldap
- fix TLS parameter controling if a cert which fails to validate
will be accepted (i.e. self-signed),
rlm_ldap config parameter=tls_require_cert
ldap LDAP_OPT_X_TLS_REQUIRE_CERT parameter was being passed to
ldap_set_option() when it should have been ldap_int_tls_config()
* Sat Nov 3 2007 <jdennis@redhat.com> - 1.1.7-3.2.ipa
- add support in rlm_ldap for SASL/GSSAPI binds to the LDAP server - add support in rlm_ldap for SASL/GSSAPI binds to the LDAP server
* Mon Sep 17 2007 Thomas Woerner <twoerner@redhat.com> 1.1.7-3.1 * Mon Sep 17 2007 Thomas Woerner <twoerner@redhat.com> 1.1.7-3.1