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

📄 rlm_attr_filter.c

📁 radius服务器
💻 C
📖 第 1 页 / 共 2 页
字号:
	VALUE_PAIR	*send_tmp = NULL;	VALUE_PAIR	*check_item;	PAIR_LIST	*pl;	int		found = 0;	int		compare;	int		pass, fail;	VALUE_PAIR	*realmpair;	REALM		*realm;	char		*realmname;	/*	 * Accounting is similar to pre-proxy.	 * Here we are concerned with what we are going to forward to	 * the remote server as opposed to concerns with what we will send	 * to the NAS based on a proxy reply to an auth request.	 */	if (request->packet->code != PW_ACCOUNTING_REQUEST) {		return (RLM_MODULE_NOOP);	}	request_pairs = request->packet->vps;	/* Get the realm from the original request vps. */	realmpair = pairfind(request_pairs, PW_REALM);	if (!realmpair) {		/* If there is no realm...NOOP */		return (RLM_MODULE_NOOP);	}	realmname = (char *) realmpair->strvalue;	realm = realm_find (realmname, FALSE);	/*	 * Find the attr_filter profile entry for the realm	 */	for (pl = inst->attrs; pl; pl = pl->next) {		/*		 * If the current entry is NOT a default,		 * AND the realm does not match the current entry,		 * then skip to the next entry.		 */		if ( (strcmp(pl->name, "DEFAULT") != 0) &&		     (strcasecmp(realmname, pl->name) != 0) ) {		    continue;		}		DEBUG2(" attr_filter: Matched entry %s at line %d", pl->name,								    pl->lineno);		found = 1;		check_item = pl->check;		while (check_item != NULL) {		    /*		     * If it is a SET operator, add the attribute to		     * the send list w/out checking.		     */		    if (check_item->operator == T_OP_SET) {			if (mypairappend(check_item, &send_tmp) < 0) {				return RLM_MODULE_FAIL;			}		    }		    check_item = check_item->next;		}		/*		 * Iterate through the request_pairs (items sent from NAS).		 * Compare each pair to every rule for this realm/DEFAULT.		 * Move an item to send_tmp if it matches all rules for		 * attribute in question.		 */		for (send_item = request_pairs; send_item != NULL;		     send_item = send_item->next ) {		    /* reset the pass/fail vars for each packet->vp. */		    pass = fail = 0;		    /* reset the check_item pointer to beginning of the list */		    check_item = pl->check;		    while (check_item != NULL) {			if (send_item->attribute == check_item->attribute) {			    compare = simplepaircmp(request, send_item,						    check_item);			    check_pair(check_item, send_item, compare,				       &pass, &fail);			}			check_item = check_item->next;		    }		    /* only send if attribute passed all rules */		    if (fail == 0 && pass > 0) {			if (mypairappend (send_item, &send_tmp) < 0) {				return RLM_MODULE_FAIL;			}		    }		}		if (!fallthrough(pl->check))		    break;	}	pairfree (&request->packet->vps);	request->packet->vps = send_tmp;	/*	 * See if we succeeded. If we didn't find the realm,	 * then exit from the module.	 */	if (!found)		return RLM_MODULE_OK;	/*	 * Remove server internal paramters.	 */	pairdelete(&send_tmp, PW_FALL_THROUGH);	return RLM_MODULE_UPDATED;}static int attr_filter_preproxy (void *instance, REQUEST *request){	struct attr_filter_instance *inst = instance;	VALUE_PAIR	*request_pairs;	VALUE_PAIR 	*send_item;	VALUE_PAIR	*send_tmp = NULL;	VALUE_PAIR	*check_item;	PAIR_LIST	*pl;	int		found = 0;	int		compare;	int		pass, fail;	VALUE_PAIR	*realmpair;	REALM		*realm;	char		*realmname;	/*	 * Pre-proxy we are         * concerned with what we are going to forward to	 * to the remote server as opposed to we will do with	 * with the remote servers' repsonse pairs. Consequently,	 * we deal with modifications to the request->packet->vps;	 */	request_pairs = request->proxy->vps;	if (request->packet->code != PW_AUTHENTICATION_REQUEST) {		return (RLM_MODULE_NOOP);	}	realmpair = pairfind(request_pairs, PW_REALM);	if (!realmpair) {		return (RLM_MODULE_NOOP);	}	realmname = (char *)realmpair->strvalue;	realm = realm_find(realmname, FALSE);	for (pl = inst->attrs; pl; pl = pl->next) {		if ( (strcmp(pl->name, "DEFAULT") != 0) &&		     (strcasecmp(realmname, pl->name) != 0) ) {		    continue;		}		DEBUG2(" attr_filter: Matched entry %s at line %d", pl->name,								    pl->lineno);		found = 1;		check_item = pl->check;		while (check_item != NULL) {		    /*		     * Append all SET operator attributes with no check.		     */		    if (check_item->operator == T_OP_SET) {			if (mypairappend(check_item, &send_tmp) < 0) {				return RLM_MODULE_FAIL;			}		    }		    check_item = check_item->next;		}		/*		 * Iterate through the request_pairs (items sent from NAS).		 * Compare each pair to every rule for this realm/DEFAULT.		 * Move an item to send_tmp if it matches all rules for		 * attribute in question.		 */		for (send_item = request_pairs;		     send_item != NULL;		    send_item = send_item->next ) {		    /* reset the pass/fail vars for each packet->vp. */		    pass = fail = 0;		    /* reset the check_item to the beginning */		    check_item = pl->check;		    /*		     * compare each packet->vp to the entire list of		     * check_items for this realm.		     */		    while (check_item != NULL) {			if (send_item->attribute == check_item->attribute) {			    compare = simplepaircmp(request, send_item,						    check_item);			    check_pair(check_item, send_item, compare,				       &pass, &fail);			}			check_item = check_item->next;		    }		    /* only send if attribute passed all rules */		    if (fail == 0 && pass > 0) {			if (mypairappend (send_item, &send_tmp) < 0) {				return RLM_MODULE_FAIL;			}		    }		}		if (!fallthrough(pl->check))		    break;	}	pairfree (&request->proxy->vps);	request->proxy->vps = send_tmp;	if (!found)		return RLM_MODULE_OK;	pairdelete(&send_tmp, PW_FALL_THROUGH);	return RLM_MODULE_UPDATED;}static int attr_filter_postproxy(void *instance, REQUEST *request){	struct attr_filter_instance *inst = instance;	VALUE_PAIR	*request_pairs;	VALUE_PAIR	**reply_items;	VALUE_PAIR	*reply_item;	VALUE_PAIR	*reply_tmp = NULL;	VALUE_PAIR	*check_item;	PAIR_LIST	*pl;	int		found = 0;	int		compare;	int		pass, fail = 0;	VALUE_PAIR	*realmpair;	REALM		*realm;	char		*realmname;	/*	 *	It's not a proxy reply, so return NOOP	 */	if( request->proxy == NULL ) {		return( RLM_MODULE_NOOP );	}	request_pairs = request->packet->vps;	reply_items = &request->proxy_reply->vps;	/*	 * Get the realm.  Can't use request->config_items as	 * that gets freed by rad_authenticate....  use the one	 * set in the original request vps	 */	realmpair = pairfind(request_pairs, PW_REALM);	if(!realmpair) {		/*    Can't find a realm, so no filtering of attributes		 *    or should we use a DEFAULT entry?		 *    For now, just return NOTFOUND. (maybe NOOP?)		 */		return RLM_MODULE_NOTFOUND;	}	realmname = (char *) realmpair->strvalue;	realm = realm_find(realmname, FALSE);	/*	 *      Find the attr_filter profile entry for the realm.	 */	for(pl = inst->attrs; pl; pl = pl->next) {		/*		 *  If the current entry is NOT a default,		 *  AND the realm does NOT match the current entry,		 *  then skip to the next entry.		 */		if ( (strcmp(pl->name, "DEFAULT") != 0) &&		     (strcmp(realmname, pl->name) != 0) )  {		    continue;		}		DEBUG2(" attr_filter: Matched entry %s at line %d", pl->name,								    pl->lineno);		found = 1;		check_item = pl->check;		while( check_item != NULL ) {		    /*		     *    If it is a SET operator, add the attribute to		     *    the reply list without checking reply_items.		     */		    if( check_item->operator == T_OP_SET ) {			if (mypairappend(check_item, &reply_tmp) < 0) {				return RLM_MODULE_FAIL;			}		    }		    check_item = check_item->next;		}		/*		 * Iterate through the reply items,		 * comparing each reply item to every rule,		 * then moving it to the reply_tmp list only if it matches all		 * rules for that attribute.		 * IE, Idle-Timeout is moved only if it matches		 * all rules that describe an Idle-Timeout.		 */		for( reply_item = *reply_items; reply_item != NULL;		     reply_item = reply_item->next ) {		    /* reset the pass,fail vars for each reply item */		    pass = fail = 0;		    /* reset the check_item pointer to beginning of the list */		    check_item = pl->check;		    while( check_item != NULL ) {			if(reply_item->attribute == check_item->attribute) {			    compare = simplepaircmp(request, reply_item,						    check_item);			    check_pair(check_item, reply_item, compare,				       &pass, &fail);			}			check_item = check_item->next;		    }		    /* only move attribute if it passed all rules */		    if (fail == 0 && pass > 0) {			if (mypairappend( reply_item, &reply_tmp) < 0) {				return RLM_MODULE_FAIL;			}		    }		}		/* If we shouldn't fall through, break */		if(!fallthrough(pl->check))		    break;	}	pairfree(&request->proxy_reply->vps);	request->proxy_reply->vps = reply_tmp;	/*	 * See if we succeeded.  If we didn't find the realm,	 * then exit from the module.	 */	if (!found)		return RLM_MODULE_OK;	/*	 *	Remove server internal parameters.	 */	pairdelete(reply_items, PW_FALL_THROUGH);	return RLM_MODULE_UPDATED;}/* *	Clean up. */static int attr_filter_detach(void *instance){	struct attr_filter_instance *inst = instance;	pairlist_free(&inst->attrs);	free(inst->attrsfile);	free(inst);	return 0;}/* globally exported name */module_t rlm_attr_filter = {	"attr_filter",	0,				/* type: reserved */	NULL,				/* initialization */	attr_filter_instantiate,	/* instantiation */	{		NULL,			/* authentication */		attr_filter_authorize,	/* authorization */		NULL,			/* preaccounting */		attr_filter_accounting,	/* accounting */		NULL,			/* checksimul */		attr_filter_preproxy,	/* pre-proxy */		attr_filter_postproxy,	/* post-proxy */		NULL			/* post-auth */	},	attr_filter_detach,		/* detach */	NULL				/* destroy */};

⌨️ 快捷键说明

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