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