Exemplo n.º 1
0
/*
 *	Evaluate a reference call to a module.
 */
static int evaluate_call(policy_state_t *state, const policy_item_t *item)
{
	int rcode;
	const policy_call_t *this;
	const policy_named_t *policy;

	this = (const policy_call_t *) item;

	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);

	/*
	 *	Push the name of the function onto the stack,
	 *	so that we can catch recursive calls.
	 *
	 *	The "pop" function will skip over it when it sees it.
	 */
	rcode = policy_stack_push(state, (const policy_item_t *) policy);
	if (!rcode) {
		return rcode;
	}

	/*
	 *	Push it onto the stack.  Other code will take care of
	 *	calling it.
	 */
	rcode = policy_stack_push(state, policy->policy);
	if (!rcode) {
		return rcode;
	}

	return 1;
}
Exemplo n.º 2
0
/*
 * (foo == bar), with nested conditionals.
 */
static int parse_condition(policy_lex_file_t *lexer, policy_item_t **tail)
{
    int rcode, seen_not = FALSE;
    policy_lex_t token, compare;
    char lhs[256], rhs[256];
    policy_condition_t *this;

    token = policy_lex_file(lexer, 0, lhs, sizeof(lhs));
    if (token != POLICY_LEX_L_BRACKET) {
        fprintf(stderr, "%s[%d]: Expected '(', got \"%s\"\n",
                lexer->filename, lexer->lineno,
                fr_int2str(rlm_policy_tokens, token, lhs));
        return 0;
    }

    this = rad_malloc(sizeof(*this));
    memset(this, 0, sizeof(*this));

    this->item.type = POLICY_TYPE_CONDITIONAL;
    this->item.lineno = lexer->lineno;

redo:
    token = policy_lex_file(lexer, 0, lhs, sizeof(lhs));
    switch (token) {
    case POLICY_LEX_L_BRACKET:
        if (!policy_lex_push_token(lexer, token)) {
            rlm_policy_free_item((policy_item_t *) this);
            return 0;
        }

        this->compare = POLICY_LEX_L_BRACKET;
        this->child_condition = POLICY_LEX_L_BRACKET;
        rcode = parse_condition(lexer, &(this->child));
        if (!rcode) {
            rlm_policy_free_item((policy_item_t *) this);
            return rcode;
        }
        break;

    case POLICY_LEX_L_NOT:
        if (seen_not) {
            fprintf(stderr, "%s[%d]: Syntax error at \"!!\"\n",
                    lexer->filename, lexer->lineno);
            rlm_policy_free_item((policy_item_t *) this);
            return 0;
        }

        debug_tokens("[NOT] ");

        token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, NULL, 0);
        if (token != POLICY_LEX_L_BRACKET) {
            seen_not = this->sense = 1;
            goto redo;
        }

        this->compare = POLICY_LEX_L_NOT;
        rcode = parse_condition(lexer, &(this->child));
        if (!rcode) {
            rlm_policy_free_item((policy_item_t *) this);
            return rcode;
        }
        break;

    case POLICY_LEX_BARE_WORD:
        this->lhs_type = token;
        token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, NULL, 0);
        if (token == POLICY_LEX_L_BRACKET) {
            debug_tokens("[IF-CALL %s] ", lhs);

            /*
             *	Function call.
             */
            if (rlm_policy_find(lexer->policies, lhs) == NULL) {
                fprintf(stderr, "%s[%d]: Undefined function \"%s\"\n",
                        lexer->filename, lexer->lineno,
                        lhs);
                rlm_policy_free_item((policy_item_t *) this);
                return 0;

            }

            /*
             *	this->lhs set up below, after "check"
             */
            this->lhs_type = POLICY_LEX_FUNCTION;

            /*
             *	Copied from parse_call
             */
            token = policy_lex_file(lexer, 0, NULL, 0);
            if (token != POLICY_LEX_L_BRACKET) {
                fprintf(stderr, "%s[%d]: Expected left bracket, got \"%s\"\n",
                        lexer->filename, lexer->lineno,
                        fr_int2str(rlm_policy_tokens, token, "?"));
                rlm_policy_free_item((policy_item_t *) this);
                return 0;
            }

            token = policy_lex_file(lexer, 0, NULL, 0);
            if (token != POLICY_LEX_R_BRACKET) {
                fprintf(stderr, "%s[%d]: Expected right bracket, got \"%s\"\n",
                        lexer->filename, lexer->lineno,
                        fr_int2str(rlm_policy_tokens, token, "?"));
                rlm_policy_free_item((policy_item_t *) this);
                return 0;
            }
        } /* else it's a comparison? */
        goto check;

    case POLICY_LEX_DOUBLE_QUOTED_STRING:
        this->lhs_type = token;

        /*
         *	Got word.  May just be test for existence.
         */
check:
        token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, NULL, 0);
        if (token == POLICY_LEX_R_BRACKET) {
            debug_tokens("[TEST %s] ", lhs);
            this->lhs = strdup(lhs);
            this->compare = POLICY_LEX_CMP_TRUE;
            break;
        }

        compare = policy_lex_file(lexer, 0, rhs, sizeof(rhs));
        switch (compare) {
        case POLICY_LEX_CMP_EQUALS:
        case POLICY_LEX_CMP_NOT_EQUALS:
        case POLICY_LEX_RX_EQUALS:
        case POLICY_LEX_RX_NOT_EQUALS:
        case POLICY_LEX_CMP_TRUE:
        case POLICY_LEX_CMP_FALSE:
        case POLICY_LEX_LT:
        case POLICY_LEX_GT:
        case POLICY_LEX_LE:
        case POLICY_LEX_GE:
            break;

        default:
            fprintf(stderr, "%s[%d]: Invalid operator \"%s\"\n",
                    lexer->filename, lexer->lineno,
                    fr_int2str(rlm_policy_tokens, compare, rhs));
            rlm_policy_free_item((policy_item_t *) this);
            return 0;
        }

        token = policy_lex_file(lexer, 0, rhs, sizeof(rhs));
        if ((token != POLICY_LEX_BARE_WORD) &&
                (token != POLICY_LEX_DOUBLE_QUOTED_STRING)) {
            fprintf(stderr, "%s[%d]: Unexpected rhs token\n",
                    lexer->filename, lexer->lineno);
            rlm_policy_free_item((policy_item_t *) this);
            return 0;
        }
        debug_tokens("[COMPARE (%s %s %s)] ",
                     lhs, fr_int2str(rlm_policy_tokens, compare, "?"), rhs);
        this->lhs = strdup(lhs);
        this->compare = compare;
        this->rhs_type = token;
        this->rhs = strdup(rhs);
        break;

    default:
        fprintf(stderr, "%s[%d]: Unexpected lhs token\n",
                lexer->filename, lexer->lineno);
        rlm_policy_free_item((policy_item_t *) this);
        return 0;
    }

    token = policy_lex_file(lexer, 0, NULL, 0);
    if (token != POLICY_LEX_R_BRACKET) {
        fprintf(stderr, "%s[%d]: Expected ')', got \"%s\"\n",
                lexer->filename, lexer->lineno,
                fr_int2str(rlm_policy_tokens, token, "?"));
        rlm_policy_free_item((policy_item_t *) this);
        return 0;
    }

    /*
     *	After the end of condition, we MAY have && or ||
     */
    token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, NULL, 0);
    if ((token == POLICY_LEX_L_AND) || (token == POLICY_LEX_L_OR)) {
        token = policy_lex_file(lexer, 0, NULL, 0); /* skip over it */
        debug_tokens("[%s] ",
                     fr_int2str(rlm_policy_tokens, token, "?"));
        this->child_condition = token;
        rcode = parse_condition(lexer, &(this->child));
        if (!rcode) {
            rlm_policy_free_item((policy_item_t *) this);
            return 0;
        }
    }

    *tail = (policy_item_t *) this;

    return 1;
}
Exemplo n.º 3
0
/*
 *	Parse one statement.  'foo = bar', or 'if (...) {...}', or '{...}',
 *	and so on.
 */
static int parse_statement(policy_lex_file_t *lexer, policy_item_t **tail)
{
    int rcode;
    policy_reserved_word_t reserved;
    policy_lex_t token, assign;
    char lhs[256], rhs[256];
    policy_assignment_t *this;

    /*
     *	See what kind of token we have.
     */
    token = policy_lex_file(lexer, 0, lhs, sizeof(lhs));
    switch (token) {
    case POLICY_LEX_LC_BRACKET:
        rcode = parse_block(lexer, tail);
        if (!rcode) {
            return 0;
        }
        break;

    case POLICY_LEX_BARE_WORD:
        reserved = fr_str2int(policy_reserved_words,
                              lhs,
                              POLICY_RESERVED_UNKNOWN);
        switch (reserved) {
        case POLICY_RESERVED_IF:
            if (parse_if(lexer, tail)) {
                return 1;
            }
            return 0;
            break;

        case POLICY_RESERVED_CONTROL:
        case POLICY_RESERVED_REQUEST:
        case POLICY_RESERVED_REPLY:
        case POLICY_RESERVED_PROXY_REQUEST:
        case POLICY_RESERVED_PROXY_REPLY:
            if (parse_attribute_block(lexer, tail,
                                      reserved))
                return 1;
            return 0;
            break;

        case POLICY_RESERVED_PRINT:
            if (parse_print(lexer, tail)) {
                return 1;
            }
            return 0;
            break;

        case POLICY_RESERVED_RETURN:
            if (parse_return(lexer, tail)) {
                return 1;
            }
            return 0;
            break;

        case POLICY_RESERVED_MODULE:
            if (parse_module(lexer, tail)) {
                return 1;
            }
            return 0;
            break;

        case POLICY_RESERVED_UNKNOWN: /* wasn't a reserved word */
            /*
             *	Is a named policy, parse the reference to it.
             */
            if (rlm_policy_find(lexer->policies, lhs) != NULL) {
                if (!parse_call(lexer, tail, lhs)) {
                    return 0;
                }
                return 1;
            }

            {
                const DICT_ATTR *dattr;

                /*
                 *	Bare words MUST be dictionary attributes
                 */

                dattr = dict_attrbyname(lhs);
                if (!dattr) {
                    fprintf(stderr, "%s[%d]: Expected attribute name, got \"%s\"\n",
                            lexer->filename, lexer->lineno, lhs);
                    return 0;
                }
                debug_tokens("%s[%d]: Got attribute %s\n",
                             lexer->filename, lexer->lineno,
                             lhs);
            }
            break;

        default:
            fprintf(stderr, "%s[%d]: Unexpected reserved word \"%s\"\n",
                    lexer->filename, lexer->lineno, lhs);
            return 0;
        } /* switch over reserved words */
        break;

    /*
     *	Return from nested blocks.
     */
    case POLICY_LEX_RC_BRACKET:
        policy_lex_push_token(lexer, token);
        return 2;	/* magic */

    case POLICY_LEX_EOF:	/* nothing more to do */
        return 3;

    default:
        fprintf(stderr, "%s[%d]: Unexpected %s\n",
                lexer->filename, lexer->lineno,
                fr_int2str(policy_explanations,
                           token, "string"));
        break;
    }

    /*
     *	Parse a bare statement.
     */
    assign = policy_lex_file(lexer, 0, rhs, sizeof(rhs));
    switch (assign) {
    case POLICY_LEX_ASSIGN:
    case POLICY_LEX_SET_EQUALS:
    case POLICY_LEX_AND_EQUALS:
    case POLICY_LEX_OR_EQUALS:
    case POLICY_LEX_PLUS_EQUALS:
        break;

    default:
        fprintf(stderr, "%s[%d]: Unexpected assign %s\n",
                lexer->filename, lexer->lineno,
                fr_int2str(policy_explanations,
                           assign, "string"));
        return 0;
    }

    this = rad_malloc(sizeof(*this));
    memset(this, 0, sizeof(*this));

    this->item.type = POLICY_TYPE_ASSIGNMENT;
    this->item.lineno = lexer->lineno;

    token = policy_lex_file(lexer, 0, rhs, sizeof(rhs));
    if ((token != POLICY_LEX_BARE_WORD) &&
            (token != POLICY_LEX_DOUBLE_QUOTED_STRING)) {
        fprintf(stderr, "%s[%d]: Unexpected rhs %s\n",
                lexer->filename, lexer->lineno,
                fr_int2str(policy_explanations,
                           token, "string"));
        rlm_policy_free_item((policy_item_t *) this);
        return 0;
    }
    this->rhs_type = token;
    this->rhs = strdup(rhs);

    token = policy_lex_file(lexer, POLICY_LEX_FLAG_RETURN_EOL,
                            rhs, sizeof(rhs));
    if (token != POLICY_LEX_EOL) {
        fprintf(stderr, "%s[%d]: Expected EOL\n",
                lexer->filename, lexer->lineno);
        rlm_policy_free_item((policy_item_t *) this);
        return 0;
    }
    debug_tokens("[ASSIGN %s %s %s]\n",
                 lhs, fr_int2str(rlm_policy_tokens, assign, "?"), rhs);

    /*
     *	Fill in the assignment struct
     */
    this->lhs = strdup(lhs);
    this->assign = assign;

    *tail = (policy_item_t *) this;

    return 1;
}