From: Arran Cudbard-Bell Date: Sat, 3 Nov 2012 21:43:04 +0000 (+0000) Subject: Add missing rlm_dhcp module X-Git-Tag: release_3_0_0_beta1~1604 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3a94aa8cd21a4cec33d5d092a7e53000da3e9dc1;p=thirdparty%2Ffreeradius-server.git Add missing rlm_dhcp module --- diff --git a/raddb/dictionary.in b/raddb/dictionary.in index ef22be9fab4..3f293db8ddc 100644 --- a/raddb/dictionary.in +++ b/raddb/dictionary.in @@ -20,7 +20,7 @@ # Ideally, the "configure" process should automatically enable this # dictionary, but we don't yet do that. # -#$INCLUDE @prefix@/share/freeradius/dictionary.dhcp +$INCLUDE @prefix@/share/freeradius/dictionary.dhcp # # The filename given here should be an absolute path. diff --git a/raddb/mods-available/dhcp b/raddb/mods-available/dhcp new file mode 100644 index 00000000000..a4316335d7f --- /dev/null +++ b/raddb/mods-available/dhcp @@ -0,0 +1,19 @@ +# -*- text -*- +# +# $Id$ + +# +# This module is useful only for 'xlat'. To use it, +# put 'dhcp' into the 'instantiate' section. +# +# %{dhcp_options:} may be used to decode +# DHCP options data included in RADIUS packets by vendors +# of DHCP to RADIUS gateways. +# +# This is known to work with the following VSAs: +# * Juniper - ERX-Dhcp-Options +# * Alcatel lucent SR - Alc-ToServer-Dhcp-Options +# - Alc-ToClient-Dhcp-Options +# +dhcp { +} diff --git a/src/modules/rlm_dhcp/Makefile b/src/modules/rlm_dhcp/Makefile new file mode 100644 index 00000000000..8e53d5b68a7 --- /dev/null +++ b/src/modules/rlm_dhcp/Makefile @@ -0,0 +1,11 @@ +TARGET = rlm_dhcp +SRCS = rlm_dhcp.c +HEADERS = +RLM_CFLAGS = +RLM_LIBS = + +include ../rules.mak + +$(STATIC_OBJS): $(HEADERS) + +$(DYNAMIC_OBJS): $(HEADERS) diff --git a/src/modules/rlm_dhcp/rlm_dhcp.c b/src/modules/rlm_dhcp/rlm_dhcp.c new file mode 100644 index 00000000000..d4c5d5c1f83 --- /dev/null +++ b/src/modules/rlm_dhcp/rlm_dhcp.c @@ -0,0 +1,173 @@ +/* + * rlm_dhcp.c + * + * Version: $Id$ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * Copyright 2012 The FreeRADIUS server project + */ + +#include +RCSID("$Id$") + +#include + +#ifdef WITH_DHCP + +#include +#include +#include + +#include + +/* + * Define a structure for our module configuration. + * + * These variables do not need to be in a structure, but it's + * a lot cleaner to do so, and a pointer to the structure can + * be used as the instance handle. + */ +typedef struct rlm_dhcp_t { +} rlm_dhcp_t; + + +/* + * Allow single attribute values to be retrieved from the dhcp. + */ +static size_t dhcp_options_xlat(UNUSED void *instance, REQUEST *request, + const char *fmt, char *out, size_t freespace) +{ + VALUE_PAIR *vp, *head = NULL, *next; + int decoded = 0; + + while (isspace((int) *fmt)) fmt++; + + + if (!radius_get_vp(request, fmt, &vp) || !vp) { + *out = '\0'; + + return 0; + } + + if ((fr_dhcp_decode_options(vp->vp_octets, vp->length, &head) < 0) || + (head == NULL)) { + RDEBUG("WARNING: DHCP option decoding failed"); + goto fail; + } + + next = head; + + do { + next = next->next; + decoded++; + } while (next); + + pairmove(&(request->packet->vps), &head); + + /* Free any unmoved pairs */ + pairfree(&head); + + fail: + + snprintf(out, freespace, "%i", decoded); + + return strlen(out); +} + + +/* + * A mapping of configuration file names to internal variables. + * + * Note that the string is dynamically allocated, so it MUST + * be freed. When the configuration file parse re-reads the string, + * it free's the old one, and strdup's the new one, placing the pointer + * to the strdup'd string into 'config.string'. This gets around + * buffer over-flows. + */ +static const CONF_PARSER module_config[] = { + { NULL, -1, 0, NULL, NULL } /* end the list */ +}; + + +/* + * Only free memory we allocated. The strings allocated via + * cf_section_parse() do not need to be freed. + */ +static int dhcp_detach(void *instance) +{ + free(instance); + return 0; +} + + +/* + * Instantiate the module. + */ +static int dhcp_instantiate(CONF_SECTION *conf, void **instance) +{ + rlm_dhcp_t *inst; + + inst = rad_malloc(sizeof(*inst)); + if (!inst) { + return -1; + } + memset(inst, 0, sizeof(*inst)); + + xlat_register("dhcp_options", dhcp_options_xlat, inst); + + /* + * If the configuration parameters can't be parsed, then + * fail. + */ + if (cf_section_parse(conf, inst, module_config) < 0) { + free(inst); + return -1; + } + + *instance = inst; + + return 0; +} + + +/* + * The module name should be the only globally exported symbol. + * That is, everything else should be 'static'. + * + * If the module needs to temporarily modify it's instantiation + * data, the type should be changed to RLM_TYPE_THREAD_UNSAFE. + * The server will then take care of ensuring that the module + * is single-threaded. + */ +module_t rlm_dhcp = { + RLM_MODULE_INIT, + "dhcp", + 0, /* type */ + dhcp_instantiate, /* instantiation */ + dhcp_detach, /* detach */ + { + NULL, /* authentication */ + NULL, /* authorization */ + NULL, /* preaccounting */ + NULL, /* accounting */ + NULL, /* checksimul */ + NULL, /* pre-proxy */ + NULL, /* post-proxy */ + NULL, /* post-auth */ + }, +}; + +#endif