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