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