diff --git a/include/ntop_defines.h b/include/ntop_defines.h
index 3f621c8133..8f88c9a2aa 100644
--- a/include/ntop_defines.h
+++ b/include/ntop_defines.h
@@ -1217,6 +1217,7 @@
#define PREF_RADIUS_ADMIN_GROUP NTOPNG_PREFS_PREFIX ".radius.radius_admin_group"
#define PREF_RADIUS_UNPRIV_CAP_GROUP \
NTOPNG_PREFS_PREFIX ".radius.radius_unpriv_capabilties_group"
+#define PREF_RADIUS_EXT_AUTHE_LOCAL_AUTHO NTOPNG_PREFS_PREFIX ".radius.external_auth_for_local_users_enabled"
#ifdef HAVE_RADIUS
#define MAX_RADIUS_LEN 256
diff --git a/scripts/locales/en.lua b/scripts/locales/en.lua
index aa23231b97..4fa786c1fe 100644
--- a/scripts/locales/en.lua
+++ b/scripts/locales/en.lua
@@ -6738,6 +6738,8 @@ local lang = {
["toggle_radius_accounting_descr"] = "Toggle traffic accounting via RADIUS server.",
["toggle_radius_auth"] = "Toggle RADIUS Authentication",
["toggle_radius_auth_descr"] = "Toggle GUI authentication via RADIUS server.",
+ ["toggle_radius_external_auth_for_local_users"] = "Toggle RADIUS Authentication of Local Users",
+ ["toggle_radius_external_auth_for_local_users_descr"] = "Toggle authentication of local users via RADIUS (remote authentication, local authorization).",
["toggle_send_telemetry_data_description"] = "Contribute to the project by sending encrypted, anonymous telemetry data to ntop.org. Data only involves the status of %{product} (e.g., uptime, status, crash reports). Nothing regarding the monitored traffic will ever be sent.",
["toggle_send_telemetry_data_title"] = "Telemetry Data",
["toggle_shaping_directions_description"] = "Enable this option to be able to set different shaping policies for ingress and egress traffic.",
diff --git a/scripts/lua/admin/prefs.lua b/scripts/lua/admin/prefs.lua
index 0cebb04cc9..76f47db640 100644
--- a/scripts/lua/admin/prefs.lua
+++ b/scripts/lua/admin/prefs.lua
@@ -122,9 +122,9 @@ if auth.has_capability(auth.capabilities.preferences) then
(_POST["radius_secret"] ~= ntop.getPref("ntopng.prefs.radius.radius_secret")) or
(_POST["radius_admin_group"] ~= ntop.getPref("ntopng.prefs.radius.radius_admin_group")) or
(_POST["radius_auth_proto"] ~= ntop.getPref("ntopng.prefs.radius.radius_auth_proto")) or
- (_POST["radius_unpriv_capabilties_group"] ~=
- ntop.getPref("ntopng.prefs.radius.radius_unpriv_capabilties_group")) or
- (_POST["toggle_radius_accounting"] ~= ntop.getPref("ntopng.prefs.radius.accounting_enabled"))) then
+ (_POST["radius_unpriv_capabilties_group"] ~= ntop.getPref("ntopng.prefs.radius.radius_unpriv_capabilties_group")) or
+ (_POST["toggle_radius_accounting"] ~= ntop.getPref("ntopng.prefs.radius.accounting_enabled")) or
+ (_POST["toggle_radius_external_auth_for_local_users"] ~= ntop.getPref("ntopng.prefs.radius.external_auth_for_local_users_enabled"))) then
-- In the minute callback there is a periodic script that in case
-- the auth changed, it's going to update the radius info
ntop.setPref("ntopng.prefs.radius.radius_server_address", _POST["radius_server_address"])
@@ -134,6 +134,7 @@ if auth.has_capability(auth.capabilities.preferences) then
ntop.setPref("ntopng.prefs.radius.radius_admin_group", _POST["radius_admin_group"])
ntop.setPref("ntopng.prefs.radius.radius_unpriv_capabilties_group", _POST["radius_unpriv_capabilties_group"])
ntop.setPref("ntopng.prefs.radius.toggle_radius_accounting", _POST["toggle_radius_accounting"])
+ ntop.setPref("ntopng.prefs.radius.external_auth_for_local_users_enabled", _POST["toggle_radius_external_auth_for_local_users"])
ntop.updateRadiusLoginInfo()
end
@@ -919,7 +920,7 @@ if auth.has_capability(auth.capabilities.preferences) then
-- RADIUS GUI authentication
- local elementToSwitch = {"row_toggle_radius_accounting", "radius_admin_group",
+ local elementToSwitch = {"row_toggle_radius_accounting", "row_toggle_radius_external_auth_for_local_users", "radius_admin_group",
"radius_unpriv_capabilties_group", "radius_server_address",
"radius_acct_server_address", "radius_secret", "row_radius_auth_proto"}
@@ -962,9 +963,21 @@ if auth.has_capability(auth.capabilities.preferences) then
"pap", "primary", "radius_auth_proto", "ntopng.prefs.radius.radius_auth_proto", nil, nil, nil, nil,
showElements)
+ local groupsElements = {"radius_admin_group", "radius_unpriv_capabilties_group"}
+ local showGroupsElements = (ntop.getPref("ntopng.prefs.radius.external_auth_for_local_users_enabled") ~= "1")
+ prefsToggleButton(subpage_active, {
+ field = "toggle_radius_external_auth_for_local_users",
+ pref = "radius.external_auth_for_local_users_enabled",
+ default = "0",
+ to_switch = groupsElements,
+ reverse_switch = true,
+ hidden = not showElements
+ })
+
prefsInputFieldPrefs(subpage_active.entries["radius_admin_group"].title,
- subpage_active.entries["radius_admin_group"].description, "ntopng.prefs.radius", "radius_admin_group", "",
- nil, showElements, true, false, {
+ subpage_active.entries["radius_admin_group"].description, "ntopng.prefs.radius",
+ "radius_admin_group", "", nil,
+ showElements and showGroupsElements, true, false, {
attributes = {
spellcheck = "false",
maxlength = 255,
@@ -974,7 +987,8 @@ if auth.has_capability(auth.capabilities.preferences) then
prefsInputFieldPrefs(subpage_active.entries["radius_unpriv_capabilties_group"].title,
subpage_active.entries["radius_unpriv_capabilties_group"].description, "ntopng.prefs.radius",
- "radius_unpriv_capabilties_group", "", nil, showElements, true, false, {
+ "radius_unpriv_capabilties_group", "", nil,
+ showElements and showGroupsElements, true, false, {
attributes = {
spellcheck = "false",
maxlength = 255,
diff --git a/scripts/lua/modules/http_lint.lua b/scripts/lua/modules/http_lint.lua
index 8692993a17..aaab427c48 100644
--- a/scripts/lua/modules/http_lint.lua
+++ b/scripts/lua/modules/http_lint.lua
@@ -2227,6 +2227,7 @@ local known_parameters = {
["toggle_ldap_auth"] = validateBool,
["toggle_local_auth"] = validateBool,
["toggle_radius_accounting"] = validateBool,
+ ["toggle_radius_external_auth_for_local_users"] = validateBool,
["toggle_radius_auth"] = validateBool,
["toggle_http_auth"] = validateBool,
["toggle_ldap_referrals"] = validateBool,
diff --git a/scripts/lua/modules/prefs_menu.lua b/scripts/lua/modules/prefs_menu.lua
index e33a03e2c2..023af5bd55 100644
--- a/scripts/lua/modules/prefs_menu.lua
+++ b/scripts/lua/modules/prefs_menu.lua
@@ -685,6 +685,13 @@ local menu_subpages = {{
}),
hidden = (not hasRadius)
},
+ toggle_radius_external_auth_for_local_users = {
+ title = i18n("prefs.toggle_radius_external_auth_for_local_users"),
+ description = i18n("prefs.toggle_radius_external_auth_for_local_users_descr", {
+ product = info.product
+ }),
+ hidden = (not hasRadius or not have_nedge)
+ },
toggle_http_auth = {
title = i18n("prefs.toggle_http_auth"),
description = i18n("prefs.toggle_http_auth_descr"),
diff --git a/src/Ntop.cpp b/src/Ntop.cpp
index fc47220838..5dde837090 100644
--- a/src/Ntop.cpp
+++ b/src/Ntop.cpp
@@ -1779,8 +1779,10 @@ bool Ntop::checkLDAPAuth(const char *user, const char *password, char *group) co
/* ******************************************* */
bool Ntop::checkRadiusAuth(const char *user, const char *password, char *group) const {
+ bool is_admin = false, has_unprivileged_capabilities = false;
+ bool external_auth_for_local_users = false;
bool radius_ret = false;
- char val[64];
+ char key[64], val[64];
#ifdef HAVE_RADIUS
/*
@@ -1797,8 +1799,6 @@ bool Ntop::checkRadiusAuth(const char *user, const char *password, char *group)
val[0] != '1')
return false;
- bool is_admin = false, has_unprivileged_capabilities = false;
-
ntop->getTrace()->traceEvent(TRACE_INFO, "Checking RADIUS auth");
if (!password || !password[0]) return false;
@@ -1807,29 +1807,42 @@ bool Ntop::checkRadiusAuth(const char *user, const char *password, char *group)
if (radiusAcc->authenticate(user, password, &has_unprivileged_capabilities,
&is_admin)) {
- /* Check permissions */
- if (has_unprivileged_capabilities) {
- changeUserPcapDownloadPermission(user, true, 86400 /* 1 day */);
- changeUserHistoricalFlowPermission(user, true, 86400 /* 1 day */);
- changeUserAlertsPermission(user, true, 86400 /* 1 day */);
- } else {
- char key[64];
- snprintf(key, sizeof(key), CONST_STR_USER_ALLOW_PCAP, user);
- ntop->getRedis()->del(key);
+ if(ntop->getRedis()->get((char *)PREF_RADIUS_EXT_AUTHE_LOCAL_AUTHO, val, sizeof(val)) >= 0 && val[0] == '1')
+ external_auth_for_local_users = true;
- snprintf(key, sizeof(key), CONST_STR_USER_ALLOW_HISTORICAL_FLOW, user);
- ntop->getRedis()->del(key);
+ if (external_auth_for_local_users) {
+ snprintf(key, sizeof(key), CONST_STR_USER_PASSWORD, user);
+ if (ntop->getRedis()->get(key, val, sizeof(val)) < 0)
+ return false; /* Local user with same name does not exist */
- snprintf(key, sizeof(key), CONST_STR_USER_ALLOW_ALERTS, user);
- ntop->getRedis()->del(key);
+ getUserGroupLocal(user, group);
+
+ } else {
+ /* Check permissions */
+ if (has_unprivileged_capabilities) {
+ changeUserPcapDownloadPermission(user, true, 86400 /* 1 day */);
+ changeUserHistoricalFlowPermission(user, true, 86400 /* 1 day */);
+ changeUserAlertsPermission(user, true, 86400 /* 1 day */);
+ } else {
+ char key[64];
+
+ snprintf(key, sizeof(key), CONST_STR_USER_ALLOW_PCAP, user);
+ ntop->getRedis()->del(key);
+
+ snprintf(key, sizeof(key), CONST_STR_USER_ALLOW_HISTORICAL_FLOW, user);
+ ntop->getRedis()->del(key);
+
+ snprintf(key, sizeof(key), CONST_STR_USER_ALLOW_ALERTS, user);
+ ntop->getRedis()->del(key);
+ }
+
+ strncpy(group,
+ is_admin ? CONST_USER_GROUP_ADMIN : CONST_USER_GROUP_UNPRIVILEGED,
+ NTOP_GROUP_MAXLEN);
+ group[NTOP_GROUP_MAXLEN - 1] = '\0';
}
- strncpy(group,
- is_admin ? CONST_USER_GROUP_ADMIN : CONST_USER_GROUP_UNPRIVILEGED,
- NTOP_GROUP_MAXLEN);
- group[NTOP_GROUP_MAXLEN - 1] = '\0';
-
radius_ret = true;
}
#endif