Merge pull request #983 from michael-mri/v3.0.x
[freeradius.git] / src / main / xlat.c
1 /*
2  *   This program is free software; you can redistribute it and/or modify
3  *   it under the terms of the GNU General Public License as published by
4  *   the Free Software Foundation; either version 2 of the License, or
5  *   (at your option) any later version.
6  *
7  *   This program is distributed in the hope that it will be useful,
8  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *   GNU General Public License for more details.
11  *
12  *   You should have received a copy of the GNU General Public License
13  *   along with this program; if not, write to the Free Software
14  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16
17 /**
18  * $Id$
19  *
20  * @file xlat.c
21  * @brief String expansion ("translation"). Implements %Attribute -> value
22  *
23  * @copyright 2000,2006  The FreeRADIUS server project
24  * @copyright 2000  Alan DeKok <aland@ox.org>
25  */
26
27 RCSID("$Id$")
28
29 #include <freeradius-devel/radiusd.h>
30 #include <freeradius-devel/parser.h>
31 #include <freeradius-devel/rad_assert.h>
32 #include <freeradius-devel/base64.h>
33
34 #include <ctype.h>
35
36 typedef struct xlat_t {
37         char                    name[MAX_STRING_LEN];   //!< Name of the xlat expansion.
38         int                     length;                 //!< Length of name.
39         void                    *instance;              //!< Module instance passed to xlat and escape functions.
40         xlat_func_t             func;                   //!< xlat function.
41         xlat_escape_t   escape;                 //!< Escape function to apply to dynamic input to func.
42         bool                    internal;               //!< If true, cannot be redefined.
43 } xlat_t;
44
45 typedef enum {
46         XLAT_LITERAL,           //!< Literal string
47         XLAT_PERCENT,           //!< Literal string with %v
48         XLAT_MODULE,            //!< xlat module
49         XLAT_VIRTUAL,           //!< virtual attribute
50         XLAT_ATTRIBUTE,         //!< xlat attribute
51 #ifdef HAVE_REGEX
52         XLAT_REGEX,             //!< regex reference
53 #endif
54         XLAT_ALTERNATE          //!< xlat conditional syntax :-
55 } xlat_state_t;
56
57 struct xlat_exp {
58         char const *fmt;        //!< The format string.
59         size_t len;             //!< Length of the format string.
60
61         xlat_state_t type;      //!< type of this expansion.
62         xlat_exp_t *next;       //!< Next in the list.
63
64         xlat_exp_t *child;      //!< Nested expansion.
65         xlat_exp_t *alternate;  //!< Alternative expansion if this one expanded to a zero length string.
66
67         vp_tmpl_t attr; //!< An attribute template.
68         xlat_t const *xlat;     //!< The xlat expansion to expand format with.
69 };
70
71 typedef struct xlat_out {
72         char const *out;        //!< Output data.
73         size_t len;             //!< Length of the output string.
74 } xlat_out_t;
75
76 static rbtree_t *xlat_root = NULL;
77
78 #ifdef WITH_UNLANG
79 static char const * const xlat_foreach_names[] = {"Foreach-Variable-0",
80                                                   "Foreach-Variable-1",
81                                                   "Foreach-Variable-2",
82                                                   "Foreach-Variable-3",
83                                                   "Foreach-Variable-4",
84                                                   "Foreach-Variable-5",
85                                                   "Foreach-Variable-6",
86                                                   "Foreach-Variable-7",
87                                                   "Foreach-Variable-8",
88                                                   "Foreach-Variable-9",
89                                                   NULL};
90 #endif
91
92
93 static int xlat_inst[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };      /* up to 10 for foreach */
94
95 /** Print length of its RHS.
96  *
97  */
98 static ssize_t xlat_strlen(UNUSED void *instance, UNUSED REQUEST *request,
99                            char const *fmt, char *out, size_t outlen)
100 {
101         snprintf(out, outlen, "%u", (unsigned int) strlen(fmt));
102         return strlen(out);
103 }
104
105 /** Print the size of the attribute in bytes.
106  *
107  */
108 static ssize_t xlat_length(UNUSED void *instance, REQUEST *request,
109                            char const *fmt, char *out, size_t outlen)
110 {
111         VALUE_PAIR *vp;
112         while (isspace((int) *fmt)) fmt++;
113
114         if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) {
115                 *out = '\0';
116                 return 0;
117         }
118
119         snprintf(out, outlen, "%zu", vp->vp_length);
120         return strlen(out);
121 }
122
123 /** Print data as integer, not as VALUE.
124  *
125  */
126 static ssize_t xlat_integer(UNUSED void *instance, REQUEST *request,
127                             char const *fmt, char *out, size_t outlen)
128 {
129         VALUE_PAIR      *vp;
130
131         uint64_t        int64 = 0;      /* Needs to be initialised to zero */
132         uint32_t        int32 = 0;      /* Needs to be initialised to zero */
133
134         while (isspace((int) *fmt)) fmt++;
135
136         if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) {
137                 *out = '\0';
138                 return 0;
139         }
140
141         switch (vp->da->type) {
142         case PW_TYPE_OCTETS:
143         case PW_TYPE_STRING:
144                 if (vp->vp_length > 8) {
145                         break;
146                 }
147
148                 if (vp->vp_length > 4) {
149                         memcpy(&int64, vp->vp_octets, vp->vp_length);
150                         return snprintf(out, outlen, "%" PRIu64, htonll(int64));
151                 }
152
153                 memcpy(&int32, vp->vp_octets, vp->vp_length);
154                 return snprintf(out, outlen, "%i", htonl(int32));
155
156         case PW_TYPE_INTEGER64:
157                 return snprintf(out, outlen, "%" PRIu64, vp->vp_integer64);
158
159         /*
160          *      IP addresses are treated specially, as parsing functions assume the value
161          *      is bigendian and will convert it for us.
162          */
163         case PW_TYPE_IPV4_ADDR:
164                 return snprintf(out, outlen, "%u", htonl(vp->vp_ipaddr));
165
166         case PW_TYPE_IPV4_PREFIX:
167                 return snprintf(out, outlen, "%u", htonl((*(uint32_t *)(vp->vp_ipv4prefix + 2))));
168
169         case PW_TYPE_INTEGER:
170         case PW_TYPE_DATE:
171                 return snprintf(out, outlen, "%u", vp->vp_integer);
172         case PW_TYPE_BYTE:
173                 return snprintf(out, outlen, "%u", (unsigned int) vp->vp_byte);
174         case PW_TYPE_SHORT:
175                 return snprintf(out, outlen, "%u", (unsigned int) vp->vp_short);
176
177         /*
178          *      Ethernet is weird... It's network related, so we assume to it should be
179          *      bigendian.
180          */
181         case PW_TYPE_ETHERNET:
182                 memcpy(&int64, vp->vp_ether, vp->vp_length);
183                 return snprintf(out, outlen, "%" PRIu64, htonll(int64));
184
185         case PW_TYPE_SIGNED:
186                 return snprintf(out, outlen, "%i", vp->vp_signed);
187
188         case PW_TYPE_IPV6_ADDR:
189                 return fr_prints_uint128(out, outlen, ntohlll(*(uint128_t const *) &vp->vp_ipv6addr));
190
191         case PW_TYPE_IPV6_PREFIX:
192                 return fr_prints_uint128(out, outlen, ntohlll(*(uint128_t const *) &vp->vp_ipv6prefix[2]));
193
194         default:
195                 break;
196         }
197
198         REDEBUG("Type '%s' of length %zu cannot be converted to integer",
199                 fr_int2str(dict_attr_types, vp->da->type, "???"), vp->vp_length);
200         *out = '\0';
201
202         return -1;
203 }
204
205 /** Print data as hex, not as VALUE.
206  *
207  */
208 static ssize_t xlat_hex(UNUSED void *instance, REQUEST *request,
209                         char const *fmt, char *out, size_t outlen)
210 {
211         size_t i;
212         VALUE_PAIR *vp;
213         uint8_t const *p;
214         ssize_t ret;
215         size_t  len;
216         value_data_t dst;
217         uint8_t const *buff = NULL;
218
219         while (isspace((int) *fmt)) fmt++;
220
221         if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) {
222         error:
223                 *out = '\0';
224                 return -1;
225         }
226
227         /*
228          *      The easy case.
229          */
230         if (vp->da->type == PW_TYPE_OCTETS) {
231                 p = vp->vp_octets;
232                 len = vp->vp_length;
233         /*
234          *      Cast the value_data_t of the VP to an octets string and
235          *      print that as hex.
236          */
237         } else {
238                 ret = value_data_cast(request, &dst, PW_TYPE_OCTETS, NULL, vp->da->type,
239                                       NULL, &vp->data, vp->vp_length);
240                 if (ret < 0) {
241                         REDEBUG("%s", fr_strerror());
242                         goto error;
243                 }
244                 len = (size_t) ret;
245                 p = buff = dst.octets;
246         }
247
248         rad_assert(p);
249
250         /*
251          *      Don't truncate the data.
252          */
253         if (outlen < (len * 2)) {
254                 rad_const_free(buff);
255                 goto error;
256         }
257
258         for (i = 0; i < len; i++) {
259                 snprintf(out + 2*i, 3, "%02x", p[i]);
260         }
261         rad_const_free(buff);
262
263         return len * 2;
264 }
265
266 /** Return the tag of an attribute reference
267  *
268  */
269 static ssize_t xlat_tag(UNUSED void *instance, REQUEST *request,
270                         char const *fmt, char *out, size_t outlen)
271 {
272         VALUE_PAIR *vp;
273
274         while (isspace((int) *fmt)) fmt++;
275
276         if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) {
277                 *out = '\0';
278                 return 0;
279         }
280
281         if (!vp->da->flags.has_tag || !TAG_VALID(vp->tag)) {
282                 *out = '\0';
283                 return 0;
284         }
285
286         return snprintf(out, outlen, "%u", vp->tag);
287 }
288
289 /** Return the vendor of an attribute reference
290  *
291  */
292 static ssize_t xlat_vendor(UNUSED void *instance, REQUEST *request,
293                            char const *fmt, char *out, size_t outlen)
294 {
295         VALUE_PAIR *vp;
296         DICT_VENDOR *vendor;
297
298         while (isspace((int) *fmt)) fmt++;
299
300         if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) {
301                 *out = '\0';
302                 return 0;
303         }
304
305         vendor = dict_vendorbyvalue(vp->da->vendor);
306         if (!vendor) {
307                 *out = '\0';
308                 return 0;
309         }
310         strlcpy(out, vendor->name, outlen);
311
312         return vendor->length;
313 }
314
315 /** Return the vendor number of an attribute reference
316  *
317  */
318 static ssize_t xlat_vendor_num(UNUSED void *instance, REQUEST *request,
319                                char const *fmt, char *out, size_t outlen)
320 {
321         VALUE_PAIR *vp;
322
323         while (isspace((int) *fmt)) fmt++;
324
325         if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) {
326                 *out = '\0';
327                 return 0;
328         }
329
330         return snprintf(out, outlen, "%u", vp->da->vendor);
331 }
332
333 /** Return the attribute name of an attribute reference
334  *
335  */
336 static ssize_t xlat_attr(UNUSED void *instance, REQUEST *request,
337                          char const *fmt, char *out, size_t outlen)
338 {
339         VALUE_PAIR *vp;
340
341         while (isspace((int) *fmt)) fmt++;
342
343         if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) {
344                 *out = '\0';
345                 return 0;
346         }
347         strlcpy(out, vp->da->name, outlen);
348
349         return strlen(vp->da->name);
350 }
351
352 /** Return the attribute number of an attribute reference
353  *
354  */
355 static ssize_t xlat_attr_num(UNUSED void *instance, REQUEST *request,
356                              char const *fmt, char *out, size_t outlen)
357 {
358         VALUE_PAIR *vp;
359
360         while (isspace((int) *fmt)) fmt++;
361
362         if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) {
363                 *out = '\0';
364                 return 0;
365         }
366
367         return snprintf(out, outlen, "%u", vp->da->attr);
368 }
369
370 /** Print out attribute info
371  *
372  * Prints out all instances of a current attribute, or all attributes in a list.
373  *
374  * At higher debugging levels, also prints out alternative decodings of the same
375  * value. This is helpful to determine types for unknown attributes of long
376  * passed vendors, or just crazy/broken NAS.
377  *
378  * This expands to a zero length string.
379  */
380 static ssize_t xlat_debug_attr(UNUSED void *instance, REQUEST *request, char const *fmt,
381                                char *out, UNUSED size_t outlen)
382 {
383         VALUE_PAIR *vp;
384         vp_cursor_t cursor;
385
386         vp_tmpl_t vpt;
387
388         if (!RDEBUG_ENABLED2) {
389                 *out = '\0';
390                 return -1;
391         }
392
393         while (isspace((int) *fmt)) fmt++;
394
395         if (tmpl_from_attr_str(&vpt, fmt, REQUEST_CURRENT, PAIR_LIST_REQUEST, false, false) <= 0) {
396                 RDEBUG("%s", fr_strerror());
397                 return -1;
398         }
399
400         RIDEBUG("Attributes matching \"%s\"", fmt);
401
402         RINDENT();
403         for (vp = tmpl_cursor_init(NULL, &cursor, request, &vpt);
404              vp;
405              vp = tmpl_cursor_next(&cursor, &vpt)) {
406                 FR_NAME_NUMBER const *type;
407                 char *value;
408
409                 value = vp_aprints_value(vp, vp, '\'');
410                 if (vp->da->flags.has_tag) {
411                         RIDEBUG2("&%s:%s:%i %s %s",
412                                 fr_int2str(pair_lists, vpt.tmpl_list, "<INVALID>"),
413                                 vp->da->name,
414                                 vp->tag,
415                                 fr_int2str(fr_tokens, vp->op, "<INVALID>"),
416                                 value);
417                 } else {
418                         RIDEBUG2("&%s:%s %s %s",
419                                 fr_int2str(pair_lists, vpt.tmpl_list, "<INVALID>"),
420                                 vp->da->name,
421                                 fr_int2str(fr_tokens, vp->op, "<INVALID>"),
422                                 value);
423                 }
424                 talloc_free(value);
425
426                 if (!RDEBUG_ENABLED3) continue;
427
428                 if (vp->da->vendor) {
429                         DICT_VENDOR *dv;
430
431                         dv = dict_vendorbyvalue(vp->da->vendor);
432                         RIDEBUG2("Vendor : %i (%s)", vp->da->vendor, dv ? dv->name : "unknown");
433                 }
434                 RIDEBUG2("Type   : %s", fr_int2str(dict_attr_types, vp->da->type, "<INVALID>"));
435                 RIDEBUG2("Length : %zu", vp->vp_length);
436
437                 if (!RDEBUG_ENABLED4) continue;
438
439                 type = dict_attr_types;
440                 while (type->name) {
441                         int pad;
442
443                         value_data_t *dst = NULL;
444
445                         ssize_t ret;
446
447                         if ((PW_TYPE) type->number == vp->da->type) {
448                                 goto next_type;
449                         }
450
451                         switch (type->number) {
452                         case PW_TYPE_INVALID:           /* Not real type */
453                         case PW_TYPE_MAX:               /* Not real type */
454                         case PW_TYPE_EXTENDED:          /* Not safe/appropriate */
455                         case PW_TYPE_LONG_EXTENDED:     /* Not safe/appropriate */
456                         case PW_TYPE_TLV:               /* Not safe/appropriate */
457                         case PW_TYPE_EVS:               /* Not safe/appropriate */
458                         case PW_TYPE_VSA:               /* @fixme We need special behaviour for these */
459                         case PW_TYPE_COMBO_IP_ADDR:     /* Covered by IPv4 address IPv6 address */
460                         case PW_TYPE_COMBO_IP_PREFIX:   /* Covered by IPv4 address IPv6 address */
461                         case PW_TYPE_TIMEVAL:           /* Not a VALUE_PAIR type */
462                                 goto next_type;
463
464                         default:
465                                 break;
466                         }
467
468                         dst = talloc_zero(vp, value_data_t);
469                         ret = value_data_cast(dst, dst, type->number, NULL, vp->da->type, vp->da,
470                                               &vp->data, vp->vp_length);
471                         if (ret < 0) goto next_type;    /* We expect some to fail */
472
473                         value = value_data_aprints(dst, type->number, NULL, dst, (size_t)ret, '\'');
474                         if (!value) goto next_type;
475
476                         if ((pad = (11 - strlen(type->name))) < 0) {
477                                 pad = 0;
478                         }
479
480                         RINDENT();
481                         RDEBUG2("as %s%*s: %s", type->name, pad, " ", value);
482                         REXDENT();
483
484                 next_type:
485                         talloc_free(dst);
486                         type++;
487                 }
488         }
489
490         *out = '\0';
491         return 0;
492 }
493
494 /** Processes fmt as a map string and applies it to the current request
495  *
496  * e.g. "%{map:&User-Name := 'foo'}"
497  *
498  * Allows sets of modifications to be cached and then applied.
499  * Useful for processing generic attributes from LDAP.
500  */
501 static ssize_t xlat_map(UNUSED void *instance, REQUEST *request,
502                         char const *fmt, char *out, size_t outlen)
503 {
504         vp_map_t *map = NULL;
505         int ret;
506
507         if (map_afrom_attr_str(request, &map, fmt,
508                                REQUEST_CURRENT, PAIR_LIST_REQUEST,
509                                REQUEST_CURRENT, PAIR_LIST_REQUEST) < 0) {
510                 REDEBUG("Failed parsing \"%s\" as map: %s", fmt, fr_strerror());
511                 return -1;
512         }
513
514         RINDENT();
515         ret = map_to_request(request, map, map_to_vp, NULL);
516         REXDENT();
517         talloc_free(map);
518         if (ret < 0) return strlcpy(out, "0", outlen);
519
520         return strlcpy(out, "1", outlen);
521 }
522
523 /** Prints the current module processing the request
524  *
525  */
526 static ssize_t xlat_module(UNUSED void *instance, REQUEST *request,
527                            UNUSED char const *fmt, char *out, size_t outlen)
528 {
529         strlcpy(out, request->module, outlen);
530
531         return strlen(out);
532 }
533
534 #if defined(HAVE_REGEX) && defined(HAVE_PCRE)
535 static ssize_t xlat_regex(UNUSED void *instance, REQUEST *request,
536                           char const *fmt, char *out, size_t outlen)
537 {
538         char *p;
539         size_t len;
540
541         if (regex_request_to_sub_named(request, &p, request, fmt) < 0) {
542                 *out = '\0';
543                 return 0;
544         }
545
546         len = talloc_array_length(p);
547         if (len > outlen) {
548                 RDEBUG("Insufficient buffer space to write subcapture value, needed %zu bytes, have %zu bytes",
549                        len, outlen);
550                 return -1;
551         }
552         strlcpy(out, p, outlen);
553
554         return len - 1; /* - \0 */
555 }
556 #endif
557
558 #ifdef WITH_UNLANG
559 /** Implements the Foreach-Variable-X
560  *
561  * @see modcall()
562  */
563 static ssize_t xlat_foreach(void *instance, REQUEST *request,
564                             UNUSED char const *fmt, char *out, size_t outlen)
565 {
566         VALUE_PAIR      **pvp;
567         size_t          len;
568
569         /*
570          *      See modcall, "FOREACH" for how this works.
571          */
572         pvp = (VALUE_PAIR **) request_data_reference(request, (void *)radius_get_vp, *(int*) instance);
573         if (!pvp || !*pvp) {
574                 *out = '\0';
575                 return 0;
576         }
577
578         len = vp_prints_value(out, outlen, *pvp, 0);
579         if (is_truncated(len, outlen)) {
580                 RDEBUG("Insufficient buffer space to write foreach value");
581                 return -1;
582         }
583
584         return len;
585 }
586 #endif
587
588 /** Print data as string, if possible.
589  *
590  * If attribute "Foo" is defined as "octets" it will normally
591  * be printed as 0x0a0a0a. The xlat "%{string:Foo}" will instead
592  * expand to "\n\n\n"
593  */
594 static ssize_t xlat_string(UNUSED void *instance, REQUEST *request,
595                            char const *fmt, char *out, size_t outlen)
596 {
597         size_t len;
598         ssize_t ret;
599         VALUE_PAIR *vp;
600         uint8_t const *p;
601
602         while (isspace((int) *fmt)) fmt++;
603
604         if (outlen < 3) {
605         nothing:
606                 *out = '\0';
607                 return 0;
608         }
609
610         if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) goto nothing;
611
612         ret = rad_vp2data(&p, vp);
613         if (ret < 0) {
614                 return ret;
615         }
616
617         switch (vp->da->type) {
618         case PW_TYPE_OCTETS:
619                 len = fr_prints(out, outlen, (char const *) p, vp->vp_length, '"');
620                 break;
621
622         case PW_TYPE_STRING:
623                 len = strlcpy(out, vp->vp_strvalue, outlen);
624                 break;
625
626         default:
627                 len = fr_prints(out, outlen, (char const *) p, ret, '\0');
628                 break;
629         }
630
631         return len;
632 }
633
634 /** xlat expand string attribute value
635  *
636  */
637 static ssize_t xlat_xlat(UNUSED void *instance, REQUEST *request,
638                         char const *fmt, char *out, size_t outlen)
639 {
640         VALUE_PAIR *vp;
641
642         while (isspace((int) *fmt)) fmt++;
643
644         if (outlen < 3) {
645         nothing:
646                 *out = '\0';
647                 return 0;
648         }
649
650         if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) goto nothing;
651
652         return radius_xlat(out, outlen, request, vp->vp_strvalue, NULL, NULL);
653 }
654
655 /** Dynamically change the debugging level for the current request
656  *
657  * Example %{debug:3}
658  */
659 static ssize_t xlat_debug(UNUSED void *instance, REQUEST *request,
660                           char const *fmt, char *out, size_t outlen)
661 {
662         int level = 0;
663
664         /*
665          *  Expand to previous (or current) level
666          */
667         snprintf(out, outlen, "%d", request->log.lvl);
668
669         /*
670          *  Assume we just want to get the current value and NOT set it to 0
671          */
672         if (!*fmt)
673                 goto done;
674
675         level = atoi(fmt);
676         if (level == 0) {
677                 request->log.lvl = RAD_REQUEST_LVL_NONE;
678                 request->log.func = NULL;
679         } else {
680                 if (level > 4) level = 4;
681
682                 request->log.lvl = level;
683                 request->log.func = vradlog_request;
684         }
685
686         done:
687         return strlen(out);
688 }
689
690 /*
691  *      Compare two xlat_t structs, based ONLY on the module name.
692  */
693 static int xlat_cmp(void const *one, void const *two)
694 {
695         xlat_t const *a = one;
696         xlat_t const *b = two;
697
698         if (a->length != b->length) {
699                 return a->length - b->length;
700         }
701
702         return memcmp(a->name, b->name, a->length);
703 }
704
705
706 /*
707  *      find the appropriate registered xlat function.
708  */
709 static xlat_t *xlat_find(char const *name)
710 {
711         xlat_t my_xlat;
712
713         strlcpy(my_xlat.name, name, sizeof(my_xlat.name));
714         my_xlat.length = strlen(my_xlat.name);
715
716         return rbtree_finddata(xlat_root, &my_xlat);
717 }
718
719
720 /** Register an xlat function.
721  *
722  * @param[in] name xlat name.
723  * @param[in] func xlat function to be called.
724  * @param[in] escape function to sanitize any sub expansions passed to the xlat function.
725  * @param[in] instance of module that's registering the xlat function.
726  * @return 0 on success, -1 on failure
727  */
728 int xlat_register(char const *name, xlat_func_t func, xlat_escape_t escape, void *instance)
729 {
730         xlat_t  *c;
731         xlat_t  my_xlat;
732         rbnode_t *node;
733
734         if (!name || !*name) {
735                 DEBUG("xlat_register: Invalid xlat name");
736                 return -1;
737         }
738
739         /*
740          *      First time around, build up the tree...
741          *
742          *      FIXME: This code should be hoisted out of this function,
743          *      and into a global "initialization".  But it isn't critical...
744          */
745         if (!xlat_root) {
746 #ifdef WITH_UNLANG
747                 int i;
748 #endif
749
750                 xlat_root = rbtree_create(NULL, xlat_cmp, NULL, RBTREE_FLAG_REPLACE);
751                 if (!xlat_root) {
752                         DEBUG("xlat_register: Failed to create tree");
753                         return -1;
754                 }
755
756 #ifdef WITH_UNLANG
757                 for (i = 0; xlat_foreach_names[i] != NULL; i++) {
758                         xlat_register(xlat_foreach_names[i],
759                                       xlat_foreach, NULL, &xlat_inst[i]);
760                         c = xlat_find(xlat_foreach_names[i]);
761                         rad_assert(c != NULL);
762                         c->internal = true;
763                 }
764 #endif
765
766 #define XLAT_REGISTER(_x) xlat_register(STRINGIFY(_x), xlat_ ## _x, NULL, NULL); \
767                 c = xlat_find(STRINGIFY(_x)); \
768                 rad_assert(c != NULL); \
769                 c->internal = true
770
771                 XLAT_REGISTER(integer);
772                 XLAT_REGISTER(strlen);
773                 XLAT_REGISTER(length);
774                 XLAT_REGISTER(hex);
775                 XLAT_REGISTER(tag);
776                 XLAT_REGISTER(vendor);
777                 XLAT_REGISTER(vendor_num);
778                 XLAT_REGISTER(attr);
779                 XLAT_REGISTER(attr_num);
780                 XLAT_REGISTER(string);
781                 XLAT_REGISTER(xlat);
782                 XLAT_REGISTER(map);
783                 XLAT_REGISTER(module);
784                 XLAT_REGISTER(debug_attr);
785 #if defined(HAVE_REGEX) && defined(HAVE_PCRE)
786                 XLAT_REGISTER(regex);
787 #endif
788
789                 xlat_register("debug", xlat_debug, NULL, &xlat_inst[0]);
790                 c = xlat_find("debug");
791                 rad_assert(c != NULL);
792                 c->internal = true;
793         }
794
795         /*
796          *      If it already exists, replace the instance.
797          */
798         strlcpy(my_xlat.name, name, sizeof(my_xlat.name));
799         my_xlat.length = strlen(my_xlat.name);
800         c = rbtree_finddata(xlat_root, &my_xlat);
801         if (c) {
802                 if (c->internal) {
803                         DEBUG("xlat_register: Cannot re-define internal xlat");
804                         return -1;
805                 }
806
807                 c->func = func;
808                 c->escape = escape;
809                 c->instance = instance;
810                 return 0;
811         }
812
813         /*
814          *      Doesn't exist.  Create it.
815          */
816         c = talloc_zero(xlat_root, xlat_t);
817
818         c->func = func;
819         c->escape = escape;
820         strlcpy(c->name, name, sizeof(c->name));
821         c->length = strlen(c->name);
822         c->instance = instance;
823
824         node = rbtree_insert_node(xlat_root, c);
825         if (!node) {
826                 talloc_free(c);
827                 return -1;
828         }
829
830         /*
831          *      Ensure that the data is deleted when the node is
832          *      deleted.
833          *
834          *      @todo: Maybe this should be the other way around...
835          *      when a thing IN the tree is deleted, it's automatically
836          *      removed from the tree.  But for now, this works.
837          */
838         (void) talloc_steal(node, c);
839         return 0;
840 }
841
842 /** Unregister an xlat function
843  *
844  * We can only have one function to call per name, so the passing of "func"
845  * here is extraneous.
846  *
847  * @param[in] name xlat to unregister.
848  * @param[in] func unused.
849  * @param[in] instance data.
850  */
851 void xlat_unregister(char const *name, UNUSED xlat_func_t func, void *instance)
852 {
853         xlat_t  *c;
854         xlat_t          my_xlat;
855
856         if (!name || !xlat_root) return;
857
858         strlcpy(my_xlat.name, name, sizeof(my_xlat.name));
859         my_xlat.length = strlen(my_xlat.name);
860
861         c = rbtree_finddata(xlat_root, &my_xlat);
862         if (!c) return;
863
864         if (c->instance != instance) return;
865
866         rbtree_deletebydata(xlat_root, c);
867 }
868
869 static int xlat_unregister_callback(void *instance, void *data)
870 {
871         xlat_t *c = (xlat_t *) data;
872
873         if (c->instance != instance) return 0; /* keep walking */
874
875         return 2;               /* delete it */
876 }
877
878 void xlat_unregister_module(void *instance)
879 {
880         rbtree_walk(xlat_root, RBTREE_DELETE_ORDER, xlat_unregister_callback, instance);
881 }
882
883 /*
884  *      Internal redundant handler for xlats
885  */
886 typedef enum xlat_redundant_type_t {
887         XLAT_INVALID = 0,
888         XLAT_REDUNDANT,
889         XLAT_LOAD_BALANCE,
890         XLAT_REDUNDANT_LOAD_BALANCE,
891 } xlat_redundant_type_t;
892
893 typedef struct xlat_redundant_t {
894         xlat_redundant_type_t type;
895         uint32_t        count;
896         CONF_SECTION *cs;
897 } xlat_redundant_t;
898
899
900 static ssize_t xlat_redundant(void *instance, REQUEST *request,
901                               char const *fmt, char *out, size_t outlen)
902 {
903         xlat_redundant_t *xr = instance;
904         CONF_ITEM *ci;
905         char const *name;
906         xlat_t *xlat;
907
908         rad_assert(xr->type == XLAT_REDUNDANT);
909
910         /*
911          *      Pick the first xlat which succeeds
912          */
913         for (ci = cf_item_find_next(xr->cs, NULL);
914              ci != NULL;
915              ci = cf_item_find_next(xr->cs, ci)) {
916                 ssize_t rcode;
917
918                 if (!cf_item_is_pair(ci)) continue;
919
920                 name = cf_pair_attr(cf_item_to_pair(ci));
921                 rad_assert(name != NULL);
922
923                 xlat = xlat_find(name);
924                 if (!xlat) continue;
925
926                 rcode = xlat->func(xlat->instance, request, fmt, out, outlen);
927                 if (rcode <= 0) continue;
928                 return rcode;
929         }
930
931         /*
932          *      Everything failed.  Oh well.
933          */
934         *out  = 0;
935         return 0;
936 }
937
938
939 static ssize_t xlat_load_balance(void *instance, REQUEST *request,
940                               char const *fmt, char *out, size_t outlen)
941 {
942         uint32_t count = 0;
943         xlat_redundant_t *xr = instance;
944         CONF_ITEM *ci;
945         CONF_ITEM *found = NULL;
946         char const *name;
947         xlat_t *xlat;
948
949         /*
950          *      Choose a child at random.
951          */
952         for (ci = cf_item_find_next(xr->cs, NULL);
953              ci != NULL;
954              ci = cf_item_find_next(xr->cs, ci)) {
955                 if (!cf_item_is_pair(ci)) continue;
956                 count++;
957
958                 /*
959                  *      Replace the previously found one with a random
960                  *      new one.
961                  */
962                 if ((count * (fr_rand() & 0xffff)) < (uint32_t) 0x10000) {
963                         found = ci;
964                 }
965         }
966
967         /*
968          *      Plain load balancing: do one child, and only one child.
969          */
970         if (xr->type == XLAT_LOAD_BALANCE) {
971                 name = cf_pair_attr(cf_item_to_pair(found));
972                 rad_assert(name != NULL);
973
974                 xlat = xlat_find(name);
975                 if (!xlat) return -1;
976
977                 return xlat->func(xlat->instance, request, fmt, out, outlen);
978         }
979
980         rad_assert(xr->type == XLAT_REDUNDANT_LOAD_BALANCE);
981
982         /*
983          *      Try the random one we found.  If it fails, keep going
984          *      through the rest of the children.
985          */
986         ci = found;
987         do {
988                 name = cf_pair_attr(cf_item_to_pair(ci));
989                 rad_assert(name != NULL);
990
991                 xlat = xlat_find(name);
992                 if (xlat) {
993                         ssize_t rcode;
994
995                         rcode = xlat->func(xlat->instance, request, fmt, out, outlen);
996                         if (rcode > 0) return rcode;
997                 }
998
999                 /*
1000                  *      Go to the next one, wrapping around at the end.
1001                  */
1002                 ci = cf_item_find_next(xr->cs, ci);
1003                 if (!ci) ci = cf_item_find_next(xr->cs, NULL);
1004         } while (ci != found);
1005
1006         return -1;
1007 }
1008
1009
1010 bool xlat_register_redundant(CONF_SECTION *cs)
1011 {
1012         char const *name1, *name2;
1013         xlat_redundant_t *xr;
1014
1015         name1 = cf_section_name1(cs);
1016         name2 = cf_section_name2(cs);
1017
1018         if (!name2) return false;
1019
1020         if (xlat_find(name2)) {
1021                 cf_log_err_cs(cs, "An expansion is already registered for this name");
1022                 return false;
1023         }
1024
1025         xr = talloc_zero(cs, xlat_redundant_t);
1026         if (!xr) return false;
1027
1028         if (strcmp(name1, "redundant") == 0) {
1029                 xr->type = XLAT_REDUNDANT;
1030
1031         } else if (strcmp(name1, "redundant-load-balance") == 0) {
1032                 xr->type = XLAT_REDUNDANT_LOAD_BALANCE;
1033
1034         } else if (strcmp(name1, "load-balance") == 0) {
1035                 xr->type = XLAT_LOAD_BALANCE;
1036
1037         } else {
1038                 return false;
1039         }
1040
1041         xr->cs = cs;
1042
1043         /*
1044          *      Get the number of children for load balancing.
1045          */
1046         if (xr->type == XLAT_REDUNDANT) {
1047                 if (xlat_register(name2, xlat_redundant, NULL, xr) < 0) {
1048                         talloc_free(xr);
1049                         return false;
1050                 }
1051
1052         } else {
1053                 CONF_ITEM *ci;
1054
1055                 for (ci = cf_item_find_next(cs, NULL);
1056                      ci != NULL;
1057                      ci = cf_item_find_next(cs, ci)) {
1058                         if (!cf_item_is_pair(ci)) continue;
1059
1060                         if (!xlat_find(cf_pair_attr(cf_item_to_pair(ci)))) {
1061                                 talloc_free(xr);
1062                                 return false;
1063                         }
1064
1065                         xr->count++;
1066                 }
1067
1068                 if (xlat_register(name2, xlat_load_balance, NULL, xr) < 0) {
1069                         talloc_free(xr);
1070                         return false;
1071                 }
1072         }
1073
1074         return true;
1075 }
1076
1077
1078 /** Crappy temporary function to add attribute ref support to xlats
1079  *
1080  * This needs to die, and hopefully will die, when xlat functions accept
1081  * xlat node structures.
1082  *
1083  * Provides either a pointer to a buffer which contains the value of the reference VALUE_PAIR
1084  * in an architecture independent format. Or a pointer to the start of the fmt string.
1085  *
1086  * The pointer is only guaranteed to be valid between calls to xlat_fmt_to_ref,
1087  * and so long as the source VALUE_PAIR is not freed.
1088  *
1089  * @param out where to write a pointer to the buffer to the data the xlat function needs to work on.
1090  * @param request current request.
1091  * @param fmt string.
1092  * @returns the length of the data or -1 on error.
1093  */
1094 ssize_t xlat_fmt_to_ref(uint8_t const **out, REQUEST *request, char const *fmt)
1095 {
1096         VALUE_PAIR *vp;
1097
1098         while (isspace((int) *fmt)) fmt++;
1099
1100         if (fmt[0] == '&') {
1101                 if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) {
1102                         *out = NULL;
1103                         return -1;
1104                 }
1105
1106                 return rad_vp2data(out, vp);
1107         }
1108
1109         *out = (uint8_t const *)fmt;
1110         return strlen(fmt);
1111 }
1112
1113 /** De-register all xlat functions, used mainly for debugging.
1114  *
1115  */
1116 void xlat_free(void)
1117 {
1118         rbtree_free(xlat_root);
1119 }
1120
1121 #ifdef DEBUG_XLAT
1122 #  define XLAT_DEBUG DEBUG3
1123 #else
1124 #  define XLAT_DEBUG(...)
1125 #endif
1126
1127 static ssize_t xlat_tokenize_expansion(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head,
1128                                        char const **error);
1129 static ssize_t xlat_tokenize_literal(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head,
1130                                      bool brace, char const **error);
1131 static size_t xlat_process(char **out, REQUEST *request, xlat_exp_t const * const head,
1132                            xlat_escape_t escape, void *escape_ctx);
1133
1134 static ssize_t xlat_tokenize_alternation(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head,
1135                                          char const **error)
1136 {
1137         ssize_t slen;
1138         char *p;
1139         xlat_exp_t *node;
1140
1141         rad_assert(fmt[0] == '%');
1142         rad_assert(fmt[1] == '{');
1143         rad_assert(fmt[2] == '%');
1144         rad_assert(fmt[3] == '{');
1145
1146         XLAT_DEBUG("ALTERNATE <-- %s", fmt);
1147
1148         node = talloc_zero(ctx, xlat_exp_t);
1149         node->type = XLAT_ALTERNATE;
1150
1151         p = fmt + 2;
1152         slen = xlat_tokenize_expansion(node, p, &node->child, error);
1153         if (slen <= 0) {
1154                 talloc_free(node);
1155                 return slen - (p - fmt);
1156         }
1157         p += slen;
1158
1159         if (p[0] != ':') {
1160                 talloc_free(node);
1161                 *error = "Expected ':' after first expansion";
1162                 return -(p - fmt);
1163         }
1164         p++;
1165
1166         if (p[0] != '-') {
1167                 talloc_free(node);
1168                 *error = "Expected '-' after ':'";
1169                 return -(p - fmt);
1170         }
1171         p++;
1172
1173         /*
1174          *      Allow the RHS to be empty as a special case.
1175          */
1176         if (*p == '}') {
1177                 /*
1178                  *      Hack up an empty string.
1179                  */
1180                 node->alternate = talloc_zero(node, xlat_exp_t);
1181                 node->alternate->type = XLAT_LITERAL;
1182                 node->alternate->fmt = talloc_typed_strdup(node->alternate, "");
1183                 *(p++) = '\0';
1184
1185         } else {
1186                 slen = xlat_tokenize_literal(node, p,  &node->alternate, true, error);
1187                 if (slen <= 0) {
1188                         talloc_free(node);
1189                         return slen - (p - fmt);
1190                 }
1191
1192                 if (!node->alternate) {
1193                         talloc_free(node);
1194                         *error = "Empty expansion is invalid";
1195                         return -(p - fmt);
1196                 }
1197                 p += slen;
1198         }
1199
1200         *head = node;
1201         return p - fmt;
1202 }
1203
1204 static ssize_t xlat_tokenize_expansion(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head,
1205                                        char const **error)
1206 {
1207         ssize_t slen;
1208         char *p, *q;
1209         xlat_exp_t *node;
1210         long num;
1211
1212         rad_assert(fmt[0] == '%');
1213         rad_assert(fmt[1] == '{');
1214
1215         /*
1216          *      %{%{...}:-bar}
1217          */
1218         if ((fmt[2] == '%') && (fmt[3] == '{')) return xlat_tokenize_alternation(ctx, fmt, head, error);
1219
1220         XLAT_DEBUG("EXPANSION <-- %s", fmt);
1221         node = talloc_zero(ctx, xlat_exp_t);
1222         node->fmt = fmt + 2;
1223         node->len = 0;
1224
1225 #ifdef HAVE_REGEX
1226         /*
1227          *      Handle regex's specially.
1228          */
1229         p = fmt + 2;
1230         num = strtol(p, &q, 10);
1231         if (p != q && (*q == '}')) {
1232                 XLAT_DEBUG("REGEX <-- %s", fmt);
1233                 *q = '\0';
1234
1235                 if ((num > REQUEST_MAX_REGEX) || (num < 0)) {
1236                         talloc_free(node);
1237                         *error = "Invalid regex reference.  Must be in range 0-" STRINGIFY(REQUEST_MAX_REGEX);
1238                         return -2;
1239                 }
1240                 node->attr.tmpl_num = num;
1241
1242                 node->type = XLAT_REGEX;
1243                 *head = node;
1244
1245                 return (q - fmt) + 1;
1246         }
1247 #endif /* HAVE_REGEX */
1248
1249         /*
1250          *      %{Attr-Name}
1251          *      %{Attr-Name[#]}
1252          *      %{Tunnel-Password:1}
1253          *      %{Tunnel-Password:1[#]}
1254          *      %{request:Attr-Name}
1255          *      %{request:Tunnel-Password:1}
1256          *      %{request:Tunnel-Password:1[#]}
1257          *      %{mod:foo}
1258          */
1259
1260         /*
1261          *      This is for efficiency, so we don't search for an xlat,
1262          *      when what's being referenced is obviously an attribute.
1263          */
1264         p = fmt + 2;
1265         for (q = p; *q != '\0'; q++) {
1266                 if (*q == ':') break;
1267
1268                 if (isspace((int) *q)) break;
1269
1270                 if (*q == '[') continue;
1271
1272                 if (*q == '}') break;
1273         }
1274
1275         /*
1276          *      Check for empty expressions %{}
1277          */
1278         if ((*q == '}') && (q == p)) {
1279                 *error = "Empty expression is invalid";
1280                 return -(p - fmt);
1281         }
1282
1283         /*
1284          *      Might be a module name reference.
1285          *
1286          *      If it's not, it's an attribute or parse error.
1287          */
1288         if (*q == ':') {
1289                 *q = '\0';
1290                 node->xlat = xlat_find(node->fmt);
1291                 if (node->xlat) {
1292                         /*
1293                          *      %{mod:foo}
1294                          */
1295                         node->type = XLAT_MODULE;
1296
1297                         p = q + 1;
1298                         XLAT_DEBUG("MOD <-- %s ... %s", node->fmt, p);
1299
1300                         slen = xlat_tokenize_literal(node, p, &node->child, true, error);
1301                         if (slen < 0) {
1302                                 talloc_free(node);
1303                                 return slen - (p - fmt);
1304                         }
1305                         p += slen;
1306
1307                         *head = node;
1308                         rad_assert(node->next == NULL);
1309
1310                         return p - fmt;
1311                 }
1312                 *q = ':';       /* Avoids a strdup */
1313         }
1314
1315         /*
1316          *      The first token ends with:
1317          *      - '[' - Which is an attribute index, so it must be an attribute.
1318          *      - '}' - The end of the expansion, which means it was a bareword.
1319          */
1320         slen = tmpl_from_attr_substr(&node->attr, p, REQUEST_CURRENT, PAIR_LIST_REQUEST, true, true);
1321         if (slen <= 0) {
1322                 /*
1323                  *      If the parse error occurred before the ':'
1324                  *      then the error is changed to 'Unknown module',
1325                  *      as it was more likely to be a bad module name,
1326                  *      than a request qualifier.
1327                  */
1328                 if ((*q == ':') && ((p + (slen * -1)) < q)) {
1329                         *error = "Unknown module";
1330                 } else {
1331                         *error = fr_strerror();
1332                 }
1333                 return slen - (p - fmt);
1334         }
1335
1336         /*
1337          *      Might be a virtual XLAT attribute
1338          */
1339         if (node->attr.type == TMPL_TYPE_ATTR_UNDEFINED) {
1340                 node->xlat = xlat_find(node->attr.tmpl_unknown_name);
1341                 if (node->xlat) {
1342                         node->type = XLAT_VIRTUAL;
1343                         node->fmt = node->attr.tmpl_unknown_name;
1344
1345                         XLAT_DEBUG("VIRTUAL <-- %s", node->fmt);
1346                         *head = node;
1347                         rad_assert(node->next == NULL);
1348                         q++;
1349                         return q - fmt;
1350                 }
1351
1352                 talloc_free(node);
1353                 *error = "Unknown attribute";
1354                 return -(p - fmt);
1355         }
1356
1357         node->type = XLAT_ATTRIBUTE;
1358         p += slen;
1359
1360         if (*p != '}') {
1361                 talloc_free(node);
1362                 *error = "No matching closing brace";
1363                 return -1;      /* second character of format string */
1364         }
1365         p++;
1366         *head = node;
1367         rad_assert(node->next == NULL);
1368
1369         return p - fmt;
1370 }
1371
1372
1373 static ssize_t xlat_tokenize_literal(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head,
1374                                      bool brace, char const **error)
1375 {
1376         char *p;
1377         xlat_exp_t *node;
1378
1379         if (!*fmt) return 0;
1380
1381         XLAT_DEBUG("LITERAL <-- %s", fmt);
1382
1383         node = talloc_zero(ctx, xlat_exp_t);
1384         node->fmt = fmt;
1385         node->len = 0;
1386         node->type = XLAT_LITERAL;
1387
1388         p = fmt;
1389
1390         while (*p) {
1391                 if (*p == '\\') {
1392                         if (!p[1]) {
1393                                 talloc_free(node);
1394                                 *error = "Invalid escape at end of string";
1395                                 return -(p - fmt);
1396                         }
1397                         p += 2;
1398                         continue;
1399                 }
1400
1401                 /*
1402                  *      Process the expansion.
1403                  */
1404                 if ((p[0] == '%') && (p[1] == '{')) {
1405                         ssize_t slen;
1406
1407                         XLAT_DEBUG("EXPANSION-2 <-- %s", node->fmt);
1408
1409                         slen = xlat_tokenize_expansion(node, p, &node->next, error);
1410                         if (slen <= 0) {
1411                                 talloc_free(node);
1412                                 return slen - (p - fmt);
1413                         }
1414                         *p = '\0'; /* end the literal */
1415                         p += slen;
1416
1417                         rad_assert(node->next != NULL);
1418
1419                         /*
1420                          *      Short-circuit the recursive call.
1421                          *      This saves another function call and
1422                          *      memory allocation.
1423                          */
1424                         if (!*p) break;
1425
1426                         /*
1427                          *      "foo %{User-Name} bar"
1428                          *      LITERAL         "foo "
1429                          *      EXPANSION       User-Name
1430                          *      LITERAL         " bar"
1431                          */
1432                         slen = xlat_tokenize_literal(node->next, p, &(node->next->next), brace, error);
1433                         rad_assert(slen != 0);
1434                         if (slen < 0) {
1435                                 talloc_free(node);
1436                                 return slen - (p - fmt);
1437                         }
1438
1439                         brace = false; /* it was found above, or else the above code errored out */
1440                         p += slen;
1441                         break;  /* stop processing the string */
1442                 }
1443
1444                 /*
1445                  *      Check for valid single-character expansions.
1446                  */
1447                 if (p[0] == '%') {
1448                         ssize_t slen;
1449                         xlat_exp_t *next;
1450
1451                         if (!p[1] || !strchr("%dlmntDGHISTYv", p[1])) {
1452                                         talloc_free(node);
1453                                         *error = "Invalid variable expansion";
1454                                         p++;
1455                                         return - (p - fmt);
1456                         }
1457
1458                         next = talloc_zero(node, xlat_exp_t);
1459                         next->len = 1;
1460
1461                         if (p[1] == '%') {
1462                                 next->fmt = talloc_typed_strdup(next, "%");
1463
1464                                 XLAT_DEBUG("LITERAL-PERCENT <-- %s", next->fmt);
1465                                 next->type = XLAT_LITERAL;
1466
1467                         } else {
1468                                 next->fmt = p + 1;
1469
1470                                 XLAT_DEBUG("PERCENT <-- %c", *next->fmt);
1471                                 next->type = XLAT_PERCENT;
1472                         }
1473
1474                         node->next = next;
1475                         *p = '\0';
1476                         p += 2;
1477
1478                         if (!*p) break;
1479
1480                         /*
1481                          *      And recurse.
1482                          */
1483                         slen = xlat_tokenize_literal(node->next, p, &(node->next->next), brace, error);
1484                         rad_assert(slen != 0);
1485                         if (slen < 0) {
1486                                 talloc_free(node);
1487                                 return slen - (p - fmt);
1488                         }
1489
1490                         brace = false; /* it was found above, or else the above code errored out */
1491                         p += slen;
1492                         break;  /* stop processing the string */
1493                 }
1494
1495                 /*
1496                  *      If required, eat the brace.
1497                  */
1498                 if (brace && (*p == '}')) {
1499                         brace = false;
1500                         *p = '\0';
1501                         p++;
1502                         break;
1503                 }
1504
1505                 p++;
1506                 node->len++;
1507         }
1508
1509         /*
1510          *      We were told to look for a brace, but we ran off of
1511          *      the end of the string before we found one.
1512          */
1513         if (brace) {
1514                 *error = "Missing closing brace at end of string";
1515                 return -(p - fmt);
1516         }
1517
1518         /*
1519          *      Squash zero-width literals
1520          */
1521         if (node->len > 0) {
1522                 *head = node;
1523
1524         } else {
1525                 (void) talloc_steal(ctx, node->next);
1526                 *head = node->next;
1527                 talloc_free(node);
1528         }
1529
1530         return p - fmt;
1531 }
1532
1533
1534 static char const xlat_tabs[] = "                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               ";
1535
1536 static void xlat_tokenize_debug(xlat_exp_t const *node, int lvl)
1537 {
1538         rad_assert(node != NULL);
1539
1540         if (lvl >= (int) sizeof(xlat_tabs)) lvl = sizeof(xlat_tabs);
1541
1542         while (node) {
1543                 switch (node->type) {
1544                 case XLAT_LITERAL:
1545                         DEBUG("%.*sliteral --> %s", lvl, xlat_tabs, node->fmt);
1546                         break;
1547
1548                 case XLAT_PERCENT:
1549                         DEBUG("%.*spercent --> %c", lvl, xlat_tabs, node->fmt[0]);
1550                         break;
1551
1552                 case XLAT_ATTRIBUTE:
1553                         rad_assert(node->attr.tmpl_da != NULL);
1554                         DEBUG("%.*sattribute --> %s", lvl, xlat_tabs, node->attr.tmpl_da->name);
1555                         rad_assert(node->child == NULL);
1556                         if ((node->attr.tmpl_tag != TAG_ANY) || (node->attr.tmpl_num != NUM_ANY)) {
1557                                 DEBUG("%.*s{", lvl, xlat_tabs);
1558
1559                                 DEBUG("%.*sref  %d", lvl + 1, xlat_tabs, node->attr.tmpl_request);
1560                                 DEBUG("%.*slist %d", lvl + 1, xlat_tabs, node->attr.tmpl_list);
1561
1562                                 if (node->attr.tmpl_tag != TAG_ANY) {
1563                                         DEBUG("%.*stag %d", lvl + 1, xlat_tabs, node->attr.tmpl_tag);
1564                                 }
1565                                 if (node->attr.tmpl_num != NUM_ANY) {
1566                                         if (node->attr.tmpl_num == NUM_COUNT) {
1567                                                 DEBUG("%.*s[#]", lvl + 1, xlat_tabs);
1568                                         } else if (node->attr.tmpl_num == NUM_ALL) {
1569                                                 DEBUG("%.*s[*]", lvl + 1, xlat_tabs);
1570                                         } else {
1571                                                 DEBUG("%.*s[%d]", lvl + 1, xlat_tabs, node->attr.tmpl_num);
1572                                         }
1573                                 }
1574
1575                                 DEBUG("%.*s}", lvl, xlat_tabs);
1576                         }
1577                         break;
1578
1579                 case XLAT_VIRTUAL:
1580                         rad_assert(node->fmt != NULL);
1581                         DEBUG("%.*svirtual --> %s", lvl, xlat_tabs, node->fmt);
1582                         break;
1583
1584                 case XLAT_MODULE:
1585                         rad_assert(node->xlat != NULL);
1586                         DEBUG("%.*sxlat --> %s", lvl, xlat_tabs, node->xlat->name);
1587                         if (node->child) {
1588                                 DEBUG("%.*s{", lvl, xlat_tabs);
1589                                 xlat_tokenize_debug(node->child, lvl + 1);
1590                                 DEBUG("%.*s}", lvl, xlat_tabs);
1591                         }
1592                         break;
1593
1594 #ifdef HAVE_REGEX
1595                 case XLAT_REGEX:
1596                         DEBUG("%.*sregex-var --> %d", lvl, xlat_tabs, node->attr.tmpl_num);
1597                         break;
1598 #endif
1599
1600                 case XLAT_ALTERNATE:
1601                         DEBUG("%.*sif {", lvl, xlat_tabs);
1602                         xlat_tokenize_debug(node->child, lvl + 1);
1603                         DEBUG("%.*s}", lvl, xlat_tabs);
1604                         DEBUG("%.*selse {", lvl, xlat_tabs);
1605                         xlat_tokenize_debug(node->alternate, lvl + 1);
1606                         DEBUG("%.*s}", lvl, xlat_tabs);
1607                         break;
1608                 }
1609                 node = node->next;
1610         }
1611 }
1612
1613 size_t xlat_sprint(char *buffer, size_t bufsize, xlat_exp_t const *node)
1614 {
1615         size_t len;
1616         char *p, *end;
1617
1618         if (!node) {
1619                 *buffer = '\0';
1620                 return 0;
1621         }
1622
1623         p = buffer;
1624         end = buffer + bufsize;
1625
1626         while (node) {
1627                 switch (node->type) {
1628                 case XLAT_LITERAL:
1629                         strlcpy(p, node->fmt, end - p);
1630                         p += strlen(p);
1631                         break;
1632
1633                 case XLAT_PERCENT:
1634                         p[0] = '%';
1635                         p[1] = node->fmt[0];
1636                         p += 2;
1637                         break;
1638
1639                 case XLAT_ATTRIBUTE:
1640                         *(p++) = '%';
1641                         *(p++) = '{';
1642
1643                         if (node->attr.tmpl_request != REQUEST_CURRENT) {
1644                                 strlcpy(p, fr_int2str(request_refs, node->attr.tmpl_request, "??"), end - p);
1645                                 p += strlen(p);
1646                                 *(p++) = '.';
1647                         }
1648
1649                         if ((node->attr.tmpl_request != REQUEST_CURRENT) ||
1650                             (node->attr.tmpl_list != PAIR_LIST_REQUEST)) {
1651                                 strlcpy(p, fr_int2str(pair_lists, node->attr.tmpl_list, "??"), end - p);
1652                                 p += strlen(p);
1653                                 *(p++) = ':';
1654                         }
1655
1656                         strlcpy(p, node->attr.tmpl_da->name, end - p);
1657                         p += strlen(p);
1658
1659                         if (node->attr.tmpl_tag != TAG_ANY) {
1660                                 *(p++) = ':';
1661                                 snprintf(p, end - p, "%u", node->attr.tmpl_tag);
1662                                 p += strlen(p);
1663                         }
1664
1665                         if (node->attr.tmpl_num != NUM_ANY) {
1666                                 *(p++) = '[';
1667                                 switch (node->attr.tmpl_num) {
1668                                 case NUM_COUNT:
1669                                         *(p++) = '#';
1670                                         break;
1671
1672                                 case NUM_ALL:
1673                                         *(p++) = '*';
1674                                         break;
1675
1676                                 default:
1677                                         snprintf(p, end - p, "%i", node->attr.tmpl_num);
1678                                         p += strlen(p);
1679                                 }
1680                                 *(p++) = ']';
1681                         }
1682                         *(p++) = '}';
1683                         break;
1684 #ifdef HAVE_REGEX
1685                 case XLAT_REGEX:
1686                         snprintf(p, end - p, "%%{%i}", node->attr.tmpl_num);
1687                         p += strlen(p);
1688                         break;
1689 #endif
1690                 case XLAT_VIRTUAL:
1691                         *(p++) = '%';
1692                         *(p++) = '{';
1693                         strlcpy(p, node->fmt, end - p);
1694                         p += strlen(p);
1695                         *(p++) = '}';
1696                         break;
1697
1698                 case XLAT_MODULE:
1699                         *(p++) = '%';
1700                         *(p++) = '{';
1701                         strlcpy(p, node->xlat->name, end - p);
1702                         p += strlen(p);
1703                         *(p++) = ':';
1704                         rad_assert(node->child != NULL);
1705                         len = xlat_sprint(p, end - p, node->child);
1706                         p += len;
1707                         *(p++) = '}';
1708                         break;
1709
1710                 case XLAT_ALTERNATE:
1711                         *(p++) = '%';
1712                         *(p++) = '{';
1713
1714                         len = xlat_sprint(p, end - p, node->child);
1715                         p += len;
1716
1717                         *(p++) = ':';
1718                         *(p++) = '-';
1719
1720                         len = xlat_sprint(p, end - p, node->alternate);
1721                         p += len;
1722
1723                         *(p++) = '}';
1724                         break;
1725                 }
1726
1727
1728                 if (p == end) break;
1729
1730                 node = node->next;
1731         }
1732
1733         *p = '\0';
1734
1735         return p - buffer;
1736 }
1737
1738 ssize_t xlat_tokenize(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head,
1739                       char const **error)
1740 {
1741         return xlat_tokenize_literal(ctx, fmt, head, false, error);
1742 }
1743
1744
1745 /** Tokenize an xlat expansion
1746  *
1747  * @param[in] request the input request.  Memory will be attached here.
1748  * @param[in] fmt the format string to expand
1749  * @param[out] head the head of the xlat list / tree structure.
1750  */
1751 static ssize_t xlat_tokenize_request(REQUEST *request, char const *fmt, xlat_exp_t **head)
1752 {
1753         ssize_t slen;
1754         char *tokens;
1755         char const *error = NULL;
1756
1757         *head = NULL;
1758
1759         /*
1760          *      Copy the original format string to a buffer so that
1761          *      the later functions can mangle it in-place, which is
1762          *      much faster.
1763          */
1764         tokens = talloc_typed_strdup(request, fmt);
1765         if (!tokens) return -1;
1766
1767         slen = xlat_tokenize_literal(request, tokens, head, false, &error);
1768
1769         /*
1770          *      Zero length expansion, return a zero length node.
1771          */
1772         if (slen == 0) {
1773                 *head = talloc_zero(request, xlat_exp_t);
1774         }
1775
1776         /*
1777          *      Output something like:
1778          *
1779          *      "format string"
1780          *      "       ^ error was here"
1781          */
1782         if (slen < 0) {
1783                 talloc_free(tokens);
1784                 rad_assert(error != NULL);
1785
1786                 REMARKER(fmt, -slen, error);
1787                 return slen;
1788         }
1789
1790         if (*head && (rad_debug_lvl > 2)) {
1791                 DEBUG("%s", fmt);
1792                 DEBUG("Parsed xlat tree:");
1793                 xlat_tokenize_debug(*head, 0);
1794         }
1795
1796         /*
1797          *      All of the nodes point to offsets in the "tokens"
1798          *      string.  Let's ensure that free'ing head will free
1799          *      "tokens", too.
1800          */
1801         (void) talloc_steal(*head, tokens);
1802
1803         return slen;
1804 }
1805
1806
1807 static char *xlat_getvp(TALLOC_CTX *ctx, REQUEST *request, vp_tmpl_t const *vpt,
1808                         bool escape, bool return_null)
1809 {
1810         VALUE_PAIR *vp = NULL, *virtual = NULL;
1811         RADIUS_PACKET *packet = NULL;
1812         DICT_VALUE *dv;
1813         char *ret = NULL;
1814         int err;
1815
1816         char quote = escape ? '"' : '\0';
1817
1818         vp_cursor_t cursor;
1819
1820         /*
1821          *      See if we're dealing with an attribute in the request
1822          *
1823          *      This allows users to manipulate virtual attributes as if
1824          *      they were real ones.
1825          */
1826         vp = tmpl_cursor_init(&err, &cursor, request, vpt);
1827         if (vp) goto do_print;
1828
1829         /*
1830          *      We didn't find the VP in a list.
1831          *      If it's not a virtual one, and we're not meant to
1832          *      be counting it, return.
1833          */
1834         if (!vpt->tmpl_da->flags.virtual) {
1835                 if (vpt->tmpl_num == NUM_COUNT) goto do_print;
1836                 return NULL;
1837         }
1838
1839         /*
1840          *      Switch out the request to the one specified by the template
1841          */
1842         if (radius_request(&request, vpt->tmpl_request) < 0) return NULL;
1843
1844         /*
1845          *      Some non-packet expansions
1846          */
1847         switch (vpt->tmpl_da->attr) {
1848         default:
1849                 break;          /* ignore them */
1850
1851         case PW_CLIENT_SHORTNAME:
1852                 if (vpt->tmpl_num == NUM_COUNT) goto count_virtual;
1853                 if (request->client && request->client->shortname) {
1854                         return talloc_typed_strdup(ctx, request->client->shortname);
1855                 }
1856                 return talloc_typed_strdup(ctx, "<UNKNOWN-CLIENT>");
1857
1858         case PW_REQUEST_PROCESSING_STAGE:
1859                 if (vpt->tmpl_num == NUM_COUNT) goto count_virtual;
1860                 if (request->component) {
1861                         return talloc_typed_strdup(ctx, request->component);
1862                 }
1863                 return talloc_typed_strdup(ctx, "server_core");
1864
1865         case PW_VIRTUAL_SERVER:
1866                 if (vpt->tmpl_num == NUM_COUNT) goto count_virtual;
1867                 if (!request->server) return NULL;
1868                 return talloc_typed_strdup(ctx, request->server);
1869
1870         case PW_MODULE_RETURN_CODE:
1871                 if (vpt->tmpl_num == NUM_COUNT) goto count_virtual;
1872                 if (!request->rcode) return NULL;
1873                 return talloc_typed_strdup(ctx, fr_int2str(modreturn_table, request->rcode, ""));
1874         }
1875
1876         /*
1877          *      All of the attributes must now refer to a packet.
1878          *      If there's no packet, we can't print any attribute
1879          *      referencing it.
1880          */
1881         packet = radius_packet(request, vpt->tmpl_list);
1882         if (!packet) {
1883                 if (return_null) return NULL;
1884                 return vp_aprints_type(ctx, vpt->tmpl_da->type);
1885         }
1886
1887         vp = NULL;
1888         switch (vpt->tmpl_da->attr) {
1889         default:
1890                 break;
1891
1892         case PW_PACKET_TYPE:
1893                 dv = dict_valbyattr(PW_PACKET_TYPE, 0, packet->code);
1894                 if (dv) return talloc_typed_strdup(ctx, dv->name);
1895                 return talloc_typed_asprintf(ctx, "%d", packet->code);
1896
1897         case PW_RESPONSE_PACKET_TYPE:
1898         {
1899                 int code = 0;
1900
1901 #ifdef WITH_PROXY
1902                 if (request->proxy_reply && (!request->reply || !request->reply->code)) {
1903                         code = request->proxy_reply->code;
1904                 } else
1905 #endif
1906                         if (request->reply) {
1907                                 code = request->reply->code;
1908                         }
1909
1910                 return talloc_typed_strdup(ctx, fr_packet_codes[code]);
1911         }
1912
1913         /*
1914          *      Virtual attributes which require a temporary VALUE_PAIR
1915          *      to be allocated. We can't use stack allocated memory
1916          *      because of the talloc checks sprinkled throughout the
1917          *      various VP functions.
1918          */
1919         case PW_PACKET_AUTHENTICATION_VECTOR:
1920                 virtual = pairalloc(ctx, vpt->tmpl_da);
1921                 pairmemcpy(virtual, packet->vector, sizeof(packet->vector));
1922                 vp = virtual;
1923                 break;
1924
1925         case PW_CLIENT_IP_ADDRESS:
1926         case PW_PACKET_SRC_IP_ADDRESS:
1927                 if (packet->src_ipaddr.af == AF_INET) {
1928                         virtual = pairalloc(ctx, vpt->tmpl_da);
1929                         virtual->vp_ipaddr = packet->src_ipaddr.ipaddr.ip4addr.s_addr;
1930                         vp = virtual;
1931                 }
1932                 break;
1933
1934         case PW_PACKET_DST_IP_ADDRESS:
1935                 if (packet->dst_ipaddr.af == AF_INET) {
1936                         virtual = pairalloc(ctx, vpt->tmpl_da);
1937                         virtual->vp_ipaddr = packet->dst_ipaddr.ipaddr.ip4addr.s_addr;
1938                         vp = virtual;
1939                 }
1940                 break;
1941
1942         case PW_PACKET_SRC_IPV6_ADDRESS:
1943                 if (packet->src_ipaddr.af == AF_INET6) {
1944                         virtual = pairalloc(ctx, vpt->tmpl_da);
1945                         memcpy(&virtual->vp_ipv6addr,
1946                                &packet->src_ipaddr.ipaddr.ip6addr,
1947                                sizeof(packet->src_ipaddr.ipaddr.ip6addr));
1948                         vp = virtual;
1949                 }
1950                 break;
1951
1952         case PW_PACKET_DST_IPV6_ADDRESS:
1953                 if (packet->dst_ipaddr.af == AF_INET6) {
1954                         virtual = pairalloc(ctx, vpt->tmpl_da);
1955                         memcpy(&virtual->vp_ipv6addr,
1956                                &packet->dst_ipaddr.ipaddr.ip6addr,
1957                                sizeof(packet->dst_ipaddr.ipaddr.ip6addr));
1958                         vp = virtual;
1959                 }
1960                 break;
1961
1962         case PW_PACKET_SRC_PORT:
1963                 virtual = pairalloc(ctx, vpt->tmpl_da);
1964                 virtual->vp_integer = packet->src_port;
1965                 vp = virtual;
1966                 break;
1967
1968         case PW_PACKET_DST_PORT:
1969                 virtual = pairalloc(ctx, vpt->tmpl_da);
1970                 virtual->vp_integer = packet->dst_port;
1971                 vp = virtual;
1972                 break;
1973         }
1974
1975         /*
1976          *      Fake various operations for virtual attributes.
1977          */
1978         if (virtual) {
1979                 if (vpt->tmpl_num != NUM_ANY) switch (vpt->tmpl_num) {
1980                 /*
1981                  *      [n] is NULL (we only have [0])
1982                  */
1983                 default:
1984                         goto finish;
1985                 /*
1986                  *      [*] means only one.
1987                  */
1988                 case NUM_ALL:
1989                         break;
1990
1991                 /*
1992                  *      [#] means 1 (as there's only one)
1993                  */
1994                 case NUM_COUNT:
1995                 count_virtual:
1996                         ret = talloc_strdup(ctx, "1");
1997                         goto finish;
1998
1999                 /*
2000                  *      [0] is fine (get the first instance)
2001                  */
2002                 case 0:
2003                         break;
2004                 }
2005                 goto print;
2006         }
2007
2008 do_print:
2009         switch (vpt->tmpl_num) {
2010         /*
2011          *      Return a count of the VPs.
2012          */
2013         case NUM_COUNT:
2014         {
2015                 int count = 0;
2016
2017                 fr_cursor_first(&cursor);
2018                 while (fr_cursor_next_by_da(&cursor, vpt->tmpl_da, vpt->tmpl_tag)) count++;
2019
2020                 return talloc_typed_asprintf(ctx, "%d", count);
2021         }
2022
2023
2024         /*
2025          *      Concatenate all values together,
2026          *      separated by commas.
2027          */
2028         case NUM_ALL:
2029         {
2030                 char *p, *q;
2031
2032                 if (!fr_cursor_current(&cursor)) return NULL;
2033                 p = vp_aprints_value(ctx, vp, quote);
2034                 if (!p) return NULL;
2035
2036                 while ((vp = tmpl_cursor_next(&cursor, vpt)) != NULL) {
2037                         q = vp_aprints_value(ctx, vp, quote);
2038                         if (!q) return NULL;
2039                         p = talloc_strdup_append(p, ",");
2040                         p = talloc_strdup_append(p, q);
2041                 }
2042
2043                 return p;
2044         }
2045
2046         default:
2047                 /*
2048                  *      The cursor was set to the correct
2049                  *      position above by tmpl_cursor_init.
2050                  */
2051                 vp = fr_cursor_current(&cursor);
2052                 break;
2053         }
2054
2055         if (!vp) {
2056                 if (return_null) return NULL;
2057                 return vp_aprints_type(ctx, vpt->tmpl_da->type);
2058         }
2059
2060 print:
2061         ret = vp_aprints_value(ctx, vp, quote);
2062
2063 finish:
2064         talloc_free(virtual);
2065         return ret;
2066 }
2067
2068 #ifdef DEBUG_XLAT
2069 static const char xlat_spaces[] = "                                                                                                                                                                                                                                                                ";
2070 #endif
2071
2072 static char *xlat_aprint(TALLOC_CTX *ctx, REQUEST *request, xlat_exp_t const * const node,
2073                          xlat_escape_t escape, void *escape_ctx, int lvl)
2074 {
2075         ssize_t rcode;
2076         char *str = NULL, *child;
2077         char const *p;
2078
2079         XLAT_DEBUG("%.*sxlat aprint %d %s", lvl, xlat_spaces, node->type, node->fmt);
2080
2081         switch (node->type) {
2082                 /*
2083                  *      Don't escape this.
2084                  */
2085         case XLAT_LITERAL:
2086                 XLAT_DEBUG("xlat_aprint LITERAL");
2087                 return talloc_typed_strdup(ctx, node->fmt);
2088
2089                 /*
2090                  *      Do a one-character expansion.
2091                  */
2092         case XLAT_PERCENT:
2093         {
2094                 char *nl;
2095                 size_t freespace = 256;
2096                 struct tm ts;
2097                 time_t when;
2098
2099                 XLAT_DEBUG("xlat_aprint PERCENT");
2100
2101                 str = talloc_array(ctx, char, freespace); /* @todo do better allocation */
2102                 p = node->fmt;
2103
2104                 when = request->timestamp;
2105                 if (request->packet) {
2106                         when = request->packet->timestamp.tv_sec;
2107                 }
2108
2109                 switch (*p) {
2110                 case '%':
2111                         str[0] = '%';
2112                         str[1] = '\0';
2113                         break;
2114
2115                 case 'd': /* request day */
2116                         if (!localtime_r(&when, &ts)) goto error;
2117                         strftime(str, freespace, "%d", &ts);
2118                         break;
2119
2120                 case 'l': /* request timestamp */
2121                         snprintf(str, freespace, "%lu",
2122                                  (unsigned long) when);
2123                         break;
2124
2125                 case 'm': /* request month */
2126                         if (!localtime_r(&when, &ts)) goto error;
2127                         strftime(str, freespace, "%m", &ts);
2128                         break;
2129
2130                 case 'n': /* Request Number*/
2131                         snprintf(str, freespace, "%u", request->number);
2132                         break;
2133
2134                 case 't': /* request timestamp */
2135                         CTIME_R(&when, str, freespace);
2136                         nl = strchr(str, '\n');
2137                         if (nl) *nl = '\0';
2138                         break;
2139
2140                 case 'D': /* request date */
2141                         if (!localtime_r(&when, &ts)) goto error;
2142                         strftime(str, freespace, "%Y%m%d", &ts);
2143                         break;
2144
2145                 case 'G': /* request minute */
2146                         if (!localtime_r(&when, &ts)) goto error;
2147                         strftime(str, freespace, "%M", &ts);
2148                         break;
2149
2150                 case 'H': /* request hour */
2151                         if (!localtime_r(&when, &ts)) goto error;
2152                         strftime(str, freespace, "%H", &ts);
2153                         break;
2154
2155                 case 'I': /* Request ID */
2156                         if (request->packet) {
2157                                 snprintf(str, freespace, "%i", request->packet->id);
2158                         }
2159                         break;
2160
2161                 case 'S': /* request timestamp in SQL format*/
2162                         if (!localtime_r(&when, &ts)) goto error;
2163                         strftime(str, freespace, "%Y-%m-%d %H:%M:%S", &ts);
2164                         break;
2165
2166                 case 'T': /* request timestamp */
2167                         if (!localtime_r(&when, &ts)) goto error;
2168                         strftime(str, freespace, "%Y-%m-%d-%H.%M.%S.000000", &ts);
2169                         break;
2170
2171                 case 'Y': /* request year */
2172                         if (!localtime_r(&when, &ts)) {
2173                                 error:
2174                                 REDEBUG("Failed converting packet timestamp to localtime: %s", fr_syserror(errno));
2175                                 talloc_free(str);
2176                                 return NULL;
2177                         }
2178                         strftime(str, freespace, "%Y", &ts);
2179                         break;
2180
2181                 case 'v': /* Version of code */
2182                         RWDEBUG("%%v is deprecated and will be removed.  Use ${version.freeradius-server}");
2183                         snprintf(str, freespace, "%s", radiusd_version_short);
2184                         break;
2185
2186                 default:
2187                         rad_assert(0 == 1);
2188                         break;
2189                 }
2190         }
2191                 break;
2192
2193         case XLAT_ATTRIBUTE:
2194                 XLAT_DEBUG("xlat_aprint ATTRIBUTE");
2195
2196                 /*
2197                  *      Some attributes are virtual <sigh>
2198                  */
2199                 str = xlat_getvp(ctx, request, &node->attr, escape ? false : true, true);
2200                 if (str) {
2201                         XLAT_DEBUG("EXPAND attr %s", node->attr.tmpl_da->name);
2202                         XLAT_DEBUG("       ---> %s", str);
2203                 }
2204                 break;
2205
2206         case XLAT_VIRTUAL:
2207                 XLAT_DEBUG("xlat_aprint VIRTUAL");
2208                 str = talloc_array(ctx, char, 2048); /* FIXME: have the module call talloc_typed_asprintf */
2209                 rcode = node->xlat->func(node->xlat->instance, request, NULL, str, 2048);
2210                 if (rcode < 0) {
2211                         talloc_free(str);
2212                         return NULL;
2213                 }
2214                 RDEBUG2("EXPAND %s", node->xlat->name);
2215                 RDEBUG2("   --> %s", str);
2216                 break;
2217
2218         case XLAT_MODULE:
2219                 XLAT_DEBUG("xlat_aprint MODULE");
2220
2221                 if (node->child) {
2222                         if (xlat_process(&child, request, node->child, node->xlat->escape, node->xlat->instance) == 0) {
2223                                 return NULL;
2224                         }
2225
2226                         XLAT_DEBUG("%.*sEXPAND mod %s %s", lvl, xlat_spaces, node->fmt, node->child->fmt);
2227                 } else {
2228                         XLAT_DEBUG("%.*sEXPAND mod %s", lvl, xlat_spaces, node->fmt);
2229                         child = talloc_typed_strdup(ctx, "");
2230                 }
2231
2232                 XLAT_DEBUG("%.*s      ---> %s", lvl, xlat_spaces, child);
2233
2234                 /*
2235                  *      Smash \n --> CR.
2236                  *
2237                  *      The OUTPUT of xlat is a printable string.  The INPUT might not be...
2238                  *
2239                  *      This is really the reverse of fr_prints().
2240                  */
2241                 if (cf_new_escape && *child) {
2242                         ssize_t slen;
2243                         PW_TYPE type;
2244                         value_data_t data;
2245
2246                         type = PW_TYPE_STRING;
2247                         slen = value_data_from_str(request, &data, &type, NULL, child, talloc_array_length(child) - 1, '"');
2248                         if (slen <= 0) {
2249                                 talloc_free(child);
2250                                 return NULL;
2251                         }
2252
2253                         talloc_free(child);
2254                         child = data.ptr;
2255
2256                 } else {
2257                         char *q;
2258
2259                         p = q = child;
2260                         while (*p) {
2261                                 if (*p == '\\') switch (p[1]) {
2262                                         default:
2263                                                 *(q++) = p[1];
2264                                                 p += 2;
2265                                                 continue;
2266
2267                                         case 'n':
2268                                                 *(q++) = '\n';
2269                                                 p += 2;
2270                                                 continue;
2271
2272                                         case 't':
2273                                                 *(q++) = '\t';
2274                                                 p += 2;
2275                                                 continue;
2276                                         }
2277
2278                                 *(q++) = *(p++);
2279                         }
2280                         *q = '\0';
2281                 }
2282
2283                 str = talloc_array(ctx, char, 2048); /* FIXME: have the module call talloc_typed_asprintf */
2284                 *str = '\0';    /* Be sure the string is NULL terminated, we now only free on error */
2285
2286                 rcode = node->xlat->func(node->xlat->instance, request, child, str, 2048);
2287                 talloc_free(child);
2288                 if (rcode < 0) {
2289                         talloc_free(str);
2290                         return NULL;
2291                 }
2292                 break;
2293
2294 #ifdef HAVE_REGEX
2295         case XLAT_REGEX:
2296                 XLAT_DEBUG("xlat_aprint REGEX");
2297                 if (regex_request_to_sub(ctx, &str, request, node->attr.tmpl_num) < 0) return NULL;
2298
2299                 break;
2300 #endif
2301
2302         case XLAT_ALTERNATE:
2303                 XLAT_DEBUG("xlat_aprint ALTERNATE");
2304                 rad_assert(node->child != NULL);
2305                 rad_assert(node->alternate != NULL);
2306
2307                 str = xlat_aprint(ctx, request, node->child, escape, escape_ctx, lvl);
2308                 if (str) {
2309                         XLAT_DEBUG("ALTERNATE got string: %s", str);
2310                         break;
2311                 }
2312
2313                 XLAT_DEBUG("ALTERNATE going to alternate");
2314                 str = xlat_aprint(ctx, request, node->alternate, escape, escape_ctx, lvl);
2315                 break;
2316
2317         }
2318
2319         /*
2320          *      If there's no data, return that, instead of an empty string.
2321          */
2322         if (str && !str[0]) {
2323                 talloc_free(str);
2324                 return NULL;
2325         }
2326
2327         /*
2328          *      Escape the non-literals we found above.
2329          */
2330         if (str && escape) {
2331                 char *escaped;
2332
2333                 escaped = talloc_array(ctx, char, 2048); /* FIXME: do something intelligent */
2334                 escape(request, escaped, 2038, str, escape_ctx);
2335                 talloc_free(str);
2336                 str = escaped;
2337         }
2338
2339         return str;
2340 }
2341
2342
2343 static size_t xlat_process(char **out, REQUEST *request, xlat_exp_t const * const head,
2344                            xlat_escape_t escape, void *escape_ctx)
2345 {
2346         int i, list;
2347         size_t total;
2348         char **array, *answer;
2349         xlat_exp_t const *node;
2350
2351         *out = NULL;
2352
2353         /*
2354          *      There are no nodes to process, so the result is a zero
2355          *      length string.
2356          */
2357         if (!head) {
2358                 *out = talloc_zero_array(request, char, 1);
2359                 return 0;
2360         }
2361
2362         /*
2363          *      Hack for speed.  If it's one expansion, just allocate
2364          *      that and return, instead of allocating an intermediary
2365          *      array.
2366          */
2367         if (!head->next) {
2368                 /*
2369                  *      Pass the MAIN escape function.  Recursive
2370                  *      calls will call node-specific escape
2371                  *      functions.
2372                  */
2373                 answer = xlat_aprint(request, request, head, escape, escape_ctx, 0);
2374                 if (!answer) {
2375                         *out = talloc_zero_array(request, char, 1);
2376                         return 0;
2377                 }
2378                 *out = answer;
2379                 return strlen(answer);
2380         }
2381
2382         list = 0;               /* FIXME: calculate this once */
2383         for (node = head; node != NULL; node = node->next) {
2384                 list++;
2385         }
2386
2387         array = talloc_array(request, char *, list);
2388         if (!array) return -1;
2389
2390         for (node = head, i = 0; node != NULL; node = node->next, i++) {
2391                 array[i] = xlat_aprint(array, request, node, escape, escape_ctx, 0); /* may be NULL */
2392         }
2393
2394         total = 0;
2395         for (i = 0; i < list; i++) {
2396                 if (array[i]) total += strlen(array[i]); /* FIXME: calculate strlen once */
2397         }
2398
2399         if (!total) {
2400                 talloc_free(array);
2401                 *out = talloc_zero_array(request, char, 1);
2402                 return 0;
2403         }
2404
2405         answer = talloc_array(request, char, total + 1);
2406
2407         total = 0;
2408         for (i = 0; i < list; i++) {
2409                 size_t len;
2410
2411                 if (array[i]) {
2412                         len = strlen(array[i]);
2413                         memcpy(answer + total, array[i], len);
2414                         total += len;
2415                 }
2416         }
2417         answer[total] = '\0';
2418         talloc_free(array);     /* and child entries */
2419
2420         *out = answer;
2421         return total;
2422 }
2423
2424
2425 /** Replace %whatever in a string.
2426  *
2427  * See 'doc/variables.txt' for more information.
2428  *
2429  * @param[out] out Where to write pointer to output buffer.
2430  * @param[in] outlen Size of out.
2431  * @param[in] request current request.
2432  * @param[in] node the xlat structure to expand
2433  * @param[in] escape function to escape final value e.g. SQL quoting.
2434  * @param[in] escape_ctx pointer to pass to escape function.
2435  * @return length of string written @bug should really have -1 for failure
2436  */
2437 static ssize_t xlat_expand_struct(char **out, size_t outlen, REQUEST *request, xlat_exp_t const *node,
2438                                   xlat_escape_t escape, void *escape_ctx)
2439 {
2440         char *buff;
2441         ssize_t len;
2442
2443         rad_assert(node != NULL);
2444
2445         len = xlat_process(&buff, request, node, escape, escape_ctx);
2446         if ((len < 0) || !buff) {
2447                 rad_assert(buff == NULL);
2448                 if (*out) *out[0] = '\0';
2449                 return len;
2450         }
2451
2452         len = strlen(buff);
2453         /*
2454          *      If out doesn't point to an existing buffer
2455          *      copy the pointer to our buffer over.
2456          */
2457         if (!*out) {
2458                 *out = buff;
2459                 return len;
2460         }
2461
2462         /*
2463          *      Otherwise copy the malloced buffer to the fixed one.
2464          */
2465         strlcpy(*out, buff, outlen);
2466         talloc_free(buff);
2467         return len;
2468 }
2469
2470 static ssize_t xlat_expand(char **out, size_t outlen, REQUEST *request, char const *fmt,
2471                            xlat_escape_t escape, void *escape_ctx) CC_HINT(nonnull (1, 3, 4));
2472
2473 /** Replace %whatever in a string.
2474  *
2475  * See 'doc/variables.txt' for more information.
2476  *
2477  * @param[out] out Where to write pointer to output buffer.
2478  * @param[in] outlen Size of out.
2479  * @param[in] request current request.
2480  * @param[in] fmt string to expand.
2481  * @param[in] escape function to escape final value e.g. SQL quoting.
2482  * @param[in] escape_ctx pointer to pass to escape function.
2483  * @return length of string written @bug should really have -1 for failure
2484  */
2485 static ssize_t xlat_expand(char **out, size_t outlen, REQUEST *request, char const *fmt,
2486                            xlat_escape_t escape, void *escape_ctx)
2487 {
2488         ssize_t len;
2489         xlat_exp_t *node;
2490
2491         /*
2492          *      Give better errors than the old code.
2493          */
2494         len = xlat_tokenize_request(request, fmt, &node);
2495         if (len == 0) {
2496                 if (*out) {
2497                         *out[0] = '\0';
2498                 } else {
2499                         *out = talloc_zero_array(request, char, 1);
2500                 }
2501                 return 0;
2502         }
2503
2504         if (len < 0) {
2505                 if (*out) *out[0] = '\0';
2506                 return -1;
2507         }
2508
2509         len = xlat_expand_struct(out, outlen, request, node, escape, escape_ctx);
2510         talloc_free(node);
2511
2512         RDEBUG2("EXPAND %s", fmt);
2513         RDEBUG2("   --> %s", *out);
2514
2515         return len;
2516 }
2517
2518 /** Try to convert an xlat to a tmpl for efficiency
2519  *
2520  * @param ctx to allocate new vp_tmpl_t in.
2521  * @param node to convert.
2522  * @return NULL if unable to convert (not necessarily error), or a new vp_tmpl_t.
2523  */
2524 vp_tmpl_t *xlat_to_tmpl_attr(TALLOC_CTX *ctx, xlat_exp_t *node)
2525 {
2526         vp_tmpl_t *vpt;
2527
2528         if (node->next || (node->type != XLAT_ATTRIBUTE)) return NULL;
2529
2530         /*
2531          *   Concat means something completely different as an attribute reference
2532          *   Count isn't implemented.
2533          */
2534         if ((node->attr.tmpl_num == NUM_COUNT) || (node->attr.tmpl_num == NUM_ALL)) return NULL;
2535
2536         vpt = tmpl_alloc(ctx, TMPL_TYPE_ATTR, node->fmt, -1);
2537         if (!vpt) return NULL;
2538         memcpy(&vpt->data, &node->attr.data, sizeof(vpt->data));
2539
2540         VERIFY_TMPL(vpt);
2541
2542         return vpt;
2543 }
2544
2545 /** Try to convert attr tmpl to an xlat for &attr[*] and artificially constructing expansions
2546  *
2547  * @param ctx to allocate new xlat_expt_t in.
2548  * @param vpt to convert.
2549  * @return NULL if unable to convert (not necessarily error), or a new vp_tmpl_t.
2550  */
2551 xlat_exp_t *xlat_from_tmpl_attr(TALLOC_CTX *ctx, vp_tmpl_t *vpt)
2552 {
2553         xlat_exp_t *node;
2554
2555         if (vpt->type != TMPL_TYPE_ATTR) return NULL;
2556
2557         node = talloc_zero(ctx, xlat_exp_t);
2558         node->fmt = talloc_bstrndup(node, vpt->name, vpt->len);
2559         tmpl_init(&node->attr, TMPL_TYPE_ATTR, node->fmt, talloc_array_length(node->fmt) - 1);
2560         memcpy(&node->attr.data, &vpt->data, sizeof(vpt->data));
2561
2562         return node;
2563 }
2564
2565 ssize_t radius_xlat(char *out, size_t outlen, REQUEST *request, char const *fmt, xlat_escape_t escape, void *ctx)
2566 {
2567         return xlat_expand(&out, outlen, request, fmt, escape, ctx);
2568 }
2569
2570 ssize_t radius_xlat_struct(char *out, size_t outlen, REQUEST *request, xlat_exp_t const *xlat, xlat_escape_t escape, void *ctx)
2571 {
2572         return xlat_expand_struct(&out, outlen, request, xlat, escape, ctx);
2573 }
2574
2575 ssize_t radius_axlat(char **out, REQUEST *request, char const *fmt, xlat_escape_t escape, void *ctx)
2576 {
2577         return xlat_expand(out, 0, request, fmt, escape, ctx);
2578 }
2579
2580 ssize_t radius_axlat_struct(char **out, REQUEST *request, xlat_exp_t const *xlat, xlat_escape_t escape, void *ctx)
2581 {
2582         return xlat_expand_struct(out, 0, request, xlat, escape, ctx);
2583 }