📄 rlm_preprocess.c
字号:
/* * rlm_preprocess.c * Contains the functions for the "huntgroups" and "hints" * files. * * Version: $Id: rlm_preprocess.c,v 1.52.2.1 2004/10/07 20:52:31 pnixon Exp $ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Copyright 2000 The FreeRADIUS server project * Copyright 2000 Alan DeKok <aland@ox.org> */static const char rcsid[] = "$Id: rlm_preprocess.c,v 1.52.2.1 2004/10/07 20:52:31 pnixon Exp $";#include "autoconf.h"#include "libradius.h"#include <sys/stat.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include "radiusd.h"#include "modules.h"typedef struct rlm_preprocess_t { char *huntgroup_file; char *hints_file; PAIR_LIST *huntgroups; PAIR_LIST *hints; int with_ascend_hack; int ascend_channels_per_line; int with_ntdomain_hack; int with_specialix_jetstream_hack; int with_cisco_vsa_hack;} rlm_preprocess_t;static CONF_PARSER module_config[] = { { "huntgroups", PW_TYPE_STRING_PTR, offsetof(rlm_preprocess_t,huntgroup_file), NULL, "${raddbdir}/huntgroups" }, { "hints", PW_TYPE_STRING_PTR, offsetof(rlm_preprocess_t,hints_file), NULL, "${raddbdir}/hints" }, { "with_ascend_hack", PW_TYPE_BOOLEAN, offsetof(rlm_preprocess_t,with_ascend_hack), NULL, "no" }, { "ascend_channels_per_line", PW_TYPE_INTEGER, offsetof(rlm_preprocess_t,ascend_channels_per_line), NULL, "23" }, { "with_ntdomain_hack", PW_TYPE_BOOLEAN, offsetof(rlm_preprocess_t,with_ntdomain_hack), NULL, "no" }, { "with_specialix_jetstream_hack", PW_TYPE_BOOLEAN, offsetof(rlm_preprocess_t,with_specialix_jetstream_hack), NULL, "no" }, { "with_cisco_vsa_hack", PW_TYPE_BOOLEAN, offsetof(rlm_preprocess_t,with_cisco_vsa_hack), NULL, "no" }, { NULL, -1, 0, NULL, NULL }};/* * dgreer -- * This hack changes Ascend's wierd port numberings * to standard 0-??? port numbers so that the "+" works * for IP address assignments. */static void ascend_nasport_hack(VALUE_PAIR *nas_port, int channels_per_line){ int service; int line; int channel; if (!nas_port) { return; } if (nas_port->lvalue > 9999) { service = nas_port->lvalue/10000; /* 1=digital 2=analog */ line = (nas_port->lvalue - (10000 * service)) / 100; channel = nas_port->lvalue-((10000 * service)+(100 * line)); nas_port->lvalue = (channel - 1) + (line - 1) * channels_per_line; }}/* * ThomasJ -- * This hack strips out Cisco's VSA duplicities in lines * (Cisco not implemented VSA's in standard way. * * Cisco sends it's VSA attributes with the attribute name *again* * in the string, like: H323-Attribute = "h323-attribute=value". * This sort of behaviour is nonsense. */static void cisco_vsa_hack(VALUE_PAIR *vp){ int vendorcode; char *ptr; char newattr[MAX_STRING_LEN]; for ( ; vp != NULL; vp = vp->next) { vendorcode = (vp->attribute >> 16); /* HACK! */ if (!((vendorcode == 9) || (vendorcode == 6618))) continue; /* not a Cisco or Quintum VSA, continue */ if (vp->type != PW_TYPE_STRING) continue; /* * No weird packing. Ignore it. */ ptr = strchr(vp->strvalue, '='); /* find an '=' */ if (!ptr) continue; /* * Cisco-AVPair's get packed as: * * Cisco-AVPair = "h323-foo-bar = baz" * Cisco-AVPair = "h323-foo-bar=baz" * * which makes sense only if you're a lunatic. * This code looks for the attribute named inside * of the string, and if it exists, adds it as a new * attribute. */ if ((vp->attribute & 0xffff) == 1) { char *p; DICT_ATTR *dattr; p = vp->strvalue; gettoken(&p, newattr, sizeof(newattr)); if (((dattr = dict_attrbyname(newattr)) != NULL) && (dattr->type == PW_TYPE_STRING)) { VALUE_PAIR *newvp; /* * Make a new attribute. */ newvp = pairmake(newattr, ptr + 1, T_OP_EQ); if (newvp) { pairadd(&vp, newvp); } } } else { /* h322-foo-bar = "h323-foo-bar = baz" */ /* * We strip out the duplicity from the * value field, we use only the value on * the right side of the '=' character. */ strNcpy(newattr, ptr + 1, sizeof(newattr)); strNcpy((char *)vp->strvalue, newattr, sizeof(vp->strvalue)); vp->length = strlen((char *)vp->strvalue); } }}/* * Mangle username if needed, IN PLACE. */static void rad_mangle(rlm_preprocess_t *data, REQUEST *request){ VALUE_PAIR *namepair; VALUE_PAIR *request_pairs; VALUE_PAIR *tmp; /* * Get the username from the request * If it isn't there, then we can't mangle the request. */ request_pairs = request->packet->vps; namepair = pairfind(request_pairs, PW_USER_NAME); if ((namepair == NULL) || (namepair->length <= 0)) { return; } if (data->with_ntdomain_hack) { char *ptr; char newname[MAX_STRING_LEN]; /* * Windows NT machines often authenticate themselves as * NT_DOMAIN\username. Try to be smart about this. * * FIXME: should we handle this as a REALM ? */ if ((ptr = strchr(namepair->strvalue, '\\')) != NULL) { strNcpy(newname, ptr + 1, sizeof(newname)); /* Same size */ strcpy(namepair->strvalue, newname); namepair->length = strlen(newname); } } if (data->with_specialix_jetstream_hack) { char *ptr; /* * Specialix Jetstream 8500 24 port access server. * If the user name is 10 characters or longer, a "/" * and the excess characters after the 10th are * appended to the user name. * * Reported by Lucas Heise <root@laonet.net> */ if ((strlen((char *)namepair->strvalue) > 10) && (namepair->strvalue[10] == '/')) { for (ptr = (char *)namepair->strvalue + 11; *ptr; ptr++) *(ptr - 1) = *ptr; *(ptr - 1) = 0; namepair->length = strlen((char *)namepair->strvalue); } } /* * Small check: if Framed-Protocol present but Service-Type * is missing, add Service-Type = Framed-User. */ if (pairfind(request_pairs, PW_FRAMED_PROTOCOL) != NULL && pairfind(request_pairs, PW_SERVICE_TYPE) == NULL) { tmp = paircreate(PW_SERVICE_TYPE, PW_TYPE_INTEGER); if (tmp) { tmp->lvalue = PW_FRAMED_USER; pairmove(&request_pairs, &tmp); } }}/* * Compare the request with the "reply" part in the * huntgroup, which normally only contains username or group. * At least one of the "reply" items has to match. */static int hunt_paircmp(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check){ VALUE_PAIR *check_item = check; VALUE_PAIR *tmp; int result = -1; if (check == NULL) return 0; while (result != 0 && check_item != NULL) { tmp = check_item->next; check_item->next = NULL; result = paircmp(req, request, check_item, NULL); check_item->next = tmp; check_item = check_item->next; } return result;}/* * Add hints to the info sent by the terminal server * based on the pattern of the username, and other attributes. */static int hints_setup(PAIR_LIST *hints, REQUEST *request){ char *name; VALUE_PAIR *add; VALUE_PAIR *tmp; PAIR_LIST *i; VALUE_PAIR *request_pairs; request_pairs = request->packet->vps; if (hints == NULL || request_pairs == NULL) return RLM_MODULE_NOOP; /* * Check for valid input, zero length names not permitted */ if ((tmp = pairfind(request_pairs, PW_USER_NAME)) == NULL) name = NULL; else name = (char *)tmp->strvalue; if (name == NULL || name[0] == 0) /* * No name, nothing to do. */ return RLM_MODULE_NOOP; for (i = hints; i; i = i->next) { /* * Use "paircmp", which is a little more general... */ if (paircmp(request, request_pairs, i->check, NULL) == 0) { DEBUG2(" hints: Matched %s at %d", i->name, i->lineno); break; } } if (i == NULL) return RLM_MODULE_NOOP;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -