示例#1
0
/*
 *	Helper function for call_modgroup, and call_modredundantloadbalance
 *
 *	Returns 0 for "stop", and "1" for continue.
 */
static int call_one(int component, modcallable *p, REQUEST *request,
		    int *priority, int *result)
{
	int r;

#ifdef RAD_REQUEST_OPTION_STOP_NOW
	/*
	 *	A module has taken too long to process the request,
	 *	and we've been told to stop processing it.
	 */
	if (request->options & RAD_REQUEST_OPTION_STOP_NOW) {
		*result = RLM_MODULE_FAIL;
		return 0;
	}
#endif
	
	/* Call this child by recursing into modcall */
	r = modcall(component, p, request);
	
#if 0
	DEBUG2("%s: action for %s is %s",
	       comp2str[component], lrad_int2str(rcode_table, r, "??"),
	       action2str(p->actions[r]));
#endif
	
	/*
	 * 	Find an action to go with the child's result. If it is
	 * 	"return", break out of the loop so the rest of the
	 * 	children in the list will be skipped.
	 */
	if (p->actions[r] == MOD_ACTION_RETURN) {
		*result = r;
		return 0;
	}
	
	/* If "reject" break out of the loop and return reject */
	if (p->actions[r] == MOD_ACTION_REJECT) {
		*result = RLM_MODULE_REJECT;
		return 0;
	}
	
	/*
	 *	Otherwise, the action is a number, the preference
	 *	level of this return code. If no higher preference has
	 *	been seen yet, remember this one
	 . */
	if (p->actions[r] >= *priority) {
		*result = r;
		*priority = p->actions[r];
	}
	
	return 1;
}
示例#2
0
rlm_rcode_t indexed_modcall(int comp, int idx, REQUEST *request)
{
	rlm_rcode_t rcode;
	modcallable *list = NULL;
	virtual_server_t *server;

	/*
	 *	Hack to find the correct virtual server.
	 */
	server = virtual_server_find(request->server);
	if (!server) {
		RDEBUG("No such virtual server \"%s\"", request->server);
		return RLM_MODULE_FAIL;
	}

	if (idx == 0) {
		list = server->mc[comp];
		if (!list) RWDEBUG2("Empty %s section.  Using default return values.", section_type_value[comp].section);

	} else {
		indexed_modcallable *this;

		this = lookup_by_index(server->components, comp, idx);
		if (this) {
			list = this->modulelist;
		} else {
			RWDEBUG2("Unknown value specified for %s.  Cannot perform requested action.",
				section_type_value[comp].typename);
		}
	}

	if (server->subcs[comp]) {
		if (idx == 0) {
			RDEBUG("# Executing section %s from file %s",
			       section_type_value[comp].section,
			       cf_section_filename(server->subcs[comp]));
		} else {
			RDEBUG("# Executing group from file %s",
			       cf_section_filename(server->subcs[comp]));
		}
	}
	request->component = section_type_value[comp].section;

	rcode = modcall(comp, list, request);

	request->module = "";
	request->component = "<core>";
	return rcode;
}
示例#3
0
static int call_modloadbalance(int component, modgroup *g, REQUEST *request,
			       int default_result)
{
	int count = 1;
	modcallable *p, *child = NULL;

	/*
	 *	Catch people who have issues.
	 */
	if (!g->children) {
		DEBUG2("  WARNING! Asked to process empty load-balance group.  Returning %s.", lrad_int2str(rcode_table, default_result, "??"));
		return default_result;
	}

	/*
	 *	Pick a random child.
	 */

	/* Loop over the children */
	for(p = g->children; p; p = p->next) {
		if (!child) {
			child = p;
			count = 1;
			continue;
		}

		/*
		 *	Keep track of how many load balancing servers
		 *	we've gone through.
		 */
		count++;

		/*
		 *	See the "camel book" for why this works.
		 *
		 *	If (rand(0..n) < 1), pick the current realm.
		 *	We add a scale factor of 65536, to avoid
		 *	floating point.
		 */
		if ((count * (lrad_rand() & 0xffff)) < (uint32_t) 0x10000) {
			child = p;
		}
	}
	rad_assert(child != NULL);

	/* Call the chosen child by recursing into modcall */
	return modcall(component, child, request);
}
示例#4
0
static int indexed_modcall(int comp, int idx, REQUEST *request)
{
	indexed_modcallable *this;

	this = lookup_by_index(components[comp], idx);
	if (!this) {
		/* Return a default value appropriate for the component */
		switch(comp) {
			case RLM_COMPONENT_AUTZ:    return RLM_MODULE_NOTFOUND;
			case RLM_COMPONENT_AUTH:    return RLM_MODULE_REJECT;
			case RLM_COMPONENT_PREACCT: return RLM_MODULE_NOOP;
			case RLM_COMPONENT_ACCT:    return RLM_MODULE_NOOP;
			case RLM_COMPONENT_SESS:    return RLM_MODULE_FAIL;
			case RLM_COMPONENT_PRE_PROXY:  return RLM_MODULE_NOOP;
			case RLM_COMPONENT_POST_PROXY: return RLM_MODULE_NOOP;
			case RLM_COMPONENT_POST_AUTH:  return RLM_MODULE_NOOP;
			default:                    return RLM_MODULE_FAIL;
		}
	}
	return modcall(comp, this->modulelist, request);
}
示例#5
0
/*
 *	Evaluate a module statement
 */
static int evaluate_module(policy_state_t *state, const policy_item_t *item)
{
	const policy_module_t *this;

	this = (const policy_module_t *) item;

	/*
	 *	Just to be paranoid.  Maybe we want to loosen this
	 *	restriction in the future?
	 */
	if (this->component != state->component) {
		DEBUG2("rlm_policy: Cannot mix & match components");
		return 0;
	}

	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 */
}