Expose core library versions and features in ${feature.*} and ${version.*}
[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         RAD_XLAT_FUNC           func;                   //!< xlat function.
41         RADIUS_ESCAPE_STRING    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         value_pair_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, "%i", 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, "%i", 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         value_pair_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 = vp_data_aprints_value(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 /** Prints the current module processing the request
495  *
496  */
497 static ssize_t xlat_module(UNUSED void *instance, REQUEST *request,
498                            UNUSED char const *fmt, char *out, size_t outlen)
499 {
500         strlcpy(out, request->module, outlen);
501
502         return strlen(out);
503 }
504
505 #if defined(HAVE_REGEX) && defined(HAVE_PCRE)
506 static ssize_t xlat_regex(UNUSED void *instance, REQUEST *request,
507                           char const *fmt, char *out, size_t outlen)
508 {
509         char *p;
510         size_t len;
511
512         if (regex_request_to_sub_named(request, &p, request, fmt) < 0) {
513                 *out = '\0';
514                 return 0;
515         }
516
517         len = talloc_array_length(p);
518         if (len > outlen) {
519                 RDEBUG("Insufficient buffer space to write subcapture value, needed %zu bytes, have %zu bytes",
520                        len, outlen);
521                 return -1;
522         }
523         strlcpy(out, p, outlen);
524
525         return len - 1; /* - \0 */
526 }
527 #endif
528
529 #ifdef WITH_UNLANG
530 /** Implements the Foreach-Variable-X
531  *
532  * @see modcall()
533  */
534 static ssize_t xlat_foreach(void *instance, REQUEST *request,
535                             UNUSED char const *fmt, char *out, size_t outlen)
536 {
537         VALUE_PAIR      **pvp;
538         size_t          len;
539
540         /*
541          *      See modcall, "FOREACH" for how this works.
542          */
543         pvp = (VALUE_PAIR **) request_data_reference(request, (void *)radius_get_vp, *(int*) instance);
544         if (!pvp || !*pvp) {
545                 *out = '\0';
546                 return 0;
547         }
548
549         len = vp_prints_value(out, outlen, *pvp, 0);
550         if (is_truncated(len, outlen)) {
551                 RDEBUG("Insufficient buffer space to write foreach value");
552                 return -1;
553         }
554
555         return len;
556 }
557 #endif
558
559 /** Print data as string, if possible.
560  *
561  * If attribute "Foo" is defined as "octets" it will normally
562  * be printed as 0x0a0a0a. The xlat "%{string:Foo}" will instead
563  * expand to "\n\n\n"
564  */
565 static ssize_t xlat_string(UNUSED void *instance, REQUEST *request,
566                            char const *fmt, char *out, size_t outlen)
567 {
568         size_t len;
569         ssize_t ret;
570         VALUE_PAIR *vp;
571         uint8_t const *p;
572
573         while (isspace((int) *fmt)) fmt++;
574
575         if (outlen < 3) {
576         nothing:
577                 *out = '\0';
578                 return 0;
579         }
580
581         if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) goto nothing;
582
583         ret = rad_vp2data(&p, vp);
584         if (ret < 0) {
585                 return ret;
586         }
587
588         switch (vp->da->type) {
589         case PW_TYPE_OCTETS:
590                 len = fr_prints(out, outlen, (char const *) p, vp->vp_length, '"');
591                 break;
592
593         case PW_TYPE_STRING:
594                 len = strlcpy(out, vp->vp_strvalue, outlen);
595                 break;
596
597         default:
598                 len = fr_prints(out, outlen, (char const *) p, ret, '\0');
599                 break;
600         }
601
602         return len;
603 }
604
605 /** xlat expand string attribute value
606  *
607  */
608 static ssize_t xlat_xlat(UNUSED void *instance, REQUEST *request,
609                         char const *fmt, char *out, size_t outlen)
610 {
611         VALUE_PAIR *vp;
612
613         while (isspace((int) *fmt)) fmt++;
614
615         if (outlen < 3) {
616         nothing:
617                 *out = '\0';
618                 return 0;
619         }
620
621         if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) goto nothing;
622
623         return radius_xlat(out, outlen, request, vp->vp_strvalue, NULL, NULL);
624 }
625
626 /** Dynamically change the debugging level for the current request
627  *
628  * Example %{debug:3}
629  */
630 static ssize_t xlat_debug(UNUSED void *instance, REQUEST *request,
631                           char const *fmt, char *out, size_t outlen)
632 {
633         int level = 0;
634
635         /*
636          *  Expand to previous (or current) level
637          */
638         snprintf(out, outlen, "%d", request->log.lvl & RAD_REQUEST_OPTION_DEBUG4);
639
640         /*
641          *  Assume we just want to get the current value and NOT set it to 0
642          */
643         if (!*fmt)
644                 goto done;
645
646         level = atoi(fmt);
647         if (level == 0) {
648                 request->log.lvl = RAD_REQUEST_OPTION_NONE;
649                 request->log.func = NULL;
650         } else {
651                 if (level > 4) level = 4;
652
653                 request->log.lvl = level;
654                 request->log.func = vradlog_request;
655         }
656
657         done:
658         return strlen(out);
659 }
660
661 /*
662  *      Compare two xlat_t structs, based ONLY on the module name.
663  */
664 static int xlat_cmp(void const *one, void const *two)
665 {
666         xlat_t const *a = one;
667         xlat_t const *b = two;
668
669         if (a->length != b->length) {
670                 return a->length - b->length;
671         }
672
673         return memcmp(a->name, b->name, a->length);
674 }
675
676
677 /*
678  *      find the appropriate registered xlat function.
679  */
680 static xlat_t *xlat_find(char const *name)
681 {
682         xlat_t my_xlat;
683
684         strlcpy(my_xlat.name, name, sizeof(my_xlat.name));
685         my_xlat.length = strlen(my_xlat.name);
686
687         return rbtree_finddata(xlat_root, &my_xlat);
688 }
689
690
691 /** Register an xlat function.
692  *
693  * @param[in] name xlat name.
694  * @param[in] func xlat function to be called.
695  * @param[in] escape function to sanitize any sub expansions passed to the xlat function.
696  * @param[in] instance of module that's registering the xlat function.
697  * @return 0 on success, -1 on failure
698  */
699 int xlat_register(char const *name, RAD_XLAT_FUNC func, RADIUS_ESCAPE_STRING escape, void *instance)
700 {
701         xlat_t  *c;
702         xlat_t  my_xlat;
703         rbnode_t *node;
704
705         if (!name || !*name) {
706                 DEBUG("xlat_register: Invalid xlat name");
707                 return -1;
708         }
709
710         /*
711          *      First time around, build up the tree...
712          *
713          *      FIXME: This code should be hoisted out of this function,
714          *      and into a global "initialization".  But it isn't critical...
715          */
716         if (!xlat_root) {
717 #ifdef WITH_UNLANG
718                 int i;
719 #endif
720
721                 xlat_root = rbtree_create(NULL, xlat_cmp, NULL, RBTREE_FLAG_REPLACE);
722                 if (!xlat_root) {
723                         DEBUG("xlat_register: Failed to create tree");
724                         return -1;
725                 }
726
727 #ifdef WITH_UNLANG
728                 for (i = 0; xlat_foreach_names[i] != NULL; i++) {
729                         xlat_register(xlat_foreach_names[i],
730                                       xlat_foreach, NULL, &xlat_inst[i]);
731                         c = xlat_find(xlat_foreach_names[i]);
732                         rad_assert(c != NULL);
733                         c->internal = true;
734                 }
735 #endif
736
737 #define XLAT_REGISTER(_x) xlat_register(STRINGIFY(_x), xlat_ ## _x, NULL, NULL); \
738                 c = xlat_find(STRINGIFY(_x)); \
739                 rad_assert(c != NULL); \
740                 c->internal = true
741
742                 XLAT_REGISTER(integer);
743                 XLAT_REGISTER(strlen);
744                 XLAT_REGISTER(length);
745                 XLAT_REGISTER(hex);
746                 XLAT_REGISTER(tag);
747                 XLAT_REGISTER(vendor);
748                 XLAT_REGISTER(vendor_num);
749                 XLAT_REGISTER(attr);
750                 XLAT_REGISTER(attr_num);
751                 XLAT_REGISTER(string);
752                 XLAT_REGISTER(xlat);
753                 XLAT_REGISTER(module);
754                 XLAT_REGISTER(debug_attr);
755 #if defined(HAVE_REGEX) && defined(HAVE_PCRE)
756                 XLAT_REGISTER(regex);
757 #endif
758
759                 xlat_register("debug", xlat_debug, NULL, &xlat_inst[0]);
760                 c = xlat_find("debug");
761                 rad_assert(c != NULL);
762                 c->internal = true;
763         }
764
765         /*
766          *      If it already exists, replace the instance.
767          */
768         strlcpy(my_xlat.name, name, sizeof(my_xlat.name));
769         my_xlat.length = strlen(my_xlat.name);
770         c = rbtree_finddata(xlat_root, &my_xlat);
771         if (c) {
772                 if (c->internal) {
773                         DEBUG("xlat_register: Cannot re-define internal xlat");
774                         return -1;
775                 }
776
777                 c->func = func;
778                 c->escape = escape;
779                 c->instance = instance;
780                 return 0;
781         }
782
783         /*
784          *      Doesn't exist.  Create it.
785          */
786         c = talloc_zero(xlat_root, xlat_t);
787
788         c->func = func;
789         c->escape = escape;
790         strlcpy(c->name, name, sizeof(c->name));
791         c->length = strlen(c->name);
792         c->instance = instance;
793
794         node = rbtree_insert_node(xlat_root, c);
795         if (!node) {
796                 talloc_free(c);
797                 return -1;
798         }
799
800         /*
801          *      Ensure that the data is deleted when the node is
802          *      deleted.
803          *
804          *      @todo: Maybe this should be the other way around...
805          *      when a thing IN the tree is deleted, it's automatically
806          *      removed from the tree.  But for now, this works.
807          */
808         (void) talloc_steal(node, c);
809         return 0;
810 }
811
812 /** Unregister an xlat function
813  *
814  * We can only have one function to call per name, so the passing of "func"
815  * here is extraneous.
816  *
817  * @param[in] name xlat to unregister.
818  * @param[in] func unused.
819  * @param[in] instance data.
820  */
821 void xlat_unregister(char const *name, UNUSED RAD_XLAT_FUNC func, void *instance)
822 {
823         xlat_t  *c;
824         xlat_t          my_xlat;
825
826         if (!name) return;
827
828         strlcpy(my_xlat.name, name, sizeof(my_xlat.name));
829         my_xlat.length = strlen(my_xlat.name);
830
831         c = rbtree_finddata(xlat_root, &my_xlat);
832         if (!c) return;
833
834         if (c->instance != instance) return;
835
836         rbtree_deletebydata(xlat_root, c);
837 }
838
839 static int xlat_unregister_callback(void *instance, void *data)
840 {
841         xlat_t *c = (xlat_t *) data;
842
843         if (c->instance != instance) return 0; /* keep walking */
844
845         return 2;               /* delete it */
846 }
847
848 void xlat_unregister_module(void *instance)
849 {
850         rbtree_walk(xlat_root, RBTREE_DELETE_ORDER, xlat_unregister_callback, instance);
851 }
852
853 /*
854  *      Internal redundant handler for xlats
855  */
856 typedef enum xlat_redundant_type_t {
857         XLAT_INVALID = 0,
858         XLAT_REDUNDANT,
859         XLAT_LOAD_BALANCE,
860         XLAT_REDUNDANT_LOAD_BALANCE,
861 } xlat_redundant_type_t;
862
863 typedef struct xlat_redundant_t {
864         xlat_redundant_type_t type;
865         uint32_t        count;
866         CONF_SECTION *cs;
867 } xlat_redundant_t;
868
869
870 static ssize_t xlat_redundant(void *instance, REQUEST *request,
871                               char const *fmt, char *out, size_t outlen)
872 {
873         xlat_redundant_t *xr = instance;
874         CONF_ITEM *ci;
875         char const *name;
876         xlat_t *xlat;
877
878         rad_assert(xr->type == XLAT_REDUNDANT);
879
880         /*
881          *      Pick the first xlat which succeeds
882          */
883         for (ci = cf_item_find_next(xr->cs, NULL);
884              ci != NULL;
885              ci = cf_item_find_next(xr->cs, ci)) {
886                 ssize_t rcode;
887
888                 if (!cf_item_is_pair(ci)) continue;
889
890                 name = cf_pair_attr(cf_item_to_pair(ci));
891                 rad_assert(name != NULL);
892
893                 xlat = xlat_find(name);
894                 if (!xlat) continue;
895
896                 rcode = xlat->func(xlat->instance, request, fmt, out, outlen);
897                 if (rcode <= 0) continue;
898                 return rcode;
899         }
900
901         /*
902          *      Everything failed.  Oh well.
903          */
904         *out  = 0;
905         return 0;
906 }
907
908
909 static ssize_t xlat_load_balance(void *instance, REQUEST *request,
910                               char const *fmt, char *out, size_t outlen)
911 {
912         uint32_t count = 0;
913         xlat_redundant_t *xr = instance;
914         CONF_ITEM *ci;
915         CONF_ITEM *found = NULL;
916         char const *name;
917         xlat_t *xlat;
918
919         /*
920          *      Choose a child at random.
921          */
922         for (ci = cf_item_find_next(xr->cs, NULL);
923              ci != NULL;
924              ci = cf_item_find_next(xr->cs, ci)) {
925                 if (!cf_item_is_pair(ci)) continue;
926                 count++;
927
928                 /*
929                  *      Replace the previously found one with a random
930                  *      new one.
931                  */
932                 if ((count * (fr_rand() & 0xffff)) < (uint32_t) 0x10000) {
933                         found = ci;
934                 }
935         }
936
937         /*
938          *      Plain load balancing: do one child, and only one child.
939          */
940         if (xr->type == XLAT_LOAD_BALANCE) {
941                 name = cf_pair_attr(cf_item_to_pair(found));
942                 rad_assert(name != NULL);
943
944                 xlat = xlat_find(name);
945                 if (!xlat) return -1;
946
947                 return xlat->func(xlat->instance, request, fmt, out, outlen);
948         }
949
950         rad_assert(xr->type == XLAT_REDUNDANT_LOAD_BALANCE);
951
952         /*
953          *      Try the random one we found.  If it fails, keep going
954          *      through the rest of the children.
955          */
956         ci = found;
957         do {
958                 name = cf_pair_attr(cf_item_to_pair(ci));
959                 rad_assert(name != NULL);
960
961                 xlat = xlat_find(name);
962                 if (xlat) {
963                         ssize_t rcode;
964
965                         rcode = xlat->func(xlat->instance, request, fmt, out, outlen);
966                         if (rcode > 0) return rcode;
967                 }
968
969                 /*
970                  *      Go to the next one, wrapping around at the end.
971                  */
972                 ci = cf_item_find_next(xr->cs, ci);
973                 if (!ci) ci = cf_item_find_next(xr->cs, NULL);
974         } while (ci != found);
975
976         return -1;
977 }
978
979
980 bool xlat_register_redundant(CONF_SECTION *cs)
981 {
982         char const *name1, *name2;
983         xlat_redundant_t *xr;
984
985         name1 = cf_section_name1(cs);
986         name2 = cf_section_name2(cs);
987
988         if (!name2) return false;
989
990         if (xlat_find(name2)) {
991                 cf_log_err_cs(cs, "An expansion is already registered for this name");
992                 return false;
993         }
994
995         xr = talloc_zero(cs, xlat_redundant_t);
996         if (!xr) return false;
997
998         if (strcmp(name1, "redundant") == 0) {
999                 xr->type = XLAT_REDUNDANT;
1000
1001         } else if (strcmp(name1, "redundant-load-balance") == 0) {
1002                 xr->type = XLAT_REDUNDANT_LOAD_BALANCE;
1003
1004         } else if (strcmp(name1, "load-balance") == 0) {
1005                 xr->type = XLAT_LOAD_BALANCE;
1006
1007         } else {
1008                 return false;
1009         }
1010
1011         xr->cs = cs;
1012
1013         /*
1014          *      Get the number of children for load balancing.
1015          */
1016         if (xr->type == XLAT_REDUNDANT) {
1017                 if (xlat_register(name2, xlat_redundant, NULL, xr) < 0) {
1018                         talloc_free(xr);
1019                         return false;
1020                 }
1021
1022         } else {
1023                 CONF_ITEM *ci;
1024
1025                 for (ci = cf_item_find_next(cs, NULL);
1026                      ci != NULL;
1027                      ci = cf_item_find_next(cs, ci)) {
1028                         if (!cf_item_is_pair(ci)) continue;
1029
1030                         if (!xlat_find(cf_pair_attr(cf_item_to_pair(ci)))) {
1031                                 talloc_free(xr);
1032                                 return false;
1033                         }
1034
1035                         xr->count++;
1036                 }
1037
1038                 if (xlat_register(name2, xlat_load_balance, NULL, xr) < 0) {
1039                         talloc_free(xr);
1040                         return false;
1041                 }
1042         }
1043
1044         return true;
1045 }
1046
1047
1048 /** Crappy temporary function to add attribute ref support to xlats
1049  *
1050  * This needs to die, and hopefully will die, when xlat functions accept
1051  * xlat node structures.
1052  *
1053  * Provides either a pointer to a buffer which contains the value of the reference VALUE_PAIR
1054  * in an architecture independent format. Or a pointer to the start of the fmt string.
1055  *
1056  * The pointer is only guaranteed to be valid between calls to xlat_fmt_to_ref,
1057  * and so long as the source VALUE_PAIR is not freed.
1058  *
1059  * @param out where to write a pointer to the buffer to the data the xlat function needs to work on.
1060  * @param request current request.
1061  * @param fmt string.
1062  * @returns the length of the data or -1 on error.
1063  */
1064 ssize_t xlat_fmt_to_ref(uint8_t const **out, REQUEST *request, char const *fmt)
1065 {
1066         VALUE_PAIR *vp;
1067
1068         while (isspace((int) *fmt)) fmt++;
1069
1070         if (fmt[0] == '&') {
1071                 if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) {
1072                         *out = NULL;
1073                         return -1;
1074                 }
1075
1076                 return rad_vp2data(out, vp);
1077         }
1078
1079         *out = (uint8_t const *)fmt;
1080         return strlen(fmt);
1081 }
1082
1083 /** De-register all xlat functions, used mainly for debugging.
1084  *
1085  */
1086 void xlat_free(void)
1087 {
1088         rbtree_free(xlat_root);
1089 }
1090
1091 #ifdef DEBUG_XLAT
1092 #  define XLAT_DEBUG DEBUG3
1093 #else
1094 #  define XLAT_DEBUG(...)
1095 #endif
1096
1097 static ssize_t xlat_tokenize_expansion(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head,
1098                                        char const **error);
1099 static ssize_t xlat_tokenize_literal(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head,
1100                                      bool brace, char const **error);
1101 static size_t xlat_process(char **out, REQUEST *request, xlat_exp_t const * const head,
1102                            RADIUS_ESCAPE_STRING escape, void *escape_ctx);
1103
1104 static ssize_t xlat_tokenize_alternation(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head,
1105                                          char const **error)
1106 {
1107         ssize_t slen;
1108         char *p;
1109         xlat_exp_t *node;
1110
1111         rad_assert(fmt[0] == '%');
1112         rad_assert(fmt[1] == '{');
1113         rad_assert(fmt[2] == '%');
1114         rad_assert(fmt[3] == '{');
1115
1116         XLAT_DEBUG("ALTERNATE <-- %s", fmt);
1117
1118         node = talloc_zero(ctx, xlat_exp_t);
1119         node->type = XLAT_ALTERNATE;
1120
1121         p = fmt + 2;
1122         slen = xlat_tokenize_expansion(node, p, &node->child, error);
1123         if (slen <= 0) {
1124                 talloc_free(node);
1125                 return slen - (p - fmt);
1126         }
1127         p += slen;
1128
1129         if (p[0] != ':') {
1130                 talloc_free(node);
1131                 *error = "Expected ':' after first expansion";
1132                 return -(p - fmt);
1133         }
1134         p++;
1135
1136         if (p[0] != '-') {
1137                 talloc_free(node);
1138                 *error = "Expected '-' after ':'";
1139                 return -(p - fmt);
1140         }
1141         p++;
1142
1143         /*
1144          *      Allow the RHS to be empty as a special case.
1145          */
1146         if (*p == '}') {
1147                 /*
1148                  *      Hack up an empty string.
1149                  */
1150                 node->alternate = talloc_zero(node, xlat_exp_t);
1151                 node->alternate->type = XLAT_LITERAL;
1152                 node->alternate->fmt = talloc_typed_strdup(node->alternate, "");
1153                 *(p++) = '\0';
1154
1155         } else {
1156                 slen = xlat_tokenize_literal(node, p,  &node->alternate, true, error);
1157                 if (slen <= 0) {
1158                         talloc_free(node);
1159                         return slen - (p - fmt);
1160                 }
1161
1162                 if (!node->alternate) {
1163                         talloc_free(node);
1164                         *error = "Empty expansion is invalid";
1165                         return -(p - fmt);
1166                 }
1167                 p += slen;
1168         }
1169
1170         *head = node;
1171         return p - fmt;
1172 }
1173
1174 static ssize_t xlat_tokenize_expansion(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head,
1175                                        char const **error)
1176 {
1177         ssize_t slen;
1178         char *p, *q;
1179         xlat_exp_t *node;
1180         long num;
1181
1182         rad_assert(fmt[0] == '%');
1183         rad_assert(fmt[1] == '{');
1184
1185         /*
1186          *      %{%{...}:-bar}
1187          */
1188         if ((fmt[2] == '%') && (fmt[3] == '{')) return xlat_tokenize_alternation(ctx, fmt, head, error);
1189
1190         XLAT_DEBUG("EXPANSION <-- %s", fmt);
1191         node = talloc_zero(ctx, xlat_exp_t);
1192         node->fmt = fmt + 2;
1193         node->len = 0;
1194
1195 #ifdef HAVE_REGEX
1196         /*
1197          *      Handle regex's specially.
1198          */
1199         p = fmt + 2;
1200         num = strtol(p, &q, 10);
1201         if (p != q && (*q == '}')) {
1202                 XLAT_DEBUG("REGEX <-- %s", fmt);
1203                 *q = '\0';
1204
1205                 if ((num > REQUEST_MAX_REGEX) || (num < 0)) {
1206                         talloc_free(node);
1207                         *error = "Invalid regex reference.  Must be in range 0-" STRINGIFY(REQUEST_MAX_REGEX);
1208                         return -2;
1209                 }
1210                 node->attr.tmpl_num = num;
1211
1212                 node->type = XLAT_REGEX;
1213                 *head = node;
1214
1215                 return (q - fmt) + 1;
1216         }
1217 #endif /* HAVE_REGEX */
1218
1219         /*
1220          *      %{Attr-Name}
1221          *      %{Attr-Name[#]}
1222          *      %{Tunnel-Password:1}
1223          *      %{Tunnel-Password:1[#]}
1224          *      %{request:Attr-Name}
1225          *      %{request:Tunnel-Password:1}
1226          *      %{request:Tunnel-Password:1[#]}
1227          *      %{mod:foo}
1228          */
1229
1230         /*
1231          *      This is for efficiency, so we don't search for an xlat,
1232          *      when what's being referenced is obviously an attribute.
1233          */
1234         p = fmt + 2;
1235         for (q = p; *q != '\0'; q++) {
1236                 if (*q == ':') break;
1237
1238                 if (isspace((int) *q)) break;
1239
1240                 if (*q == '[') continue;
1241
1242                 if (*q == '}') break;
1243         }
1244
1245         /*
1246          *      Check for empty expressions %{}
1247          */
1248         if ((*q == '}') && (q == p)) {
1249                 *error = "Empty expression is invalid";
1250                 return -(p - fmt);
1251         }
1252
1253         /*
1254          *      Might be a module name reference.
1255          *
1256          *      If it's not, it's an attribute or parse error.
1257          */
1258         if (*q == ':') {
1259                 *q = '\0';
1260                 node->xlat = xlat_find(node->fmt);
1261                 if (node->xlat) {
1262                         /*
1263                          *      %{mod:foo}
1264                          */
1265                         node->type = XLAT_MODULE;
1266
1267                         p = q + 1;
1268                         XLAT_DEBUG("MOD <-- %s ... %s", node->fmt, p);
1269
1270                         slen = xlat_tokenize_literal(node, p, &node->child, true, error);
1271                         if (slen <= 0) {
1272                                 talloc_free(node);
1273                                 return slen - (p - fmt);
1274                         }
1275                         p += slen;
1276
1277                         *head = node;
1278                         rad_assert(node->next == NULL);
1279
1280                         return p - fmt;
1281                 }
1282                 *q = ':';       /* Avoids a strdup */
1283         }
1284
1285         /*
1286          *      The first token ends with:
1287          *      - '[' - Which is an attribute index, so it must be an attribute.
1288          *      - '}' - The end of the expansion, which means it was a bareword.
1289          */
1290         slen = tmpl_from_attr_substr(&node->attr, p, REQUEST_CURRENT, PAIR_LIST_REQUEST, true, true);
1291         if (slen <= 0) {
1292                 /*
1293                  *      If the parse error occurred before the ':'
1294                  *      then the error is changed to 'Unknown module',
1295                  *      as it was more likely to be a bad module name,
1296                  *      than a request qualifier.
1297                  */
1298                 if ((*q == ':') && ((p + (slen * -1)) < q)) {
1299                         *error = "Unknown module";
1300                 } else {
1301                         *error = fr_strerror();
1302                 }
1303                 return slen - (p - fmt);
1304         }
1305
1306         /*
1307          *      Might be a virtual XLAT attribute
1308          */
1309         if (node->attr.type == TMPL_TYPE_ATTR_UNDEFINED) {
1310                 node->xlat = xlat_find(node->attr.tmpl_unknown_name);
1311                 if (node->xlat) {
1312                         node->type = XLAT_VIRTUAL;
1313                         node->fmt = node->attr.tmpl_unknown_name;
1314
1315                         XLAT_DEBUG("VIRTUAL <-- %s", node->fmt);
1316                         *head = node;
1317                         rad_assert(node->next == NULL);
1318                         q++;
1319                         return q - fmt;
1320                 }
1321
1322                 talloc_free(node);
1323                 *error = "Unknown attribute";
1324                 return -(p - fmt);
1325         }
1326
1327         node->type = XLAT_ATTRIBUTE;
1328         p += slen;
1329
1330         if (*p != '}') {
1331                 talloc_free(node);
1332                 *error = "No matching closing brace";
1333                 return -1;      /* second character of format string */
1334         }
1335         p++;
1336         *head = node;
1337         rad_assert(node->next == NULL);
1338
1339         return p - fmt;
1340 }
1341
1342
1343 static ssize_t xlat_tokenize_literal(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head,
1344                                      bool brace, char const **error)
1345 {
1346         char *p;
1347         xlat_exp_t *node;
1348
1349         if (!*fmt) return 0;
1350
1351         XLAT_DEBUG("LITERAL <-- %s", fmt);
1352
1353         node = talloc_zero(ctx, xlat_exp_t);
1354         node->fmt = fmt;
1355         node->len = 0;
1356         node->type = XLAT_LITERAL;
1357
1358         p = fmt;
1359
1360         while (*p) {
1361                 if (*p == '\\') {
1362                         if (!p[1]) {
1363                                 talloc_free(node);
1364                                 *error = "Invalid escape at end of string";
1365                                 return -(p - fmt);
1366                         }
1367                         p += 2;
1368                         continue;
1369                 }
1370
1371                 /*
1372                  *      Process the expansion.
1373                  */
1374                 if ((p[0] == '%') && (p[1] == '{')) {
1375                         ssize_t slen;
1376
1377                         XLAT_DEBUG("EXPANSION-2 <-- %s", node->fmt);
1378
1379                         slen = xlat_tokenize_expansion(node, p, &node->next, error);
1380                         if (slen <= 0) {
1381                                 talloc_free(node);
1382                                 return slen - (p - fmt);
1383                         }
1384                         *p = '\0'; /* end the literal */
1385                         p += slen;
1386
1387                         rad_assert(node->next != NULL);
1388
1389                         /*
1390                          *      Short-circuit the recursive call.
1391                          *      This saves another function call and
1392                          *      memory allocation.
1393                          */
1394                         if (!*p) break;
1395
1396                         /*
1397                          *      "foo %{User-Name} bar"
1398                          *      LITERAL         "foo "
1399                          *      EXPANSION       User-Name
1400                          *      LITERAL         " bar"
1401                          */
1402                         slen = xlat_tokenize_literal(node->next, p, &(node->next->next), brace, error);
1403                         rad_assert(slen != 0);
1404                         if (slen < 0) {
1405                                 talloc_free(node);
1406                                 return slen - (p - fmt);
1407                         }
1408
1409                         brace = false; /* it was found above, or else the above code errored out */
1410                         p += slen;
1411                         break;  /* stop processing the string */
1412                 }
1413
1414                 /*
1415                  *      Check for valid single-character expansions.
1416                  */
1417                 if (p[0] == '%') {
1418                         ssize_t slen;
1419                         xlat_exp_t *next;
1420
1421                         if (!p[1] || !strchr("%dlmntDGHISTYv", p[1])) {
1422                                         talloc_free(node);
1423                                         *error = "Invalid variable expansion";
1424                                         p++;
1425                                         return - (p - fmt);
1426                         }
1427
1428                         next = talloc_zero(node, xlat_exp_t);
1429                         next->len = 1;
1430
1431                         if (p[1] == '%') {
1432                                 next->fmt = talloc_typed_strdup(next, "%");
1433
1434                                 XLAT_DEBUG("LITERAL-PERCENT <-- %s", next->fmt);
1435                                 next->type = XLAT_LITERAL;
1436
1437                         } else {
1438                                 next->fmt = p + 1;
1439
1440                                 XLAT_DEBUG("PERCENT <-- %c", *next->fmt);
1441                                 next->type = XLAT_PERCENT;
1442                         }
1443
1444                         node->next = next;
1445                         *p = '\0';
1446                         p += 2;
1447
1448                         if (!*p) break;
1449
1450                         /*
1451                          *      And recurse.
1452                          */
1453                         slen = xlat_tokenize_literal(node->next, p, &(node->next->next), brace, error);
1454                         rad_assert(slen != 0);
1455                         if (slen < 0) {
1456                                 talloc_free(node);
1457                                 return slen - (p - fmt);
1458                         }
1459
1460                         brace = false; /* it was found above, or else the above code errored out */
1461                         p += slen;
1462                         break;  /* stop processing the string */
1463                 }
1464
1465                 /*
1466                  *      If required, eat the brace.
1467                  */
1468                 if (brace && (*p == '}')) {
1469                         brace = false;
1470                         *p = '\0';
1471                         p++;
1472                         break;
1473                 }
1474
1475                 p++;
1476                 node->len++;
1477         }
1478
1479         /*
1480          *      We were told to look for a brace, but we ran off of
1481          *      the end of the string before we found one.
1482          */
1483         if (brace) {
1484                 *error = "Missing closing brace at end of string";
1485                 return -(p - fmt);
1486         }
1487
1488         /*
1489          *      Squash zero-width literals
1490          */
1491         if (node->len > 0) {
1492                 *head = node;
1493
1494         } else {
1495                 (void) talloc_steal(ctx, node->next);
1496                 *head = node->next;
1497                 talloc_free(node);
1498         }
1499
1500         return p - fmt;
1501 }
1502
1503
1504 static char const xlat_tabs[] = "                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               ";
1505
1506 static void xlat_tokenize_debug(xlat_exp_t const *node, int lvl)
1507 {
1508         rad_assert(node != NULL);
1509
1510         if (lvl >= (int) sizeof(xlat_tabs)) lvl = sizeof(xlat_tabs);
1511
1512         while (node) {
1513                 switch (node->type) {
1514                 case XLAT_LITERAL:
1515                         DEBUG("%.*sliteral --> %s", lvl, xlat_tabs, node->fmt);
1516                         break;
1517
1518                 case XLAT_PERCENT:
1519                         DEBUG("%.*spercent --> %c", lvl, xlat_tabs, node->fmt[0]);
1520                         break;
1521
1522                 case XLAT_ATTRIBUTE:
1523                         rad_assert(node->attr.tmpl_da != NULL);
1524                         DEBUG("%.*sattribute --> %s", lvl, xlat_tabs, node->attr.tmpl_da->name);
1525                         rad_assert(node->child == NULL);
1526                         if ((node->attr.tmpl_tag != TAG_ANY) || (node->attr.tmpl_num != NUM_ANY)) {
1527                                 DEBUG("%.*s{", lvl, xlat_tabs);
1528
1529                                 DEBUG("%.*sref  %d", lvl + 1, xlat_tabs, node->attr.tmpl_request);
1530                                 DEBUG("%.*slist %d", lvl + 1, xlat_tabs, node->attr.tmpl_list);
1531
1532                                 if (node->attr.tmpl_tag != TAG_ANY) {
1533                                         DEBUG("%.*stag %d", lvl + 1, xlat_tabs, node->attr.tmpl_tag);
1534                                 }
1535                                 if (node->attr.tmpl_num != NUM_ANY) {
1536                                         if (node->attr.tmpl_num == NUM_COUNT) {
1537                                                 DEBUG("%.*s[#]", lvl + 1, xlat_tabs);
1538                                         } else if (node->attr.tmpl_num == NUM_ALL) {
1539                                                 DEBUG("%.*s[*]", lvl + 1, xlat_tabs);
1540                                         } else {
1541                                                 DEBUG("%.*s[%d]", lvl + 1, xlat_tabs, node->attr.tmpl_num);
1542                                         }
1543                                 }
1544
1545                                 DEBUG("%.*s}", lvl, xlat_tabs);
1546                         }
1547                         break;
1548
1549                 case XLAT_VIRTUAL:
1550                         rad_assert(node->fmt != NULL);
1551                         DEBUG("%.*svirtual --> %s", lvl, xlat_tabs, node->fmt);
1552                         break;
1553
1554                 case XLAT_MODULE:
1555                         rad_assert(node->xlat != NULL);
1556                         DEBUG("%.*sxlat --> %s", lvl, xlat_tabs, node->xlat->name);
1557                         if (node->child) {
1558                                 DEBUG("%.*s{", lvl, xlat_tabs);
1559                                 xlat_tokenize_debug(node->child, lvl + 1);
1560                                 DEBUG("%.*s}", lvl, xlat_tabs);
1561                         }
1562                         break;
1563
1564 #ifdef HAVE_REGEX
1565                 case XLAT_REGEX:
1566                         DEBUG("%.*sregex-var --> %d", lvl, xlat_tabs, node->attr.tmpl_num);
1567                         break;
1568 #endif
1569
1570                 case XLAT_ALTERNATE:
1571                         DEBUG("%.*sif {", lvl, xlat_tabs);
1572                         xlat_tokenize_debug(node->child, lvl + 1);
1573                         DEBUG("%.*s}", lvl, xlat_tabs);
1574                         DEBUG("%.*selse {", lvl, xlat_tabs);
1575                         xlat_tokenize_debug(node->alternate, lvl + 1);
1576                         DEBUG("%.*s}", lvl, xlat_tabs);
1577                         break;
1578                 }
1579                 node = node->next;
1580         }
1581 }
1582
1583 size_t xlat_sprint(char *buffer, size_t bufsize, xlat_exp_t const *node)
1584 {
1585         size_t len;
1586         char *p, *end;
1587
1588         if (!node) {
1589                 *buffer = '\0';
1590                 return 0;
1591         }
1592
1593         p = buffer;
1594         end = buffer + bufsize;
1595
1596         while (node) {
1597                 switch (node->type) {
1598                 case XLAT_LITERAL:
1599                         strlcpy(p, node->fmt, end - p);
1600                         p += strlen(p);
1601                         break;
1602
1603                 case XLAT_PERCENT:
1604                         p[0] = '%';
1605                         p[1] = node->fmt[0];
1606                         p += 2;
1607                         break;
1608
1609                 case XLAT_ATTRIBUTE:
1610                         *(p++) = '%';
1611                         *(p++) = '{';
1612
1613                         if (node->attr.tmpl_request != REQUEST_CURRENT) {
1614                                 strlcpy(p, fr_int2str(request_refs, node->attr.tmpl_request, "??"), end - p);
1615                                 p += strlen(p);
1616                                 *(p++) = '.';
1617                         }
1618
1619                         if ((node->attr.tmpl_request != REQUEST_CURRENT) ||
1620                             (node->attr.tmpl_list != PAIR_LIST_REQUEST)) {
1621                                 strlcpy(p, fr_int2str(pair_lists, node->attr.tmpl_list, "??"), end - p);
1622                                 p += strlen(p);
1623                                 *(p++) = ':';
1624                         }
1625
1626                         strlcpy(p, node->attr.tmpl_da->name, end - p);
1627                         p += strlen(p);
1628
1629                         if (node->attr.tmpl_tag != TAG_ANY) {
1630                                 *(p++) = ':';
1631                                 snprintf(p, end - p, "%u", node->attr.tmpl_tag);
1632                                 p += strlen(p);
1633                         }
1634
1635                         if (node->attr.tmpl_num != NUM_ANY) {
1636                                 *(p++) = '[';
1637                                 switch (node->attr.tmpl_num) {
1638                                 case NUM_COUNT:
1639                                         *(p++) = '#';
1640                                         break;
1641
1642                                 case NUM_ALL:
1643                                         *(p++) = '*';
1644                                         break;
1645
1646                                 default:
1647                                         snprintf(p, end - p, "%i", node->attr.tmpl_num);
1648                                         p += strlen(p);
1649                                 }
1650                                 *(p++) = ']';
1651                         }
1652                         *(p++) = '}';
1653                         break;
1654 #ifdef HAVE_REGEX
1655                 case XLAT_REGEX:
1656                         snprintf(p, end - p, "%%{%i}", node->attr.tmpl_num);
1657                         p += strlen(p);
1658                         break;
1659 #endif
1660                 case XLAT_VIRTUAL:
1661                         *(p++) = '%';
1662                         *(p++) = '{';
1663                         strlcpy(p, node->fmt, end - p);
1664                         p += strlen(p);
1665                         *(p++) = '}';
1666                         break;
1667
1668                 case XLAT_MODULE:
1669                         *(p++) = '%';
1670                         *(p++) = '{';
1671                         strlcpy(p, node->xlat->name, end - p);
1672                         p += strlen(p);
1673                         *(p++) = ':';
1674                         rad_assert(node->child != NULL);
1675                         len = xlat_sprint(p, end - p, node->child);
1676                         p += len;
1677                         *(p++) = '}';
1678                         break;
1679
1680                 case XLAT_ALTERNATE:
1681                         *(p++) = '%';
1682                         *(p++) = '{';
1683
1684                         len = xlat_sprint(p, end - p, node->child);
1685                         p += len;
1686
1687                         *(p++) = ':';
1688                         *(p++) = '-';
1689
1690                         len = xlat_sprint(p, end - p, node->alternate);
1691                         p += len;
1692
1693                         *(p++) = '}';
1694                         break;
1695                 }
1696
1697
1698                 if (p == end) break;
1699
1700                 node = node->next;
1701         }
1702
1703         *p = '\0';
1704
1705         return p - buffer;
1706 }
1707
1708 ssize_t xlat_tokenize(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head,
1709                       char const **error)
1710 {
1711         return xlat_tokenize_literal(ctx, fmt, head, false, error);
1712 }
1713
1714
1715 /** Tokenize an xlat expansion
1716  *
1717  * @param[in] request the input request.  Memory will be attached here.
1718  * @param[in] fmt the format string to expand
1719  * @param[out] head the head of the xlat list / tree structure.
1720  */
1721 static ssize_t xlat_tokenize_request(REQUEST *request, char const *fmt, xlat_exp_t **head)
1722 {
1723         ssize_t slen;
1724         char *tokens;
1725         char const *error = NULL;
1726
1727         *head = NULL;
1728
1729         /*
1730          *      Copy the original format string to a buffer so that
1731          *      the later functions can mangle it in-place, which is
1732          *      much faster.
1733          */
1734         tokens = talloc_typed_strdup(request, fmt);
1735         if (!tokens) return -1;
1736
1737         slen = xlat_tokenize_literal(request, tokens, head, false, &error);
1738
1739         /*
1740          *      Zero length expansion, return a zero length node.
1741          */
1742         if (slen == 0) {
1743                 *head = talloc_zero(request, xlat_exp_t);
1744         }
1745
1746         /*
1747          *      Output something like:
1748          *
1749          *      "format string"
1750          *      "       ^ error was here"
1751          */
1752         if (slen < 0) {
1753                 talloc_free(tokens);
1754                 rad_assert(error != NULL);
1755
1756                 REMARKER(fmt, -slen, error);
1757                 return slen;
1758         }
1759
1760         if (*head && (debug_flag > 2)) {
1761                 DEBUG("%s", fmt);
1762                 DEBUG("Parsed xlat tree:");
1763                 xlat_tokenize_debug(*head, 0);
1764         }
1765
1766         /*
1767          *      All of the nodes point to offsets in the "tokens"
1768          *      string.  Let's ensure that free'ing head will free
1769          *      "tokens", too.
1770          */
1771         (void) talloc_steal(*head, tokens);
1772
1773         return slen;
1774 }
1775
1776
1777 static char *xlat_getvp(TALLOC_CTX *ctx, REQUEST *request, value_pair_tmpl_t const *vpt,
1778                         bool escape, bool return_null)
1779 {
1780         VALUE_PAIR *vp = NULL, *virtual = NULL;
1781         RADIUS_PACKET *packet = NULL;
1782         DICT_VALUE *dv;
1783         char *ret = NULL;
1784         int err;
1785
1786         char quote = escape ? '"' : '\0';
1787
1788         vp_cursor_t cursor;
1789
1790         /*
1791          *      See if we're dealing with an attribute in the request
1792          *
1793          *      This allows users to manipulate virtual attributes as if
1794          *      they were real ones.
1795          */
1796         vp = tmpl_cursor_init(&err, &cursor, request, vpt);
1797         if (vp) goto do_print;
1798
1799         /*
1800          *      We didn't find the VP in a list.
1801          *      If it's not a virtual one, and we're not meant to
1802          *      be counting it, return.
1803          */
1804         if (!vpt->tmpl_da->flags.virtual) {
1805                 if (vpt->tmpl_num == NUM_COUNT) goto do_print;
1806                 return NULL;
1807         }
1808
1809         /*
1810          *      Switch out the request to the one specified by the template
1811          */
1812         if (radius_request(&request, vpt->tmpl_request) < 0) return NULL;
1813
1814         /*
1815          *      Some non-packet expansions
1816          */
1817         switch (vpt->tmpl_da->attr) {
1818         default:
1819                 break;          /* ignore them */
1820
1821         case PW_CLIENT_SHORTNAME:
1822                 if (vpt->tmpl_num == NUM_COUNT) goto count_virtual;
1823                 if (request->client && request->client->shortname) {
1824                         return talloc_typed_strdup(ctx, request->client->shortname);
1825                 }
1826                 return talloc_typed_strdup(ctx, "<UNKNOWN-CLIENT>");
1827
1828         case PW_REQUEST_PROCESSING_STAGE:
1829                 if (vpt->tmpl_num == NUM_COUNT) goto count_virtual;
1830                 if (request->component) {
1831                         return talloc_typed_strdup(ctx, request->component);
1832                 }
1833                 return talloc_typed_strdup(ctx, "server_core");
1834
1835         case PW_VIRTUAL_SERVER:
1836                 if (vpt->tmpl_num == NUM_COUNT) goto count_virtual;
1837                 if (!request->server) return NULL;
1838                 return talloc_typed_strdup(ctx, request->server);
1839
1840         case PW_MODULE_RETURN_CODE:
1841                 if (vpt->tmpl_num == NUM_COUNT) goto count_virtual;
1842                 if (!request->rcode) return NULL;
1843                 return talloc_typed_strdup(ctx, fr_int2str(modreturn_table, request->rcode, ""));
1844         }
1845
1846         /*
1847          *      All of the attributes must now refer to a packet.
1848          *      If there's no packet, we can't print any attribute
1849          *      referencing it.
1850          */
1851         packet = radius_packet(request, vpt->tmpl_list);
1852         if (!packet) {
1853                 if (return_null) return NULL;
1854                 return vp_aprints_type(ctx, vpt->tmpl_da->type);
1855         }
1856
1857         vp = NULL;
1858         switch (vpt->tmpl_da->attr) {
1859         default:
1860                 break;
1861
1862         case PW_PACKET_TYPE:
1863                 dv = dict_valbyattr(PW_PACKET_TYPE, 0, packet->code);
1864                 if (dv) return talloc_typed_strdup(ctx, dv->name);
1865                 return talloc_typed_asprintf(ctx, "%d", packet->code);
1866
1867         case PW_RESPONSE_PACKET_TYPE:
1868         {
1869                 int code = 0;
1870
1871 #ifdef WITH_PROXY
1872                 if (request->proxy_reply && (!request->reply || !request->reply->code)) {
1873                         code = request->proxy_reply->code;
1874                 } else
1875 #endif
1876                         if (request->reply) {
1877                                 code = request->reply->code;
1878                         }
1879
1880                 return talloc_typed_strdup(ctx, fr_packet_codes[code]);
1881         }
1882
1883         /*
1884          *      Virtual attributes which require a temporary VALUE_PAIR
1885          *      to be allocated. We can't use stack allocated memory
1886          *      because of the talloc checks sprinkled throughout the
1887          *      various VP functions.
1888          */
1889         case PW_PACKET_AUTHENTICATION_VECTOR:
1890                 virtual = pairalloc(ctx, vpt->tmpl_da);
1891                 pairmemcpy(virtual, packet->vector, sizeof(packet->vector));
1892                 vp = virtual;
1893                 break;
1894
1895         case PW_CLIENT_IP_ADDRESS:
1896         case PW_PACKET_SRC_IP_ADDRESS:
1897                 if (packet->src_ipaddr.af == AF_INET) {
1898                         virtual = pairalloc(ctx, vpt->tmpl_da);
1899                         virtual->vp_ipaddr = packet->src_ipaddr.ipaddr.ip4addr.s_addr;
1900                         vp = virtual;
1901                 }
1902                 break;
1903
1904         case PW_PACKET_DST_IP_ADDRESS:
1905                 if (packet->dst_ipaddr.af == AF_INET) {
1906                         virtual = pairalloc(ctx, vpt->tmpl_da);
1907                         virtual->vp_ipaddr = packet->dst_ipaddr.ipaddr.ip4addr.s_addr;
1908                         vp = virtual;
1909                 }
1910                 break;
1911
1912         case PW_PACKET_SRC_IPV6_ADDRESS:
1913                 if (packet->src_ipaddr.af == AF_INET6) {
1914                         virtual = pairalloc(ctx, vpt->tmpl_da);
1915                         memcpy(&virtual->vp_ipv6addr,
1916                                &packet->src_ipaddr.ipaddr.ip6addr,
1917                                sizeof(packet->src_ipaddr.ipaddr.ip6addr));
1918                         vp = virtual;
1919                 }
1920                 break;
1921
1922         case PW_PACKET_DST_IPV6_ADDRESS:
1923                 if (packet->dst_ipaddr.af == AF_INET6) {
1924                         virtual = pairalloc(ctx, vpt->tmpl_da);
1925                         memcpy(&virtual->vp_ipv6addr,
1926                                &packet->dst_ipaddr.ipaddr.ip6addr,
1927                                sizeof(packet->dst_ipaddr.ipaddr.ip6addr));
1928                         vp = virtual;
1929                 }
1930                 break;
1931
1932         case PW_PACKET_SRC_PORT:
1933                 virtual = pairalloc(ctx, vpt->tmpl_da);
1934                 virtual->vp_integer = packet->src_port;
1935                 vp = virtual;
1936                 break;
1937
1938         case PW_PACKET_DST_PORT:
1939                 virtual = pairalloc(ctx, vpt->tmpl_da);
1940                 virtual->vp_integer = packet->dst_port;
1941                 vp = virtual;
1942                 break;
1943         }
1944
1945         /*
1946          *      Fake various operations for virtual attributes.
1947          */
1948         if (virtual) {
1949                 if (vpt->tmpl_num != NUM_ANY) switch (vpt->tmpl_num) {
1950                 /*
1951                  *      [n] is NULL (we only have [0])
1952                  */
1953                 default:
1954                         goto finish;
1955                 /*
1956                  *      [*] means only one.
1957                  */
1958                 case NUM_ALL:
1959                         break;
1960
1961                 /*
1962                  *      [#] means 1 (as there's only one)
1963                  */
1964                 case NUM_COUNT:
1965                 count_virtual:
1966                         ret = talloc_strdup(ctx, "1");
1967                         goto finish;
1968
1969                 /*
1970                  *      [0] is fine (get the first instance)
1971                  */
1972                 case 0:
1973                         break;
1974                 }
1975                 goto print;
1976         }
1977
1978 do_print:
1979         switch (vpt->tmpl_num) {
1980         /*
1981          *      Return a count of the VPs.
1982          */
1983         case NUM_COUNT:
1984         {
1985                 int count = 0;
1986
1987                 fr_cursor_first(&cursor);
1988                 while (fr_cursor_next_by_da(&cursor, vpt->tmpl_da, vpt->tmpl_tag)) count++;
1989
1990                 return talloc_typed_asprintf(ctx, "%d", count);
1991         }
1992
1993
1994         /*
1995          *      Concatenate all values together,
1996          *      separated by commas.
1997          */
1998         case NUM_ALL:
1999         {
2000                 char *p, *q;
2001
2002                 if (!fr_cursor_current(&cursor)) return NULL;
2003                 p = vp_aprints_value(ctx, vp, quote);
2004                 if (!p) return NULL;
2005
2006                 while ((vp = tmpl_cursor_next(&cursor, vpt)) != NULL) {
2007                         q = vp_aprints_value(ctx, vp, quote);
2008                         if (!q) return NULL;
2009                         p = talloc_strdup_append(p, ",");
2010                         p = talloc_strdup_append(p, q);
2011                 }
2012
2013                 return p;
2014         }
2015
2016         default:
2017                 /*
2018                  *      The cursor was set to the correct
2019                  *      position above by tmpl_cursor_init.
2020                  */
2021                 vp = fr_cursor_current(&cursor);
2022                 break;
2023         }
2024
2025         if (!vp) {
2026                 if (return_null) return NULL;
2027                 return vp_aprints_type(ctx, vpt->tmpl_da->type);
2028         }
2029
2030 print:
2031         ret = vp_aprints_value(ctx, vp, quote);
2032
2033 finish:
2034         talloc_free(virtual);
2035         return ret;
2036 }
2037
2038 #ifdef DEBUG_XLAT
2039 static const char xlat_spaces[] = "                                                                                                                                                                                                                                                                ";
2040 #endif
2041
2042 static char *xlat_aprint(TALLOC_CTX *ctx, REQUEST *request, xlat_exp_t const * const node,
2043                          RADIUS_ESCAPE_STRING escape, void *escape_ctx, int lvl)
2044 {
2045         ssize_t rcode;
2046         char *str = NULL, *child;
2047         char const *p;
2048
2049         XLAT_DEBUG("%.*sxlat aprint %d", lvl, xlat_spaces, node->type);
2050
2051         switch (node->type) {
2052                 /*
2053                  *      Don't escape this.
2054                  */
2055         case XLAT_LITERAL:
2056                 XLAT_DEBUG("xlat_aprint LITERAL");
2057                 return talloc_typed_strdup(ctx, node->fmt);
2058
2059                 /*
2060                  *      Do a one-character expansion.
2061                  */
2062         case XLAT_PERCENT:
2063         {
2064                 char *nl;
2065                 size_t freespace = 256;
2066                 struct tm ts;
2067                 time_t when;
2068
2069                 XLAT_DEBUG("xlat_aprint PERCENT");
2070
2071                 str = talloc_array(ctx, char, freespace); /* @todo do better allocation */
2072                 p = node->fmt;
2073
2074                 when = request->timestamp;
2075                 if (request->packet) {
2076                         when = request->packet->timestamp.tv_sec;
2077                 }
2078
2079                 switch (*p) {
2080                 case '%':
2081                         str[0] = '%';
2082                         str[1] = '\0';
2083                         break;
2084
2085                 case 'd': /* request day */
2086                         if (!localtime_r(&when, &ts)) goto error;
2087                         strftime(str, freespace, "%d", &ts);
2088                         break;
2089
2090                 case 'l': /* request timestamp */
2091                         snprintf(str, freespace, "%lu",
2092                                  (unsigned long) when);
2093                         break;
2094
2095                 case 'm': /* request month */
2096                         if (!localtime_r(&when, &ts)) goto error;
2097                         strftime(str, freespace, "%m", &ts);
2098                         break;
2099
2100                 case 'n': /* Request Number*/
2101                         snprintf(str, freespace, "%u", request->number);
2102                         break;
2103
2104                 case 't': /* request timestamp */
2105                         CTIME_R(&when, str, freespace);
2106                         nl = strchr(str, '\n');
2107                         if (nl) *nl = '\0';
2108                         break;
2109
2110                 case 'D': /* request date */
2111                         if (!localtime_r(&when, &ts)) goto error;
2112                         strftime(str, freespace, "%Y%m%d", &ts);
2113                         break;
2114
2115                 case 'G': /* request minute */
2116                         if (!localtime_r(&when, &ts)) goto error;
2117                         strftime(str, freespace, "%M", &ts);
2118                         break;
2119
2120                 case 'H': /* request hour */
2121                         if (!localtime_r(&when, &ts)) goto error;
2122                         strftime(str, freespace, "%H", &ts);
2123                         break;
2124
2125                 case 'I': /* Request ID */
2126                         if (request->packet) {
2127                                 snprintf(str, freespace, "%i", request->packet->id);
2128                         }
2129                         break;
2130
2131                 case 'S': /* request timestamp in SQL format*/
2132                         if (!localtime_r(&when, &ts)) goto error;
2133                         strftime(str, freespace, "%Y-%m-%d %H:%M:%S", &ts);
2134                         break;
2135
2136                 case 'T': /* request timestamp */
2137                         if (!localtime_r(&when, &ts)) goto error;
2138                         strftime(str, freespace, "%Y-%m-%d-%H.%M.%S.000000", &ts);
2139                         break;
2140
2141                 case 'Y': /* request year */
2142                         if (!localtime_r(&when, &ts)) {
2143                                 error:
2144                                 REDEBUG("Failed converting packet timestamp to localtime: %s", fr_syserror(errno));
2145                                 talloc_free(str);
2146                                 return NULL;
2147                         }
2148                         strftime(str, freespace, "%Y", &ts);
2149                         break;
2150
2151                 case 'v': /* Version of code */
2152                         RWDEBUG("%%v is deprecated and will be removed.  Use ${version.freeradius-server}");
2153                         snprintf(str, freespace, "%s", radiusd_version_short);
2154                         break;
2155
2156                 default:
2157                         rad_assert(0 == 1);
2158                         break;
2159                 }
2160         }
2161                 break;
2162
2163         case XLAT_ATTRIBUTE:
2164                 XLAT_DEBUG("xlat_aprint ATTRIBUTE");
2165
2166                 /*
2167                  *      Some attributes are virtual <sigh>
2168                  */
2169                 str = xlat_getvp(ctx, request, &node->attr, escape ? false : true, true);
2170                 if (str) {
2171                         XLAT_DEBUG("EXPAND attr %s", node->attr.tmpl_da->name);
2172                         XLAT_DEBUG("       ---> %s", str);
2173                 }
2174                 break;
2175
2176         case XLAT_VIRTUAL:
2177                 XLAT_DEBUG("xlat_aprint VIRTUAL");
2178                 str = talloc_array(ctx, char, 2048); /* FIXME: have the module call talloc_typed_asprintf */
2179                 rcode = node->xlat->func(node->xlat->instance, request, NULL, str, 2048);
2180                 if (rcode < 0) {
2181                         talloc_free(str);
2182                         return NULL;
2183                 }
2184                 RDEBUG2("EXPAND %s", node->xlat->name);
2185                 RDEBUG2("   --> %s", str);
2186                 break;
2187
2188         case XLAT_MODULE:
2189                 XLAT_DEBUG("xlat_aprint MODULE");
2190                 if (xlat_process(&child, request, node->child, node->xlat->escape, node->xlat->instance) == 0) {
2191                         return NULL;
2192                 }
2193
2194                 XLAT_DEBUG("%.*sEXPAND mod %s %s", lvl, xlat_spaces, node->fmt, node->child->fmt);
2195                 XLAT_DEBUG("%.*s      ---> %s", lvl, xlat_spaces, child);
2196
2197                 /*
2198                  *      Smash \n --> CR.
2199                  *
2200                  *      The OUTPUT of xlat is a printable string.  The INPUT might not be...
2201                  *
2202                  *      This is really the reverse of fr_prints().
2203                  */
2204                 if (cf_new_escape && *child) {
2205                         ssize_t slen;
2206                         PW_TYPE type;
2207                         value_data_t data;
2208
2209                         type = PW_TYPE_STRING;
2210                         slen = value_data_from_str(request, &data, &type, NULL, child, talloc_array_length(child) - 1, '"');
2211                         rad_assert(slen > 0);
2212
2213                         talloc_free(child);
2214                         child = data.ptr;
2215
2216                 } else {
2217                         char *q;
2218
2219                         p = q = child;
2220                         while (*p) {
2221                                 if (*p == '\\') switch (p[1]) {
2222                                         default:
2223                                                 *(q++) = p[1];
2224                                                 p += 2;
2225                                                 continue;
2226
2227                                         case 'n':
2228                                                 *(q++) = '\n';
2229                                                 p += 2;
2230                                                 continue;
2231
2232                                         case 't':
2233                                                 *(q++) = '\t';
2234                                                 p += 2;
2235                                                 continue;
2236                                         }
2237
2238                                 *(q++) = *(p++);
2239                         }
2240                         *q = '\0';
2241                 }
2242
2243                 str = talloc_array(ctx, char, 2048); /* FIXME: have the module call talloc_typed_asprintf */
2244                 *str = '\0';    /* Be sure the string is NULL terminated, we now only free on error */
2245
2246                 rcode = node->xlat->func(node->xlat->instance, request, child, str, 2048);
2247                 talloc_free(child);
2248                 if (rcode < 0) {
2249                         talloc_free(str);
2250                         return NULL;
2251                 }
2252                 break;
2253
2254 #ifdef HAVE_REGEX
2255         case XLAT_REGEX:
2256                 XLAT_DEBUG("xlat_aprint REGEX");
2257                 if (regex_request_to_sub(ctx, &str, request, node->attr.tmpl_num) < 0) return NULL;
2258
2259                 break;
2260 #endif
2261
2262         case XLAT_ALTERNATE:
2263                 XLAT_DEBUG("xlat_aprint ALTERNATE");
2264                 rad_assert(node->child != NULL);
2265                 rad_assert(node->alternate != NULL);
2266
2267                 str = xlat_aprint(ctx, request, node->child, escape, escape_ctx, lvl);
2268                 if (str) break;
2269
2270                 str = xlat_aprint(ctx, request, node->alternate, escape, escape_ctx, lvl);
2271                 break;
2272
2273         }
2274
2275         /*
2276          *      Escape the non-literals we found above.
2277          */
2278         if (str && escape) {
2279                 char *escaped;
2280
2281                 escaped = talloc_array(ctx, char, 2048); /* FIXME: do something intelligent */
2282                 escape(request, escaped, 2038, str, escape_ctx);
2283                 talloc_free(str);
2284                 str = escaped;
2285         }
2286
2287         return str;
2288 }
2289
2290
2291 static size_t xlat_process(char **out, REQUEST *request, xlat_exp_t const * const head,
2292                            RADIUS_ESCAPE_STRING escape, void *escape_ctx)
2293 {
2294         int i, list;
2295         size_t total;
2296         char **array, *answer;
2297         xlat_exp_t const *node;
2298
2299         *out = NULL;
2300
2301         /*
2302          *      There are no nodes to process, so the result is a zero
2303          *      length string.
2304          */
2305         if (!head) {
2306                 *out = talloc_zero_array(request, char, 1);
2307                 return 0;
2308         }
2309
2310         /*
2311          *      Hack for speed.  If it's one expansion, just allocate
2312          *      that and return, instead of allocating an intermediary
2313          *      array.
2314          */
2315         if (!head->next) {
2316                 /*
2317                  *      Pass the MAIN escape function.  Recursive
2318                  *      calls will call node-specific escape
2319                  *      functions.
2320                  */
2321                 answer = xlat_aprint(request, request, head, escape, escape_ctx, 0);
2322                 if (!answer) {
2323                         *out = talloc_zero_array(request, char, 1);
2324                         return 0;
2325                 }
2326                 *out = answer;
2327                 return strlen(answer);
2328         }
2329
2330         list = 0;               /* FIXME: calculate this once */
2331         for (node = head; node != NULL; node = node->next) {
2332                 list++;
2333         }
2334
2335         array = talloc_array(request, char *, list);
2336         if (!array) return -1;
2337
2338         for (node = head, i = 0; node != NULL; node = node->next, i++) {
2339                 array[i] = xlat_aprint(array, request, node, escape, escape_ctx, 0); /* may be NULL */
2340         }
2341
2342         total = 0;
2343         for (i = 0; i < list; i++) {
2344                 if (array[i]) total += strlen(array[i]); /* FIXME: calculate strlen once */
2345         }
2346
2347         if (!total) {
2348                 talloc_free(array);
2349                 *out = talloc_zero_array(request, char, 1);
2350                 return 0;
2351         }
2352
2353         answer = talloc_array(request, char, total + 1);
2354
2355         total = 0;
2356         for (i = 0; i < list; i++) {
2357                 size_t len;
2358
2359                 if (array[i]) {
2360                         len = strlen(array[i]);
2361                         memcpy(answer + total, array[i], len);
2362                         total += len;
2363                 }
2364         }
2365         answer[total] = '\0';
2366         talloc_free(array);     /* and child entries */
2367
2368         *out = answer;
2369         return total;
2370 }
2371
2372
2373 /** Replace %whatever in a string.
2374  *
2375  * See 'doc/variables.txt' for more information.
2376  *
2377  * @param[out] out Where to write pointer to output buffer.
2378  * @param[in] outlen Size of out.
2379  * @param[in] request current request.
2380  * @param[in] node the xlat structure to expand
2381  * @param[in] escape function to escape final value e.g. SQL quoting.
2382  * @param[in] escape_ctx pointer to pass to escape function.
2383  * @return length of string written @bug should really have -1 for failure
2384  */
2385 static ssize_t xlat_expand_struct(char **out, size_t outlen, REQUEST *request, xlat_exp_t const *node,
2386                                   RADIUS_ESCAPE_STRING escape, void *escape_ctx)
2387 {
2388         char *buff;
2389         ssize_t len;
2390
2391         rad_assert(node != NULL);
2392
2393         len = xlat_process(&buff, request, node, escape, escape_ctx);
2394         if ((len < 0) || !buff) {
2395                 rad_assert(buff == NULL);
2396                 if (*out) *out[0] = '\0';
2397                 return len;
2398         }
2399
2400         if (!*out) {
2401                 *out = buff;
2402         } else {
2403                 strlcpy(*out, buff, outlen);
2404                 talloc_free(buff);
2405         }
2406
2407         return strlen(*out);
2408 }
2409
2410 static ssize_t xlat_expand(char **out, size_t outlen, REQUEST *request, char const *fmt,
2411                            RADIUS_ESCAPE_STRING escape, void *escape_ctx) CC_HINT(nonnull (1, 3, 4));
2412
2413 /** Replace %whatever in a string.
2414  *
2415  * See 'doc/variables.txt' for more information.
2416  *
2417  * @param[out] out Where to write pointer to output buffer.
2418  * @param[in] outlen Size of out.
2419  * @param[in] request current request.
2420  * @param[in] fmt string to expand.
2421  * @param[in] escape function to escape final value e.g. SQL quoting.
2422  * @param[in] escape_ctx pointer to pass to escape function.
2423  * @return length of string written @bug should really have -1 for failure
2424  */
2425 static ssize_t xlat_expand(char **out, size_t outlen, REQUEST *request, char const *fmt,
2426                            RADIUS_ESCAPE_STRING escape, void *escape_ctx)
2427 {
2428         ssize_t len;
2429         xlat_exp_t *node;
2430
2431         /*
2432          *      Give better errors than the old code.
2433          */
2434         len = xlat_tokenize_request(request, fmt, &node);
2435         if (len == 0) {
2436                 if (*out) {
2437                         *out[0] = '\0';
2438                 } else {
2439                         *out = talloc_zero_array(request, char, 1);
2440                 }
2441                 return 0;
2442         }
2443
2444         if (len < 0) {
2445                 if (*out) *out[0] = '\0';
2446                 return -1;
2447         }
2448
2449         len = xlat_expand_struct(out, outlen, request, node, escape, escape_ctx);
2450         talloc_free(node);
2451
2452         RDEBUG2("EXPAND %s", fmt);
2453         RDEBUG2("   --> %s", *out);
2454
2455         return len;
2456 }
2457
2458 /** Try to convert an xlat to a tmpl for efficiency
2459  *
2460  * @param ctx to allocate new value_pair_tmpl_t in.
2461  * @param node to convert.
2462  * @return NULL if unable to convert (not necessarily error), or a new value_pair_tmpl_t.
2463  */
2464 value_pair_tmpl_t *xlat_to_tmpl_attr(TALLOC_CTX *ctx, xlat_exp_t *node)
2465 {
2466         value_pair_tmpl_t *vpt;
2467
2468         if (node->next || (node->type != XLAT_ATTRIBUTE)) return NULL;
2469
2470         /*
2471          *   Concat means something completely different as an attribute reference
2472          *   Count isn't implemented.
2473          */
2474         if ((node->attr.tmpl_num == NUM_COUNT) || (node->attr.tmpl_num == NUM_ALL)) return NULL;
2475
2476         vpt = tmpl_alloc(ctx, TMPL_TYPE_ATTR, node->fmt, -1);
2477         if (!vpt) return NULL;
2478         memcpy(&vpt->data, &node->attr.data, sizeof(vpt->data));
2479
2480         VERIFY_TMPL(vpt);
2481
2482         return vpt;
2483 }
2484
2485 /** Try to convert attr tmpl to an xlat for &attr[*] and artificially constructing expansions
2486  *
2487  * @param ctx to allocate new xlat_expt_t in.
2488  * @param vpt to convert.
2489  * @return NULL if unable to convert (not necessarily error), or a new value_pair_tmpl_t.
2490  */
2491 xlat_exp_t *xlat_from_tmpl_attr(TALLOC_CTX *ctx, value_pair_tmpl_t *vpt)
2492 {
2493         xlat_exp_t *node;
2494
2495         if (vpt->type != TMPL_TYPE_ATTR) return NULL;
2496
2497         node = talloc_zero(ctx, xlat_exp_t);
2498         node->fmt = talloc_memdup(node, vpt->name, vpt->len);
2499         tmpl_init(&node->attr, TMPL_TYPE_ATTR, node->fmt, talloc_array_length(node->fmt) - 1);
2500         memcpy(&node->attr.data, &vpt->data, sizeof(vpt->data));
2501
2502         return node;
2503 }
2504
2505 ssize_t radius_xlat(char *out, size_t outlen, REQUEST *request, char const *fmt, RADIUS_ESCAPE_STRING escape, void *ctx)
2506 {
2507         return xlat_expand(&out, outlen, request, fmt, escape, ctx);
2508 }
2509
2510 ssize_t radius_axlat(char **out, REQUEST *request, char const *fmt, RADIUS_ESCAPE_STRING escape, void *ctx)
2511 {
2512         return xlat_expand(out, 0, request, fmt, escape, ctx);
2513 }
2514
2515 ssize_t radius_axlat_struct(char **out, REQUEST *request, xlat_exp_t const *xlat, RADIUS_ESCAPE_STRING escape, void *ctx)
2516 {
2517         return xlat_expand_struct(out, 0, request, xlat, escape, ctx);
2518 }