HOME_TYPE_INVALID = 0,
HOME_TYPE_AUTH, //!< Authentication server
HOME_TYPE_ACCT, //!< Accounting server
- HOME_TYPE_AUTH_ACCT //!< Authentication and accounting server
+ HOME_TYPE_AUTH_ACCT, //!< Authentication and accounting server
#ifdef WITH_COA
- ,HOME_TYPE_COA //!< CoA destination (NAS or Proxy)
+ HOME_TYPE_COA, //!< CoA destination (NAS or Proxy)
+
+#ifdef WITH_COA_TUNNEL
+ HOME_TYPE_AUTH_COA, //!< auth + coa
+ HOME_TYPE_AUTH_ACCT_COA, //!< auth + acct + coa
+#endif
#endif
} home_type_t;
bool dual; //!< One of a pair of homeservers on consecutive ports.
bool dynamic; //!< is this a dynamically added home server?
+#ifdef WITH_COA_TUNNEL
+ bool recv_coa; //!< receive CoA packets, too
+#endif
char const *server; //!< For internal proxying
char const *parent_server;
uint32_t coa_mrc;
uint32_t coa_mrt;
uint32_t coa_mrd;
+#ifdef WITH_COA_TUNNEL
+ char const *coa_server; //!< for accepting incoming CoA requests
+#endif
#endif
#ifdef WITH_TLS
fr_tls_server_conf_t *tls;
{ "acct", HOME_TYPE_ACCT },
{ "auth+acct", HOME_TYPE_AUTH_ACCT },
{ "coa", HOME_TYPE_COA },
+#ifdef WITH_COA_TUNNEL
+ { "auth+coa", HOME_TYPE_AUTH_COA },
+ { "auth+acct+coa", HOME_TYPE_AUTH_ACCT_COA },
+#endif
{ NULL, 0 }
};
{ "mrd", FR_CONF_OFFSET(PW_TYPE_INTEGER, home_server_t, coa_mrd), STRINGIFY(30) },
CONF_PARSER_TERMINATOR
};
+
+
+
+#ifdef WITH_COA_TUNNEL
+static CONF_PARSER home_server_recv_coa[] = {
+ { "virtual_server", FR_CONF_OFFSET(PW_TYPE_STRING, home_server_t, coa_server), NULL },
+ CONF_PARSER_TERMINATOR
+};
+#endif
+
#endif
static CONF_PARSER home_server_config[] = {
#ifdef WITH_COA
{ "coa", FR_CONF_POINTER(PW_TYPE_SUBSECTION, NULL), (void const *) home_server_coa },
+#ifdef WITH_COA_TUNNEL
+ { "recv_coa", FR_CONF_POINTER(PW_TYPE_SUBSECTION, NULL), (void const *) home_server_recv_coa },
+#endif
#endif
CONF_PARSER_TERMINATOR
}
}
+#ifdef WITH_COA_TUNNEL
+ if (home->recv_coa) {
+ if (!home->tls) {
+ ERROR("TLS is required in order to accept CoA requests from a home server");
+ return false;
+ }
+
+ if (!home->coa_server) {
+ ERROR("A 'virtual_server' configuration is required in order to accept CoA requests from a home server");
+ return false;
+ }
+ }
+#endif
+
/*
* Mark it as already processed
*/
}
/*
- * Try and find a 'server' section off the root of
+ * Try and find a "server" section off the root of
* the config with a name that matches the
* virtual_server.
*/
goto error;
}
break;
+
+#ifdef WITH_COA_TUNNEL
+ case HOME_TYPE_AUTH_ACCT_COA:
+ home->dual = true;
+ home->recv_coa = true;
+ break;
+
+ case HOME_TYPE_AUTH_COA:
+ home->recv_coa = true;
+ break;
+#endif
#endif
case HOME_TYPE_INVALID:
}
if (((home->type == HOME_TYPE_AUTH) ||
+#ifdef WITH_COA_TUNNEL
+ (home->type == HOME_TYPE_AUTH_COA) ||
+ (home->type == HOME_TYPE_AUTH_ACCT_COA) ||
+#endif
(home->type == HOME_TYPE_AUTH_ACCT)) && !home->ping_user_password) {
cf_log_err_cs(cs, "You must supply a 'password' to enable status_check=request");
goto error;
}
#endif
+ /*
+ * Check the reverse CoA configuration.
+ */
+#ifdef WITH_COA_TUNNEL
+ if (home->recv_coa) {
+ if (!tls) {
+ ERROR("TLS is required in order to accept CoA requests from a home server");
+ goto error;
+ }
+
+ if (!home->coa_server) {
+ ERROR("A 'virtual_server' configuration is required in order to accept CoA requests from a home server");
+ goto error;
+ }
+
+ /*
+ * Try and find a 'server' section off the root of
+ * the config with a name that matches the coa
+ * virtual_server.
+ */
+ if (!rc) {
+ ERROR("Dynamic home servers cannot accept CoA requests");
+ goto error;
+ }
+
+ if (!cf_section_sub_find_name2(rc->cs, "server", home->coa_server)) {
+ cf_log_err_cs(cs, "No such coa server %s", home->coa_server);
+ goto error;
+ }
+ }
+#endif
+
/*
* If were doing RADSEC (tls+tcp) the secret should default
* to radsec, else a secret must be set.
case HOME_TYPE_ACCT:
myhome.type = HOME_TYPE_AUTH_ACCT;
home = rbtree_finddata(home_servers_byname, &myhome);
+#ifdef WITH_COA_TUNNEL
+ if (!home) {
+ myhome.type = HOME_TYPE_AUTH_COA;
+ home = rbtree_finddata(home_servers_byname, &myhome);
+ if(!home) {
+ myhome.type = HOME_TYPE_AUTH_ACCT_COA;
+ home = rbtree_finddata(home_servers_byname, &myhome);
+ }
+ }
+#endif
if (home) {
*phome = home;
return 1;
case HOME_TYPE_ACCT:
myhome.type = HOME_TYPE_AUTH_ACCT;
home = rbtree_finddata(home_servers_byname, &myhome);
+#ifdef WITH_COA_TUNNEL
+ if (!home) {
+ myhome.type = HOME_TYPE_AUTH_COA;
+ home = rbtree_finddata(home_servers_byname, &myhome);
+ if (!home) {
+ myhome.type = HOME_TYPE_AUTH_ACCT_COA;
+ home = rbtree_finddata(home_servers_byname, &myhome);
+ }
+ }
+#endif
break;
default:
goto error;
}
+#ifdef COA_TUNNEL
+ if (home->recv_coa) {
+ fr_strerror_printf("Dynamic home_server '%s' cannot receive CoA requests'", p);
+ talloc_free(home);
+ goto error;
+ }
+#endif
+
if (!realm_home_server_add(home)) {
fr_strerror_printf("Failed adding home_server to the internal data structures");
talloc_free(home);