diff --git a/contrib/openldap/core-fd-conf.schema b/contrib/openldap/core-fd-conf.schema index 0db3f0fdba060ea5bee1d18c10db851329b048c6..cff504d0596a1f59a0e7ac3073a803c7f3f1c1be 100644 --- a/contrib/openldap/core-fd-conf.schema +++ b/contrib/openldap/core-fd-conf.schema @@ -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' diff --git a/html/index.php b/html/index.php index 4f2f6957cc255aaf343284d8fb4a4a3d128fb059..284e526ac7c828814836854824362b6b9e12b7fe 100644 --- a/html/index.php +++ b/html/index.php @@ -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(); } diff --git a/html/main.php b/html/main.php index bcb65607127ee723eef2d8fc3a5134b396aaf9b1..88a6c53f5ad71a26fff8c320dbea5ce9f981614d 100644 --- a/html/main.php +++ b/html/main.php @@ -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> ".$ui->username); + $smarty->assign ('username', '<div style="color:#FF0000;">'._('User ACL checks disabled').'</div> '.$ui->uid); } else { - $smarty->assign ("username", $ui->username); + $smarty->assign ('username', $ui->uid); } $smarty->assign ("menu", $plist->menu); $smarty->assign ("plug", "$plug"); diff --git a/include/class_userinfo.inc b/include/class_userinfo.inc index 0572936de14e3a5d0bb4c85a4c5c5bd5993a212b..d98634da09ee1b9a771c771ca3e325ac597401c7 100644 --- a/include/class_userinfo.inc +++ b/include/class_userinfo.inc @@ -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]; } diff --git a/include/functions.inc b/include/functions.inc index 5b47912cc289d9f8c6cdcb50eba4ae626dd1d35e..99d550f16b769e5ba38a6275196ec488cfe76c4f 100644 --- a/include/functions.inc +++ b/include/functions.inc @@ -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(); diff --git a/plugins/config/class_configInLdap.inc b/plugins/config/class_configInLdap.inc index ee81dae3bfd620ab69437b28d17113d5308b1585..9b343f224f946fc2b15f4686e7c9ff0254dbb552 100644 --- a/plugins/config/class_configInLdap.inc +++ b/plugins/config/class_configInLdap.inc @@ -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() diff --git a/setup/class_setupStep_Finish.inc b/setup/class_setupStep_Finish.inc index 3c3b0252760bd03d76c8fe5a97a0418b6d5a0a18..4e7b06dba5bf22ce8081e23484bb0ac5e23dd3c5 100644 --- a/setup/class_setupStep_Finish.inc +++ b/setup/class_setupStep_Finish.inc @@ -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();