1 /*
2  * pair.c	Functions to handle VALUE_PAIRs
3  *
4  * Version:	$Id: 146c82f95b551ed0f704ed5ba0814014fbc778b7 $
5  *
6  *   This library is free software; you can redistribute it and/or
7  *   modify it under the terms of the GNU Lesser General Public
8  *   License as published by the Free Software Foundation; either
9  *   version 2.1 of the License, or (at your option) any later version.
10  *
11  *   This library is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  *   Lesser General Public License for more details.
15  *
16  *   You should have received a copy of the GNU Lesser General Public
17  *   License along with this library; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2000,2006  The FreeRADIUS server project
21  */
22 
23 RCSID("$Id: 146c82f95b551ed0f704ed5ba0814014fbc778b7 $")
24 
25 #include <freeradius-devel/libradius.h>
26 #include <freeradius-devel/regex.h>
27 
28 #include <ctype.h>
29 
30 /** Free a VALUE_PAIR
31  *
32  * @note Do not call directly, use talloc_free instead.
33  *
34  * @param vp to free.
35  * @return 0
36  */
_fr_pair_free(VALUE_PAIR * vp)37 static int _fr_pair_free(VALUE_PAIR *vp) {
38 #ifndef NDEBUG
39 	vp->vp_integer = 0xf4eef4ee;
40 #endif
41 
42 #ifdef TALLOC_DEBUG
43 	talloc_report_depth_cb(NULL, 0, -1, fr_talloc_verify_cb, NULL);
44 #endif
45 	return 0;
46 }
47 
fr_pair_alloc(TALLOC_CTX * ctx)48 VALUE_PAIR *fr_pair_alloc(TALLOC_CTX *ctx)
49 {
50 	VALUE_PAIR *vp;
51 
52 	vp = talloc_zero(ctx, VALUE_PAIR);
53 	if (!vp) {
54 		fr_strerror_printf("Out of memory");
55 		return NULL;
56 	}
57 
58 	vp->op = T_OP_EQ;
59 	vp->tag = TAG_ANY;
60 	vp->type = VT_NONE;
61 
62 	talloc_set_destructor(vp, _fr_pair_free);
63 
64 	return vp;
65 }
66 
67 
68 /** Dynamically allocate a new attribute
69  *
70  * Allocates a new attribute and a new dictionary attr if no DA is provided.
71  *
72  * @param[in] ctx for allocated memory, usually a pointer to a RADIUS_PACKET
73  * @param[in] da Specifies the dictionary attribute to build the VP from.
74  * @return a new value pair or NULL if an error occurred.
75  */
fr_pair_afrom_da(TALLOC_CTX * ctx,DICT_ATTR const * da)76 VALUE_PAIR *fr_pair_afrom_da(TALLOC_CTX *ctx, DICT_ATTR const *da)
77 {
78 	VALUE_PAIR *vp;
79 
80 	/*
81 	 *	Caller must specify a da else we don't know what the attribute type is.
82 	 */
83 	if (!da) {
84 		fr_strerror_printf("Invalid arguments");
85 		return NULL;
86 	}
87 
88 	vp = fr_pair_alloc(ctx);
89 	if (!vp) {
90 		fr_strerror_printf("Out of memory");
91 		return NULL;
92 	}
93 
94 	/*
95 	 *	Use the 'da' to initialize more fields.
96 	 */
97 	vp->da = da;
98 	vp->vp_length = da->flags.length;
99 
100 	return vp;
101 }
102 
103 /** Create a new valuepair
104  *
105  * If attr and vendor match a dictionary entry then a VP with that DICT_ATTR
106  * will be returned.
107  *
108  * If attr or vendor are uknown will call dict_attruknown to create a dynamic
109  * DICT_ATTR of PW_TYPE_OCTETS.
110  *
111  * Which type of DICT_ATTR the VALUE_PAIR was created with can be determined by
112  * checking @verbatim vp->da->flags.is_unknown @endverbatim.
113  *
114  * @param[in] ctx for allocated memory, usually a pointer to a RADIUS_PACKET
115  * @param[in] attr number.
116  * @param[in] vendor number.
117  * @return the new valuepair or NULL on error.
118  */
fr_pair_afrom_num(TALLOC_CTX * ctx,unsigned int attr,unsigned int vendor)119 VALUE_PAIR *fr_pair_afrom_num(TALLOC_CTX *ctx, unsigned int attr, unsigned int vendor)
120 {
121 	DICT_ATTR const *da;
122 
123 	da = dict_attrbyvalue(attr, vendor);
124 	if (!da) return NULL;
125 
126 	return fr_pair_afrom_da(ctx, da);
127 }
128 
129 /** Free memory used by a valuepair list.
130  *
131  * @todo TLV: needs to free all dependents of each VP freed.
132  */
fr_pair_list_free(VALUE_PAIR ** vps)133 void fr_pair_list_free(VALUE_PAIR **vps)
134 {
135 	VALUE_PAIR	*vp;
136 	vp_cursor_t	cursor;
137 
138 	if (!vps || !*vps) {
139 		return;
140 	}
141 
142 	for (vp = fr_cursor_init(&cursor, vps);
143 	     vp;
144 	     vp = fr_cursor_next(&cursor)) {
145 		VERIFY_VP(vp);
146 		talloc_free(vp);
147 	}
148 
149 	*vps = NULL;
150 }
151 
152 /** Mark malformed or unrecognised attributed as unknown
153  *
154  * @param vp to change DICT_ATTR of.
155  * @return 0 on success (or if already unknown) else -1 on error.
156  */
fr_pair_to_unknown(VALUE_PAIR * vp)157 int fr_pair_to_unknown(VALUE_PAIR *vp)
158 {
159 	DICT_ATTR const *da;
160 
161 	VERIFY_VP(vp);
162 	if (vp->da->flags.is_unknown) {
163 		return 0;
164 	}
165 
166 	da = dict_unknown_afrom_fields(vp, vp->da->attr, vp->da->vendor);
167 	if (!da) {
168 		return -1;
169 	}
170 
171 	vp->da = da;
172 
173 	return 0;
174 }
175 
176 /** Find the pair with the matching DAs
177  *
178  */
fr_pair_find_by_da(VALUE_PAIR * vp,DICT_ATTR const * da,int8_t tag)179 VALUE_PAIR *fr_pair_find_by_da(VALUE_PAIR *vp, DICT_ATTR const *da, int8_t tag)
180 {
181 	vp_cursor_t 	cursor;
182 
183 	if(!fr_assert(da)) {
184 		 return NULL;
185 	}
186 
187 	(void) fr_cursor_init(&cursor, &vp);
188 	return fr_cursor_next_by_da(&cursor, da, tag);
189 }
190 
191 
192 /** Find the pair with the matching attribute
193  *
194  * @todo should take DAs and do a pointer comparison.
195  */
fr_pair_find_by_num(VALUE_PAIR * vp,unsigned int attr,unsigned int vendor,int8_t tag)196 VALUE_PAIR *fr_pair_find_by_num(VALUE_PAIR *vp, unsigned int attr, unsigned int vendor, int8_t tag)
197 {
198 	vp_cursor_t 	cursor;
199 
200 	/* List head may be NULL if it contains no VPs */
201 	if (!vp) return NULL;
202 
203 	VERIFY_LIST(vp, "");
204 
205 	(void) fr_cursor_init(&cursor, &vp);
206 	return fr_cursor_next_by_num(&cursor, attr, vendor, tag);
207 }
208 
209 /** Delete matching pairs
210  *
211  * Delete matching pairs from the attribute list.
212  *
213  * @param[in,out] first VP in list.
214  * @param[in] attr to match.
215  * @param[in] vendor to match.
216  * @param[in] tag to match. TAG_ANY matches any tag, TAG_NONE matches tagless VPs.
217  *
218  * @todo should take DAs and do a point comparison.
219  */
fr_pair_delete_by_num(VALUE_PAIR ** first,unsigned int attr,unsigned int vendor,int8_t tag)220 void fr_pair_delete_by_num(VALUE_PAIR **first, unsigned int attr, unsigned int vendor, int8_t tag)
221 {
222 	VALUE_PAIR *i, *next;
223 	VALUE_PAIR **last = first;
224 
225 	for(i = *first; i; i = next) {
226 		VERIFY_VP(i);
227 		next = i->next;
228 		if ((i->da->attr == attr) && (i->da->vendor == vendor) &&
229 		    (!i->da->flags.has_tag || TAG_EQ(tag, i->tag))) {
230 			*last = next;
231 			talloc_free(i);
232 		} else {
233 			last = &i->next;
234 		}
235 	}
236 }
237 
238 /** Add a VP to the end of the list.
239  *
240  * Locates the end of 'first', and links an additional VP 'add' at the end.
241  *
242  * @param[in] first VP in linked list. Will add new VP to the end of this list.
243  * @param[in] add VP to add to list.
244  */
fr_pair_add(VALUE_PAIR ** first,VALUE_PAIR * add)245 void fr_pair_add(VALUE_PAIR **first, VALUE_PAIR *add)
246 {
247 	VALUE_PAIR *i;
248 
249 	if (!add) return;
250 
251 	VERIFY_VP(add);
252 
253 	if (*first == NULL) {
254 		*first = add;
255 		return;
256 	}
257 
258 	for (i = *first; i->next; i = i->next) {
259 #ifdef WITH_VERIFY_PTR
260 		VERIFY_VP(i);
261 		/*
262 		 *	The same VP should never by added multiple times
263 		 *	to the same list.
264 		 */
265 		fr_assert(i != add);
266 #endif
267 	}
268 
269 	i->next = add;
270 }
271 
272 /** Add a VP to the start of the list.
273  *
274  * Links the new VP to 'first', then points 'first' at the new VP.
275  *
276  * @param[in] first VP in linked list. Will add new VP to the start of this list.
277  * @param[in] add VP to add to list.
278  */
fr_pair_prepend(VALUE_PAIR ** first,VALUE_PAIR * add)279 void fr_pair_prepend(VALUE_PAIR **first, VALUE_PAIR *add)
280 {
281 	VALUE_PAIR *i;
282 
283 	if (!add) return;
284 
285 	VERIFY_VP(add);
286 
287 	if (*first == NULL) {
288 		*first = add;
289 		return;
290 	}
291 
292 	/*
293 	 *	Find the end of the list to be prepended
294 	 */
295 	for (i = add; i->next; i = i->next) {
296 #ifdef WITH_VERIFY_PTR
297 		VERIFY_VP(i);
298 		/*
299 		 *	The same VP should never by added multiple times
300 		 *	to the same list.
301 		 */
302 		fr_assert(*first != i);
303 #endif
304 	}
305 	i->next = *first;
306 	*first = add;
307 }
308 
309 /** Replace all matching VPs
310  *
311  * Walks over 'first', and replaces the first VP that matches 'replace'.
312  *
313  * @note Memory used by the VP being replaced will be freed.
314  * @note Will not work with unknown attributes.
315  *
316  * @param[in,out] first VP in linked list. Will search and replace in this list.
317  * @param[in] replace VP to replace.
318  */
fr_pair_replace(VALUE_PAIR ** first,VALUE_PAIR * replace)319 void fr_pair_replace(VALUE_PAIR **first, VALUE_PAIR *replace)
320 {
321 	VALUE_PAIR *i, *next;
322 	VALUE_PAIR **prev = first;
323 
324 	VERIFY_VP(replace);
325 
326 	if (*first == NULL) {
327 		*first = replace;
328 		return;
329 	}
330 
331 	/*
332 	 *	Not an empty list, so find item if it is there, and
333 	 *	replace it. Note, we always replace the first one, and
334 	 *	we ignore any others that might exist.
335 	 */
336 	for(i = *first; i; i = next) {
337 		VERIFY_VP(i);
338 		next = i->next;
339 
340 		/*
341 		 *	Found the first attribute, replace it,
342 		 *	and return.
343 		 */
344 		if ((i->da == replace->da) && (!i->da->flags.has_tag || TAG_EQ(replace->tag, i->tag))) {
345 			*prev = replace;
346 
347 			/*
348 			 *	Should really assert that replace->next == NULL
349 			 */
350 			replace->next = next;
351 			talloc_free(i);
352 			return;
353 		}
354 
355 		/*
356 		 *	Point to where the attribute should go.
357 		 */
358 		prev = &i->next;
359 	}
360 
361 	/*
362 	 *	If we got here, we didn't find anything to replace, so
363 	 *	stopped at the last item, which we just append to.
364 	 */
365 	*prev = replace;
366 }
367 
fr_pair_cmp_by_da_tag(void const * a,void const * b)368 int8_t fr_pair_cmp_by_da_tag(void const *a, void const *b)
369 {
370 	VALUE_PAIR const *my_a = a;
371 	VALUE_PAIR const *my_b = b;
372 
373 	VERIFY_VP(my_a);
374 	VERIFY_VP(my_b);
375 
376 	uint8_t cmp;
377 
378 	cmp = fr_pointer_cmp(my_a->da, my_b->da);
379 	if (cmp != 0) return cmp;
380 
381 	if (my_a->tag < my_b->tag) return -1;
382 
383 	if (my_a->tag > my_b->tag) return 1;
384 
385 	return 0;
386 }
387 
fr_pair_list_sort_split(VALUE_PAIR * source,VALUE_PAIR ** front,VALUE_PAIR ** back)388 static void fr_pair_list_sort_split(VALUE_PAIR *source, VALUE_PAIR **front, VALUE_PAIR **back)
389 {
390 	VALUE_PAIR *fast;
391 	VALUE_PAIR *slow;
392 
393 	/*
394 	 *	Stopping condition - no more elements left to split
395 	 */
396 	if (!source || !source->next) {
397 		*front = source;
398 		*back = NULL;
399 
400 		return;
401 	}
402 
403 	/*
404 	 *	Fast advances twice as fast as slow, so when it gets to the end,
405 	 *	slow will point to the middle of the linked list.
406 	 */
407 	slow = source;
408 	fast = source->next;
409 
410 	while (fast) {
411 		fast = fast->next;
412 		if (fast) {
413 			slow = slow->next;
414 			fast = fast->next;
415 		}
416 	}
417 
418 	*front = source;
419 	*back = slow->next;
420 	slow->next = NULL;
421 }
422 
fr_pair_list_sort_merge(VALUE_PAIR * a,VALUE_PAIR * b,fr_cmp_t cmp)423 static VALUE_PAIR *fr_pair_list_sort_merge(VALUE_PAIR *a, VALUE_PAIR *b, fr_cmp_t cmp)
424 {
425 	VALUE_PAIR *result = NULL;
426 
427 	if (!a) return b;
428 	if (!b) return a;
429 
430 	/*
431 	 *	Compare the DICT_ATTRs and tags
432 	 */
433 	if (cmp(a, b) <= 0) {
434 		result = a;
435 		result->next = fr_pair_list_sort_merge(a->next, b, cmp);
436 	} else {
437 		result = b;
438 		result->next = fr_pair_list_sort_merge(a, b->next, cmp);
439 	}
440 
441 	return result;
442 }
443 
444 /** Sort a linked list of VALUE_PAIRs using merge sort
445  *
446  * @param[in,out] vps List of VALUE_PAIRs to sort.
447  * @param[in] cmp to sort with
448  */
fr_pair_list_sort(VALUE_PAIR ** vps,fr_cmp_t cmp)449 void fr_pair_list_sort(VALUE_PAIR **vps, fr_cmp_t cmp)
450 {
451 	VALUE_PAIR *head = *vps;
452 	VALUE_PAIR *a;
453 	VALUE_PAIR *b;
454 
455 	/*
456 	 *	If there's 0-1 elements it must already be sorted.
457 	 */
458 	if (!head || !head->next) {
459 		return;
460 	}
461 
462 	fr_pair_list_sort_split(head, &a, &b);	/* Split into sublists */
463 	fr_pair_list_sort(&a, cmp);		/* Traverse left */
464 	fr_pair_list_sort(&b, cmp);		/* Traverse right */
465 
466 	/*
467 	 *	merge the two sorted lists together
468 	 */
469 	*vps = fr_pair_list_sort_merge(a, b, cmp);
470 }
471 
472 /** Write an error to the library errorbuff detailing the mismatch
473  *
474  * Retrieve output with fr_strerror();
475  *
476  * @todo add thread specific talloc contexts.
477  *
478  * @param ctx a hack until we have thread specific talloc contexts.
479  * @param failed pair of attributes which didn't match.
480  */
fr_pair_validate_debug(TALLOC_CTX * ctx,VALUE_PAIR const * failed[2])481 void fr_pair_validate_debug(TALLOC_CTX *ctx, VALUE_PAIR const *failed[2])
482 {
483 	VALUE_PAIR const *filter = failed[0];
484 	VALUE_PAIR const *list = failed[1];
485 
486 	char *value, *str;
487 
488 	(void) fr_strerror();	/* Clear any existing messages */
489 
490 	if (!fr_assert(!(!filter && !list))) return;
491 
492 	if (!list) {
493 		if (!filter) return;
494 		fr_strerror_printf("Attribute \"%s\" not found in list", filter->da->name);
495 		return;
496 	}
497 
498 	if (!filter || (filter->da != list->da)) {
499 		fr_strerror_printf("Attribute \"%s\" not found in filter", list->da->name);
500 		return;
501 	}
502 
503 	if (!TAG_EQ(filter->tag, list->tag)) {
504 		fr_strerror_printf("Attribute \"%s\" tag \"%i\" didn't match filter tag \"%i\"",
505 				   list->da->name, list->tag, filter->tag);
506 		return;
507 	}
508 
509 
510 	value = vp_aprints_value(ctx, list, '"');
511 	str = vp_aprints(ctx, filter, '"');
512 
513 	fr_strerror_printf("Attribute value \"%s\" didn't match filter: %s", value, str);
514 
515 	talloc_free(str);
516 	talloc_free(value);
517 
518 	return;
519 }
520 
521 /** Uses fr_pair_cmp to verify all VALUE_PAIRs in list match the filter defined by check
522  *
523  * @note will sort both filter and list in place.
524  *
525  * @param failed pointer to an array to write the pointers of the filter/list attributes that didn't match.
526  *	  May be NULL.
527  * @param filter attributes to check list against.
528  * @param list attributes, probably a request or reply
529  */
fr_pair_validate(VALUE_PAIR const * failed[2],VALUE_PAIR * filter,VALUE_PAIR * list)530 bool fr_pair_validate(VALUE_PAIR const *failed[2], VALUE_PAIR *filter, VALUE_PAIR *list)
531 {
532 	vp_cursor_t filter_cursor;
533 	vp_cursor_t list_cursor;
534 
535 	VALUE_PAIR *check, *match;
536 
537 	if (!filter && !list) {
538 		return true;
539 	}
540 
541 	/*
542 	 *	This allows us to verify the sets of validate and reply are equal
543 	 *	i.e. we have a validate rule which matches every reply attribute.
544 	 *
545 	 *	@todo this should be removed one we have sets and lists
546 	 */
547 	fr_pair_list_sort(&filter, fr_pair_cmp_by_da_tag);
548 	fr_pair_list_sort(&list, fr_pair_cmp_by_da_tag);
549 
550 	check = fr_cursor_init(&filter_cursor, &filter);
551 	match = fr_cursor_init(&list_cursor, &list);
552 	while (match || check) {
553 		/*
554 		 *	Lists are of different lengths
555 		 */
556 		if (!match || !check) goto mismatch;
557 
558 		/*
559 		 *	The lists are sorted, so if the first
560 		 *	attributes aren't of the same type, then we're
561 		 *	done.
562 		 */
563 		if (!ATTRIBUTE_EQ(check, match)) goto mismatch;
564 
565 		/*
566 		 *	They're of the same type, but don't have the
567 		 *	same values.  This is a problem.
568 		 *
569 		 *	Note that the RFCs say that for attributes of
570 		 *	the same type, order is important.
571 		 */
572 		if (fr_pair_cmp(check, match) != 1) goto mismatch;
573 
574 		check = fr_cursor_next(&filter_cursor);
575 		match = fr_cursor_next(&list_cursor);
576 	}
577 
578 	return true;
579 
580 mismatch:
581 	if (failed) {
582 		failed[0] = check;
583 		failed[1] = match;
584 	}
585 	return false;
586 }
587 
588 /** Uses fr_pair_cmp to verify all VALUE_PAIRs in list match the filter defined by check
589  *
590  * @note will sort both filter and list in place.
591  *
592  * @param failed pointer to an array to write the pointers of the filter/list attributes that didn't match.
593  *	  May be NULL.
594  * @param filter attributes to check list against.
595  * @param list attributes, probably a request or reply
596  */
fr_pair_validate_relaxed(VALUE_PAIR const * failed[2],VALUE_PAIR * filter,VALUE_PAIR * list)597 bool fr_pair_validate_relaxed(VALUE_PAIR const *failed[2], VALUE_PAIR *filter, VALUE_PAIR *list)
598 {
599 	vp_cursor_t filter_cursor;
600 	vp_cursor_t list_cursor;
601 
602 	VALUE_PAIR *check, *last_check = NULL, *match = NULL;
603 
604 	if (!filter && !list) {
605 		return true;
606 	}
607 
608 	/*
609 	 *	This allows us to verify the sets of validate and reply are equal
610 	 *	i.e. we have a validate rule which matches every reply attribute.
611 	 *
612 	 *	@todo this should be removed one we have sets and lists
613 	 */
614 	fr_pair_list_sort(&filter, fr_pair_cmp_by_da_tag);
615 	fr_pair_list_sort(&list, fr_pair_cmp_by_da_tag);
616 
617 	fr_cursor_init(&list_cursor, &list);
618 	for (check = fr_cursor_init(&filter_cursor, &filter);
619 	     check;
620 	     check = fr_cursor_next(&filter_cursor)) {
621 		/*
622 		 *	Were processing check attributes of a new type.
623 		 */
624 		if (!ATTRIBUTE_EQ(last_check, check)) {
625 			/*
626 			 *	Record the start of the matching attributes in the pair list
627 			 *	For every other operator we require the match to be present
628 			 */
629 			match = fr_cursor_next_by_da(&list_cursor, check->da, check->tag);
630 			if (!match) {
631 				if (check->op == T_OP_CMP_FALSE) continue;
632 				goto mismatch;
633 			}
634 
635 			fr_cursor_init(&list_cursor, &match);
636 			last_check = check;
637 		}
638 
639 		/*
640 		 *	Now iterate over all attributes of the same type.
641 		 */
642 		for (match = fr_cursor_first(&list_cursor);
643 		     ATTRIBUTE_EQ(match, check);
644 		     match = fr_cursor_next(&list_cursor)) {
645 			/*
646 			 *	This attribute passed the filter
647 			 */
648 			if (!fr_pair_cmp(check, match)) goto mismatch;
649 		}
650 	}
651 
652 	return true;
653 
654 mismatch:
655 	if (failed) {
656 		failed[0] = check;
657 		failed[1] = match;
658 	}
659 	return false;
660 }
661 
662 /** Copy a single valuepair
663  *
664  * Allocate a new valuepair and copy the da from the old vp.
665  *
666  * @param[in] ctx for talloc
667  * @param[in] vp to copy.
668  * @return a copy of the input VP or NULL on error.
669  */
fr_pair_copy(TALLOC_CTX * ctx,VALUE_PAIR const * vp)670 VALUE_PAIR *fr_pair_copy(TALLOC_CTX *ctx, VALUE_PAIR const *vp)
671 {
672 	VALUE_PAIR *n;
673 
674 	if (!vp) return NULL;
675 
676 	VERIFY_VP(vp);
677 
678 	n = fr_pair_afrom_da(ctx, vp->da);
679 	if (!n) return NULL;
680 
681 	memcpy(n, vp, sizeof(*n));
682 
683 	/*
684 	 *	If the DA is unknown, steal "n" to "ctx".  This does
685 	 *	nothing for "n", but will also copy the unknown "da".
686 	 */
687 	if (n->da->flags.is_unknown) {
688 		fr_pair_steal(ctx, n);
689 	}
690 
691 	n->next = NULL;
692 
693 	/*
694 	 *	If it's an xlat, copy the raw string and return early,
695 	 *	so we don't pre-expand or otherwise mangle the VALUE_PAIR.
696 	 */
697 	if (vp->type == VT_XLAT) {
698 		n->value.xlat = talloc_typed_strdup(n, n->value.xlat);
699 		return n;
700 	}
701 
702 	switch (vp->da->type) {
703 	case PW_TYPE_OCTETS:
704 		n->vp_octets = NULL;	/* else fr_pair_value_memcpy will free vp's value */
705 		fr_pair_value_memcpy(n, vp->vp_octets, n->vp_length);
706 		break;
707 
708 	case PW_TYPE_STRING:
709 		n->vp_strvalue = NULL;	/* else pairstrnpy will free vp's value */
710 		fr_pair_value_bstrncpy(n, vp->vp_strvalue, n->vp_length);
711 		break;
712 
713 	default:
714 		break;
715 	}
716 
717 	return n;
718 }
719 
720 /** Copy a pairlist.
721  *
722  * Copy all pairs from 'from' regardless of tag, attribute or vendor.
723  *
724  * @param[in] ctx for new VALUE_PAIRs to be allocated in.
725  * @param[in] from whence to copy VALUE_PAIRs.
726  * @return the head of the new VALUE_PAIR list or NULL on error.
727  */
fr_pair_list_copy(TALLOC_CTX * ctx,VALUE_PAIR * from)728 VALUE_PAIR *fr_pair_list_copy(TALLOC_CTX *ctx, VALUE_PAIR *from)
729 {
730 	vp_cursor_t src, dst;
731 
732 	VALUE_PAIR *out = NULL, *vp;
733 
734 	fr_cursor_init(&dst, &out);
735 	for (vp = fr_cursor_init(&src, &from);
736 	     vp;
737 	     vp = fr_cursor_next(&src)) {
738 		VERIFY_VP(vp);
739 		vp = fr_pair_copy(ctx, vp);
740 		if (!vp) {
741 			fr_pair_list_free(&out);
742 			return NULL;
743 		}
744 		fr_cursor_insert(&dst, vp); /* fr_pair_list_copy sets next pointer to NULL */
745 	}
746 
747 	return out;
748 }
749 
750 /** Copy matching pairs
751  *
752  * Copy pairs of a matching attribute number, vendor number and tag from the
753  * the input list to a new list, and returns the head of this list.
754  *
755  * @param[in] ctx for talloc
756  * @param[in] from whence to copy VALUE_PAIRs.
757  * @param[in] attr to match. If attribute PW_VENDOR_SPECIFIC and vendor 0,
758  *	will match (and therefore copy) only VSAs.
759  *	If attribute 0 and vendor 0  will match (and therefore copy) all
760  *	attributes.
761  * @param[in] vendor to match.
762  * @param[in] tag to match, TAG_ANY matches any tag, TAG_NONE matches tagless VPs.
763  * @return the head of the new VALUE_PAIR list or NULL on error.
764  */
fr_pair_list_copy_by_num(TALLOC_CTX * ctx,VALUE_PAIR * from,unsigned int attr,unsigned int vendor,int8_t tag)765 VALUE_PAIR *fr_pair_list_copy_by_num(TALLOC_CTX *ctx, VALUE_PAIR *from,
766 				     unsigned int attr, unsigned int vendor, int8_t tag)
767 {
768 	vp_cursor_t src, dst;
769 
770 	VALUE_PAIR *out = NULL, *vp;
771 
772 	fr_cursor_init(&dst, &out);
773 	for (vp = fr_cursor_init(&src, &from);
774 	     vp;
775 	     vp = fr_cursor_next(&src)) {
776 		VERIFY_VP(vp);
777 
778 		if (vp->da->flags.has_tag && !TAG_EQ(tag, vp->tag)) {
779 			continue;
780 		}
781 
782 		/*
783 		 *	Attr/vendor of 0 means "move them all".
784 		 *	It's better than "fr_pair_copy(foo,bar);bar=NULL"
785 		 */
786 		if ((attr == 0) && (vendor == 0)) {
787 			goto do_copy;
788 		}
789 
790 		/*
791 		 *	vendor=0, attr = PW_VENDOR_SPECIFIC means
792 		 *	"match any vendor attribute".
793 		 */
794 		if ((vendor == 0) && (attr == PW_VENDOR_SPECIFIC)) {
795 			/*
796 			 *	It's a VSA: copy it over.
797 			 */
798 			if (vp->da->vendor != 0) goto do_copy;
799 
800 			/*
801 			 *	It's Vendor-Specific: copy it over.
802 			 */
803 			if (vp->da->attr == attr) goto do_copy;
804 
805 			/*
806 			 *	It's not a VSA: ignore it.
807 			 */
808 			continue;
809 		}
810 
811 		if ((vp->da->attr != attr) || (vp->da->vendor != vendor)) {
812 			continue;
813 		}
814 
815 	do_copy:
816 		vp = fr_pair_copy(ctx, vp);
817 		if (!vp) {
818 			fr_pair_list_free(&out);
819 			return NULL;
820 		}
821 		fr_cursor_insert(&dst, vp);
822 	}
823 
824 	return out;
825 }
826 
827 /** Steal one VP
828  *
829  * @param[in] ctx to move VALUE_PAIR into
830  * @param[in] vp VALUE_PAIR to move into the new context.
831  */
fr_pair_steal(TALLOC_CTX * ctx,VALUE_PAIR * vp)832 void fr_pair_steal(TALLOC_CTX *ctx, VALUE_PAIR *vp)
833 {
834 	(void) talloc_steal(ctx, vp);
835 
836 	/*
837 	 *	The DA may be unknown.  If we're stealing the VPs to a
838 	 *	different context, copy the unknown DA.  We use the VP
839 	 *	as a context here instead of "ctx", so that when the
840 	 *	VP is freed, so is the DA.
841 	 *
842 	 *	Since we have no introspection into OTHER VPs using
843 	 *	the same DA, we can't have multiple VPs use the same
844 	 *	DA.  So we might as well tie it to this VP.
845 	 */
846 	if (vp->da->flags.is_unknown) {
847 		DICT_ATTR *da;
848 		char *p;
849 		size_t size;
850 
851 		size = talloc_get_size(vp->da);
852 
853 		p = talloc_zero_array(vp, char, size);
854 		da = (DICT_ATTR *) p;
855 		talloc_set_type(p, DICT_ATTR);
856 		memcpy(da, vp->da, size);
857 		vp->da = da;
858 	}
859 }
860 
861 /** Move pairs from source list to destination list respecting operator
862  *
863  * @note This function does some additional magic that's probably not needed
864  *	 in most places. Consider using radius_pairmove in server code.
865  *
866  * @note fr_pair_list_free should be called on the head of the source list to free
867  *	 unmoved attributes (if they're no longer needed).
868  *
869  * @note Does not respect tags when matching.
870  *
871  * @param[in] ctx for talloc
872  * @param[in,out] to destination list.
873  * @param[in,out] from source list.
874  * @param[in] op operator for move.
875  *
876  * @see radius_pairmove
877  */
fr_pair_list_move(TALLOC_CTX * ctx,VALUE_PAIR ** to,VALUE_PAIR ** from,FR_TOKEN op)878 void fr_pair_list_move(TALLOC_CTX *ctx, VALUE_PAIR **to, VALUE_PAIR **from, FR_TOKEN op)
879 {
880 	VALUE_PAIR *i, *found;
881 	VALUE_PAIR *head_new, **tail_new;
882 	VALUE_PAIR *head_prepend;
883 	VALUE_PAIR **tail_from;
884 
885 	if (!to || !from || !*from) return;
886 
887 	/*
888 	 *	We're editing the "to" list while we're adding new
889 	 *	attributes to it.  We don't want the new attributes to
890 	 *	be edited, so we create an intermediate list to hold
891 	 *	them during the editing process.
892 	 */
893 	head_new = NULL;
894 	tail_new = &head_new;
895 
896 	/*
897 	 *	Any attributes that are requested to be prepended
898 	 *	are added to a temporary list here
899 	 */
900 	head_prepend = NULL;
901 
902 	/*
903 	 *	We're looping over the "from" list, moving some
904 	 *	attributes out, but leaving others in place.
905 	 */
906 	tail_from = from;
907 	while ((i = *tail_from) != NULL) {
908 		VALUE_PAIR *j;
909 
910 		VERIFY_VP(i);
911 
912 		/*
913 		 *	We never move Fall-Through.
914 		 */
915 		if (!i->da->vendor && i->da->attr == PW_FALL_THROUGH) {
916 			tail_from = &(i->next);
917 			continue;
918 		}
919 
920 		/*
921 		 *	Unlike previous versions, we treat all other
922 		 *	attributes as normal.  i.e. there's no special
923 		 *	treatment for passwords or Hint.
924 		 */
925 
926 		switch (i->op) {
927 		/*
928 		 *	Anything else are operators which
929 		 *	shouldn't occur.  We ignore them, and
930 		 *	leave them in place.
931 		 */
932 		default:
933 			tail_from = &(i->next);
934 			continue;
935 
936 		/*
937 		 *	Add it to the "to" list, but only if
938 		 *	it doesn't already exist.
939 		 */
940 		case T_OP_EQ:
941 			found = fr_pair_find_by_da(*to, i->da, TAG_ANY);
942 			if (!found) goto do_add;
943 
944 			tail_from = &(i->next);
945 			continue;
946 
947 		/*
948 		 *	Add it to the "to" list, and delete any attribute
949 		 *	of the same vendor/attr which already exists.
950 		 */
951 		case T_OP_SET:
952 			found = fr_pair_find_by_da(*to, i->da, TAG_ANY);
953 			if (!found) goto do_add;
954 
955 			/*
956 			 *	Do NOT call fr_pair_delete_by_num() here,
957 			 *	due to issues with re-writing
958 			 *	"request->username".
959 			 *
960 			 *	Everybody calls fr_pair_move, and
961 			 *	expects it to work.  We can't
962 			 *	update request->username here,
963 			 *	so instead we over-write the
964 			 *	vp that it's pointing to.
965 			 */
966 			switch (found->da->type) {
967 			default:
968 				j = found->next;
969 				memcpy(found, i, sizeof(*found));
970 				found->next = j;
971 				break;
972 
973 			case PW_TYPE_OCTETS:
974 				fr_pair_value_memsteal(found, i->vp_octets);
975 				i->vp_octets = NULL;
976 				break;
977 
978 			case PW_TYPE_STRING:
979 				fr_pair_value_strsteal(found, i->vp_strvalue);
980 				i->vp_strvalue = NULL;
981 				found->tag = i->tag;
982 				break;
983 			}
984 
985 			/*
986 			 *	Delete *all* of the attributes
987 			 *	of the same number.
988 			 */
989 			fr_pair_delete_by_num(&found->next,
990 				   found->da->attr,
991 				   found->da->vendor, TAG_ANY);
992 
993 			/*
994 			 *	Remove this attribute from the
995 			 *	"from" list.
996 			 */
997 			*tail_from = i->next;
998 			i->next = NULL;
999 			fr_pair_list_free(&i);
1000 			continue;
1001 
1002 		/*
1003 		 *	Move it from the old list and add it
1004 		 *	to the new list.
1005 		 */
1006 		case T_OP_ADD:
1007 	do_add:
1008 			*tail_from = i->next;
1009 			i->next = NULL;
1010 			*tail_new = i;
1011 			fr_pair_steal(ctx, i);
1012 			tail_new = &(i->next);
1013 			continue;
1014 		case T_OP_PREPEND:
1015 			i->next = head_prepend;
1016 			head_prepend = i;
1017 			fr_pair_steal(ctx, i);
1018 			continue;
1019 		}
1020 	} /* loop over the "from" list. */
1021 
1022 	/*
1023 	 * 	If the op parameter was prepend, add the "new" list
1024 	 *	attributes first as those whose individual operator
1025 	 *	is prepend should be prepended to the resulting list
1026 	 */
1027 	if (op == T_OP_PREPEND) {
1028 		fr_pair_prepend(to, head_new);
1029 	}
1030 
1031 	/*
1032 	 *	If there are any items in the prepend list prepend
1033 	 *	it to the "to" list
1034 	 */
1035 	fr_pair_prepend(to, head_prepend);
1036 
1037 	/*
1038 	 *	If the op parameter was not prepend, take the "new"
1039 	 *	list, and append it to the "to" list.
1040 	 */
1041 	if (op != T_OP_PREPEND) {
1042 		fr_pair_add(to, head_new);
1043 	}
1044 }
1045 
1046 /** Move matching pairs between VALUE_PAIR lists
1047  *
1048  * Move pairs of a matching attribute number, vendor number and tag from the
1049  * the input list to the output list.
1050  *
1051  * @note fr_pair_list_free should be called on the head of the old list to free unmoved
1052 	 attributes (if they're no longer needed).
1053  *
1054  * @param[in] ctx for talloc
1055  * @param[in,out] to destination list.
1056  * @param[in,out] from source list.
1057  * @param[in] attr to match. If attribute PW_VENDOR_SPECIFIC and vendor 0,
1058  *	will match (and therefore copy) only VSAs.
1059  *	If attribute 0 and vendor 0  will match (and therefore copy) all
1060  *	attributes.
1061  * @param[in] vendor to match.
1062  * @param[in] tag to match, TAG_ANY matches any tag, TAG_NONE matches tagless VPs.
1063  * @param[in] move if set to "true", VPs are moved.  If set to "false", VPs are copied, and the old one deleted.
1064  */
fr_pair_list_move_by_num_internal(TALLOC_CTX * ctx,VALUE_PAIR ** to,VALUE_PAIR ** from,unsigned int attr,unsigned int vendor,int8_t tag,bool move)1065 static void fr_pair_list_move_by_num_internal(TALLOC_CTX *ctx, VALUE_PAIR **to, VALUE_PAIR **from,
1066 					      unsigned int attr, unsigned int vendor, int8_t tag,
1067 					      bool move)
1068 {
1069 	VALUE_PAIR *to_tail, *i, *next, *this;
1070 	VALUE_PAIR *iprev = NULL;
1071 
1072 	/*
1073 	 *	Find the last pair in the "to" list and put it in "to_tail".
1074 	 *
1075 	 *	@todo: replace the "if" with "VALUE_PAIR **tail"
1076 	 */
1077 	if (*to != NULL) {
1078 		to_tail = *to;
1079 		for(i = *to; i; i = i->next) {
1080 			VERIFY_VP(i);
1081 			to_tail = i;
1082 		}
1083 	} else
1084 		to_tail = NULL;
1085 
1086 	/*
1087 	 *	Attr/vendor of 0 means "move them all".
1088 	 *	It's better than "fr_pair_add(foo,bar);bar=NULL"
1089 	 */
1090 	if ((vendor == 0) && (attr == 0)) {
1091 		if (*to) {
1092 			to_tail->next = *from;
1093 		} else {
1094 			*to = *from;
1095 		}
1096 
1097 		for (i = *from; i; i = i->next) {
1098 			fr_pair_steal(ctx, i);
1099 		}
1100 
1101 		*from = NULL;
1102 		return;
1103 	}
1104 
1105 	for(i = *from; i; i = next) {
1106 		VERIFY_VP(i);
1107 		next = i->next;
1108 
1109 		if (i->da->flags.has_tag && !TAG_EQ(tag, i->tag)) {
1110 			iprev = i;
1111 			continue;
1112 		}
1113 
1114 		/*
1115 		 *	vendor=0, attr = PW_VENDOR_SPECIFIC means
1116 		 *	"match any vendor attribute".
1117 		 */
1118 		if ((vendor == 0) && (attr == PW_VENDOR_SPECIFIC)) {
1119 			/*
1120 			 *	It's a VSA: move it over.
1121 			 */
1122 			if (i->da->vendor != 0) goto move;
1123 
1124 			/*
1125 			 *	It's Vendor-Specific: move it over.
1126 			 */
1127 			if (i->da->attr == attr) goto move;
1128 
1129 			/*
1130 			 *	It's not a VSA: ignore it.
1131 			 */
1132 			iprev = i;
1133 			continue;
1134 		}
1135 
1136 		/*
1137 		 *	If it isn't an exact match, ignore it.
1138 		 */
1139 		if (!((i->da->vendor == vendor) && (i->da->attr == attr))) {
1140 			iprev = i;
1141 			continue;
1142 		}
1143 
1144 	move:
1145 		/*
1146 		 *	Remove the attribute from the "from" list.
1147 		 */
1148 		if (iprev)
1149 			iprev->next = next;
1150 		else
1151 			*from = next;
1152 
1153 		if (move) {
1154 			this = i;
1155 		} else {
1156 			this = fr_pair_copy(ctx, i);
1157 		}
1158 
1159 		/*
1160 		 *	Add the attribute to the "to" list.
1161 		 */
1162 		if (to_tail)
1163 			to_tail->next = this;
1164 		else
1165 			*to = this;
1166 		to_tail = this;
1167 		this->next = NULL;
1168 
1169 		if (move) {
1170 			fr_pair_steal(ctx, i);
1171 		} else {
1172 			talloc_free(i);
1173 		}
1174 	}
1175 }
1176 
1177 
1178 /** Move matching pairs between VALUE_PAIR lists
1179  *
1180  * Move pairs of a matching attribute number, vendor number and tag from the
1181  * the input list to the output list.
1182  *
1183  * @note pairs which are moved have their parent changed to ctx.
1184  *
1185  * @note fr_pair_list_free should be called on the head of the old list to free unmoved
1186 	 attributes (if they're no longer needed).
1187  *
1188  * @param[in] ctx for talloc
1189  * @param[in,out] to destination list.
1190  * @param[in,out] from source list.
1191  * @param[in] attr to match. If attribute PW_VENDOR_SPECIFIC and vendor 0,
1192  *	will match (and therefore copy) only VSAs.
1193  *	If attribute 0 and vendor 0  will match (and therefore copy) all
1194  *	attributes.
1195  * @param[in] vendor to match.
1196  * @param[in] tag to match, TAG_ANY matches any tag, TAG_NONE matches tagless VPs.
1197  */
fr_pair_list_move_by_num(TALLOC_CTX * ctx,VALUE_PAIR ** to,VALUE_PAIR ** from,unsigned int attr,unsigned int vendor,int8_t tag)1198 void fr_pair_list_move_by_num(TALLOC_CTX *ctx, VALUE_PAIR **to, VALUE_PAIR **from,
1199 			      unsigned int attr, unsigned int vendor, int8_t tag)
1200 {
1201 	fr_pair_list_move_by_num_internal(ctx, to, from, attr, vendor, tag, true);
1202 }
1203 
1204 
1205 /** Copy / delete matching pairs between VALUE_PAIR lists
1206  *
1207  * Move pairs of a matching attribute number, vendor number and tag from the
1208  * the input list to the output list.  Like fr_pair_list_move_by_num(), but
1209  * instead does copy / delete.
1210  *
1211  * @note The pair is NOT reparented.  It is copied and deleted.
1212  *
1213  * @note fr_pair_list_free should be called on the head of the old list to free unmoved
1214 	 attributes (if they're no longer needed).
1215  *
1216  * @param[in] ctx for talloc
1217  * @param[in,out] to destination list.
1218  * @param[in,out] from source list.
1219  * @param[in] attr to match. If attribute PW_VENDOR_SPECIFIC and vendor 0,
1220  *	will match (and therefore copy) only VSAs.
1221  *	If attribute 0 and vendor 0  will match (and therefore copy) all
1222  *	attributes.
1223  * @param[in] vendor to match.
1224  * @param[in] tag to match, TAG_ANY matches any tag, TAG_NONE matches tagless VPs.
1225  */
fr_pair_list_mcopy_by_num(TALLOC_CTX * ctx,VALUE_PAIR ** to,VALUE_PAIR ** from,unsigned int attr,unsigned int vendor,int8_t tag)1226 void fr_pair_list_mcopy_by_num(TALLOC_CTX *ctx, VALUE_PAIR **to, VALUE_PAIR **from,
1227 			      unsigned int attr, unsigned int vendor, int8_t tag)
1228 {
1229 	fr_pair_list_move_by_num_internal(ctx, to, from, attr, vendor, tag, false);
1230 }
1231 
1232 
1233 /** Convert string value to native attribute value
1234  *
1235  * @param vp to assign value to.
1236  * @param value string to convert. Binary safe for variable length values if len is provided.
1237  * @param inlen may be < 0 in which case strlen(len) is used to determine length, else inline
1238  *	  should be the length of the string or sub string to parse.
1239  * @return 0 on success -1 on error.
1240  */
fr_pair_value_from_str(VALUE_PAIR * vp,char const * value,size_t inlen)1241 int fr_pair_value_from_str(VALUE_PAIR *vp, char const *value, size_t inlen)
1242 {
1243 	ssize_t ret;
1244 	PW_TYPE type;
1245 	VERIFY_VP(vp);
1246 
1247 	if (!value) return -1;
1248 
1249 	type = vp->da->type;
1250 
1251 	/*
1252 	 *	We presume that the input data is from a double quoted
1253 	 *	string, and needs escaping
1254 	 */
1255 	ret = value_data_from_str(vp, &vp->data, &type, vp->da, value, inlen, '"');
1256 	if (ret < 0) return -1;
1257 
1258 	/*
1259 	 *	If we parsed to a different type than the DA associated with
1260 	 *	the VALUE_PAIR we now need to fixup the DA.
1261 	 */
1262 	if (type != vp->da->type) {
1263 		DICT_ATTR const *da;
1264 
1265 		da = dict_attrbytype(vp->da->attr, vp->da->vendor, type);
1266 		if (!da) {
1267 			fr_strerror_printf("Cannot find %s variant of attribute \"%s\"",
1268 					   fr_int2str(dict_attr_types, type, "<INVALID>"), vp->da->name);
1269 			return -1;
1270 		}
1271 		vp->da = da;
1272 	}
1273 
1274 	vp->vp_length = ret;
1275 	vp->type = VT_DATA;
1276 
1277 	VERIFY_VP(vp);
1278 
1279 	return 0;
1280 }
1281 
1282 /** Use simple heuristics to create an VALUE_PAIR from an unknown address string
1283  *
1284  * If a DICT_ATTR is not provided for the address type, parsing will fail with
1285  * and error.
1286  *
1287  * @param ctx to allocate VP in.
1288  * @param value IPv4/IPv6 address/prefix string.
1289  * @param ipv4 dictionary attribute to use for an IPv4 address.
1290  * @param ipv6 dictionary attribute to use for an IPv6 address.
1291  * @param ipv4_prefix dictionary attribute to use for an IPv4 prefix.
1292  * @param ipv6_prefix dictionary attribute to use for an IPv6 prefix.
1293  * @return NULL on error, or new VALUE_PAIR.
1294  */
fr_pair_afrom_ip_str(TALLOC_CTX * ctx,char const * value,DICT_ATTR * ipv4,DICT_ATTR * ipv6,DICT_ATTR * ipv4_prefix,DICT_ATTR * ipv6_prefix)1295 VALUE_PAIR *fr_pair_afrom_ip_str(TALLOC_CTX *ctx, char const *value, DICT_ATTR *ipv4, DICT_ATTR *ipv6,
1296 				 DICT_ATTR *ipv4_prefix, DICT_ATTR *ipv6_prefix)
1297 {
1298 	VALUE_PAIR *vp;
1299 	DICT_ATTR *da = NULL;
1300 
1301 	if (!fr_assert(ipv4 || ipv6 || ipv4_prefix || ipv6_prefix)) {
1302 		return NULL;
1303 	}
1304 
1305 	/* No point in repeating the work of fr_pair_value_from_str */
1306 	if (strchr(value, ':')) {
1307 		if (strchr(value, '/')) {
1308 			da = ipv6_prefix;
1309 			goto finish;
1310 		}
1311 
1312 		da = ipv6;
1313 		goto finish;
1314 	}
1315 
1316 	if (strchr(value, '/')) {
1317 		da = ipv4_prefix;
1318 		goto finish;
1319 	}
1320 
1321 	if (ipv4) {
1322 		da = ipv4;
1323 		goto finish;
1324 	}
1325 
1326 	fr_strerror_printf("Invalid IP value specified, allowed types are %s%s%s%s",
1327 			   ipv4 ? "ipaddr " : "", ipv6 ? "ipv6addr " : "",
1328 			   ipv4_prefix ? "ipv4prefix " : "", ipv6_prefix ? "ipv6prefix" : "");
1329 
1330 finish:
1331 	vp = fr_pair_afrom_da(ctx, da);
1332 	if (!vp) return NULL;
1333 	if (fr_pair_value_from_str(vp, value, -1) < 0) {
1334 		talloc_free(vp);
1335 		return NULL;
1336 	}
1337 
1338 	return vp;
1339 }
1340 
1341 
1342 /** Create a valuepair from an ASCII attribute and value
1343  *
1344  * Where the attribute name is in the form:
1345  *  - Attr-%d
1346  *  - Attr-%d.%d.%d...
1347  *  - Vendor-%d-Attr-%d
1348  *  - VendorName-Attr-%d
1349  *
1350  * @param ctx for talloc
1351  * @param attribute name to parse.
1352  * @param value to parse (must be a hex string).
1353  * @param op to assign to new valuepair.
1354  * @return new valuepair or NULL on error.
1355  */
fr_pair_make_unknown(TALLOC_CTX * ctx,char const * attribute,char const * value,FR_TOKEN op)1356 static VALUE_PAIR *fr_pair_make_unknown(TALLOC_CTX *ctx,
1357 					char const *attribute, char const *value,
1358 					FR_TOKEN op)
1359 {
1360 	VALUE_PAIR	*vp, *vp2;
1361 	DICT_ATTR const *da;
1362 
1363 	uint8_t 	*data;
1364 	size_t		size;
1365 	ssize_t		len;
1366 
1367 	vp = fr_pair_alloc(ctx);
1368 	if (!vp) return NULL;
1369 
1370 	vp->da = dict_unknown_afrom_str(vp, attribute);
1371 	if (!vp->da) {
1372 		talloc_free(vp);
1373 		return NULL;
1374 	}
1375 
1376 	/*
1377 	 *	No value.  Nothing more to do.
1378 	 */
1379 	if (!value) return vp;
1380 
1381 	/*
1382 	 *	Unknown attributes MUST be of type 'octets'
1383 	 */
1384 	if (strncasecmp(value, "0x", 2) != 0) {
1385 		fr_strerror_printf("Unknown attribute \"%s\" requires a hex "
1386 				   "string, not \"%s\"", attribute, value);
1387 		talloc_free(vp);
1388 		return NULL;
1389 	}
1390 
1391 	/*
1392 	 *	Convert the hex data to binary.
1393 	 */
1394 	size = strlen(value + 2);
1395 
1396 	vp->vp_length = size >> 1;
1397 	vp->vp_octets = data = talloc_array(vp, uint8_t, vp->vp_length);
1398 	vp->type = VT_DATA;
1399 	vp->op = (op == 0) ? T_OP_EQ : op;
1400 
1401 	if (fr_hex2bin(data, vp->vp_length, value + 2, size) != vp->vp_length) {
1402 		fr_strerror_printf("Invalid hex string");
1403 		talloc_free(vp);
1404 		return NULL;
1405 	}
1406 
1407 	/*
1408 	 *	It's still unknown, return it as-is.
1409 	 */
1410 	da = dict_attrbyvalue(vp->da->attr, vp->da->vendor);
1411 	if (!da) return vp;
1412 
1413 	/*
1414 	 *	It MIGHT be known.  See if we can decode the raw data
1415 	 *	into a valid attribute.
1416 	 */
1417 	len = data2vp(ctx, NULL, NULL, NULL, da,
1418 		      vp->vp_octets, vp->vp_length, vp->vp_length,
1419 		      &vp2);
1420 	if (len <= 0) return vp;
1421 
1422 	/*
1423 	 *	It's still unknown.  Return the original VP.
1424 	 */
1425 	if (vp2->da->flags.is_unknown) {
1426 		fr_pair_list_free(&vp2);
1427 		return vp;
1428 	}
1429 
1430 	/*
1431 	 *	Didn't parse all of it.  Return the "unknown" one.
1432 	 *
1433 	 *	FIXME: it COULD have parsed 2 attributes and
1434 	 *	then not the third, so returning 2 "knowns"
1435 	 *	and 1 "unknown" is likely preferable.
1436 	 */
1437 	if ((size_t) len < vp->vp_length) {
1438 		fr_pair_list_free(&vp2);
1439 		return vp;
1440 	}
1441 
1442 	fr_pair_list_free(&vp);
1443 	return vp2;
1444 }
1445 
1446 
1447 /** Create a VALUE_PAIR from ASCII strings
1448  *
1449  * Converts an attribute string identifier (with an optional tag qualifier)
1450  * and value string into a VALUE_PAIR.
1451  *
1452  * The string value is parsed according to the type of VALUE_PAIR being created.
1453  *
1454  * @param[in] ctx for talloc
1455  * @param[in] vps list where the attribute will be added (optional)
1456  * @param[in] attribute name.
1457  * @param[in] value attribute value (may be NULL if value will be set later).
1458  * @param[in] op to assign to new VALUE_PAIR.
1459  * @return a new VALUE_PAIR.
1460  */
fr_pair_make(TALLOC_CTX * ctx,VALUE_PAIR ** vps,char const * attribute,char const * value,FR_TOKEN op)1461 VALUE_PAIR *fr_pair_make(TALLOC_CTX *ctx, VALUE_PAIR **vps,
1462 			char const *attribute, char const *value, FR_TOKEN op)
1463 {
1464 	DICT_ATTR const *da;
1465 	VALUE_PAIR	*vp;
1466 	char		*tc, *ts;
1467 	int8_t		tag;
1468 	bool		found_tag;
1469 	char		buffer[256];
1470 	char const	*attrname = attribute;
1471 
1472 	/*
1473 	 *    Check for tags in 'Attribute:Tag' format.
1474 	 */
1475 	found_tag = false;
1476 	tag = TAG_ANY;
1477 
1478 	ts = strrchr(attribute, ':');
1479 	if (ts && !ts[1]) {
1480 		fr_strerror_printf("Invalid tag for attribute %s", attribute);
1481 		return NULL;
1482 	}
1483 
1484 	if (ts && ts[1]) {
1485 		strlcpy(buffer, attribute, sizeof(buffer));
1486 		attrname = buffer;
1487 		ts = strrchr(attrname, ':');
1488 		if (!ts) return NULL;
1489 
1490 		 /* Colon found with something behind it */
1491 		 if (ts[1] == '*' && ts[2] == 0) {
1492 			 /* Wildcard tag for check items */
1493 			 tag = TAG_ANY;
1494 			 *ts = '\0';
1495 		 } else if ((ts[1] >= '0') && (ts[1] <= '9')) {
1496 			 /* It's not a wild card tag */
1497 			 tag = strtol(ts + 1, &tc, 0);
1498 			 if (tc && !*tc && TAG_VALID_ZERO(tag))
1499 				 *ts = '\0';
1500 			 else tag = TAG_ANY;
1501 		 } else {
1502 			 fr_strerror_printf("Invalid tag for attribute %s", attribute);
1503 			 return NULL;
1504 		 }
1505 		 found_tag = true;
1506 	}
1507 
1508 	/*
1509 	 *	It's not found in the dictionary, so we use
1510 	 *	another method to create the attribute.
1511 	 */
1512 	da = dict_attrbyname(attrname);
1513 	if (!da) {
1514 		vp = fr_pair_make_unknown(ctx, attrname, value, op);
1515 		if (vp && vps) fr_pair_add(vps, vp);
1516 		return vp;
1517 	}
1518 
1519 	/*      Check for a tag in the 'Merit' format of:
1520 	 *      :Tag:Value.  Print an error if we already found
1521 	 *      a tag in the Attribute.
1522 	 */
1523 
1524 	if (value && (*value == ':' && da->flags.has_tag)) {
1525 		/* If we already found a tag, this is invalid */
1526 		if(found_tag) {
1527 			fr_strerror_printf("Duplicate tag %s for attribute %s",
1528 				   value, da->name);
1529 			DEBUG("Duplicate tag %s for attribute %s\n",
1530 				   value, da->name);
1531 			return NULL;
1532 		}
1533 		/* Colon found and attribute allows a tag */
1534 		if (value[1] == '*' && value[2] == ':') {
1535 		       /* Wildcard tag for check items */
1536 		       tag = TAG_ANY;
1537 		       value += 3;
1538 		} else {
1539 		       /* Real tag */
1540 		       tag = strtol(value + 1, &tc, 0);
1541 		       if (tc && *tc==':' && TAG_VALID_ZERO(tag))
1542 			    value = tc + 1;
1543 		       else tag = 0;
1544 		}
1545 	}
1546 
1547 	vp = fr_pair_afrom_da(ctx, da);
1548 	if (!vp) return NULL;
1549 	vp->op = (op == 0) ? T_OP_EQ : op;
1550 	vp->tag = tag;
1551 
1552 	switch (vp->op) {
1553 	case T_OP_CMP_TRUE:
1554 	case T_OP_CMP_FALSE:
1555 		vp->vp_strvalue = NULL;
1556 		vp->vp_length = 0;
1557 		value = NULL;	/* ignore it! */
1558 		break;
1559 
1560 		/*
1561 		 *	Regular expression comparison of integer attributes
1562 		 *	does a STRING comparison of the names of their
1563 		 *	integer attributes.
1564 		 */
1565 	case T_OP_REG_EQ:	/* =~ */
1566 	case T_OP_REG_NE:	/* !~ */
1567 	{
1568 #ifndef HAVE_REGEX
1569 		fr_strerror_printf("Regular expressions are not supported");
1570 		return NULL;
1571 #else
1572 		ssize_t slen;
1573 		regex_t *preg;
1574 
1575 		/*
1576 		 *	Someone else will fill in the value.
1577 		 */
1578 		if (!value) break;
1579 
1580 		talloc_free(vp);
1581 
1582 		slen = regex_compile(ctx, &preg, value, strlen(value), false, false, false, true);
1583 		if (slen <= 0) {
1584 			fr_strerror_printf("Error at offset %zu compiling regex for %s: %s", -slen,
1585 					   attribute, fr_strerror());
1586 			return NULL;
1587 		}
1588 		talloc_free(preg);
1589 
1590 		vp = fr_pair_make(ctx, NULL, attribute, NULL, op);
1591 		if (!vp) return NULL;
1592 
1593 		if (fr_pair_mark_xlat(vp, value) < 0) {
1594 			talloc_free(vp);
1595 			return NULL;
1596 		}
1597 
1598 		value = NULL;	/* ignore it */
1599 		break;
1600 #endif
1601 	}
1602 	default:
1603 		break;
1604 	}
1605 
1606 	/*
1607 	 *	We allow this for stupidity, but it's really a bad idea.
1608 	 */
1609 	if (vp->da->type == PW_TYPE_TLV) {
1610 		ssize_t len;
1611 		DICT_ATTR const *unknown;
1612 		VALUE_PAIR *head = NULL;
1613 		VALUE_PAIR **tail = &head;
1614 
1615 		if (!value) {
1616 			talloc_free(vp);
1617 			return NULL;
1618 		}
1619 
1620 		unknown = dict_unknown_afrom_fields(vp, vp->da->attr, vp->da->vendor);
1621 		if (!unknown) {
1622 			talloc_free(vp);
1623 			return NULL;
1624 		}
1625 
1626 		vp->da = unknown;
1627 
1628 		/*
1629 		 *	Parse it as an unknown type, i.e. octets.
1630 		 */
1631 		if (fr_pair_value_from_str(vp, value, -1) < 0) {
1632 			talloc_free(vp);
1633 			return NULL;
1634 		}
1635 
1636 		/*
1637 		 *	It's badly formatted.  Treat it as unknown.
1638 		 */
1639 		if (rad_tlv_ok(vp->vp_octets, vp->vp_length, 1, 1) < 0) {
1640 			goto do_add;
1641 		}
1642 
1643 		/*
1644 		 *	Decode the TLVs
1645 		 */
1646 		len = rad_data2vp_tlvs(ctx, NULL, NULL, NULL, da, vp->vp_octets,
1647 				       vp->vp_length, tail);
1648 		if (len < 0) {
1649 			goto do_add;
1650 		}
1651 
1652 		talloc_free(vp);
1653 		vp = head;
1654 		goto do_add;
1655 	}
1656 
1657 	/*
1658 	 *	FIXME: if (strcasecmp(attribute, vp->da->name) != 0)
1659 	 *	then the user MAY have typed in the attribute name
1660 	 *	as Vendor-%d-Attr-%d, and the value MAY be octets.
1661 	 *
1662 	 *	We probably want to fix fr_pair_value_from_str to accept
1663 	 *	octets as values for any attribute.
1664 	 */
1665 	if (value && (fr_pair_value_from_str(vp, value, -1) < 0)) {
1666 		talloc_free(vp);
1667 		return NULL;
1668 	}
1669 
1670 do_add:
1671 	if (vps) fr_pair_add(vps, vp);
1672 	return vp;
1673 }
1674 
1675 /** Mark a valuepair for xlat expansion
1676  *
1677  * Copies xlat source (unprocessed) string to valuepair value,
1678  * and sets value type.
1679  *
1680  * @param vp to mark for expansion.
1681  * @param value to expand.
1682  * @return 0 if marking succeeded or -1 if vp already had a value, or OOM.
1683  */
fr_pair_mark_xlat(VALUE_PAIR * vp,char const * value)1684 int fr_pair_mark_xlat(VALUE_PAIR *vp, char const *value)
1685 {
1686 	char *raw;
1687 
1688 	/*
1689 	 *	valuepair should not already have a value.
1690 	 */
1691 	if (vp->type != VT_NONE) {
1692 		fr_strerror_printf("Pair already has a value");
1693 		return -1;
1694 	}
1695 
1696 	raw = talloc_typed_strdup(vp, value);
1697 	if (!raw) {
1698 		fr_strerror_printf("Out of memory");
1699 		return -1;
1700 	}
1701 
1702 	vp->type = VT_XLAT;
1703 	vp->value.xlat = raw;
1704 	vp->vp_length = 0;
1705 
1706 	return 0;
1707 }
1708 
1709 
1710 /** Read a single valuepair from a buffer, and advance the pointer
1711  *
1712  *  Returns T_EOL if end of line was encountered.
1713  *
1714  * @param[in,out] ptr to read from and update.
1715  * @param[out] raw The struct to write the raw VALUE_PAIR to.
1716  * @return the last token read.
1717  */
fr_pair_raw_from_str(char const ** ptr,VALUE_PAIR_RAW * raw)1718 FR_TOKEN fr_pair_raw_from_str(char const **ptr, VALUE_PAIR_RAW *raw)
1719 {
1720 	char const	*p;
1721 	char *q;
1722 	FR_TOKEN	ret = T_INVALID, next, quote;
1723 	char		buf[8];
1724 
1725 	if (!ptr || !*ptr || !raw) {
1726 		fr_strerror_printf("Invalid arguments");
1727 		return T_INVALID;
1728 	}
1729 
1730 	/*
1731 	 *	Skip leading spaces
1732 	 */
1733 	p = *ptr;
1734 	while ((*p == ' ') || (*p == '\t')) p++;
1735 
1736 	if (!*p) {
1737 		fr_strerror_printf("No token read where we expected "
1738 				   "an attribute name");
1739 		return T_INVALID;
1740 	}
1741 
1742 	if (*p == '#') return T_HASH;
1743 
1744 	/*
1745 	 *	Try to get the attribute name.
1746 	 */
1747 	q = raw->l_opand;
1748 	*q = '\0';
1749 	while (*p) {
1750 		uint8_t const *t = (uint8_t const *) p;
1751 
1752 		if (q >= (raw->l_opand + sizeof(raw->l_opand))) {
1753 		too_long:
1754 			fr_strerror_printf("Attribute name too long");
1755 			return T_INVALID;
1756 		}
1757 
1758 		/*
1759 		 *	This is arguably easier than trying to figure
1760 		 *	out which operators come after the attribute
1761 		 *	name.  Yes, our "lexer" is bad.
1762 		 */
1763 		if (!dict_attr_allowed_chars[(unsigned int) *t]) {
1764 			break;
1765 		}
1766 
1767 		/*
1768 		 *	Attribute:=value is NOT
1769 		 *
1770 		 *	Attribute:
1771 		 *	=
1772 		 *	value
1773 		 */
1774 		if ((*p == ':') && (!isdigit((int) p[1]))) {
1775 			break;
1776 		}
1777 
1778 		*(q++) = *(p++);
1779 	}
1780 
1781 	/*
1782 	 *	Haven't found any valid characters in the name.
1783 	 */
1784 	if (!*raw->l_opand) {
1785 		fr_strerror_printf("Invalid attribute name");
1786 		return T_INVALID;
1787 	}
1788 
1789 	/*
1790 	 *	Look for tag (:#).  This is different from :=, which
1791 	 *	is an operator.
1792 	 */
1793 	if ((*p == ':') && (isdigit((int) p[1]))) {
1794 		if (q >= (raw->l_opand + sizeof(raw->l_opand))) {
1795 			goto too_long;
1796 		}
1797 		*(q++) = *(p++);
1798 
1799 		while (isdigit((int) *p)) {
1800 			if (q >= (raw->l_opand + sizeof(raw->l_opand))) {
1801 				goto too_long;
1802 			}
1803 			*(q++) = *(p++);
1804 		}
1805 	}
1806 
1807 	*q = '\0';
1808 	*ptr = p;
1809 
1810 	/* Now we should have an operator here. */
1811 	raw->op = gettoken(ptr, buf, sizeof(buf), false);
1812 	if (raw->op  < T_EQSTART || raw->op  > T_EQEND) {
1813 		fr_strerror_printf("Expecting operator");
1814 
1815 		return T_INVALID;
1816 	}
1817 
1818 	/*
1819 	 *	Read value.  Note that empty string values are allowed
1820 	 */
1821 	quote = gettoken(ptr, raw->r_opand, sizeof(raw->r_opand), false);
1822 	if (quote == T_EOL) {
1823 		fr_strerror_printf("Failed to get value");
1824 
1825 		return T_INVALID;
1826 	}
1827 
1828 	/*
1829 	 *	Peek at the next token. Must be T_EOL, T_COMMA, or T_HASH
1830 	 */
1831 	p = *ptr;
1832 
1833 	next = gettoken(&p, buf, sizeof(buf), false);
1834 	switch (next) {
1835 	case T_HASH:
1836 		next = T_EOL;
1837 		break;
1838 
1839 	case T_EOL:
1840 		break;
1841 
1842 	case T_COMMA:
1843 		*ptr = p;
1844 		break;
1845 
1846 	default:
1847 		fr_strerror_printf("Expected end of line or comma");
1848 		return T_INVALID;
1849 	}
1850 	ret = next;
1851 
1852 	switch (quote) {
1853 	/*
1854 	 *	Perhaps do xlat's
1855 	 */
1856 	case T_DOUBLE_QUOTED_STRING:
1857 		/*
1858 		 *	Only report as double quoted if it contained valid
1859 		 *	a valid xlat expansion.
1860 		 */
1861 		p = strchr(raw->r_opand, '%');
1862 		if (p && (p[1] == '{')) {
1863 			raw->quote = quote;
1864 		} else {
1865 			raw->quote = T_SINGLE_QUOTED_STRING;
1866 		}
1867 
1868 		break;
1869 
1870 	case T_SINGLE_QUOTED_STRING:
1871 	case T_BACK_QUOTED_STRING:
1872 	case T_BARE_WORD:
1873 		raw->quote = quote;
1874 		break;
1875 
1876 	default:
1877 		fr_strerror_printf("Failed to find expected value on right hand side in %s", raw->l_opand);
1878 		return T_INVALID;
1879 	}
1880 
1881 	return ret;
1882 }
1883 
1884 /** Read one line of attribute/value pairs into a list.
1885  *
1886  * The line may specify multiple attributes separated by commas.
1887  *
1888  * @note If the function returns T_INVALID, an error has occurred and
1889  * @note the valuepair list should probably be freed.
1890  *
1891  * @param ctx for talloc
1892  * @param buffer to read valuepairs from.
1893  * @param list where the parsed VALUE_PAIRs will be appended.
1894  * @return the last token parsed, or T_INVALID
1895  */
fr_pair_list_afrom_str(TALLOC_CTX * ctx,char const * buffer,VALUE_PAIR ** list)1896 FR_TOKEN fr_pair_list_afrom_str(TALLOC_CTX *ctx, char const *buffer, VALUE_PAIR **list)
1897 {
1898 	VALUE_PAIR	*vp, *head, **tail;
1899 	char const	*p;
1900 	FR_TOKEN	last_token = T_INVALID;
1901 	VALUE_PAIR_RAW	raw;
1902 
1903 	/*
1904 	 *	We allow an empty line.
1905 	 */
1906 	if (buffer[0] == 0) {
1907 		return T_EOL;
1908 	}
1909 
1910 	head = NULL;
1911 	tail = &head;
1912 
1913 	p = buffer;
1914 	do {
1915 		raw.l_opand[0] = '\0';
1916 		raw.r_opand[0] = '\0';
1917 
1918 		last_token = fr_pair_raw_from_str(&p, &raw);
1919 
1920 		/*
1921 		 *	JUST a hash.  Don't try to create a VP.
1922 		 *	Let the caller determine if an empty list is OK.
1923 		 */
1924 		if (last_token == T_HASH) {
1925 			last_token = T_EOL;
1926 			break;
1927 		}
1928 		if (last_token == T_INVALID) break;
1929 
1930 		if (raw.quote == T_DOUBLE_QUOTED_STRING) {
1931 			vp = fr_pair_make(ctx, NULL, raw.l_opand, NULL, raw.op);
1932 			if (!vp) {
1933 				last_token = T_INVALID;
1934 				break;
1935 			}
1936 			if (fr_pair_mark_xlat(vp, raw.r_opand) < 0) {
1937 				talloc_free(vp);
1938 				last_token = T_INVALID;
1939 				break;
1940 			}
1941 		} else {
1942 			vp = fr_pair_make(ctx, NULL, raw.l_opand, raw.r_opand, raw.op);
1943 			if (!vp) {
1944 				last_token = T_INVALID;
1945 				break;
1946 			}
1947 		}
1948 
1949 		*tail = vp;
1950 		tail = &((*tail)->next);
1951 	} while (*p && (last_token == T_COMMA));
1952 
1953 	if (last_token == T_INVALID) {
1954 		fr_pair_list_free(&head);
1955 	} else {
1956 		fr_pair_add(list, head);
1957 	}
1958 
1959 	/*
1960 	 *	And return the last token which we read.
1961 	 */
1962 	return last_token;
1963 }
1964 
1965 /*
1966  *	Read valuepairs from the fp up to End-Of-File.
1967  */
fr_pair_list_afrom_file(TALLOC_CTX * ctx,VALUE_PAIR ** out,FILE * fp,bool * pfiledone)1968 int fr_pair_list_afrom_file(TALLOC_CTX *ctx, VALUE_PAIR **out, FILE *fp, bool *pfiledone)
1969 {
1970 	char buf[8192];
1971 	FR_TOKEN last_token = T_EOL;
1972 
1973 	vp_cursor_t cursor;
1974 
1975 	VALUE_PAIR *vp = NULL;
1976 	fr_cursor_init(&cursor, out);
1977 
1978 	while (fgets(buf, sizeof(buf), fp) != NULL) {
1979 		/*
1980 		 *      If we get a '\n' by itself, we assume that's
1981 		 *      the end of that VP
1982 		 */
1983 		if (buf[0] == '\n') {
1984 			if (vp) {
1985 				*pfiledone = false;
1986 				return 0;
1987 			}
1988 			continue;
1989 		}
1990 
1991 		/*
1992 		 *	Comments get ignored
1993 		 */
1994 		if (buf[0] == '#') continue;
1995 
1996 		/*
1997 		 *	Read all of the attributes on the current line.
1998 		 */
1999 		vp = NULL;
2000 		last_token = fr_pair_list_afrom_str(ctx, buf, &vp);
2001 		if (!vp) {
2002 			if (last_token != T_EOL) goto error;
2003 			break;
2004 		}
2005 
2006 		fr_cursor_merge(&cursor, vp);
2007 		buf[0] = '\0';
2008 	}
2009 	*pfiledone = true;
2010 
2011 	return 0;
2012 
2013 error:
2014 	*pfiledone = false;
2015 	vp = fr_cursor_first(&cursor);
2016 	if (vp) fr_pair_list_free(&vp);
2017 
2018 	return -1;
2019 }
2020 
2021 /** Compare two pairs, using the operator from "a"
2022  *
2023  *	i.e. given two attributes, it does:
2024  *
2025  *	(b->data) (a->operator) (a->data)
2026  *
2027  *	e.g. "foo" != "bar"
2028  *
2029  * @param[in] a the first attribute
2030  * @param[in] b the second attribute
2031  * @return 1 if true, 0 if false, -1 on error.
2032  */
fr_pair_cmp(VALUE_PAIR * a,VALUE_PAIR * b)2033 int fr_pair_cmp(VALUE_PAIR *a, VALUE_PAIR *b)
2034 {
2035 	if (!a) return -1;
2036 
2037 	VERIFY_VP(a);
2038 	if (b) VERIFY_VP(b);
2039 
2040 	switch (a->op) {
2041 	case T_OP_CMP_TRUE:
2042 		return (b != NULL);
2043 
2044 	case T_OP_CMP_FALSE:
2045 		return (b == NULL);
2046 
2047 		/*
2048 		 *	a is a regex, compile it, print b to a string,
2049 		 *	and then do string comparisons.
2050 		 */
2051 	case T_OP_REG_EQ:
2052 	case T_OP_REG_NE:
2053 #ifndef HAVE_REGEX
2054 		return -1;
2055 #else
2056 		if (!b) return false;
2057 
2058 		{
2059 			ssize_t	slen;
2060 			regex_t	*preg;
2061 			char	*value;
2062 
2063 			if (!fr_assert(a->da->type == PW_TYPE_STRING)) return -1;
2064 
2065 			slen = regex_compile(NULL, &preg, a->value.xlat, talloc_array_length(a->value.xlat) - 1, false, false, false, true);
2066 			if (slen <= 0) {
2067 				fr_strerror_printf("Error at offset %zu compiling regex for %s: %s",
2068 						   -slen, a->da->name, fr_strerror());
2069 				return -1;
2070 			}
2071 			value = vp_aprints_value(NULL, b, '\0');
2072 			if (!value) {
2073 				talloc_free(preg);
2074 				return -1;
2075 			}
2076 
2077 			/*
2078 			 *	Don't care about substring matches, oh well...
2079 			 */
2080 			slen = regex_exec(preg, value, talloc_array_length(value) - 1, NULL, NULL);
2081 			talloc_free(preg);
2082 			talloc_free(value);
2083 
2084 			if (slen < 0) return -1;
2085 			if (a->op == T_OP_REG_EQ) return (int)slen;
2086 			return !slen;
2087 		}
2088 #endif
2089 
2090 	default:		/* we're OK */
2091 		if (!b) return false;
2092 		break;
2093 	}
2094 
2095 	return fr_pair_cmp_op(a->op, b, a);
2096 }
2097 
2098 /** Determine equality of two lists
2099  *
2100  * This is useful for comparing lists of attributes inserted into a binary tree.
2101  *
2102  * @param a first list of VALUE_PAIRs.
2103  * @param b second list of VALUE_PAIRs.
2104  * @return -1 if a < b, 0 if the two lists are equal, 1 if a > b, -2 on error.
2105  */
fr_pair_list_cmp(VALUE_PAIR * a,VALUE_PAIR * b)2106 int fr_pair_list_cmp(VALUE_PAIR *a, VALUE_PAIR *b)
2107 {
2108 	vp_cursor_t a_cursor, b_cursor;
2109 	VALUE_PAIR *a_p, *b_p;
2110 	int ret;
2111 
2112 	for (a_p = fr_cursor_init(&a_cursor, &a), b_p = fr_cursor_init(&b_cursor, &b);
2113 	     a_p && b_p;
2114 	     a_p = fr_cursor_next(&a_cursor), b_p = fr_cursor_next(&b_cursor)) {
2115 		/* Same VP, no point doing expensive checks */
2116 		if (a_p == b_p) {
2117 			continue;
2118 		}
2119 
2120 		if (a_p->da < b_p->da) {
2121 			return -1;
2122 		}
2123 		if (a_p->da > b_p->da) {
2124 			return 1;
2125 		}
2126 
2127 		if (a_p->tag < b_p->tag) {
2128 			return -1;
2129 		}
2130 		if (a_p->tag > b_p->tag) {
2131 			return 1;
2132 		}
2133 
2134 		ret = value_data_cmp(a_p->da->type, &a_p->data, a_p->vp_length,
2135 				     b_p->da->type, &b_p->data, b_p->vp_length);
2136 		if (ret != 0) {
2137 			fr_assert(ret >= -1); 	/* Comparison error */
2138 			return ret;
2139 		}
2140 	}
2141 
2142 	if (!a_p && !b_p) {
2143 		return 0;
2144 	}
2145 
2146 	if (!a_p) {
2147 		return -1;
2148 	}
2149 
2150 	/* if(!b_p) */
2151 	return 1;
2152 }
2153 
2154 /** Set the type of the VALUE_PAIR value buffer to match it's DICT_ATTR
2155  *
2156  * @param vp to fixup.
2157  */
fr_pair_value_set_type(VALUE_PAIR * vp)2158 static void fr_pair_value_set_type(VALUE_PAIR *vp)
2159 {
2160 	if (!vp->data.ptr) return;
2161 
2162 	switch (vp->da->type) {
2163 	case PW_TYPE_OCTETS:
2164 		talloc_set_type(vp->data.ptr, uint8_t);
2165 		return;
2166 
2167 	case PW_TYPE_STRING:
2168 		talloc_set_type(vp->data.ptr, char);
2169 		return;
2170 
2171 	default:
2172 		return;
2173 	}
2174 }
2175 
2176 /** Copy data into an "octets" data type.
2177  *
2178  * @param[in,out] vp to update
2179  * @param[in] src data to copy
2180  * @param[in] size of the data, may be 0 in which case previous value will be freed.
2181  */
fr_pair_value_memcpy(VALUE_PAIR * vp,uint8_t const * src,size_t size)2182 void fr_pair_value_memcpy(VALUE_PAIR *vp, uint8_t const *src, size_t size)
2183 {
2184 	uint8_t *p = NULL, *q;
2185 
2186 	VERIFY_VP(vp);
2187 
2188 	if (size > 0) {
2189 		p = talloc_memdup(vp, src, size);
2190 		if (!p) return;
2191 		talloc_set_type(p, uint8_t);
2192 	}
2193 
2194 	memcpy(&q, &vp->vp_octets, sizeof(q));
2195 	TALLOC_FREE(q);
2196 
2197 	vp->vp_octets = p;
2198 	vp->vp_length = size;
2199 
2200 	if (size > 0) fr_pair_value_set_type(vp);
2201 }
2202 
2203 /** Reparent an allocated octet buffer to a VALUE_PAIR
2204  *
2205  * @param[in,out] vp to update
2206  * @param[in] src buffer to steal.
2207  */
fr_pair_value_memsteal(VALUE_PAIR * vp,uint8_t const * src)2208 void fr_pair_value_memsteal(VALUE_PAIR *vp, uint8_t const *src)
2209 {
2210 	uint8_t *q;
2211 
2212 	VERIFY_VP(vp);
2213 
2214 	memcpy(&q, &vp->vp_octets, sizeof(q));
2215 	talloc_free(q);
2216 
2217 	vp->vp_octets = talloc_steal(vp, src);
2218 	vp->type = VT_DATA;
2219 	vp->vp_length = talloc_array_length(vp->vp_strvalue);
2220 	fr_pair_value_set_type(vp);
2221 }
2222 
2223 /** Reparent an allocated char buffer to a VALUE_PAIR
2224  *
2225  * @param[in,out] vp to update
2226  * @param[in] src buffer to steal.
2227  */
fr_pair_value_strsteal(VALUE_PAIR * vp,char const * src)2228 void fr_pair_value_strsteal(VALUE_PAIR *vp, char const *src)
2229 {
2230 	uint8_t *q;
2231 
2232 	VERIFY_VP(vp);
2233 
2234 	memcpy(&q, &vp->vp_octets, sizeof(q));
2235 	talloc_free(q);
2236 
2237 	vp->vp_strvalue = talloc_steal(vp, src);
2238 	vp->type = VT_DATA;
2239 	vp->vp_length = talloc_array_length(vp->vp_strvalue) - 1;
2240 	fr_pair_value_set_type(vp);
2241 }
2242 
2243 /** Copy data into an "string" data type.
2244  *
2245  * @param[in,out] vp to update
2246  * @param[in] src data to copy
2247  */
fr_pair_value_strcpy(VALUE_PAIR * vp,char const * src)2248 void fr_pair_value_strcpy(VALUE_PAIR *vp, char const *src)
2249 {
2250 	char *p, *q;
2251 
2252 	VERIFY_VP(vp);
2253 
2254 	p = talloc_strdup(vp, src);
2255 
2256 	if (!p) return;
2257 
2258 	memcpy(&q, &vp->vp_strvalue, sizeof(q));
2259 	talloc_free(q);
2260 
2261 	vp->vp_strvalue = p;
2262 	vp->type = VT_DATA;
2263 	vp->vp_length = talloc_array_length(vp->vp_strvalue) - 1;
2264 	fr_pair_value_set_type(vp);
2265 }
2266 
2267 /** Copy data into an "string" data type.
2268  *
2269  * @note unlike the original strncpy, this function does not stop
2270  *	if it finds \0 bytes embedded in the string.
2271  *
2272  * @param[in,out] vp to update.
2273  * @param[in] src data to copy.
2274  * @param[in] len of data to copy.
2275  */
fr_pair_value_bstrncpy(VALUE_PAIR * vp,void const * src,size_t len)2276 void fr_pair_value_bstrncpy(VALUE_PAIR *vp, void const *src, size_t len)
2277 {
2278 	char *p, *q;
2279 
2280 	VERIFY_VP(vp);
2281 
2282 	p = talloc_array(vp, char, len + 1);
2283 	if (!p) return;
2284 
2285 	memcpy(p, src, len);	/* embdedded \0 safe */
2286 	p[len] = '\0';
2287 
2288 	memcpy(&q, &vp->vp_strvalue, sizeof(q));
2289 	talloc_free(q);
2290 
2291 	vp->vp_strvalue = p;
2292 	vp->type = VT_DATA;
2293 	vp->vp_length = len;
2294 	fr_pair_value_set_type(vp);
2295 }
2296 
2297 /** Print data into an "string" data type.
2298  *
2299  * @param[in,out] vp to update
2300  * @param[in] fmt the format string
2301  */
fr_pair_value_sprintf(VALUE_PAIR * vp,char const * fmt,...)2302 void fr_pair_value_sprintf(VALUE_PAIR *vp, char const *fmt, ...)
2303 {
2304 	va_list ap;
2305 	char *p, *q;
2306 
2307 	VERIFY_VP(vp);
2308 
2309 	va_start(ap, fmt);
2310 	p = talloc_vasprintf(vp, fmt, ap);
2311 	va_end(ap);
2312 
2313 	if (!p) return;
2314 
2315 	memcpy(&q, &vp->vp_strvalue, sizeof(q));
2316 	talloc_free(q);
2317 
2318 	vp->vp_strvalue = p;
2319 	vp->type = VT_DATA;
2320 
2321 	vp->vp_length = talloc_array_length(vp->vp_strvalue) - 1;
2322 	fr_pair_value_set_type(vp);
2323 }
2324 
2325 #ifdef WITH_VERIFY_PTR
2326 /*
2327  *	Verify a VALUE_PAIR
2328  */
fr_pair_verify(char const * file,int line,VALUE_PAIR const * vp)2329 inline void fr_pair_verify(char const *file, int line, VALUE_PAIR const *vp)
2330 {
2331 	if (!vp) {
2332 		FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: VALUE_PAIR pointer was NULL", file, line);
2333 		fr_assert(0);
2334 		fr_exit_now(1);
2335 	}
2336 
2337 	(void) talloc_get_type_abort(vp, VALUE_PAIR);
2338 
2339 	if (!vp->da) {
2340 		FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: VALUE_PAIR da pointer was NULL", file, line);
2341 		fr_assert(0);
2342 		fr_exit_now(1);
2343 	}
2344 
2345 	if (vp->data.ptr) switch (vp->da->type) {
2346 	case PW_TYPE_OCTETS:
2347 	{
2348 		size_t len;
2349 		TALLOC_CTX *parent;
2350 
2351 		if (!talloc_get_type(vp->data.ptr, uint8_t)) {
2352 			FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: VALUE_PAIR \"%s\" data buffer type should be "
2353 				     "uint8_t but is %s\n", file, line, vp->da->name, talloc_get_name(vp->data.ptr));
2354 			(void) talloc_get_type_abort(vp->data.ptr, uint8_t);
2355 		}
2356 
2357 		len = talloc_array_length(vp->vp_octets);
2358 		if (vp->vp_length > len) {
2359 			FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: VALUE_PAIR \"%s\" length %zu is greater than "
2360 				     "uint8_t data buffer length %zu\n", file, line, vp->da->name, vp->vp_length, len);
2361 			fr_assert(0);
2362 			fr_exit_now(1);
2363 		}
2364 
2365 		parent = talloc_parent(vp->data.ptr);
2366 		if (parent != vp) {
2367 			FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: VALUE_PAIR \"%s\" char buffer is not "
2368 				     "parented by VALUE_PAIR %p, instead parented by %p (%s)\n",
2369 				     file, line, vp->da->name,
2370 				     vp, parent, parent ? talloc_get_name(parent) : "NULL");
2371 			fr_assert(0);
2372 			fr_exit_now(1);
2373 		}
2374 	}
2375 		break;
2376 
2377 	case PW_TYPE_STRING:
2378 	{
2379 		size_t len;
2380 		TALLOC_CTX *parent;
2381 
2382 		if (!talloc_get_type(vp->data.ptr, char)) {
2383 			FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: VALUE_PAIR \"%s\" data buffer type should be "
2384 				     "char but is %s\n", file, line, vp->da->name, talloc_get_name(vp->data.ptr));
2385 			(void) talloc_get_type_abort(vp->data.ptr, char);
2386 		}
2387 
2388 		len = (talloc_array_length(vp->vp_strvalue) - 1);
2389 		if (vp->vp_length > len) {
2390 			FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: VALUE_PAIR \"%s\" length %zu is greater than "
2391 				     "char buffer length %zu\n", file, line, vp->da->name, vp->vp_length, len);
2392 			fr_assert(0);
2393 			fr_exit_now(1);
2394 		}
2395 
2396 		if (vp->vp_strvalue[vp->vp_length] != '\0') {
2397 			FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: VALUE_PAIR \"%s\" char buffer not \\0 "
2398 				     "terminated\n", file, line, vp->da->name);
2399 			fr_assert(0);
2400 			fr_exit_now(1);
2401 		}
2402 
2403 		parent = talloc_parent(vp->data.ptr);
2404 		if (parent != vp) {
2405 			FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: VALUE_PAIR \"%s\" char buffer is not "
2406 				     "parented by VALUE_PAIR %p, instead parented by %p (%s)\n",
2407 				     file, line, vp->da->name,
2408 				     vp, parent, parent ? talloc_get_name(parent) : "NULL");
2409 			fr_assert(0);
2410 			fr_exit_now(1);
2411 		}
2412 	}
2413 		break;
2414 
2415 	default:
2416 		break;
2417 	}
2418 
2419 	if (vp->da->flags.is_unknown) {
2420 		(void) talloc_get_type_abort(vp->da, DICT_ATTR);
2421 	} else {
2422 		DICT_ATTR const *da;
2423 
2424 		/*
2425 		 *	Attribute may be present with multiple names
2426 		 */
2427 		da = dict_attrbyname(vp->da->name);
2428 		if (!da) {
2429 			FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: VALUE_PAIR attribute %p \"%s\" (%s) "
2430 				     "not found in global dictionary",
2431 				     file, line, vp->da, vp->da->name,
2432 				     fr_int2str(dict_attr_types, vp->da->type, "<INVALID>"));
2433 			fr_assert(0);
2434 			fr_exit_now(1);
2435 		}
2436 
2437 		if (da->type == PW_TYPE_COMBO_IP_ADDR) {
2438 			da = dict_attrbytype(vp->da->attr, vp->da->vendor, vp->da->type);
2439 			if (!da) {
2440 				FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: VALUE_PAIR attribute %p \"%s\" "
2441 					     "variant (%s) not found in global dictionary",
2442 					     file, line, vp->da, vp->da->name,
2443 					     fr_int2str(dict_attr_types, vp->da->type, "<INVALID>"));
2444 				fr_assert(0);
2445 				fr_exit_now(1);
2446 			}
2447 		}
2448 
2449 
2450 		if (da != vp->da) {
2451 			FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: VALUE_PAIR "
2452 				     "dictionary pointer %p \"%s\" (%s) "
2453 				     "and global dictionary pointer %p \"%s\" (%s) differ",
2454 				     file, line, vp->da, vp->da->name,
2455 				     fr_int2str(dict_attr_types, vp->da->type, "<INVALID>"),
2456 				     da, da->name, fr_int2str(dict_attr_types, da->type, "<INVALID>"));
2457 			fr_assert(0);
2458 			fr_exit_now(1);
2459 		}
2460 	}
2461 }
2462 
2463 /*
2464  *	Verify a pair list
2465  */
fr_pair_list_verify(char const * file,int line,TALLOC_CTX * expected,VALUE_PAIR * vps,char const * name)2466 void fr_pair_list_verify(char const *file, int line, TALLOC_CTX *expected, VALUE_PAIR *vps, char const *name)
2467 {
2468 	vp_cursor_t cursor;
2469 	VALUE_PAIR *vp;
2470 	TALLOC_CTX *parent;
2471 
2472 	for (vp = fr_cursor_init(&cursor, &vps);
2473 	     vp;
2474 	     vp = fr_cursor_next(&cursor)) {
2475 		VERIFY_VP(vp);
2476 
2477 		parent = talloc_parent(vp);
2478 		if (expected && (parent != expected)) {
2479 			FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: Expected VALUE_PAIR \"%s\" to be parented "
2480 				     "by %p (%s) name %s, instead parented by %p (%s)\n",
2481 				     file, line, vp->da->name,
2482 				     expected, talloc_get_name(expected), name,
2483 				     parent, parent ? talloc_get_name(parent) : "NULL");
2484 
2485 			fr_log_talloc_report(expected);
2486 			if (parent) fr_log_talloc_report(parent);
2487 
2488 			fr_assert(0);
2489 			fr_exit_now(1);
2490 		}
2491 
2492 	}
2493 }
2494 #endif
2495