static void policy_print(const policy_item_t *item, int indent)
{
if (!item) {
- if (indent) printf("%*s", indent, " ");
- printf("[NULL]\n");
+ if (indent) fprintf(fr_log_fp, "%*s", indent, " ");
+ fprintf(fr_log_fp, "[NULL]\n");
return;
}
-
+
while (item) {
switch (item->type) {
case POLICY_TYPE_BAD:
- if (indent) printf("%*s", indent, " ");
- printf("[BAD STATEMENT]");
+ if (indent) fprintf(fr_log_fp, "%*s", indent, " ");
+ fprintf(fr_log_fp, "[BAD STATEMENT]");
break;
-
+
case POLICY_TYPE_PRINT:
- if (indent) printf("%*s", indent, " ");
+ if (indent) fprintf(fr_log_fp, "%*s", indent, " ");
{
const policy_print_t *this;
this = (const policy_print_t *) item;
-
+
if (this->rhs_type == POLICY_LEX_BARE_WORD) {
- printf("print %s\n", this->rhs);
+ fprintf(fr_log_fp, "print %s\n", this->rhs);
} else {
- printf("print \"%s\"\n", this->rhs);
+ fprintf(fr_log_fp, "print \"%s\"\n", this->rhs);
}
}
break;
-
+
case POLICY_TYPE_ASSIGNMENT:
{
const policy_assignment_t *assign;
-
+
assign = (const policy_assignment_t *) item;
- if (indent) printf("%*s", indent, " ");
+ if (indent) fprintf(fr_log_fp, "%*s", indent, " ");
- printf("\t%s %s ", assign->lhs,
- lrad_int2str(rlm_policy_tokens,
+ fprintf(fr_log_fp, "\t%s %s ", assign->lhs,
+ fr_int2str(rlm_policy_tokens,
assign->assign, "?"));
if (assign->rhs_type == POLICY_LEX_BARE_WORD) {
- printf("%s\n", assign->rhs);
+ fprintf(fr_log_fp, "%s\n", assign->rhs);
} else {
/*
* FIXME: escape "
*/
- printf("\"%s\"\n", assign->rhs);
+ fprintf(fr_log_fp, "\"%s\"\n", assign->rhs);
}
}
break;
condition = (const policy_condition_t *) item;
- printf("(");
+ fprintf(fr_log_fp, "(");
+
+ if (condition->sense) {
+ fprintf(fr_log_fp, "!");
+ }
/*
* Nested conditions.
*/
if (condition->compare == POLICY_LEX_L_BRACKET) {
policy_print(condition->child, indent);
- printf(")");
+ fprintf(fr_log_fp, ")");
break;
}
if (condition->compare == POLICY_LEX_L_NOT) {
- printf("!");
+ fprintf(fr_log_fp, "!");
policy_print(condition->child, indent);
- printf(")");
+ fprintf(fr_log_fp, ")");
break;
}
if (condition->compare == POLICY_LEX_CMP_TRUE) {
- printf("%s)", condition->lhs);
+ fprintf(fr_log_fp, "%s)", condition->lhs);
break;
}
if (condition->lhs_type == POLICY_LEX_FUNCTION) {
- printf("%s()", condition->lhs);
+ fprintf(fr_log_fp, "%s()", condition->lhs);
} else {
/*
* FIXME: escape ",
* and move all of this logic
* to a function.
*/
- printf("\"%s\"", condition->lhs);
+ fprintf(fr_log_fp, "\"%s\"", condition->lhs);
}
/*
* We always print this condition.
*/
- printf(" %s ", lrad_int2str(rlm_policy_tokens,
+ fprintf(fr_log_fp, " %s ", fr_int2str(rlm_policy_tokens,
condition->compare,
"?"));
if (condition->rhs_type == POLICY_LEX_BARE_WORD) {
- printf("%s", condition->rhs);
+ fprintf(fr_log_fp, "%s", condition->rhs);
} else {
/*
* FIXME: escape ",
* and move all of this logic
* to a function.
*/
- printf("\"%s\"", condition->rhs);
+ fprintf(fr_log_fp, "\"%s\"", condition->rhs);
}
- printf(")");
-
+ fprintf(fr_log_fp, ")");
+
if ((condition->child_condition != POLICY_LEX_BAD) &&
(condition->child_condition != POLICY_LEX_BARE_WORD)) {
- printf(" %s ", lrad_int2str(rlm_policy_tokens, condition->child_condition, "?"));
+ fprintf(fr_log_fp, " %s ", fr_int2str(rlm_policy_tokens, condition->child_condition, "?"));
policy_print(condition->child, indent);
}
}
statement = (const policy_if_t *) item;
- if (indent) printf("%*s", indent, " ");
- printf("if ");
+ if (indent) fprintf(fr_log_fp, "%*s", indent, " ");
+ fprintf(fr_log_fp, "if ");
policy_print(statement->condition, indent);
- printf(" {\n");
+ fprintf(fr_log_fp, " {\n");
policy_print(statement->if_true, indent + 1);
- if (indent) printf("%*s", indent, " ");
+ if (indent) fprintf(fr_log_fp, "%*s", indent, " ");
if (statement->if_false) {
- printf("} else ");
+ fprintf(fr_log_fp, "} else ");
if (statement->if_false->type == POLICY_TYPE_ASSIGNMENT) {
- printf(" { ");
+ fprintf(fr_log_fp, " { ");
policy_print(statement->if_false, indent + 1);
- if (indent) printf("%*s", indent, " ");
- printf(" }");
+ if (indent) fprintf(fr_log_fp, "%*s", indent, " ");
+ fprintf(fr_log_fp, " }");
} else {
policy_print(statement->if_false, indent + 1);
}
} else {
- printf("}\n");
+ fprintf(fr_log_fp, "}\n");
}
}
break;
this = (const policy_attributes_t *) item;
- if (indent) printf("%*s", indent, " ");
- printf("%s %s {\n",
- lrad_int2str(policy_reserved_words,
+ if (indent) fprintf(fr_log_fp, "%*s", indent, " ");
+ fprintf(fr_log_fp, "%s %s {\n",
+ fr_int2str(policy_reserved_words,
this->where, "?"),
- lrad_int2str(rlm_policy_tokens,
+ fr_int2str(rlm_policy_tokens,
this->how, "?"));
policy_print(this->attributes, indent + 1);
- if (indent) printf("%*s", indent, " ");
- printf("}\n");
+ if (indent) fprintf(fr_log_fp, "%*s", indent, " ");
+ fprintf(fr_log_fp, "}\n");
}
break;
const policy_named_t *this;
this = (const policy_named_t *) item;
- if (indent) printf("%*s", indent, " ");
- printf("policy %s {\n", this->name);
+ if (indent) fprintf(fr_log_fp, "%*s", indent, " ");
+ fprintf(fr_log_fp, "policy %s {\n", this->name);
policy_print(this->policy, indent + 1);
- if (indent) printf("%*s", indent, " ");
- printf("}\n");
+ if (indent) fprintf(fr_log_fp, "%*s", indent, " ");
+ fprintf(fr_log_fp, "}\n");
}
break;
const policy_call_t *this;
this = (const policy_call_t *) item;
- if (indent) printf("%*s", indent, " ");
- printf("call %s\n", this->name);
+ if (indent) fprintf(fr_log_fp, "%*s", indent, " ");
+ fprintf(fr_log_fp, "call %s\n", this->name);
}
break;
const policy_return_t *this;
this = (const policy_return_t *) item;
- if (indent) printf("%*s", indent, " ");
- printf("return %s\n",
- lrad_int2str(policy_return_codes,
+ if (indent) fprintf(fr_log_fp, "%*s", indent, " ");
+ fprintf(fr_log_fp, "return %s\n",
+ fr_int2str(policy_return_codes,
this->rcode, "???"));
}
break;
const policy_module_t *this;
this = (const policy_module_t *) item;
- if (indent) printf("%*s", indent, " ");
- printf("module %s <stuff>\n",
- lrad_int2str(policy_component_names,
+ if (indent) fprintf(fr_log_fp, "%*s", indent, " ");
+ fprintf(fr_log_fp, "module %s <stuff>\n",
+ fr_int2str(policy_component_names,
this->component, "???"));
}
break;
default:
- if (indent) printf("%*s", indent, " ");
- printf("[HUH?]\n");
+ if (indent) fprintf(fr_log_fp, "%*s", indent, " ");
+ fprintf(fr_log_fp, "[HUH?]\n");
break;
-
+
}
item = item->next;
void rlm_policy_print(const policy_item_t *item)
{
- printf("----------------------------------------------------------\n");
+ if (!fr_log_fp) return;
+
+ fprintf(fr_log_fp, "# rlm_policy \n");
policy_print(item, 0);
- printf("----------------------------------------------------------\n");
}
/*
{
const policy_print_t *this;
+ if (!fr_log_fp) return 1;
+
this = (const policy_print_t *) item;
if (this->rhs_type == POLICY_LEX_BARE_WORD) {
- printf("%s\n", this->rhs);
+ fprintf(fr_log_fp, "%s\n", this->rhs);
} else {
char buffer[1024];
radius_xlat(buffer, sizeof(buffer), this->rhs,
state->request, NULL);
- printf("%s", buffer);
+ fprintf(fr_log_fp, "%s", buffer);
+ if (!strchr(buffer, '\n')) fprintf(fr_log_fp, "\n");
}
/*
} else if (strncasecmp(name, "reply:", 6) == 0) {
p += 6;
vps = request->reply->vps;
+#ifdef WITH_PROXY
} else if (strncasecmp(name, "proxy-request:", 14) == 0) {
p += 14;
if (request->proxy) {
if (request->proxy_reply) {
vps = request->proxy_reply->vps;
}
+#endif
} else if (strncasecmp(name, "control:", 8) == 0) {
p += 8;
vps = request->config_items;
return NULL; /* no such attribute */
}
- return pairfind(vps, dattr->attr);
+ return pairfind(vps, dattr->attr, dattr->vendor);
}
*
* Not really used much...
*/
-static int evaluate_assignment(policy_state_t *state, const policy_item_t *item)
+static int evaluate_assignment(UNUSED policy_state_t *state, const policy_item_t *item)
{
const policy_assignment_t *this;
#if 0
* evaluate all of it...
*/
rcode = policy_evaluate_name(state, this->lhs);
- data = lrad_int2str(policy_return_codes, rcode, "???");
+ data = fr_int2str(policy_return_codes, rcode, "???");
strlcpy(lhs_buffer, data, sizeof(lhs_buffer)); /* FIXME: yuck */
} else if (this->lhs_type == POLICY_LEX_DOUBLE_QUOTED_STRING) {
if (radius_xlat(lhs_buffer, sizeof(lhs_buffer), this->lhs,
}
}
}
-
+
switch (this->compare) {
case POLICY_LEX_L_BRACKET: /* nested brackets are a special case */
rcode = evaluate_condition(state, this->child);
vp = find_vp(state->request, this->lhs);
/*
- * A op B always returns FALSE if A doesn't
+ * A op B is FALSE if A doesn't
* exist.
*/
- if (!vp) return FALSE; /* not in the request */
+ if (!vp) {
+ rcode = FALSE;
+ break;
+ }
/*
* FIXME: Move sanity checks to
*/
vp_prints_value(buffer, sizeof(buffer), vp, 0);
myvp = pairmake(vp->name, this->rhs, T_OP_EQ);
+ if (!myvp) return FALSE; /* memory failure */
data = buffer;
/*
compare = radius_callback_compare(state->request,
vp, myvp, NULL, NULL);
pairfree(&myvp);
-
+
} else {
/*
* FIXME: Do something for RHS type?
*/
- printf("CMP %s %s\n", lhs_buffer, this->rhs);
+ fr_printf_log("CMP %s %s\n", lhs_buffer, this->rhs);
compare = strcmp(lhs_buffer, this->rhs);
}
debug_evaluate("CONDITION COMPARE %d\n", compare);
-
+
switch (this->compare) {
case POLICY_LEX_CMP_EQUALS:
rcode = (compare == 0);
break;
-
+
case POLICY_LEX_CMP_NOT_EQUALS:
rcode = (compare != 0);
break;
-
+
case POLICY_LEX_LT:
rcode = (compare < 0);
break;
-
+
case POLICY_LEX_GT:
rcode = (compare > 0);
break;
-
+
case POLICY_LEX_LE:
rcode =(compare <= 0);
break;
-
+
case POLICY_LEX_GE:
rcode = (compare >= 0);
break;
-
+
#ifdef HAVE_REGEX_H
case POLICY_LEX_RX_EQUALS:
{ /* FIXME: copied from src/main/valuepair.c */
int i;
regmatch_t rxmatch[REQUEST_MAX_REGEX + 1];
-
+
/*
* Include substring matches.
*/
if (regcomp(®, this->rhs,
REG_EXTENDED) != 0) {
+ /* FIXME: print error */
return FALSE;
}
rad_assert(data != NULL);
rxmatch, 0);
rcode = (rcode == 0);
regfree(®);
-
+
/*
* Add %{0}, %{1}, etc.
*/
for (i = 0; i <= REQUEST_MAX_REGEX; i++) {
char *p;
char rxbuffer[256];
-
+
/*
* Didn't match: delete old
* match, if it existed.
free(p);
continue;
}
-
+
/*
* No previous match
* to delete, stop.
*/
break;
}
-
+
/*
* Copy substring into buffer.
*/
data + rxmatch[i].rm_so,
rxmatch[i].rm_eo - rxmatch[i].rm_so);
rxbuffer[rxmatch[i].rm_eo - rxmatch[i].rm_so] = '\0';
-
+
/*
* Copy substring, and add it to
* the request.
REQUEST_DATA_REGEX | i,
p, free);
}
-
+
}
break;
-
+
case POLICY_LEX_RX_NOT_EQUALS:
regcomp(®, this->rhs, REG_EXTENDED|REG_NOSUB);
rad_assert(data != NULL);
break; /* default from first switch over compare */
}
+ if (this->sense) rcode = (rcode == FALSE); /* reverse sense of test */
+
/*
* No trailing &&, ||
*/
const policy_assignment_t *assign)
{
VALUE_PAIR *vp;
- LRAD_TOKEN operator = T_OP_EQ;
+ FR_TOKEN operator = T_OP_EQ;
const char *value = assign->rhs;
char buffer[2048];
case POLICY_LEX_SET_EQUALS:
operator = T_OP_SET;
break;
-
+
case POLICY_LEX_PLUS_EQUALS:
operator = T_OP_ADD;
break;
-
+
default:
fprintf(stderr, "Expected '=' for operator, not '%s' at line %d\n",
- lrad_int2str(rlm_policy_tokens,
+ fr_int2str(rlm_policy_tokens,
assign->assign, "?"),
assign->item.lineno);
return NULL;
}
-
+
vp = pairmake(assign->lhs, value, operator);
if (!vp) {
- fprintf(stderr, "SHIT: %s %s\n", value, librad_errstr);
+ fprintf(stderr, "Failed creating pair: %s %s\n", value, fr_strerror());
}
return vp;
VALUE_PAIR **vps = NULL;
VALUE_PAIR *vp, *head, **tail;
const policy_item_t *attr;
+ policy_lex_t this_how;
this = (const policy_attributes_t *) item;
vps = &(state->request->reply->vps);
break;
+#ifdef WITH_PROXY
case POLICY_RESERVED_PROXY_REQUEST:
if (!state->request->proxy) return 0; /* FIXME: print error */
vps = &(state->request->proxy->vps);
if (!state->request->proxy_reply) return 0; /* FIXME: print error */
vps = &(state->request->proxy_reply->vps);
break;
+#endif
default:
return 0;
tail = &(vp->next);
}
- switch (this->how) {
+ this_how = this->how;
+ retry_how:
+ switch (this_how) {
case POLICY_LEX_SET_EQUALS: /* dangerous: removes all previous things! */
pairfree(vps);
*vps = head;
break;
+ case POLICY_LEX_AFTER_TAIL_ASSIGN:
+ pairmove(vps, &head);
+ pairfree(&head);
+ break;
+
case POLICY_LEX_ASSIGN: /* 'union' */
pairmove(vps, &head);
pairfree(&head);
break;
+ case POLICY_LEX_BEFORE_HEAD_ASSIGN:
+ pairmove(&head, vps);
+ pairfree(vps);
+ *vps = head;
+ break;
+
+ case POLICY_LEX_AFTER_TAIL_EQUALS:
case POLICY_LEX_CONCAT_EQUALS:
pairadd(vps, head);
break;
+ case POLICY_LEX_BEFORE_HEAD_EQUALS:
+ pairadd(&head, *vps);
+ *vps = head;
+ break;
+
+ case POLICY_LEX_BEFORE_WHERE_EQUALS:
+ case POLICY_LEX_AFTER_WHERE_EQUALS:
+ case POLICY_LEX_BEFORE_WHERE_ASSIGN:
+ case POLICY_LEX_AFTER_WHERE_ASSIGN:
+ /* find location*/
+ {
+ VALUE_PAIR *vpprev = NULL, *vpnext = NULL, *lvp;
+
+ for(lvp = *vps; lvp; vpprev = lvp, lvp = lvp->next) {
+ vpnext = lvp->next;
+ lvp->next = NULL;
+ if (evaluate_condition(state, this->where_loc))
+ break;
+ lvp->next = vpnext;
+ }
+
+ if (lvp) {
+ switch(this_how) {
+ case POLICY_LEX_BEFORE_WHERE_EQUALS:
+ case POLICY_LEX_BEFORE_WHERE_ASSIGN:
+ if (vpprev) {
+ lvp->next = vpnext;
+ vpnext = lvp;
+ vpprev->next = NULL;
+ lvp = vpprev;
+ }
+ default: /* always reached */
+ break;
+ }
+
+ switch(this_how) {
+ case POLICY_LEX_BEFORE_WHERE_EQUALS:
+ if (vpprev)
+ pairadd(&lvp, head);
+ else
+ *vps = lvp = head;
+ break;
+ case POLICY_LEX_AFTER_WHERE_EQUALS:
+ pairadd(&lvp, head);
+ break;
+ case POLICY_LEX_BEFORE_WHERE_ASSIGN:
+ if (vpprev) {
+ pairmove(&lvp, &head);
+ pairfree(&head);
+ }
+ else
+ *vps = lvp = head;
+ break;
+ case POLICY_LEX_AFTER_WHERE_ASSIGN:
+ pairmove(&lvp, &head);
+ pairfree(&head);
+ break;
+ default:/*never reached*/
+ break;
+ }
+ for( ; lvp && lvp->next; lvp = lvp->next);
+ if (lvp)
+ lvp->next = vpnext;
+ break;
+ }
+
+ switch(this_how) {
+ case POLICY_LEX_BEFORE_WHERE_EQUALS:
+ this_how = POLICY_LEX_BEFORE_HEAD_EQUALS;
+ break;
+ case POLICY_LEX_AFTER_WHERE_EQUALS:
+ this_how = POLICY_LEX_AFTER_TAIL_EQUALS;
+ break;
+ case POLICY_LEX_BEFORE_WHERE_ASSIGN:
+ this_how = POLICY_LEX_BEFORE_HEAD_ASSIGN;
+ break;
+ case POLICY_LEX_AFTER_WHERE_ASSIGN:
+ this_how = POLICY_LEX_AFTER_TAIL_ASSIGN;
+ break;
+ default: /*never reached*/
+ break;
+ }
+ goto retry_how;
+ }
+ /* FALL-THROUGH */
+
default:
fprintf(stderr, "HUH?\n");
pairfree(&head);
policy = rlm_policy_find(state->inst->policies, this->name);
if (!policy) return 0; /* not found... */
-
+
DEBUG2("rlm_policy: Evaluating policy %s", this->name);
-
+
rad_assert(policy->policy->type != POLICY_TYPE_BAD);
rad_assert(policy->policy->type < POLICY_TYPE_NUM_TYPES);
this = (const policy_return_t *) item;
state->rcode = this->rcode;
-
+
return 1; /* we succeeded */
}
DEBUG2("rlm_policy: begin nested call");
state->rcode = modcall(this->component, this->mc, state->request);
DEBUG2("rlm_policy: end nested call");
-
+
return 1; /* we succeeded */
}
int rcode;
const policy_item_t *this;
policy_named_t mypolicy, *policy;
-
+
mypolicy.name = name;
policy = rbtree_finddata(state->inst->policies, &mypolicy);
if (!policy) return RLM_MODULE_FAIL;
-
+
DEBUG2("rlm_policy: Evaluating policy %s", name);
-
+
rad_assert(policy->item.type != POLICY_TYPE_BAD);
rad_assert(policy->item.type < POLICY_TYPE_NUM_TYPES);
-
+
rcode = policy_stack_push(state, policy->policy);
if (!rcode) {
return RLM_MODULE_FAIL;
rad_assert(this != NULL);
rad_assert(this->type != POLICY_TYPE_BAD);
rad_assert(this->type < POLICY_TYPE_NUM_TYPES);
-
+
debug_evaluate("Evaluating at line %d\n",
this->lineno);
rcode = (*evaluate_functions[this->type])(state,
state->request = request;
state->inst = inst;
state->rcode = RLM_MODULE_OK;
- state->component = lrad_str2int(policy_component_names, name,
+ state->component = fr_str2int(policy_component_names, name,
RLM_COMPONENT_COUNT);
rcode = policy_evaluate_name(state, name);