Esempio n. 1
0
/*
 *	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);
}
Esempio n. 2
0
/** Copy VP(s) from the specified request.
 *
 * @param ctx to alloc new VALUE_PAIRs in.
 * @param out where to write the pointer to the copied VP.
 *	Will be NULL if the attribute couldn't be resolved.
 * @param request current request.
 * @param name attribute name including qualifiers.
 * @return -4 if either the attribute or qualifier were invalid, and the same error codes as tmpl_find_vp for other
 *	error conditions.
 */
int radius_copy_vp(TALLOC_CTX *ctx, VALUE_PAIR **out, REQUEST *request, char const *name)
{
	value_pair_tmpl_t vpt;

	*out = NULL;

	if (tmpl_from_attr_str(&vpt, name, REQUEST_CURRENT, PAIR_LIST_REQUEST) < 0) {
		return -4;
	}

	return tmpl_copy_vps(ctx, out, request, &vpt);
}
Esempio n. 3
0
/** Return a VP from the specified request.
 *
 * @param out where to write the pointer to the resolved VP.
 *	Will be NULL if the attribute couldn't be resolved.
 * @param request current request.
 * @param name attribute name including qualifiers.
 * @return -4 if either the attribute or qualifier were invalid, and the same error codes as tmpl_find_vp for other
 *	error conditions.
 */
int radius_get_vp(VALUE_PAIR **out, REQUEST *request, char const *name)
{
	value_pair_tmpl_t vpt;

	*out = NULL;

	if (tmpl_from_attr_str(&vpt, name, REQUEST_CURRENT, PAIR_LIST_REQUEST) < 0) {
		return -4;
	}

	return tmpl_find_vp(out, request, &vpt);
}
/** Create a new rlm_cache_redis instance
 *
 * @copydetails cache_instantiate_t
 */
static int mod_instantiate(CONF_SECTION *conf, rlm_cache_config_t const *config, void *driver_inst)
{
	rlm_cache_redis_t	*driver = driver_inst;
	char			buffer[256];

	buffer[0] = '\0';

	fr_redis_version_print();

	if (cf_section_parse(conf, driver, driver_config) < 0) return -1;

	snprintf(buffer, sizeof(buffer), "rlm_cache (%s)", config->name);

	driver->cluster = fr_redis_cluster_alloc(driver, conf, &driver->conf);
	if (!driver->cluster) {
		ERROR("rlm_cache_redis: Cluster failure");
		return -1;
	}

	/*
	 *	These never change, so do it once on instantiation
	 */
	if (tmpl_from_attr_str(&driver->created_attr, "&Cache-Created",
			       REQUEST_CURRENT, PAIR_LIST_REQUEST, false, false) < 0) {
		ERROR("rlm_cache_redis: Cache-Created attribute not defined");
		return -1;
	}

	if (tmpl_from_attr_str(&driver->expires_attr, "&Cache-Expires",
			       REQUEST_CURRENT, PAIR_LIST_REQUEST, false, false) < 0) {
		ERROR("rlm_cache_redis: Cache-Expires attribute not defined");
		return -1;
	}

	return 0;
}
Esempio n. 5
0
/** Parse qualifiers to convert attrname into a value_pair_tmpl_t.
 *
 * VPTs are used in various places where we need to pre-parse configuration
 * sections into attribute mappings.
 *
 * @param[in] ctx for talloc
 * @param[in] name attribute name including qualifiers.
 * @param[in] request_def The default request to insert unqualified
 *	attributes into.
 * @param[in] list_def The default list to insert unqualified attributes into.
 * @return pointer to a value_pair_tmpl_t struct (must be freed with
 *	tmpl_free) or NULL on error.
 */
value_pair_tmpl_t *tmpl_afrom_attr_str(TALLOC_CTX *ctx, char const *name, request_refs_t request_def,
				       pair_lists_t list_def)
{
	value_pair_tmpl_t *vpt;
	char const *copy;

	vpt = talloc(ctx, value_pair_tmpl_t); /* parse_attr zeroes it */
	copy = talloc_typed_strdup(vpt, name);

	if (tmpl_from_attr_str(vpt, copy, request_def, list_def) < 0) {
		ERROR("%s", fr_strerror());
		tmpl_free(&vpt);
		return NULL;
	}

	return vpt;
}
Esempio n. 6
0
/** Convert module specific attribute id to value_pair_tmpl_t.
 *
 * @param[in] ctx for talloc
 * @param[in] name string to convert.
 * @param[in] type Type of quoting around value.
 * @param[in] request_def The default request to insert unqualified
 *	attributes into.
 * @param[in] list_def The default list to insert unqualified attributes into.
 * @return pointer to new VPT.
 */
value_pair_tmpl_t *tmpl_afrom_str(TALLOC_CTX *ctx, char const *name, FR_TOKEN type,
				  request_refs_t request_def, pair_lists_t list_def)
{
	int rcode;
	char const *p;
	value_pair_tmpl_t *vpt;
	char buffer[1024];

	vpt = talloc_zero(ctx, value_pair_tmpl_t);
	vpt->name = talloc_typed_strdup(vpt, name);

	switch (type) {
	case T_BARE_WORD:
		/*
		 *	If we can parse it as an attribute, it's an attribute.
		 *	Otherwise, treat it as a literal.
		 */
		rcode = tmpl_from_attr_str(vpt, vpt->name, request_def, list_def);
		if (rcode == -2) {
			talloc_free(vpt);
			return NULL;
		}
		if (rcode == 0) {
			break;
		}
		/* FALL-THROUGH */

	case T_SINGLE_QUOTED_STRING:
		vpt->type = TMPL_TYPE_LITERAL;
		break;

	case T_DOUBLE_QUOTED_STRING:
		p = name;
		while (*p) {
			if (*p == '\\') {
				if (!p[1]) break;
				p += 2;
				continue;
			}

			if (*p == '%') break;

			p++;
		}

		/*
		 *	If the double quoted string needs to be
		 *	expanded at run time, make it an xlat
		 *	expansion.  Otherwise, convert it to be a
		 *	literal.
		 */
		if (*p) {
			vpt->type = TMPL_TYPE_XLAT;
		} else {
			vpt->type = TMPL_TYPE_LITERAL;
		}
		break;

	case T_BACK_QUOTED_STRING:
		vpt->type = TMPL_TYPE_EXEC;
		break;

	case T_OP_REG_EQ: /* hack */
		vpt->type = TMPL_TYPE_REGEX;
		break;

	default:
		rad_assert(0);
		return NULL;
	}

	tmpl_prints(buffer, sizeof(buffer), vpt);

	return vpt;
}