Fix GUI auth from RADIUS to grab group names from the Class attribute. Implements #935

The RADIUS server must populate the Class attribute with a string, semicolon-separated, of user groups. Similar to LDAP, local groups must exist with matching names, and privileges are determined by the local matching groups.
This commit is contained in:
jim-p 2015-08-12 12:07:15 -04:00
parent 24850bca18
commit 709c2f99f1
5 changed files with 34 additions and 9 deletions

View File

@ -1236,6 +1236,24 @@ function radius_backed($username, $passwd, $authcfg, &$attributes = array()) {
return $ret;
}
/*
$attributes must contain a "class" key containing the groups and local
groups must exist to match.
*/
function radius_get_groups($attributes) {
$groups = array();
if (!empty($attributes) && is_array($attributes) && !empty($attributes['class'])) {
$groups = explode(";", $attributes['class']);
foreach ($groups as & $grp) {
$grp = strtolower(trim($grp));
if (substr($grp, 0, 3) == "ou=") {
$grp = substr($grp, 3);
}
}
}
return $groups;
}
function get_user_expiration_date($username) {
$user = getUserEntry($username);
if ($user['expires'])
@ -1289,7 +1307,7 @@ function auth_get_authserver_list() {
return $list;
}
function getUserGroups($username, $authcfg) {
function getUserGroups($username, $authcfg, &$attributes = array()) {
global $config;
$allowed_groups = array();
@ -1299,6 +1317,7 @@ function getUserGroups($username, $authcfg) {
$allowed_groups = @ldap_get_groups($username, $authcfg);
break;
case 'radius':
$allowed_groups = @radius_get_groups($attributes);
break;
default:
$user = getUserEntry($username);
@ -1363,14 +1382,16 @@ function session_auth() {
return false;
/* Validate incoming login request */
$attributes = array();
if (isset($_POST['login']) && !empty($_POST['usernamefld']) && !empty($_POST['passwordfld'])) {
$authcfg = auth_get_authserver($config['system']['webgui']['authmode']);
if (authenticate_user($_POST['usernamefld'], $_POST['passwordfld'], $authcfg) ||
authenticate_user($_POST['usernamefld'], $_POST['passwordfld'])) {
if (authenticate_user($_POST['usernamefld'], $_POST['passwordfld'], $authcfg, $attributes) ||
authenticate_user($_POST['usernamefld'], $_POST['passwordfld'])) {
// Generate a new id to avoid session fixation
session_regenerate_id();
$_SESSION['Logged_In'] = "True";
$_SESSION['Username'] = $_POST['usernamefld'];
$_SESSION['user_radius_attributes'] = $attributes;
$_SESSION['last_access'] = time();
$_SESSION['protocol'] = $config['system']['webgui']['protocol'];
if(! isset($config['system']['webgui']['quietlogin'])) {

View File

@ -53,7 +53,7 @@ if (!session_auth()) {
* We give them access only to the appropriate pages based on
* the user or group privileges.
*/
$allowedpages = getAllowedPages($_SESSION['Username']);
$allowedpages = getAllowedPages($_SESSION['Username'], $_SESSION['user_radius_attributes']);
/*
* redirect to first allowed page if requesting a wrong url

View File

@ -240,7 +240,7 @@ function getPrivPages(& $entry, & $allowed_pages) {
}
}
function getAllowedPages($username) {
function getAllowedPages($username, &$attributes = array()) {
global $config, $_SESSION;
if (!function_exists("ldap_connect"))
@ -251,8 +251,11 @@ function getAllowedPages($username) {
$authcfg = auth_get_authserver($config['system']['webgui']['authmode']);
// obtain ldap groups if we are in ldap mode
if ($authcfg['type'] == "ldap")
if ($authcfg['type'] == "ldap") {
$allowed_groups = @ldap_get_groups($username, $authcfg);
} elseif ($authcfg['type'] == "radius") {
$allowed_groups = @radius_get_groups($attributes);
}
if (!$allowed_groups) {
// search for a local user by name

View File

@ -484,7 +484,7 @@ class Auth_RADIUS extends PEAR {
break;
case RADIUS_CLASS:
$this->attributes['class'] = radius_cvt_int($data);
$this->attributes['class'] = radius_cvt_string($data);
break;
case RADIUS_FRAMED_PROTOCOL:

View File

@ -55,9 +55,10 @@ if ($_POST) {
$input_errors[] = gettext("A username and password must be specified.");
if (!$input_errors) {
if (authenticate_user($_POST['username'], $_POST['passwordfld'], $authcfg)) {
$attributes = array();
if (authenticate_user($_POST['username'], $_POST['passwordfld'], $authcfg, $attributes)) {
$savemsg = gettext("User") . ": " . $_POST['username'] . " " . gettext("authenticated successfully.");
$groups = getUserGroups($_POST['username'], $authcfg);
$groups = getUserGroups($_POST['username'], $authcfg, $attributes);
$savemsg .= "<br />" . gettext("This user is a member of these groups") . ": <br />";
foreach ($groups as $group)
$savemsg .= "{$group} ";