コード例 #1
0
ファイル: rlm_dhcp.c プロジェクト: roocell/freeradius-server
/*
 *	Allow single attribute values to be retrieved from the dhcp.
 */
static ssize_t dhcp_options_xlat(UNUSED void *instance, REQUEST *request,
				 char const *fmt, char **out, size_t freespace)
{
	vp_cursor_t	cursor, src_cursor;
	vp_tmpl_t	src;
	VALUE_PAIR	*vp, *head = NULL;
	int		decoded = 0;
	ssize_t		slen;

	while (isspace((int) *fmt)) fmt++;

	slen = tmpl_from_attr_str(&src, fmt, REQUEST_CURRENT, PAIR_LIST_REQUEST, false, false);
	if (slen <= 0) {
		REMARKER(fmt, slen, fr_strerror());
	error:
		return -1;
	}

	if (src.type != TMPL_TYPE_ATTR) {
		REDEBUG("dhcp_options cannot operate on a %s", fr_int2str(tmpl_names, src.type, "<INVALID>"));
		goto error;
	}

	if (src.tmpl_da->type != PW_TYPE_OCTETS) {
		REDEBUG("dhcp_options got a %s attribute needed octets",
			fr_int2str(dict_attr_types, src.tmpl_da->type, "<INVALID>"));
		goto error;
	}

	for (vp = tmpl_cursor_init(NULL, &src_cursor, request, &src);
	     vp;
	     vp = tmpl_cursor_next(&src_cursor, &src)) {
		/*
		 *	@fixme: we should pass in a cursor, then decoding multiple
		 *	source attributes can be made atomic.
		 */
		if ((fr_dhcp_decode_options(request->packet, &head, vp->vp_octets, vp->vp_length) < 0) || (!head)) {
			RWDEBUG("DHCP option decoding failed: %s", fr_strerror());
			goto error;
		}

		for (vp = fr_cursor_init(&cursor, &head);
		     vp;
		     vp = fr_cursor_next(&cursor)) {
			rdebug_pair(L_DBG_LVL_2, request, vp, "dhcp_options: ");
			decoded++;
		}

		fr_pair_list_move(request->packet, &(request->packet->vps), &head);

		/* Free any unmoved pairs */
		fr_pair_list_free(&head);
	}

	snprintf(*out, freespace, "%i", decoded);

	return strlen(*out);
}
コード例 #2
0
ファイル: rlm_files.c プロジェクト: geaaru/freeradius-server
/*
 *	Common code called by everything below.
 */
static rlm_rcode_t file_common(rlm_files_t const *inst, REQUEST *request, char const *filename, rbtree_t *tree,
			       RADIUS_PACKET *request_packet, RADIUS_PACKET *reply_packet)
{
	char const	*name;
	VALUE_PAIR	*check_tmp = NULL;
	VALUE_PAIR	*reply_tmp = NULL;
	PAIR_LIST const *user_pl, *default_pl;
	bool		found = false;
	PAIR_LIST	my_pl;
	char		buffer[256];

	if (!inst->key) {
		VALUE_PAIR	*namepair;

		namepair = request->username;
		name = namepair ? namepair->vp_strvalue : "NONE";
	} else {
		int len;

		len = xlat_eval(buffer, sizeof(buffer), request, inst->key, NULL, NULL);
		if (len < 0) {
			return RLM_MODULE_FAIL;
		}

		name = len ? buffer : "NONE";
	}

	if (!tree) return RLM_MODULE_NOOP;

	my_pl.name = name;
	user_pl = rbtree_finddata(tree, &my_pl);
	my_pl.name = "DEFAULT";
	default_pl = rbtree_finddata(tree, &my_pl);

	/*
	 *	Find the entry for the user.
	 */
	while (user_pl || default_pl) {
		fr_cursor_t cursor;
		VALUE_PAIR *vp;
		PAIR_LIST const *pl;

		/*
		 *	Figure out which entry to match on.
		 */

		if (!default_pl && user_pl) {
			pl = user_pl;
			user_pl = user_pl->next;

		} else if (!user_pl && default_pl) {
			pl = default_pl;
			default_pl = default_pl->next;

		} else if (user_pl->order < default_pl->order) {
			pl = user_pl;
			user_pl = user_pl->next;

		} else {
			pl = default_pl;
			default_pl = default_pl->next;
		}

		MEM(fr_pair_list_copy(request, &check_tmp, pl->check) >= 0);
		for (vp = fr_cursor_init(&cursor, &check_tmp);
		     vp;
		     vp = fr_cursor_next(&cursor)) {
			if (xlat_eval_pair(request, vp) < 0) {
				RWARN("Failed parsing expanded value for check item, skipping entry: %s", fr_strerror());
				fr_pair_list_free(&check_tmp);
				continue;
			}
		}

		if (paircmp(request, request_packet->vps, check_tmp, &reply_packet->vps) == 0) {
			RDEBUG2("Found match \"%s\" one line %d of %s", pl->name, pl->lineno, filename);
			found = true;

			/* ctx may be reply or proxy */
			MEM(fr_pair_list_copy(reply_packet, &reply_tmp, pl->reply) >= 0);

			radius_pairmove(request, &reply_packet->vps, reply_tmp, true);
			fr_pair_list_move(&request->control, &check_tmp);

			reply_tmp = NULL;	/* radius_pairmove() frees input attributes */
			fr_pair_list_free(&check_tmp);

			/*
			 *	Fallthrough?
			 */
			if (!fall_through(pl->reply)) break;
		}
	}

	/*
	 *	Remove server internal parameters.
	 */
	fr_pair_delete_by_da(&reply_packet->vps, attr_fall_through);

	/*
	 *	See if we succeeded.
	 */
	if (!found)
		return RLM_MODULE_NOOP; /* on to the next module */

	return RLM_MODULE_OK;

}