Certain data types are forbidden in casts
[freeradius.git] / src / main / parser.c
1 /*
2  * parser.c     Parse various things
3  *
4  * Version:     $Id$
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2013  Alan DeKok <aland@freeradius.org>
21  */
22
23 RCSID("$Id$")
24
25 #include <freeradius-devel/radiusd.h>
26 #include <freeradius-devel/parser.h>
27 #include <freeradius-devel/rad_assert.h>
28
29 #include <ctype.h>
30
31 #define PW_CAST_BASE (1850)
32
33 static const FR_NAME_NUMBER allowed_return_codes[] = {
34         { "reject",     1 },
35         { "fail",       1 },
36         { "ok",         1 },
37         { "handled",    1 },
38         { "invalid",    1 },
39         { "userlock",   1 },
40         { "notfound",   1 },
41         { "noop",       1 },
42         { "updated",    1 },
43         { NULL, 0 }
44 };
45
46 /*
47  *      This file shouldn't use any functions from the server core.
48  */
49
50 size_t fr_cond_sprint(char *buffer, size_t bufsize, fr_cond_t const *c)
51 {
52         size_t len;
53         char *p = buffer;
54         char *end = buffer + bufsize - 1;
55
56 next:
57         if (c->negate) {
58                 *(p++) = '!';   /* FIXME: only allow for child? */
59         }
60
61         switch (c->type) {
62         case COND_TYPE_EXISTS:
63                 rad_assert(c->data.vpt != NULL);
64                 if (c->cast) {
65                         len = snprintf(p, end - p, "<%s>", fr_int2str(dict_attr_types,
66                                                                       c->cast->type, "??"));
67                         p += len;
68                 }
69
70                 len = radius_tmpl2str(p, end - p, c->data.vpt);
71                 p += len;
72                 break;
73
74         case COND_TYPE_MAP:
75                 rad_assert(c->data.map != NULL);
76 #if 0
77                 *(p++) = '[';   /* for extra-clear debugging */
78 #endif
79                 if (c->cast) {
80                         len = snprintf(p, end - p, "<%s>", fr_int2str(dict_attr_types,
81                                                                       c->cast->type, "??"));
82                         p += len;
83                 }
84
85                 len = radius_map2str(p, end - p, c->data.map);
86                 p += len;
87 #if 0
88                 *(p++) = ']';
89 #endif
90                 break;
91
92         case COND_TYPE_CHILD:
93                 rad_assert(c->data.child != NULL);
94                 *(p++) = '(';
95                 len = fr_cond_sprint(p, end - p, c->data.child);
96                 p += len;
97                 *(p++) = ')';
98                 break;
99
100         case COND_TYPE_TRUE:
101                 strlcpy(buffer, "true", bufsize);
102                 return strlen(buffer);
103
104         case COND_TYPE_FALSE:
105                 strlcpy(buffer, "false", bufsize);
106                 return strlen(buffer);
107
108         default:
109                 *buffer = '\0';
110                 return 0;
111         }
112
113         if (c->next_op == COND_NONE) {
114                 rad_assert(c->next == NULL);
115                 *p = '\0';
116                 return p - buffer;
117         }
118
119         if (c->next_op == COND_AND) {
120                 strlcpy(p, " && ", end - p);
121                 p += strlen(p);
122
123         } else if (c->next_op == COND_OR) {
124                 strlcpy(p, " || ", end - p);
125                 p += strlen(p);
126
127         } else {
128                 rad_assert(0 == 1);
129         }
130
131         c = c->next;
132         goto next;
133 }
134
135
136 static ssize_t condition_tokenize_string(TALLOC_CTX *ctx, char const *start, char **out,
137                                          FR_TOKEN *op, char const **error)
138 {
139         char const *p = start;
140         char *q;
141
142         switch (*p++) {
143         default:
144                 return -1;
145
146         case '"':
147                 *op = T_DOUBLE_QUOTED_STRING;
148                 break;
149
150         case '\'':
151                 *op = T_SINGLE_QUOTED_STRING;
152                 break;
153
154         case '`':
155                 *op = T_BACK_QUOTED_STRING;
156                 break;
157
158         case '/':
159                 *op = T_OP_REG_EQ; /* a bit of a hack. */
160                 break;
161
162         }
163
164         *out = talloc_array(ctx, char, strlen(start) - 1); /* + 2 - 1 */
165         if (!*out) return -1;
166
167         q = *out;
168
169         while (*p) {
170                 if (*p == *start) {
171                         *q = '\0';
172                         p++;
173                         return (p - start);
174                 }
175
176                 if (*p == '\\') {
177                         p++;
178                         if (!*p) {
179                                 *error = "End of string after escape";
180                                 return -(p - start);
181                         }
182
183                         switch (*p) {
184                         case 'r':
185                                 *q++ = '\r';
186                                 break;
187                         case 'n':
188                                 *q++ = '\n';
189                                 break;
190                         case 't':
191                                 *q++ = '\t';
192                                 break;
193                         default:
194                                 *q++ = *p;
195                                 break;
196                         }
197                         p++;
198                         continue;
199                 }
200
201                 *(q++) = *(p++);
202         }
203
204         *error = "Unterminated string";
205         return -1;
206 }
207
208 static ssize_t condition_tokenize_word(TALLOC_CTX *ctx, char const *start, char **out,
209                                        FR_TOKEN *op, char const **error)
210 {
211         size_t len;
212         char const *p = start;
213
214         if ((*p == '"') || (*p == '\'') || (*p == '`') || (*p == '/')) {
215                 return condition_tokenize_string(ctx, start, out, op, error);
216         }
217
218         *op = T_BARE_WORD;
219         if (*p == '&') p++;     /* special-case &User-Name */
220
221         while (*p) {
222                 /*
223                  *      The LHS should really be limited to only a few
224                  *      things.  For now, we allow pretty much anything.
225                  */
226                 if (*p == '\\') {
227                         *error = "Unexpected escape";
228                         return -(p - start);
229                 }
230
231                 /*
232                  *      ("foo") is valid.
233                  */
234                 if (*p == ')') {
235                         break;
236                 }
237
238                 /*
239                  *      Spaces or special characters delineate the word
240                  */
241                 if (isspace((int) *p) || (*p == '&') || (*p == '|') ||
242                     (*p == '!') || (*p == '=') || (*p == '<') || (*p == '>')) {
243                         break;
244                 }
245
246                 if ((*p == '"') || (*p == '\'') || (*p == '`')) {
247                         *error = "Unexpected start of string";
248                         return -(p - start);
249                 }
250
251                 p++;
252         }
253
254         len = p - start;
255         if (!len) {
256                 *error = "Empty string is invalid";
257                 return 0;
258         }
259
260         *out = talloc_array(ctx, char, len + 1);
261         memcpy(*out, start, len);
262         (*out)[len] = '\0';
263         return len;
264 }
265
266
267 static ssize_t condition_tokenize_cast(char const *start, DICT_ATTR const **pda, char const **error)
268 {
269         char const *p = start;
270         char const *q;
271         PW_TYPE cast;
272
273         while (isspace((int) *p)) p++; /* skip spaces before condition */
274
275         if (*p != '<') return 0;
276         p++;
277
278         q = p;
279         while (*q && *q != '>') q++;
280
281         cast = fr_substr2int(dict_attr_types, p, PW_TYPE_INVALID, q - p);
282         if (cast == PW_TYPE_INVALID) {
283                 *error = "Invalid data type in cast";
284                 return -(p - start);
285         }
286
287         /*
288          *      We can only cast to basic data types.  Complex ones
289          *      are forbidden.
290          */
291         switch (cast) {
292 #ifdef WITH_ASCEND_BINARY
293         case PW_TYPE_ABINARY:
294 #endif
295         case PW_TYPE_COMBO_IP:
296         case PW_TYPE_TLV:
297         case PW_TYPE_EXTENDED:
298         case PW_TYPE_LONG_EXTENDED:
299         case PW_TYPE_EVS:
300         case PW_TYPE_VSA:
301                 *error = "Forbidden data type in cast";
302                 return -(p - start);
303
304         default:
305                 break;
306         }
307
308         *pda = dict_attrbyvalue(PW_CAST_BASE + cast, 0);
309         if (!*pda) {
310                 *error = "Cannot cast to this data type";
311                 return -(p - start);
312         }
313
314         q++;
315
316         while (isspace((int) *q)) q++; /* skip spaces after cast */
317
318         return q - start;
319 }
320
321 /*
322  *      Less code means less bugs
323  */
324 #define return_P(_x) *error = _x;goto return_p
325 #define return_0(_x) *error = _x;goto return_0
326 #define return_lhs(_x) *error = _x;goto return_lhs
327 #define return_rhs(_x) *error = _x;goto return_rhs
328 #define return_SLEN goto return_slen
329
330
331 /** Tokenize a conditional check
332  *
333  *  @param[in] ctx for talloc
334  *  @param[in] ci for CONF_ITEM
335  *  @param[in] start the start of the string to process.  Should be "(..."
336  *  @param[in] brace look for a closing brace
337  *  @param[in] flags do one/two pass
338  *  @param[out] pcond pointer to the returned condition structure
339  *  @param[out] error the parse error (if any)
340  *  @return length of the string skipped, or when negative, the offset to the offending error
341  */
342 static ssize_t condition_tokenize(TALLOC_CTX *ctx, CONF_ITEM *ci, char const *start, int brace, fr_cond_t **pcond, char const **error, int flags)
343 {
344         ssize_t slen;
345         char const *p = start;
346         char const *lhs_p, *rhs_p;
347         fr_cond_t *c;
348         char *lhs, *rhs;
349         FR_TOKEN op, lhs_type, rhs_type;
350
351         c = talloc_zero(ctx, fr_cond_t);
352
353         rad_assert(c != NULL);
354         lhs = rhs = NULL;
355         lhs_type = rhs_type = T_OP_INVALID;
356
357         while (isspace((int) *p)) p++; /* skip spaces before condition */
358
359         if (!*p) {
360                 return_P("Empty condition is invalid");
361         }
362
363         /*
364          *      !COND
365          */
366         if (*p == '!') {
367                 p++;
368                 c->negate = true;
369                 while (isspace((int) *p)) p++; /* skip spaces after negation */
370
371                 /*
372                  *  Just for stupidity
373                  */
374                 if (*p == '!') {
375                         return_P("Double negation is invalid");
376                 }
377         }
378
379         /*
380          *      (COND)
381          */
382         if (*p == '(') {
383                 p++;
384
385                 /*
386                  *      We've already eaten one layer of
387                  *      brackets.  Go recurse to get more.
388                  */
389                 c->type = COND_TYPE_CHILD;
390                 c->ci = ci;
391                 slen = condition_tokenize(c, ci, p, true, &c->data.child, error, flags);
392                 if (slen <= 0) {
393                         return_SLEN;
394                 }
395
396                 if (!c->data.child) {
397                         return_P("Empty condition is invalid");
398                 }
399
400                 p += slen;
401                 while (isspace((int) *p)) p++; /* skip spaces after (COND)*/
402
403         } else { /* it's a bare FOO==BAR */
404                 /*
405                  *      We didn't see anything special.  The condition must be one of
406                  *
407                  *      FOO
408                  *      FOO OP BAR
409                  */
410
411                 /*
412                  *      Grab the LHS
413                  */
414                 if (*p == '/') {
415                         return_P("Conditional check cannot begin with a regular expression");
416                 }
417
418                 slen = condition_tokenize_cast(p, &c->cast, error);
419                 if (slen < 0) {
420                         return_SLEN;
421                 }
422                 p += slen;
423
424                 lhs_p = p;
425                 slen = condition_tokenize_word(c, p, &lhs, &lhs_type, error);
426                 if (slen <= 0) {
427                         return_SLEN;
428                 }
429                 p += slen;
430
431                 while (isspace((int)*p)) p++; /* skip spaces after LHS */
432
433                 /*
434                  *      We may (or not) have an operator
435                  */
436
437
438                 /*
439                  *      (FOO)
440                  */
441                 if (*p == ')') {
442                         /*
443                          *      don't skip the brace.  We'll look for it later.
444                          */
445                         goto exists;
446
447                         /*
448                          *      FOO
449                          */
450                 } else if (!*p) {
451                         if (brace) {
452                                 return_P("No closing brace at end of string");
453                         }
454
455                         goto exists;
456
457                         /*
458                          *      FOO && ...
459                          */
460                 } else if (((p[0] == '&') && (p[1] == '&')) ||
461                            ((p[0] == '|') && (p[1] == '|'))) {
462
463                 exists:
464                         if (c->cast) {
465                                 return_0("Cannot do cast for existence check");
466                         }
467
468                         c->type = COND_TYPE_EXISTS;
469                         c->ci = ci;
470
471                         c->data.vpt = radius_str2tmpl(c, lhs, lhs_type, REQUEST_CURRENT, PAIR_LIST_REQUEST);
472                         if (!c->data.vpt) {
473                                 return_P("Failed creating exists");
474                         }
475
476                         rad_assert(c->data.vpt->type != VPT_TYPE_REGEX);
477
478                 } else { /* it's an operator */
479                         int regex;
480
481                         /*
482                          *      The next thing should now be a comparison operator.
483                          */
484                         regex = false;
485                         c->type = COND_TYPE_MAP;
486                         c->ci = ci;
487
488                         switch (*p) {
489                         default:
490                                 return_P("Invalid text. Expected comparison operator");
491
492                         case '!':
493                                 if (p[1] == '=') {
494                                         op = T_OP_NE;
495                                         p += 2;
496
497                                 } else if (p[1] == '~') {
498                                 regex = true;
499
500                                 op = T_OP_REG_NE;
501                                 p += 2;
502
503                                 } else if (p[1] == '*') {
504                                         if (lhs_type != T_BARE_WORD) {
505                                                 return_P("Cannot use !* on a string");
506                                         }
507
508                                         op = T_OP_CMP_FALSE;
509                                         p += 2;
510
511                                 } else {
512                                         goto invalid_operator;
513                                 }
514                                 break;
515
516                         case '=':
517                                 if (p[1] == '=') {
518                                         op = T_OP_CMP_EQ;
519                                         p += 2;
520
521                                 } else if (p[1] == '~') {
522                                         regex = true;
523
524                                         op = T_OP_REG_EQ;
525                                         p += 2;
526
527                                 } else if (p[1] == '*') {
528                                         if (lhs_type != T_BARE_WORD) {
529                                                 return_P("Cannot use =* on a string");
530                                         }
531
532                                         op = T_OP_CMP_TRUE;
533                                         p += 2;
534
535                                 } else {
536                                 invalid_operator:
537                                         return_P("Invalid operator");
538                                 }
539
540                                 break;
541
542                         case '<':
543                                 if (p[1] == '=') {
544                                         op = T_OP_LE;
545                                         p += 2;
546
547                                 } else {
548                                         op = T_OP_LT;
549                                         p++;
550                                 }
551                                 break;
552
553                         case '>':
554                                 if (p[1] == '=') {
555                                         op = T_OP_GE;
556                                         p += 2;
557
558                                 } else {
559                                         op = T_OP_GT;
560                                         p++;
561                                 }
562                                 break;
563                         }
564
565                         while (isspace((int) *p)) p++; /* skip spaces after operator */
566
567                         if (!*p) {
568                                 return_P("Expected text after operator");
569                         }
570
571                         /*
572                          *      Cannot have a cast on the RHS.
573                          *      But produce good errors, too.
574                          */
575                         if (*p == '<') {
576                                 DICT_ATTR const *cast_da;
577
578                                 slen = condition_tokenize_cast(p, &cast_da, error);
579                                 if (slen < 0) {
580                                         return_SLEN;
581                                 }
582
583                                 if (!c->cast) {
584                                         return_P("Unexpected cast");
585                                 }
586
587                                 if (c->cast != cast_da) {
588                                         return_P("Cannot cast to a different data type");
589                                 }
590
591                                 return_P("Unnecessary cast");
592                         }
593
594                         /*
595                          *      Grab the RHS
596                          */
597                         rhs_p = p;
598                         slen = condition_tokenize_word(c, p, &rhs, &rhs_type, error);
599                         if (slen <= 0) {
600                                 return_SLEN;
601                         }
602
603                         /*
604                          *      Sanity checks for regexes.
605                          */
606                         if (regex) {
607                                 if (*p != '/') {
608                                         return_P("Expected regular expression");
609                                 }
610
611                                 /*
612                                  *      Allow /foo/i
613                                  */
614                                 if (p[slen] == 'i') {
615                                         c->regex_i = true;
616                                         slen++;
617                                 }
618
619                         } else if (!regex && (*p == '/')) {
620                                 return_P("Unexpected regular expression");
621                         }
622
623                         c->data.map = radius_str2map(c, lhs, lhs_type, op, rhs, rhs_type,
624                                                      REQUEST_CURRENT, PAIR_LIST_REQUEST,
625                                                      REQUEST_CURRENT, PAIR_LIST_REQUEST);
626                         if (!c->data.map) {
627                                 if (*lhs == '&') {
628                                         /*
629                                          *      FIXME: In the future,
630                                          *      have str2map above
631                                          *      know whether this is
632                                          *      pass1 or pass2.  If
633                                          *      it's pass2, then an
634                                          *      unknown attribute is a
635                                          *      soft fail.
636                                          */
637                                         return_0("Unknown attribute");
638                                 }
639                                 return_0("Syntax error");
640                         }
641
642                         /*
643                          *      Could have been a reference to an attribute which is registered later.
644                          *      Mark it as being checked in pass2.
645                          */
646                         if ((lhs_type == T_BARE_WORD) &&
647                             (c->data.map->dst->type == VPT_TYPE_LITERAL)) {
648                                 c->pass2_fixup = PASS2_FIXUP_ATTR;
649                         }
650
651                         /*
652                          *      Save the CONF_ITEM for later.
653                          */
654                         c->data.map->ci = ci;
655
656                         /*
657                          *      @todo: check LHS and RHS separately, to
658                          *      get better errors
659                          */
660                         if ((c->data.map->src->type == VPT_TYPE_LIST) ||
661                             (c->data.map->dst->type == VPT_TYPE_LIST)) {
662                                 return_0("Cannot use list references in condition");
663                         }
664
665                         /*
666                          *      Check cast type.  We can have the RHS
667                          *      a string if the LHS has a cast.  But
668                          *      if the RHS is an attr, it MUST be the
669                          *      same type as the LHS.
670                          */
671                         if (c->cast) {
672                                 if ((c->data.map->src->type == VPT_TYPE_ATTR) &&
673                                     (c->cast->type != c->data.map->src->da->type)) {
674                                         goto same_type;
675                                 }
676
677                                 if (c->data.map->src->type == VPT_TYPE_REGEX) {
678                                         return_0("Cannot use cast with regex comparison");
679                                 }
680
681                                 /*
682                                  *      The LHS is a literal which has been cast to a data type.
683                                  *      Cast it to the appropriate data type.
684                                  */
685                                 if ((c->data.map->dst->type == VPT_TYPE_LITERAL) &&
686                                     !radius_cast_tmpl(c->data.map->dst, c->cast)) {
687                                         *error = "Failed to parse field";
688                                         if (lhs) talloc_free(lhs);
689                                         if (rhs) talloc_free(rhs);
690                                         talloc_free(c);
691                                         return -(lhs_p - start);
692                                 }
693
694                                 /*
695                                  *      The RHS is a literal, and the LHS has been cast to a data
696                                  *      type.
697                                  */
698                                 if ((c->data.map->dst->type == VPT_TYPE_DATA) &&
699                                     (c->data.map->src->type == VPT_TYPE_LITERAL) &&
700                                     !radius_cast_tmpl(c->data.map->src, c->data.map->dst->da)) {
701                                         return_rhs("Failed to parse field");
702                                 }
703
704                                 /*
705                                  *      Casting to a redundant type means we don't need the cast.
706                                  *
707                                  *      Do this LAST, as the rest of the code above assumes c->cast
708                                  *      is not NULL.
709                                  */
710                                 if ((c->data.map->dst->type == VPT_TYPE_ATTR) &&
711                                     (c->cast->type == c->data.map->dst->da->type)) {
712                                         c->cast = NULL;
713                                 }
714
715                         } else {
716                                 /*
717                                  *      Two attributes?  They must be of the same type
718                                  */
719                                 if ((c->data.map->src->type == VPT_TYPE_ATTR) &&
720                                     (c->data.map->dst->type == VPT_TYPE_ATTR) &&
721                                     (c->data.map->dst->da->type != c->data.map->src->da->type)) {
722                                 same_type:
723                                         return_0("Attribute comparisons must be of the same data type");
724                                 }
725
726                                 /*
727                                  *      Without a cast, we can't compare "foo" to User-Name,
728                                  *      it has to be done the other way around.
729                                  */
730                                 if ((c->data.map->src->type == VPT_TYPE_ATTR) &&
731                                     (c->data.map->dst->type != VPT_TYPE_ATTR)) {
732                                         *error = "Cannot use attribute reference on right side of condition";
733                                 return_0:
734                                         if (lhs) talloc_free(lhs);
735                                         if (rhs) talloc_free(rhs);
736                                         talloc_free(c);
737                                         return 0;
738                                 }
739
740                                 /*
741                                  *      Invalid: User-Name == bob
742                                  *      Valid:   User-Name == "bob"
743                                  *
744                                  *      There's no real reason for
745                                  *      this, other than consistency.
746                                  */
747                                 if ((c->data.map->dst->type == VPT_TYPE_ATTR) &&
748                                     (c->data.map->src->type != VPT_TYPE_ATTR) &&
749                                     (c->data.map->dst->da->type == PW_TYPE_STRING) &&
750                                     (c->data.map->op != T_OP_CMP_TRUE) &&
751                                     (c->data.map->op != T_OP_CMP_FALSE) &&
752                                     (rhs_type == T_BARE_WORD)) {
753                                         return_rhs("Must have string as value for attribute");
754                                 }
755
756                                 /*
757                                  *      Quotes around non-string
758                                  *      attributes mean that it's
759                                  *      either xlat, or an exec.
760                                  */
761                                 if ((c->data.map->dst->type == VPT_TYPE_ATTR) &&
762                                     (c->data.map->src->type != VPT_TYPE_ATTR) &&
763                                     (c->data.map->dst->da->type != PW_TYPE_STRING) &&
764                                     (c->data.map->dst->da->type != PW_TYPE_OCTETS) &&
765                                     (c->data.map->dst->da->type != PW_TYPE_DATE) &&
766                                     (rhs_type == T_SINGLE_QUOTED_STRING)) {
767                                         *error = "Value must be an unquoted string";
768                                 return_rhs:
769                                         if (lhs) talloc_free(lhs);
770                                         if (rhs) talloc_free(rhs);
771                                         talloc_free(c);
772                                         return -(rhs_p - start);
773                                 }
774
775                                 /*
776                                  *      The LHS has been cast to a data type, and the RHS is a
777                                  *      literal.  Cast the RHS to the type of the cast.
778                                  */
779                                 if (c->cast && (c->data.map->src->type == VPT_TYPE_LITERAL) &&
780                                     !radius_cast_tmpl(c->data.map->src, c->cast)) {
781                                         return_rhs("Failed to parse field");
782                                 }
783
784                                 /*
785                                  *      The LHS is an attribute, and the RHS is a literal.  Cast the
786                                  *      RHS to the data type of the LHS.
787                                  */
788                                 if ((c->data.map->dst->type == VPT_TYPE_ATTR) &&
789                                     (c->data.map->src->type == VPT_TYPE_LITERAL) &&
790                                     !radius_cast_tmpl(c->data.map->src, c->data.map->dst->da)) {
791                                         DICT_ATTR const *da = c->data.map->dst->da;
792
793                                         if ((da->vendor == 0) &&
794                                             ((da->attr == PW_AUTH_TYPE) ||
795                                              (da->attr == PW_AUTZ_TYPE) ||
796                                              (da->attr == PW_ACCT_TYPE) ||
797                                              (da->attr == PW_SESSION_TYPE) ||
798                                              (da->attr == PW_POST_AUTH_TYPE) ||
799                                              (da->attr == PW_PRE_PROXY_TYPE) ||
800                                              (da->attr == PW_POST_PROXY_TYPE) ||
801                                              (da->attr == PW_PRE_ACCT_TYPE) ||
802                                              (da->attr == PW_RECV_COA_TYPE) ||
803                                              (da->attr == PW_SEND_COA_TYPE))) {
804                                                 /*
805                                                  *      The types for these attributes are dynamically allocated
806                                                  *      by modules.c, so we can't enforce strictness here.
807                                                  */
808                                                 c->pass2_fixup = PASS2_FIXUP_TYPE;
809
810                                         } else {
811                                                 return_rhs("Failed to parse value for attribute");
812                                         }
813                                 }
814                         }
815
816                         p += slen;
817
818                         while (isspace((int) *p)) p++; /* skip spaces after RHS */
819                 } /* parse OP RHS */
820         } /* parse a condition (COND) or FOO OP BAR*/
821
822         /*
823          *      ...COND)
824          */
825         if (*p == ')') {
826                 if (!brace) {
827                         return_P("Unexpected closing brace");
828                 }
829
830                 p++;
831                 while (isspace((int) *p)) p++; /* skip spaces after closing brace */
832                 goto done;
833         }
834
835         /*
836          *      End of string is now allowed.
837          */
838         if (!*p) {
839                 if (brace) {
840                         return_P("No closing brace at end of string");
841                 }
842
843                 goto done;
844         }
845
846         if (!(((p[0] == '&') && (p[1] == '&')) ||
847               ((p[0] == '|') && (p[1] == '|')))) {
848                 *error = "Unexpected text after condition";
849         return_p:
850                 if (lhs) talloc_free(lhs);
851                 if (rhs) talloc_free(rhs);
852                 talloc_free(c);
853                 return -(p - start);
854         }
855
856         /*
857          *      Recurse to parse the next condition.
858          */
859         c->next_op = p[0];
860         p += 2;
861
862         /*
863          *      May still be looking for a closing brace.
864          */
865         slen = condition_tokenize(c, ci, p, brace, &c->next, error, flags);
866         if (slen <= 0) {
867         return_slen:
868                 if (lhs) talloc_free(lhs);
869                 if (rhs) talloc_free(rhs);
870                 talloc_free(c);
871                 return slen - (p - start);
872         }
873         p += slen;
874
875 done:
876         /*
877          *      Normalize the condition before returning.
878          *
879          *      We collapse multiple levels of braces to one.  Then
880          *      convert maps to literals.  Then literals to true/false
881          *      statements.  Then true/false ||/&& followed by other
882          *      conditions to just conditions.
883          *
884          *      Order is important.  The more complex cases are
885          *      converted to simpler ones, from the most complex cases
886          *      to the simplest ones.
887          */
888
889         /*
890          *      (FOO)     --> FOO
891          *      (FOO) ... --> FOO ...
892          */
893         if ((c->type == COND_TYPE_CHILD) && !c->data.child->next) {
894                 fr_cond_t *child;
895
896                 child = talloc_steal(ctx, c->data.child);
897                 c->data.child = NULL;
898
899                 child->next = talloc_steal(child, c->next);
900                 c->next = NULL;
901
902                 child->next_op = c->next_op;
903
904                 /*
905                  *      Set the negation properly
906                  */
907                 if ((c->negate && !child->negate) ||
908                     (!c->negate && child->negate)) {
909                         child->negate = true;
910                 } else {
911                         child->negate = false;
912                 }
913
914                 lhs = rhs = NULL;
915                 talloc_free(c);
916                 c = child;
917         }
918
919         /*
920          *      (FOO ...) --> FOO ...
921          *
922          *      But don't do !(FOO || BAR) --> !FOO || BAR
923          *      Because that's different.
924          */
925         if ((c->type == COND_TYPE_CHILD) &&
926             !c->next && !c->negate) {
927                 fr_cond_t *child;
928
929                 child = talloc_steal(ctx, c->data.child);
930                 c->data.child = NULL;
931
932                 lhs = rhs = NULL;
933                 talloc_free(c);
934                 c = child;
935         }
936
937         /*
938          *      Convert maps to literals.  Convert one form of map to
939          *      a standardized form.  This doesn't make any
940          *      theoretical difference, but it does mean that the
941          *      run-time evaluation has fewer cases to check.
942          */
943         if (c->type == COND_TYPE_MAP) do {
944                 /*
945                  *      !FOO !~ BAR --> FOO =~ BAR
946                  */
947                 if (c->negate && (c->data.map->op == T_OP_REG_NE)) {
948                         c->negate = false;
949                         c->data.map->op = T_OP_REG_EQ;
950                 }
951
952                 /*
953                  *      FOO !~ BAR --> !FOO =~ BAR
954                  */
955                 if (!c->negate && (c->data.map->op == T_OP_REG_NE)) {
956                         c->negate = true;
957                         c->data.map->op = T_OP_REG_EQ;
958                 }
959
960                 /*
961                  *      !FOO != BAR --> FOO == BAR
962                  */
963                 if (c->negate && (c->data.map->op == T_OP_NE)) {
964                         c->negate = false;
965                         c->data.map->op = T_OP_CMP_EQ;
966                 }
967
968                 /*
969                  *      This next one catches "LDAP-Group != foo",
970                  *      which doesn't work as-is, but this hack fixes
971                  *      it.
972                  *
973                  *      FOO != BAR --> !FOO == BAR
974                  */
975                 if (!c->negate && (c->data.map->op == T_OP_NE)) {
976                         c->negate = true;
977                         c->data.map->op = T_OP_CMP_EQ;
978                 }
979
980                 /*
981                  *      FOO =* BAR --> FOO
982                  *      FOO !* BAR --> !FOO
983                  */
984                 if ((c->data.map->op == T_OP_CMP_TRUE) ||
985                     (c->data.map->op == T_OP_CMP_FALSE)) {
986                         value_pair_tmpl_t *vpt;
987
988                         vpt = talloc_steal(c, c->data.map->dst);
989                         c->data.map->dst = NULL;
990
991                         /*
992                          *      Invert the negation bit.
993                          */
994                         if (c->data.map->op == T_OP_CMP_FALSE) {
995                                 c->negate = !c->negate;
996                         }
997
998                         TALLOC_FREE(c->data.map);
999
1000                         c->type = COND_TYPE_EXISTS;
1001                         c->data.vpt = vpt;
1002                         break;  /* it's no longer a map */
1003                 }
1004
1005                 /*
1006                  *      Both are data (IP address, integer, etc.)
1007                  *
1008                  *      We can do the evaluation here, so that it
1009                  *      doesn't need to be done at run time
1010                  */
1011                 if ((c->data.map->dst->type == VPT_TYPE_DATA) &&
1012                     (c->data.map->src->type == VPT_TYPE_DATA)) {
1013                         int rcode;
1014
1015                         rad_assert(c->cast != NULL);
1016
1017                         rcode = radius_evaluate_map(NULL, 0, 0, c);
1018                         TALLOC_FREE(c->data.map);
1019                         c->cast = NULL;
1020                         c->regex_i = false;
1021                         if (rcode) {
1022                                 c->type = COND_TYPE_TRUE;
1023                         } else {
1024                                 c->type = COND_TYPE_FALSE;
1025                         }
1026
1027                         break;  /* it's no longer a map */
1028                 }
1029
1030                 /*
1031                  *      Both are literal strings.  They're not parsed
1032                  *      as VPT_TYPE_DATA because there's no cast to an
1033                  *      attribute.
1034                  *
1035                  *      We can do the evaluation here, so that it
1036                  *      doesn't need to be done at run time
1037                  */
1038                 if ((c->data.map->src->type == VPT_TYPE_LITERAL) &&
1039                     (c->data.map->dst->type == VPT_TYPE_LITERAL)) {
1040                         int rcode;
1041
1042                         rad_assert(c->cast == NULL);
1043                         rad_assert(c->regex_i == false);
1044
1045                         rcode = radius_evaluate_map(NULL, 0, 0, c);
1046                         if (rcode) {
1047                                 c->type = COND_TYPE_TRUE;
1048                         } else {
1049                                 c->type = COND_TYPE_FALSE;
1050                         }
1051
1052                         /*
1053                          *      Free map after using it above.
1054                          */
1055                         TALLOC_FREE(c->data.map);
1056                         break;
1057                 }
1058         } while (0);
1059
1060         /*
1061          *      Existence checks.  We short-circuit static strings,
1062          *      too.
1063          */
1064         if (c->type == COND_TYPE_EXISTS) {
1065                 switch (c->data.vpt->type) {
1066                 case VPT_TYPE_XLAT:
1067                 case VPT_TYPE_ATTR:
1068                 case VPT_TYPE_LIST:
1069                 case VPT_TYPE_EXEC:
1070                         break;
1071
1072                         /*
1073                          *      'true' and 'false' are special strings
1074                          *      which mean themselves.
1075                          *
1076                          *      For integers, 0 is false, all other
1077                          *      integers are true.
1078                          *
1079                          *      For strings, '' and "" are false.
1080                          *      'foo' and "foo" are true.
1081                          *
1082                          *      The str2tmpl function takes care of
1083                          *      marking "%{foo}" as VPT_TYPE_XLAT, so
1084                          *      the strings here are fixed at compile
1085                          *      time.
1086                          *
1087                          *      `exec` and "%{...}" are left alone.
1088                          *
1089                          *      Bare words must be module return
1090                          *      codes.
1091                          */
1092                 case VPT_TYPE_LITERAL:
1093                         if ((strcmp(c->data.vpt->name, "true") == 0) ||
1094                             (strcmp(c->data.vpt->name, "1") == 0)) {
1095                                 c->type = COND_TYPE_TRUE;
1096                                 TALLOC_FREE(c->data.vpt);
1097
1098                         } else if ((strcmp(c->data.vpt->name, "false") == 0) ||
1099                                    (strcmp(c->data.vpt->name, "0") == 0)) {
1100                                 c->type = COND_TYPE_FALSE;
1101                                 TALLOC_FREE(c->data.vpt);
1102
1103                         } else if (!*c->data.vpt->name) {
1104                                 c->type = COND_TYPE_FALSE;
1105                                 TALLOC_FREE(c->data.vpt);
1106
1107                         } else if ((lhs_type == T_SINGLE_QUOTED_STRING) ||
1108                                    (lhs_type == T_DOUBLE_QUOTED_STRING)) {
1109                                 c->type = COND_TYPE_TRUE;
1110                                 TALLOC_FREE(c->data.vpt);
1111
1112                         } else if (lhs_type == T_BARE_WORD) {
1113                                 int rcode;
1114                                 char const *q;
1115
1116                                 for (q = c->data.vpt->name;
1117                                      *q != '\0';
1118                                      q++) {
1119                                         if (!isdigit((int) *q)) {
1120                                                 break;
1121                                         }
1122                                 }
1123
1124                                 /*
1125                                  *      It's all digits, and therefore
1126                                  *      'true'.
1127                                  */
1128                                 if (!*q) {
1129                                         c->type = COND_TYPE_TRUE;
1130                                         TALLOC_FREE(c->data.vpt);
1131                                         break;
1132                                 }
1133
1134                                 rcode = fr_str2int(allowed_return_codes,
1135                                                    c->data.vpt->name, 0);
1136                                 if (!rcode) {
1137                                         return_0("Expected a module return code");
1138                                 }
1139                         }
1140
1141                         /*
1142                          *      Else lhs_type==T_OP_INVALID, and this
1143                          *      node was made by promoting a child
1144                          *      which had already been normalized.
1145                          */
1146                         break;
1147
1148                 case VPT_TYPE_DATA:
1149                         return_0("Cannot use data here");
1150
1151                 default:
1152                         return_0("Internal sanity check failed");
1153                 }
1154         }
1155
1156         /*
1157          *      !TRUE -> FALSE
1158          */
1159         if (c->type == COND_TYPE_TRUE) {
1160                 if (c->negate) {
1161                         c->negate = false;
1162                         c->type = COND_TYPE_FALSE;
1163                 }
1164         }
1165
1166         /*
1167          *      !FALSE -> TRUE
1168          */
1169         if (c->type == COND_TYPE_FALSE) {
1170                 if (c->negate) {
1171                         c->negate = false;
1172                         c->type = COND_TYPE_TRUE;
1173                 }
1174         }
1175
1176         /*
1177          *      true && FOO --> FOO
1178          */
1179         if ((c->type == COND_TYPE_TRUE) &&
1180             (c->next_op == COND_AND)) {
1181                 fr_cond_t *next;
1182
1183                 next = talloc_steal(ctx, c->next);
1184                 c->next = NULL;
1185
1186                 lhs = rhs = NULL;
1187                 talloc_free(c);
1188                 c = next;
1189         }
1190
1191         /*
1192          *      false && FOO --> false
1193          */
1194         if ((c->type == COND_TYPE_FALSE) &&
1195             (c->next_op == COND_AND)) {
1196                 talloc_free(c->next);
1197                 c->next = NULL;
1198                 c->next_op = COND_NONE;
1199         }
1200
1201         /*
1202          *      false || FOO --> FOO
1203          */
1204         if ((c->type == COND_TYPE_FALSE) &&
1205             (c->next_op == COND_OR)) {
1206                 fr_cond_t *next;
1207
1208                 next = talloc_steal(ctx, c->next);
1209                 c->next = NULL;
1210
1211                 lhs = rhs = NULL;
1212                 talloc_free(c);
1213                 c = next;
1214         }
1215
1216         /*
1217          *      true || FOO --> true
1218          */
1219         if ((c->type == COND_TYPE_TRUE) &&
1220             (c->next_op == COND_OR)) {
1221                 talloc_free(c->next);
1222                 c->next = NULL;
1223                 c->next_op = COND_NONE;
1224         }
1225
1226         if (lhs) talloc_free(lhs);
1227         if (rhs) talloc_free(rhs);
1228
1229         *pcond = c;
1230         return p - start;
1231 }
1232
1233 /** Tokenize a conditional check
1234  *
1235  *  @param[in] ctx for talloc
1236  *  @param[in] ci for CONF_ITEM
1237  *  @param[in] start the start of the string to process.  Should be "(..."
1238  *  @param[out] head the parsed condition structure
1239  *  @param[out] error the parse error (if any)
1240  *  @param[in] flags do one/two pass
1241  *  @return length of the string skipped, or when negative, the offset to the offending error
1242  */
1243 ssize_t fr_condition_tokenize(TALLOC_CTX *ctx, CONF_ITEM *ci, char const *start, fr_cond_t **head, char const **error, int flags)
1244 {
1245         return condition_tokenize(ctx, ci, start, false, head, error, flags);
1246 }
1247
1248 /*
1249  *      Walk in order.
1250  */
1251 bool fr_condition_walk(fr_cond_t *c, bool (*callback)(void *, fr_cond_t *), void *ctx)
1252 {
1253         while (c) {
1254                 /*
1255                  *      Process this one, exit on error.
1256                  */
1257                 if (!callback(ctx, c)) return false;
1258
1259                 switch (c->type) {
1260                 case COND_TYPE_INVALID:
1261                         return false;
1262
1263                 case COND_TYPE_EXISTS:
1264                 case COND_TYPE_MAP:
1265                 case COND_TYPE_TRUE:
1266                 case COND_TYPE_FALSE:
1267                         break;
1268
1269                 case COND_TYPE_CHILD:
1270                         /*
1271                          *      Walk over the child.
1272                          */
1273                         if (!fr_condition_walk(c->data.child, callback, ctx)) {
1274                                 return false;
1275                         }
1276                 }
1277
1278                 /*
1279                  *      No sibling, stop.
1280                  */
1281                 if (c->next_op == COND_NONE) break;
1282
1283                 /*
1284                  *      process the next sibling
1285                  */
1286                 c = c->next;
1287         }
1288
1289         return true;
1290 }