Added module return codes to conditions in unlang
authoraland <aland>
Mon, 2 Jul 2007 10:01:36 +0000 (10:01 +0000)
committeraland <aland>
Mon, 2 Jul 2007 10:01:36 +0000 (10:01 +0000)
man/man5/unlang.5
src/include/radiusd.h
src/main/evaluate.c
src/main/modcall.c

index 459e90f..c2494e1 100644 (file)
@@ -225,11 +225,38 @@ conditions
        (foo)
 .DE
 
-Evalutes to true if 'foo' is a non-empty string, or if 'foo' is a
+Evalutes to true if 'foo' is a non-empty string (single quotes, double
+quotes, or back-quoted).  Also evaluates to true if 'foo' is a
 non-zero number.  Note that the language is not typed, so the string
 "0000" can be interpreted as a numerical zero.  This issue can be
 avoided by comparings strings to an empty string, rather than by
 evaluating the string by itself.
+
+If the text is not quoted, then it is parsed as one of the module
+return codes.  The condition evaluates to true if the most recent
+module return code matches the name given here.  Valid module return
+codes are:
+
+.br
+.DS
+       notfound        informatation was not found
+.br
+       noop            the module did nothing
+.br
+       ok              the module succeeded
+.br
+       updated         the module updated the request
+.br
+       fail            the module failed
+.br
+       reject          the module rejected the request
+.br
+       userlock        the user was locked out
+.br
+       invalid         the configuration was invalid
+.br
+       handled         the module has handled the request itself
+.DE
 .IP Negation
 .DS
        (!foo)
@@ -533,9 +560,6 @@ keyword can be used to over-ride earlier failures, if the local
 administrator determines that the faiures are not catastrophic.
 .IP reject
 Causes the request to be immediately rejected
-.IP return
-Stops processsing of the current section, and returns to process the
-next keyword in the parent section.
 .SH FILES
 /etc/raddb/vmpsd.conf,
 /etc/raddb/radiusd.conf
index eb0b4b5..9389e6f 100644 (file)
@@ -484,7 +484,7 @@ int received_request(rad_listen_t *listener,
 REQUEST *received_proxy_response(RADIUS_PACKET *packet);
 
 /* evaluate.c */
-int radius_evaluate_condition(REQUEST *request, int depth,
+int radius_evaluate_condition(REQUEST *request, int modreturn, int depth,
                              const char **ptr, int evaluate_it, int *presult);
 int radius_update_attrlist(REQUEST *request, CONF_SECTION *cs,
                           VALUE_PAIR *input_vps, const char *name);
index 9ca1041..21c2640 100644 (file)
@@ -192,7 +192,20 @@ static LRAD_TOKEN getregex(char **ptr, char *buffer, size_t buflen, int *pcflags
 }
 #endif
 
-int radius_evaluate_condition(REQUEST *request, int depth,
+static const LRAD_NAME_NUMBER modreturn_table[] = {
+       { "reject",     RLM_MODULE_REJECT       },
+       { "fail",       RLM_MODULE_FAIL         },
+       { "ok",         RLM_MODULE_OK           },
+       { "handled",    RLM_MODULE_HANDLED      },
+       { "invalid",    RLM_MODULE_INVALID      },
+       { "userlock",   RLM_MODULE_USERLOCK     },
+       { "notfound",   RLM_MODULE_NOTFOUND     },
+       { "noop",       RLM_MODULE_NOOP         },
+       { "updated",    RLM_MODULE_UPDATED      },
+       { NULL, 0 }
+};
+
+int radius_evaluate_condition(REQUEST *request, int modreturn, int depth,
                              const char **ptr, int evaluate_it, int *presult)
 {
        int found_condition = FALSE;
@@ -235,8 +248,8 @@ int radius_evaluate_condition(REQUEST *request, int depth,
                         *      parse error.
                         */
                        DEBUG4(">>> CALLING EVALUATE %s", end);
-                       if (!radius_evaluate_condition(request, depth + 1,
-                                                      &end,
+                       if (!radius_evaluate_condition(request, modreturn,
+                                                      depth + 1, &end,
                                                       evaluate_next_condition,
                                                       &result)) {
                                return FALSE;
@@ -381,6 +394,9 @@ int radius_evaluate_condition(REQUEST *request, int depth,
                        if (all_digits(pleft)) {
                                lint = atoi(pleft);
                                result = (lint != 0);
+
+                       } else if (lt == T_BARE_WORD) {
+                               result = (modreturn == lrad_str2int(modreturn_table, pleft, -1));
                        } else {
                                result = (*pleft != '\0');
                        }
index 7b831e6..f02719c 100644 (file)
@@ -368,8 +368,9 @@ int modcall(int component, modcallable *c, REQUEST *request)
                               (child->type == MOD_IF) ? "if" : "elsif",
                               child->name);
 
-                       if (radius_evaluate_condition(request, 0, &p,
-                                                      TRUE, &condition)) {
+                       if (radius_evaluate_condition(request,
+                                                     stack.result[stack.pointer],
+                                                     0, &p, TRUE, &condition)) {
                                DEBUG2("%.*s? %s %s -> %s",
                                       stack.pointer + 1, modcall_spaces,
                                       (child->type == MOD_IF) ? "if" : "elsif",
@@ -1371,7 +1372,7 @@ static modcallable *do_compile_modsingle(modcallable *parent,
                        if (!csingle) return NULL;
                        csingle->type = MOD_IF;
 
-                       if (!radius_evaluate_condition(NULL, 0, modname,
+                       if (!radius_evaluate_condition(NULL, 0, 0, modname,
                                                       FALSE, &result)) {
                                modcallable_free(&csingle);
                                return NULL;
@@ -1400,7 +1401,7 @@ static modcallable *do_compile_modsingle(modcallable *parent,
                        if (!csingle) return NULL;
                        csingle->type = MOD_ELSIF;
 
-                       if (!radius_evaluate_condition(NULL, 0, modname,
+                       if (!radius_evaluate_condition(NULL, 0, 0, modname,
                                                       FALSE, &result)) {
                                modcallable_free(&csingle);
                                return NULL;