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

📄 evaluate.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
				radlog(L_ERR, "Unexpected trailing text at: %s", p);				return FALSE;			}		} /* else it wasn't an opening brace */		while ((*p == ' ') || (*p == '\t')) p++;		/*		 *	More conditions, keep going.		 */		if ((*p == '(') || (p[0] == '!')) continue;		DEBUG4(">>> LOOKING AT %s", p);		start = p;		/*		 *	Look for common errors.		 */		if ((p[0] == '%') && (p[1] == '{')) {			radlog(L_ERR, "Bare %%{...} is invalid in condition at: %s", p);			return FALSE;		}		/*		 *	Look for word == value		 */		lt = gettoken(&p, left, sizeof(left));		if ((lt != T_BARE_WORD) &&		    (lt != T_DOUBLE_QUOTED_STRING) &&		    (lt != T_SINGLE_QUOTED_STRING) &&		    (lt != T_BACK_QUOTED_STRING)) {			radlog(L_ERR, "Expected string or numbers at: %s", p);			return FALSE;		}		pleft = left;		if (evaluate_next_condition) {			pleft = expand_string(xleft, sizeof(xleft), request,					      lt, left);			if (!pleft) {				radlog(L_ERR, "Failed expanding string at: %s",				       left);				return FALSE;			}		}		/*		 *	Peek ahead.  Maybe it's just a check for		 *	existence.  If so, there shouldn't be anything		 *	else.		 */		q = p;		while ((*q == ' ') || (*q == '\t')) q++;		/*		 *	End of condition, 		 */		if (!*q || (*q == ')') ||		    ((*q == '!') && (q[1] != '=') && (q[1] != '~')) ||		    ((q[0] == '&') && (q[1] == '&')) ||		    ((q[0] == '|') && (q[1] == '|'))) {			/*			 *	Simplify the code.			 */			token = T_OP_CMP_TRUE;			rt = T_OP_INVALID;			pright = NULL;			goto do_cmp;		}		/*		 *	Else it's a full "foo == bar" thingy.		 */		token = gettoken(&p, comp, sizeof(comp));		if ((token < T_OP_NE) || (token > T_OP_CMP_EQ) ||		    (token == T_OP_CMP_TRUE) ||		    (token == T_OP_CMP_FALSE)) {			radlog(L_ERR, "Expected comparison at: %s", comp);			return FALSE;		}				/*		 *	Look for common errors.		 */		if ((p[0] == '%') && (p[1] == '{')) {			radlog(L_ERR, "Bare %%{...} is invalid in condition at: %s", p);			return FALSE;		}				/*		 *	Validate strings.		 */#ifdef HAVE_REGEX_H		if ((token == T_OP_REG_EQ) ||		    (token == T_OP_REG_NE)) {			rt = getregex(&p, right, sizeof(right), &cflags);			if (rt != T_DOUBLE_QUOTED_STRING) {				radlog(L_ERR, "Expected regular expression at: %s", p);				return FALSE;			}		} else#endif			rt = gettoken(&p, right, sizeof(right));		if ((rt != T_BARE_WORD) &&		    (rt != T_DOUBLE_QUOTED_STRING) &&		    (rt != T_SINGLE_QUOTED_STRING) &&		    (rt != T_BACK_QUOTED_STRING)) {			radlog(L_ERR, "Expected string or numbers at: %s", p);			return FALSE;		}				pright = right;		if (evaluate_next_condition) {			pright = expand_string(xright, sizeof(xright), request,					       rt, right);			if (!pright) {				radlog(L_ERR, "Failed expanding string at: %s",				       right);				return FALSE;			}		}				DEBUG4(">>> %d:%s %d %d:%s",		       lt, pleft, token, rt, pright);			do_cmp:		if (evaluate_next_condition) {			/*			 *	More parse errors.			 */			if (!radius_do_cmp(request, &result, lt, pleft, token,					   rt, pright, cflags, modreturn)) {				return FALSE;			}			DEBUG2("%.*s Evaluating %s(%.*s) -> %s",			       depth, filler,			       invert ? "!" : "", p - start, start,			       (result != FALSE) ? "TRUE" : "FALSE");			DEBUG4(">>> GOT result %d", result);			/*			 *	Not evaluating it.  We may be just			 *	parsing it.			 */		} else if (request) {			DEBUG2("%.*s Skipping %s(%.*s)",			       depth, filler,			       invert ? "!" : "", p - start, start);		}		if (invert) {			DEBUG4(">>> INVERTING result");			result = (result == FALSE);			invert = FALSE;		}		/*		 *	Don't evaluate it.		 */		DEBUG4(">>> EVALUATE %d ::%s::",			evaluate_next_condition, p);		while ((*p == ' ') || (*p == '\t')) p++;		/*		 *	Closing brace or EOL, return.		 */		if (!*p || (*p == ')') ||		    ((*p == '!') && (p[1] != '=') && (p[1] != '~')) ||		    ((p[0] == '&') && (p[1] == '&')) ||		    ((p[0] == '|') && (p[1] == '|'))) {			DEBUG4(">>> AT EOL2a");			*ptr = p;			if (evaluate_next_condition) *presult = result;			return TRUE;		}	} /* loop over the input condition */	DEBUG4(">>> AT EOL2b");	*ptr = p;	if (evaluate_next_condition) *presult = result;	return TRUE;}static void fix_up(REQUEST *request){	VALUE_PAIR *vp;	request->username = NULL;	request->password = NULL;		for (vp = request->packet->vps; vp != NULL; vp = vp->next) {		if ((vp->attribute == PW_USER_NAME) &&		    !request->username) {			request->username = vp;					} else if (vp->attribute == PW_STRIPPED_USER_NAME) {			request->username = vp;					} else if (vp->attribute == PW_USER_PASSWORD) {			request->password = vp;		}	}}/* *	The pairmove() function in src/lib/valuepair.c does all sorts of *	extra magic that we don't want here. * *	FIXME: integrate this with the code calling it, so that we *	only paircopy() those attributes that we're really going to *	use. */void radius_pairmove(REQUEST *request, VALUE_PAIR **to, VALUE_PAIR *from){	int i, j, count, from_count, to_count, tailto;	VALUE_PAIR *vp, *next, **last;	VALUE_PAIR **from_list, **to_list;	int *edited = NULL;	/*	 *	Set up arrays for editing, to remove some of the	 *	O(N^2) dependencies.  This also makes it easier to	 *	insert and remove attributes.	 *	 *	It also means that the operators apply ONLY to the	 *	attributes in the original list.  With the previous	 *	implementation of pairmove(), adding two attributes	 *	via "+=" and then "=" would mean that the second one	 *	wasn't added, because of the existence of the first	 *	one in the "to" list.  This implementation doesn't	 *	have that bug.	 *	 *	Also, the previous implementation did NOT implement	 *	"-=" correctly.  If two of the same attributes existed	 *	in the "to" list, and you tried to subtract something	 *	matching the *second* value, then the pairdelete()	 *	function was called, and the *all* attributes of that	 *	number were deleted.  With this implementation, only	 *	the matching attributes are deleted.	 */	count = 0;	for (vp = from; vp != NULL; vp = vp->next) count++;	from_list = rad_malloc(sizeof(*from_list) * count);	for (vp = *to; vp != NULL; vp = vp->next) count++;	to_list = rad_malloc(sizeof(*to_list) * count);	/*	 *	Move the lists to the arrays, and break the list	 *	chains.	 */	from_count = 0;	for (vp = from; vp != NULL; vp = next) {		next = vp->next;		from_list[from_count++] = vp;		vp->next = NULL;	}	to_count = 0;	for (vp = *to; vp != NULL; vp = next) {		next = vp->next;		to_list[to_count++] = vp;		vp->next = NULL;	}	tailto = to_count;	edited = rad_malloc(sizeof(*edited) * to_count);	memset(edited, 0, sizeof(*edited) * to_count);	DEBUG4("::: FROM %d TO %d MAX %d", from_count, to_count, count);	/*	 *	Now that we have the lists initialized, start working	 *	over them.	 */	for (i = 0; i < from_count; i++) {		int found;		DEBUG4("::: Examining %s", from_list[i]->name);		/*		 *	Attribute should be appended, OR the "to" list		 *	is empty, and we're supposed to replace or		 *	"add if not existing".		 */		if (from_list[i]->operator == T_OP_ADD) goto append;		found = FALSE;		for (j = 0; j < to_count; j++) {			if (edited[j]) continue;			/*			 *	Attributes aren't the same, skip them.			 */			if (from_list[i]->attribute != to_list[j]->attribute) {				continue;			}			/*			 *	We don't use a "switch" statement here			 *	because we want to break out of the			 *	"for" loop over 'j' in most cases.			 */			/*			 *	Over-write the FIRST instance of the			 *	matching attribute name.  We free the			 *	one in the "to" list, and move over			 *	the one in the "from" list.			 */			if (from_list[i]->operator == T_OP_SET) {				DEBUG4("::: OVERWRITING %s FROM %d TO %d",				       to_list[j]->name, i, j);				pairfree(&to_list[j]);				to_list[j] = from_list[i];				from_list[i] = NULL;				edited[j] = TRUE;				break;			}			/*			 *	Add the attribute only if it does not			 *	exist... but it exists, so we stop			 *	looking.			 */			if (from_list[i]->operator == T_OP_EQ) {				found = TRUE;				break;			}			/*			 *	Delete all matching attributes from			 *	"to"			 */			if ((from_list[i]->operator == T_OP_SUB) ||			    (from_list[i]->operator == T_OP_CMP_EQ) ||			    (from_list[i]->operator == T_OP_LE) ||			    (from_list[i]->operator == T_OP_GE)) {				int rcode;				int old_op = from_list[i]->operator;				/*				 *	Check for equality.				 */				from_list[i]->operator = T_OP_CMP_EQ;				/*				 *	If equal, delete the one in				 *	the "to" list.				 */				rcode = radius_compare_vps(NULL, from_list[i],							   to_list[j]);				/*				 *	We may want to do more				 *	subtractions, so we re-set the				 *	operator back to it's original				 *	value.				 */				from_list[i]->operator = old_op;				switch (old_op) {				case T_OP_CMP_EQ:					if (rcode != 0) goto delete;					break;				case T_OP_SUB:					if (rcode == 0) {					delete:						DEBUG4("::: DELETING %s FROM %d TO %d",						       from_list[i]->name, i, j);						pairfree(&to_list[j]);						to_list[j] = NULL;					}					break;					/*					 *	Enforce <=.  If it's					 *	>, replace it.					 */				case T_OP_LE:					if (rcode > 0) {						DEBUG4("::: REPLACING %s FROM %d TO %d",						       from_list[i]->name, i, j);						pairfree(&to_list[j]);						to_list[j] = from_list[i];						from_list[i] = NULL;						edited[j] = TRUE;					}					break;				case T_OP_GE:					if (rcode < 0) {						DEBUG4("::: REPLACING %s FROM %d TO %d",						       from_list[i]->name, i, j);						pairfree(&to_list[j]);						to_list[j] = from_list[i];						from_list[i] = NULL;						edited[j] = TRUE;					}					break;				}				continue;			}			rad_assert(0 == 1); /* panic! */		}		/*		 *	We were asked to add it if it didn't exist,		 *	and it doesn't exist.  Move it over to the		 *	tail of the "to" list, UNLESS it was already		 *	moved by another operator.		 */		if (!found && from_list[i]) {			if ((from_list[i]->operator == T_OP_EQ) ||			    (from_list[i]->operator == T_OP_LE) ||			    (from_list[i]->operator == T_OP_GE) ||			    (from_list[i]->operator == T_OP_SET)) {			append:				DEBUG4("::: APPENDING %s FROM %d TO %d",				       from_list[i]->name, i, tailto);				to_list[tailto++] = from_list[i];				from_list[i] = NULL;			}		}	}	/*	 *	Delete attributes in the "from" list.	 */	for (i = 0; i < from_count; i++) {		if (!from_list[i]) continue;		pairfree(&from_list[i]);	}	free(from_list);	DEBUG4("::: TO in %d out %d", to_count, tailto);	/*	 *	Re-chain the "to" list.	 */	*to = NULL;	last = to;	for (i = 0; i < tailto; i++) {		if (!to_list[i]) continue;				DEBUG4("::: to[%d] = %s", i, to_list[i]->name);		/*		 *	Mash the operator to a simple '='.  The		 *	operators in the "to" list aren't used for		 *	anything.  BUT they're used in the "detail"		 *	file and debug output, where we don't want to		 *	see the operators.		 */		to_list[i]->operator = T_OP_EQ;		*last = to_list[i];		last = &(*last)->next;	}	/*	 *	Fix dumb cache issues	 */	if (to == &request->packet->vps) {		fix_up(request);	} else if (request->parent && (to == &request->parent->packet->vps)) {		fix_up(request->parent);	}	free(to_list);	free(edited);}/* *     Copied shamelessly from conffile.c, to simplify the API for *     now... */typedef enum conf_type {	CONF_ITEM_INVALID = 0,	CONF_ITEM_PAIR,	CONF_ITEM_SECTION,	CONF_ITEM_DATA} CONF_ITEM_TYPE;struct conf_item {	struct conf_item *next;	struct conf_part *parent;	int lineno;	const char *filename;	CONF_ITEM_TYPE type;};struct conf_pair {	CONF_ITEM item;	char *attr;	char *value;	FR_TOKEN operator;	FR_TOKEN value_type;};/* *	Add attributes to a list. */int radius_update_attrlist(REQUEST *request, CONF_SECTION *cs,			   VALUE_PAIR *input_vps, const char *name){	CONF_ITEM *ci;	VALUE_PAIR *newlist, *vp;	VALUE_PAIR **output_vps = NULL;	REQUEST *request_vps = request;	if (!request || !cs) return RLM_MODULE_INVALID;	/*	 *	If we are an inner tunnel session, permit the	 *	policy to update the outer lists directly.	 */	if (strncmp(name, "outer.", 6) == 0) {		if (!request->parent) return RLM_MODULE_NOOP;		request_vps = request->parent;		name += 6;	}	if (strcmp(name, "request") == 0) {		output_vps = &request_vps->packet->vps;	} else if (strcmp(name, "reply") == 0) {		output_vps = &request_vps->reply->vps;	} else if (strcmp(name, "proxy-request") == 0) {		if (request->proxy) output_vps = &request_vps->proxy->vps;	} else if (strcmp(name, "proxy-reply") == 0) {		if (request->proxy_reply) output_vps = &request->proxy_reply->vps;	} else if (strcmp(name, "config") == 0) {		output_vps = &request_vps->config_items;	} else if (strcmp(name, "control") == 0) {		output_vps = &request_vps->config_items;	} else {		return RLM_MODULE_INVALID;	}	if (!output_vps) return RLM_MODULE_NOOP; /* didn't update the list */	newlist = paircopy(input_vps);	if (!newlist) {		DEBUG2("Out of memory");		return RLM_MODULE_FAIL;	}	vp = newlist;	for (ci=cf_item_find_next(cs, NULL);	     ci != NULL;	     ci=cf_item_find_next(cs, ci)) {		CONF_PAIR *cp;		/*		 *	This should never happen.		 */		if (cf_item_is_section(ci)) {			pairfree(&newlist);			return RLM_MODULE_INVALID;		}		cp = cf_itemtopair(ci);		/*		 *	The VP && CF lists should be in sync.  If they're		 *	not, panic.		 */		if (vp->flags.do_xlat) {			const char *value;			char buffer[2048];			value = expand_string(buffer, sizeof(buffer), request,					      cp->value_type, cp->value);			if (!value) {				pairfree(&newlist);				return RLM_MODULE_INVALID;			}			if (!pairparsevalue(vp, value)) {				DEBUG2("ERROR: Failed parsing value \"%s\" for attribute %s: %s",				       value, vp->name, librad_errstr);				pairfree(&newlist);				return RLM_MODULE_FAIL;			}			vp->flags.do_xlat = 0;		}		vp = vp->next;	}	radius_pairmove(request, output_vps, newlist);	return RLM_MODULE_UPDATED;}

⌨️ 快捷键说明

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