Commit 7702a7fe authored by Côme Chilliet's avatar Côme Chilliet
Browse files

Fixes #4219 Added CAS support

parent a2d2277a
......@@ -429,6 +429,41 @@ attributetype ( 1.3.6.1.4.1.38414.8.20.3 NAME 'fdSslCertPath'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
SINGLE-VALUE)
# CAS
attributetype ( 1.3.6.1.4.1.38414.8.21.1 NAME 'fdCasActivated'
DESC 'FusionDirectory - CAS activation'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.38414.8.21.2 NAME 'fdCasServerCaCertPath'
DESC 'FusionDirectory - CAS server CA certificate path'
EQUALITY caseExactIA5Match
SUBSTR caseExactIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
SINGLE-VALUE)
attributetype ( 1.3.6.1.4.1.38414.8.21.3 NAME 'fdCasHost'
DESC 'FusionDirectory - CAS host'
EQUALITY caseExactIA5Match
SUBSTR caseExactIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
SINGLE-VALUE)
attributetype ( 1.3.6.1.4.1.38414.8.21.4 NAME 'fdCasPort'
DESC 'FusionDirectory - CAS port'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
SINGLE-VALUE)
attributetype ( 1.3.6.1.4.1.38414.8.21.5 NAME 'fdCasContext'
DESC 'FusionDirectory - CAS context'
EQUALITY caseExactIA5Match
SUBSTR caseExactIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
SINGLE-VALUE)
# merged from dashboard-fd.schema - Needed by Fusion Directory for dashboard options
attributetype ( 1.3.6.1.4.1.38414.27.1.1 NAME 'fdDashboardPrefix'
......@@ -533,7 +568,8 @@ objectclass ( 1.3.6.1.4.1.38414.8.2.1 NAME 'fusionDirectoryConf'
fdAclTabOnObjects $
fdRfc2307bis $ fdCopyPaste $ fdSnapshotURI $
fdSnapshotAdminDn $ fdSnapshotAdminPassword $ fdPersonalTitleInDN $ fdAccountRDN $
fdSslCaCertPath $ fdSslKeyPath $ fdSslCertPath
fdSslCaCertPath $ fdSslKeyPath $ fdSslCertPath $
fdCasActivated $ fdCasServerCaCertPath $ fdCasHost $ fdCasPort $ fdCasContext
) )
objectclass ( 1.3.6.1.4.1.38414.8.2.2 NAME 'fusionDirectoryPluginsConf'
......
......@@ -34,8 +34,8 @@ function displayLogin()
error_reporting(E_ALL | E_STRICT);
/* Fill template with required values */
$username = "";
if (isset($_POST["username"])) {
$username = '';
if (isset($_POST['username'])) {
$username = trim($_POST['username']);
}
$smarty->assign ('date', gmdate("D, d M Y H:i:s"));
......@@ -223,43 +223,22 @@ class Index {
self::$password = NULL;
}
/* Check LDAP connection */
static function checkLdapConnection()
{
global $config, $ldap;
$ldap = $config->get_ldap_link();
/* FIXME - The following line is needed to put objectClass list in cache otherwise schemaCheck fails but I don’t get why */
$ldap->get_objectclasses();
if (is_null($ldap) || (is_int($ldap) && $ldap == 0)) {
return msgPool::ldaperror($ldap->get_error(), $this->dn, 0, get_class());
}
return TRUE;
}
/* Runs schemaCheck if activated in configuration */
static function runSchemaCheck()
{
global $config, $ldap;
global $config;
if ($config->get_cfg_value('schemaCheck') != 'TRUE') {
return TRUE;
}
$recursive = ($config->get_cfg_value('ldapFollowReferrals') == 'TRUE');
$tls = ($config->get_cfg_value('ldapTLS') == 'TRUE');
if (!count($ldap->get_objectclasses())) {
return _('Cannot detect information about the installed LDAP schema!');
} else {
$cfg = array();
$cfg['admin'] = $config->current['ADMINDN'];
$cfg['password'] = $config->current['ADMINPASSWORD'];
$cfg['connection'] = $config->current['SERVER'];
$cfg['tls'] = $tls;
$str = check_schema($cfg);
$checkarr = array();
foreach ($str as $tr) {
if (isset($tr['IS_MUST_HAVE']) && !$tr['STATUS']) {
// FIXME - Is that the correct error message?
return _('Your LDAP setup contains old schema definitions:').'<br/><br/><i>'.$tr['MSG'].'</i>';
}
$cfg = array();
$cfg['admin'] = $config->current['ADMINDN'];
$cfg['password'] = $config->current['ADMINPASSWORD'];
$cfg['connection'] = $config->current['SERVER'];
$cfg['tls'] = ($config->get_cfg_value('ldapTLS') == 'TRUE');
$str = check_schema($cfg);
foreach ($str as $tr) {
if (isset($tr['IS_MUST_HAVE']) && !$tr['STATUS']) {
return _('LDAP schema check reported errors:').'<br/><br/><i>'.$tr['MSG'].'</i>';
}
}
return TRUE;
......@@ -268,7 +247,8 @@ class Index {
/* Check locking LDAP branch is here or create it */
static function checkForLockingBranch()
{
global $config,$ldap;
global $config;
$ldap = $config->get_ldap_link();
$ldap->cat(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE'], array('dn'));
$attrs = $ldap->fetch();
if (!count($attrs)) {
......@@ -389,7 +369,6 @@ class Index {
$success = self::runSteps(array(
'validateUserInput',
'checkLdapConnection',
'ldapLoginUser',
'loginAndCheckExpired',
'runSchemaCheck',
......@@ -401,10 +380,66 @@ class Index {
self::redirect();
}
}
/* All login steps in the right order for CAS login */
static function casLoginProcess()
{
global $config, $message;
self::init();
/* Reset error messages */
$message = '';
//~ phpCAS::setDebug();
// Initialize phpCAS
phpCAS::client(
CAS_VERSION_2_0,
$config->get_cfg_value('casHost', 'localhost'),
(int)($config->get_cfg_value('casPort', 443)),
$config->get_cfg_value('casContext', '/cas')
);
// Set the CA certificate that is the issuer of the cert
phpCAS::setCasServerCACert($config->get_cfg_value('casServerCaCertPath'));
//~ phpCAS::setNoCasServerValidation();
// force CAS authentication
phpCAS::forceAuthentication();
self::$username = phpCAS::getUser();
$ldap = $config->get_ldap_link();
$ldap->cd($config->current['BASE']);
$verify_attr = explode(',', $config->get_cfg_value('loginAttribute', 'uid'));
$filter = '';
foreach ($verify_attr as $attr) {
$filter .= '('.$attr.'='.self::$username.')';
}
$ldap->search('(&(|'.$filter.')(objectClass=inetOrgPerson))');
$ldap->fetch();
$ui = new userinfo($config, $ldap->getDn());
$success = self::runSteps(array(
'loginAndCheckExpired',
'runSchemaCheck',
'checkForLockingBranch',
));
if ($success) {
/* Everything went well, redirect to main.php */
self::redirect();
}
}
}
/* Got a formular answer, validate and try to log in */
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['login'])) {
if ($config->get_cfg_value('casActivated') == 'TRUE') {
require_once('CAS.php');
/* Move CAS autoload before FD autoload */
spl_autoload_unregister('CAS_autoload');
spl_autoload_register('CAS_autoload', TRUE, TRUE);
Index::casLoginProcess();
} elseif ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['login'])) {
/* Got a formular answer, validate and try to log in */
Index::fullLoginProcess();
}
......
......@@ -132,11 +132,11 @@ $plist->gen_menu();
$smarty->assign("hideMenus", FALSE);
if ($config->get_cfg_value("handleExpiredAccounts") == "TRUE") {
$expired = $ui->expired_status();
if ($expired == POSIX_WARN_ABOUT_EXPIRATION && !session::is_set('POSIX_WARN_ABOUT_EXPIRATION__DONE')) {
@DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $expired, "This user account (".$ui->username.") is about to expire");
if (($expired == POSIX_WARN_ABOUT_EXPIRATION) && !session::is_set('POSIX_WARN_ABOUT_EXPIRATION__DONE')) {
@DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $expired, "This user account (".$ui->uid.") is about to expire");
// The users password is about to xpire soon, display a warning message.
new log("security", "fusiondirectory", "", array(), "password for user '".$ui->username."' is about to expire");
new log("security", "fusiondirectory", "", array(), "password for user '".$ui->uid."' is about to expire");
msg_dialog::display(_("Password change"), _("Your password is about to expire, please change your password!"), INFO_DIALOG);
session::set('POSIX_WARN_ABOUT_EXPIRATION__DONE', TRUE);
} elseif ($expired == POSIX_FORCE_PASSWORD_CHANGE) {
......@@ -245,9 +245,9 @@ if (isset($plug)) {
}
if ($ui->ignore_acl_for_current_user()) {
$smarty->assign ("username", "<div style='color:#FF0000;'>"._("User ACL checks disabled")."</div>&nbsp;".$ui->username);
$smarty->assign ('username', '<div style="color:#FF0000;">'._('User ACL checks disabled').'</div>&nbsp;'.$ui->uid);
} else {
$smarty->assign ("username", $ui->username);
$smarty->assign ('username', $ui->uid);
}
$smarty->assign ("menu", $plist->menu);
$smarty->assign ("plug", "$plug");
......
......@@ -34,7 +34,6 @@ class userinfo
{
var $dn;
var $ip;
var $username;
var $cn;
var $uid;
var $gidNumber = -1;
......@@ -56,11 +55,13 @@ class userinfo
{
$this->config = &$config;
$ldap = $this->config->get_ldap_link();
$ldap->cat($userdn, array('sn', 'givenName', 'uid', 'gidNumber', 'preferredLanguage'));
$ldap->cat($userdn, array('cn', 'sn', 'givenName', 'uid', 'gidNumber', 'preferredLanguage'));
$attrs = $ldap->fetch();
if (isset($attrs['givenName'][0]) && isset($attrs['sn'][0])) {
$this->cn = $attrs['givenName'][0]." ".$attrs['sn'][0];
if (isset($attrs['cn'][0])) {
$this->cn = $attrs['cn'][0];
} elseif (isset($attrs['givenName'][0]) && isset($attrs['sn'][0])) {
$this->cn = $attrs['givenName'][0].' '.$attrs['sn'][0];
} else {
$this->cn = $attrs['uid'][0];
}
......
......@@ -450,14 +450,14 @@ function fusiondirectory_log ($message)
global $ui;
/* Preset to something reasonable */
$username = "[unauthenticated]";
$username = '[unauthenticated]';
/* Replace username if object is present */
if (isset($ui)) {
if ($ui->username != "") {
$username = "[$ui->username]";
if ($ui->uid != '') {
$username = '['.$ui->uid.']';
} else {
$username = "[unknown]";
$username = '[unknown]';
}
}
......@@ -527,10 +527,10 @@ function ldap_login_user ($username, $password)
}
$ldap->cd($config->current['BASE']);
$allowed_attributes = array("uid","mail");
$allowed_attributes = array('uid','mail');
$verify_attr = array();
if ($config->get_cfg_value("loginAttribute") != "") {
$tmp = explode(",", $config->get_cfg_value("loginAttribute"));
if ($config->get_cfg_value('loginAttribute') != '') {
$tmp = explode(',', $config->get_cfg_value('loginAttribute'));
foreach ($tmp as $attr) {
if (in_array($attr, $allowed_attributes)) {
$verify_attr[] = $attr;
......@@ -539,15 +539,15 @@ function ldap_login_user ($username, $password)
}
if (count($verify_attr) == 0) {
$verify_attr = array("uid");
$verify_attr = array('uid');
}
$tmp = $verify_attr;
$tmp[] = "uid";
$filter = "";
$tmp[] = 'uid';
$filter = '';
foreach ($verify_attr as $attr) {
$filter .= "(".$attr."=".$username.")";
$filter .= '('.$attr.'='.$username.')';
}
$filter = "(&(|".$filter.")(objectClass=inetOrgPerson))";
$filter = '(&(|'.$filter.')(objectClass=inetOrgPerson))';
$ldap->search($filter, $tmp);
/* get results, only a count of 1 is valid */
......@@ -580,7 +580,6 @@ function ldap_login_user ($username, $password)
/* got user dn, fill acl's */
$ui = new userinfo($config, $ldap->getDN());
$ui->username = $attrs['uid'][0];
/* password check, bind as user with supplied password */
$ldap->disconnect();
......
......@@ -250,6 +250,36 @@ class configInLdap extends simplePlugin
),
)
),
'cas' => array(
'name' => _('CAS'),
'attrs' => array(
new BooleanAttribute (
_('Enable CAS'), _('CAS login will be used instead of LDAP bind'),
'fdCasActivated', FALSE,
FALSE
),
new StringAttribute (
_('CA certificate path'), _('Path to the CA certificate of the CAS server'),
'fdCasServerCaCertPath', FALSE,
'/etc/ssl/certs/ca.cert'
),
new StringAttribute (
_('Host'), _('Host of the CAS server'),
'fdCasHost', FALSE,
'localhost'
),
new IntAttribute (
_('Port'), _('Port the CAS server is listening on'),
'fdCasPort', FALSE,
0 /*min*/, FALSE /*no max*/, 443
),
new StringAttribute (
_('CAS context'), _('CAS context to be used'),
'fdCasContext', FALSE,
'/cas'
),
)
),
'people_and_group' => array(
'name' => _('People and group storage'),
'class' => array('critical'),
......@@ -471,6 +501,18 @@ class configInLdap extends simplePlugin
)
)
);
$this->attributesAccess['fdCasActivated']->setManagedAttributes(
array(
'disable' => array (
FALSE => array (
'fdCasServerCaCertPath',
'fdCasHost',
'fdCasPort',
'fdCasContext',
)
)
)
);
}
function compute_dn()
......
......@@ -66,8 +66,7 @@ class Step_Finish extends setupStep
/* Create ui object */
/* got user dn, fill acl's */
$ui = new userinfo($config, $cv['valid_admin']);
$ui->username = 'fd-admin';
$ui = new userinfo($config, $cv['valid_admin']);
/* Username is set, load subtreeACL's now */
$ui->loadACL();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment