From: Alan T. DeKok Date: Wed, 23 May 2012 13:29:48 +0000 (+0200) Subject: Added support for CoA proxying via Operator-Name X-Git-Tag: release_3_0_0_beta0~189 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fbe50e825ff60a905bc1c2cadffa7501f71b8a94;p=thirdparty%2Ffreeradius-server.git Added support for CoA proxying via Operator-Name and examples --- diff --git a/raddb/proxy.conf b/raddb/proxy.conf index 533bd74e301..810b48598d1 100644 --- a/raddb/proxy.conf +++ b/raddb/proxy.conf @@ -667,6 +667,15 @@ realm example.com { auth_pool = my_auth_failover # acct_pool = acct + # As of Version 3.0, the server can proxy CoA packets + # based on the Operator-Name attribute. This requires + # that the "suffix" module be listed in the "recv-coa" + # section. + # + # See raddb/sites-available/coa + # +# coa_pool = name_of_coa_pool + # # Normally, when an incoming User-Name is matched against the # realm, the realm name is "stripped" off, and the "stripped" diff --git a/raddb/sites-available/coa b/raddb/sites-available/coa index 8aaa492c3d3..66caa31c7b1 100644 --- a/raddb/sites-available/coa +++ b/raddb/sites-available/coa @@ -26,6 +26,12 @@ server coa { # Just set Proxy-To-Realm, or Home-Server-Pool, and the # packets will be proxied. + # Do proxying based on realms here. You don't need + # "IPASS" or "ntdomain", as the proxying is based on + # the Operator-Name attribute. It contains the realm, + # and ONLY the realm (prefixed by a '1') + suffix + # Insert your own policies here. ok } diff --git a/src/modules/rlm_realm/rlm_realm.c b/src/modules/rlm_realm/rlm_realm.c index afb3d5913c1..18d68b37c13 100644 --- a/src/modules/rlm_realm/rlm_realm.c +++ b/src/modules/rlm_realm/rlm_realm.c @@ -457,6 +457,57 @@ static int realm_preacct(void *instance, REQUEST *request) return RLM_MODULE_UPDATED; /* try the next module */ } +#ifdef WITH_COA +/* + * CoA realms via Operator-Name. Because the realm isn't in a + * User-Name, concepts like "prefix" and "suffix' don't matter. + */ +static int realm_coa(UNUSED void *instance, REQUEST *request) +{ + VALUE_PAIR *vp; + REALM *realm; + + if (pairfind(request->packet->vps, PW_REALM, 0) != NULL) { + RDEBUG2("Request already proxied. Ignoring."); + return RLM_MODULE_OK; + } + + vp = pairfind(request->packet->vps, PW_OPERATOR_NAME, 0); + + /* + * Catch the case of broken dictionaries. + */ + if (vp->type != PW_TYPE_STRING) return RLM_MODULE_NOOP; + + /* + * The string is too short. + */ + if (vp->length == 1) return RLM_MODULE_NOOP; + + /* + * '1' means "the rest of the string is a realm" + */ + if (vp->vp_strvalue[0] != '1') return RLM_MODULE_NOOP; + + realm = realm_find(vp->vp_strvalue + 1); + if (!realm) return RLM_MODULE_NOTFOUND; + + if (!realm->coa_pool) { + RDEBUG2("CoA realm is LOCAL."); + return RLM_MODULE_OK; + } + + /* + * Maybe add a Proxy-To-Realm attribute to the request. + */ + RDEBUG2("Preparing to proxy authentication request to realm \"%s\"\n", + realm->name); + add_proxy_to_realm(&request->config_items, realm); + + return RLM_MODULE_UPDATED; /* try the next module */ +} +#endif + static int realm_detach(void *instance) { free(instance); @@ -479,5 +530,9 @@ module_t rlm_realm = { NULL, /* pre-proxy */ NULL, /* post-proxy */ NULL /* post-auth */ +#ifdef WITH_COA + , realm_coa, /* recv-coa */ + NULL /* send-coa */ +#endif }, };