⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rlm_preprocess.c

📁 RADIUS 服务器介绍 RADIUS服务器支持标准的RADIUS协议
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * rlm_preprocess.c *		Contains the functions for the "huntgroups" and "hints" *		files. * * Version:     $Id: rlm_preprocess.c,v 1.45 2003/07/07 19:17:31 aland 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.45 2003/07/07 19:17:31 aland 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 == 0) continue;	/* ignore non-VSA attributes */		if (vendorcode == 0) continue; /* ignore unknown VSA's */		if (vendorcode != 9) continue; /* not a Cisco 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"		 *		 *	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;			getword(&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(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(NULL, request, check_item, NULL);		check_item->next = tmp;		check_item = check_item->next;	}	return result;}/* *	Compare prefix/suffix */static int presufcmp(VALUE_PAIR *check, char *name, char *rest){	int		len, namelen;	int		ret = -1;#if 0 /* DEBUG */	printf("Comparing %s and %s, check->attr is %d\n",		name, check->strvalue, check->attribute);#endif	len = strlen((char *)check->strvalue);	switch (check->attribute) {		case PW_PREFIX:			ret = strncmp(name, (char *)check->strvalue, len);			if (ret == 0 && rest)				strcpy(rest, name + len);			break;		case PW_SUFFIX:			namelen = strlen(name);			if (namelen < len)				break;			ret = strcmp(name + namelen - len,				     (char *)check->strvalue);			if (ret == 0 && rest) {				strncpy(rest, name, namelen - len);				rest[namelen - len] = 0;			}			break;	}	return ret;}/* *	Match a username with a wildcard expression. *	Is very limited for now. */static int matches(char *name, PAIR_LIST *pl, char *matchpart){	int len, wlen;	int ret = 0;	char *wild = pl->name;	VALUE_PAIR *tmp;	/*	 *	We now support both:	 *	 *		DEFAULT	Prefix = "P"	 *	 *	and	 *		P*	 */	if ((tmp = pairfind(pl->check, PW_PREFIX)) != NULL ||	    (tmp = pairfind(pl->check, PW_SUFFIX)) != NULL) {		if (strncmp(pl->name, "DEFAULT", 7) == 0 ||		    strcmp(pl->name, name) == 0)			return !presufcmp(tmp, name, matchpart);	}	/*	 *	Shortcut if there's no '*' in pl->name.	 */	if (strchr(pl->name, '*') == NULL &&	    (strncmp(pl->name, "DEFAULT", 7) == 0 ||	     strcmp(pl->name, name) == 0)) {		strcpy(matchpart, name);		return 1;	}	/*	 *	Normally, we should return 0 here, but we	 *	support the old * stuff.	 */	len = strlen(name);	wlen = strlen(wild);	if (len == 0 || wlen == 0) return 0;	if (wild[0] == '*') {		wild++;		wlen--;		if (wlen <= len && strcmp(name + (len - wlen), wild) == 0) {			strcpy(matchpart, name);			matchpart[len - wlen] = 0;			ret = 1;		}	} else if (wild[wlen - 1] == '*') {		if (wlen <= len && strncmp(name, wild, wlen - 1) == 0) {			strcpy(matchpart, name + wlen - 1);			ret = 1;		}	}	return ret;}/* *	Add hints to the info sent by the terminal server *	based on the pattern of the username. */static int hints_setup(PAIR_LIST *hints, REQUEST *request){	char		newname[MAX_STRING_LEN];	char		*name;	VALUE_PAIR	*add;	VALUE_PAIR	*last;	VALUE_PAIR	*tmp;	PAIR_LIST	*i;	int		do_strip;	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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -