From 167588a3d0179287b92dd36b88467dba00babd11 Mon Sep 17 00:00:00 2001 From: Roland Gruber Date: Tue, 23 Aug 2011 19:05:05 +0000 Subject: [PATCH] HTTP authentication --- lam/docs/manual-sources/howto.xml | 28 ++- .../manual-sources/images/configProfiles7.png | Bin 17624 -> 18625 bytes .../manual-sources/images/configProfiles8.png | Bin 0 -> 17945 bytes lam/help/help.inc | 2 + lam/lib/config.inc | 24 ++- lam/templates/config/confmain.php | 8 + lam/templates/lib/500_lam.js | 2 + lam/templates/login.php | 185 ++++++++++-------- 8 files changed, 159 insertions(+), 90 deletions(-) create mode 100644 lam/docs/manual-sources/images/configProfiles8.png diff --git a/lam/docs/manual-sources/howto.xml b/lam/docs/manual-sources/howto.xml index 9f1c9041..147fa2e5 100644 --- a/lam/docs/manual-sources/howto.xml +++ b/lam/docs/manual-sources/howto.xml @@ -1034,13 +1034,16 @@ Have fun! - + - LAM supports two methods for login. You may either specify a - fixed list of LDAP DNs or let LAM search for the DN in your + LAM supports two methods for login. The first one is to + specify a fixed list of LDAP DNs that are allowed to login. Please + enter one DN per line. + + The second one is to let LAM search for the DN in your directory. E.g. if a user logs in with the user name "joe" then LAM will do an LDAP search for this user name. When it finds a matching DN then it will use this to authenticate the user. The wildcard @@ -1048,8 +1051,23 @@ Have fun! provide login by user name, email address or other LDAP attributes. - You may also change the password of this server - profile. + Additionally, you can enable HTTP authentication when using + "LDAP search". This way the web server is responsible to + authenticate your users. LAM will use the given user name + password + for the LDAP login. To setup HTTP authentication in Apache please + see this link. + + + + + + + + + + You may also change the password of this server profile. + Please just enter the new password in both password fields.
diff --git a/lam/docs/manual-sources/images/configProfiles7.png b/lam/docs/manual-sources/images/configProfiles7.png index 54867c57cc4a36038c17ad6670b5f9528f7273a2..e2bfff4f9dcfdce4d3865849145f07fddba36cb5 100644 GIT binary patch literal 18625 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 ATL1t6 literal 17624 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 e{E7H8k*JX!O?kAHBJMzgC<-!fq|2q=eg0p _("Please enter the LDAP suffix where LAM should start to search for users. The LDAP filter needs to match the given user name to exactly one DN. The value \"%USER%\" will be replaced by the user name from the login page.")), "222" => array ("Headline" => _("LDAP search limit"), "Text" => _("Here you can set a limit for LDAP searches. This will restrict the number of results for LDAP searches. Please use this if LAM's LDAP queries produce too much load.")), + "223" => array ("Headline" => _("HTTP authentication"), + "Text" => _("If enabled then LAM will use user and password that is provided by the web server via HTTP authentication.")), "230" => array ("Headline" => _("Profile management") . " - " . _("Add profile"), "Text" => _("Please enter the name of the new profile and the password to change its settings. Profile names may contain letters, numbers and -/_.")), "231" => array ("Headline" => _("Profile management") . " - " . _("Rename profile"), diff --git a/lam/lib/config.inc b/lam/lib/config.inc index af116af6..9636644c 100644 --- a/lam/lib/config.inc +++ b/lam/lib/config.inc @@ -254,6 +254,9 @@ class LAMConfig { /** search filter for login */ private $loginSearchFilter = 'uid=%USER%'; + /** specifies if HTTP authentication should be used */ + private $httpAuthentication = 'false'; + /** email address for sender of password reset mails */ private $lamProMailFrom = ''; @@ -274,7 +277,7 @@ class LAMConfig { "defaultLanguage", "scriptPath", "scriptServer", "scriptRights", "cachetimeout", "modules", "activeTypes", "types", "accessLevel", 'loginMethod', 'loginSearchSuffix', 'loginSearchFilter', 'searchLimit', 'lamProMailFrom', 'lamProMailReplyTo', 'lamProMailSubject', - 'lamProMailText', 'lamProMailIsHTML'); + 'lamProMailText', 'lamProMailIsHTML', 'httpAuthentication'); /** @@ -425,6 +428,7 @@ class LAMConfig { if (!in_array("loginMethod", $saved)) array_push($file_array, "\n\n# Login method.\n" . "loginMethod: " . $this->loginMethod . "\n"); if (!in_array("loginSearchSuffix", $saved)) array_push($file_array, "\n\n# Search suffix for LAM login.\n" . "loginSearchSuffix: " . $this->loginSearchSuffix . "\n"); if (!in_array("loginSearchFilter", $saved)) array_push($file_array, "\n\n# Search filter for LAM login.\n" . "loginSearchFilter: " . $this->loginSearchFilter . "\n"); + if (!in_array("httpAuthentication", $saved)) array_push($file_array, "\n\n# HTTP authentication for LAM login.\n" . "httpAuthentication: " . $this->httpAuthentication . "\n"); if (!in_array("lamProMailFrom", $saved)) array_push($file_array, "\n\n# Password mail from\n" . "lamProMailFrom: " . $this->lamProMailFrom . "\n"); if (!in_array("lamProMailReplyTo", $saved)) array_push($file_array, "\n\n# Password mail reply-to\n" . "lamProMailReplyTo: " . $this->lamProMailReplyTo . "\n"); if (!in_array("lamProMailSubject", $saved)) array_push($file_array, "\n\n# Password mail subject\n" . "lamProMailSubject: " . $this->lamProMailSubject . "\n"); @@ -1022,6 +1026,24 @@ class LAMConfig { $this->loginSearchFilter = $loginSearchFilter; } + /** + * Returns if HTTP authentication should be used. + * + * @return String $httpAuthentication use HTTP authentication ('true' or 'false') + */ + public function getHttpAuthentication() { + return $this->httpAuthentication; + } + + /** + * Specifies if HTTP authentication should be used. + * + * @param String $httpAuthentication use HTTP authentication ('true' or 'false') + */ + public function setHttpAuthentication($httpAuthentication) { + $this->httpAuthentication = $httpAuthentication; + } + /** * Returns the login search suffix. * diff --git a/lam/templates/config/confmain.php b/lam/templates/config/confmain.php index 0cd811da..de0ab46a 100644 --- a/lam/templates/config/confmain.php +++ b/lam/templates/config/confmain.php @@ -358,6 +358,8 @@ $securitySettingsContent->addElement($searchSuffixInput, true); $searchFilterInput = new htmlTableExtendedInputField(_("LDAP filter"), 'loginSearchFilter', $conf->getLoginSearchFilter(), '221'); $searchFilterInput->setRequired(true); $securitySettingsContent->addElement($searchFilterInput, true); +// HTTP authentication +$securitySettingsContent->addElement(new htmlTableExtendedInputCheckbox('httpAuthentication', ($conf->getHttpAuthentication() == 'true'), _('HTTP authentication'), '223', true), true); $securitySettingsContent->addElement(new htmlSpacer(null, '10px'), true); // new password $password1 = new htmlTableExtendedInputField(_("New password"), 'passwd1', null, '212'); @@ -443,6 +445,12 @@ function checkInput() { $conf->setLoginMethod($_POST['loginMethod']); $conf->setLoginSearchFilter($_POST['loginSearchFilter']); $conf->setLoginSearchSuffix($_POST['loginSearchSuffix']); + if (isset($_POST['httpAuthentication']) && ($_POST['httpAuthentication'] == 'on')) { + $conf->setHttpAuthentication('true'); + } + else { + $conf->setHttpAuthentication('false'); + } if (!$conf->set_Adminstring(implode(";", $adminTextNew))) { $errors[] = array("ERROR", _("List of admin users is empty or invalid!")); } diff --git a/lam/templates/lib/500_lam.js b/lam/templates/lib/500_lam.js index a268cb30..0c8d3ea5 100644 --- a/lam/templates/lib/500_lam.js +++ b/lam/templates/lib/500_lam.js @@ -157,11 +157,13 @@ function configLoginMethodChanged() { jQuery('textarea[name=admins]').parent().parent().show(); jQuery('input[name=loginSearchSuffix]').parent().parent().hide(); jQuery('input[name=loginSearchFilter]').parent().parent().hide(); + jQuery('input[name=httpAuthentication]').parent().parent().hide(); } else { jQuery('textarea[name=admins]').parent().parent().hide(); jQuery('input[name=loginSearchSuffix]').parent().parent().show(); jQuery('input[name=loginSearchFilter]').parent().parent().show(); + jQuery('input[name=httpAuthentication]').parent().parent().show(); } } diff --git a/lam/templates/login.php b/lam/templates/login.php index 2be4722e..ea629a15 100644 --- a/lam/templates/login.php +++ b/lam/templates/login.php @@ -285,7 +285,12 @@ function display_LoginPage($config_object) { echo ''; } else { - echo ''; + if ($config_object->getHttpAuthentication() == 'true') { + echo htmlspecialchars($_SERVER['PHP_AUTH_USER']); + } + else { + echo ''; + } } ?> @@ -297,7 +302,14 @@ function display_LoginPage($config_object) { ?>    - + getLoginMethod() == LAMConfig::LOGIN_SEARCH) && ($config_object->getHttpAuthentication() == 'true')) { + echo '**********'; + } + else { + echo ''; + } + ?> @@ -432,55 +444,55 @@ if(!empty($_POST['checklogin'])) { $_SESSION['ldap'] = new Ldap($_SESSION['config']); // Create new Ldap object - if($_POST['passwd'] == "") { - logNewMessage(LOG_DEBUG, "Empty password for login"); - $error_message = _("Empty password submitted. Please try again."); - display_LoginPage($_SESSION['config']); // Empty password submitted. Return to login page. - exit(); + $clientSource = $_SERVER['REMOTE_ADDR']; + if (isset($_SERVER['REMOTE_HOST'])) { + $clientSource .= '/' . $_SERVER['REMOTE_HOST']; + } + if (($_SESSION['config']->getLoginMethod() == LAMConfig::LOGIN_SEARCH) && ($_SESSION['config']->getHttpAuthentication() == 'true')) { + $username = $_SERVER['PHP_AUTH_USER']; + $password = $_SERVER['PHP_AUTH_PW']; } else { - $clientSource = $_SERVER['REMOTE_ADDR']; - if (isset($_SERVER['REMOTE_HOST'])) { - $clientSource .= '/' . $_SERVER['REMOTE_HOST']; + if($_POST['passwd'] == "") { + logNewMessage(LOG_DEBUG, "Empty password for login"); + $error_message = _("Empty password submitted. Please try again."); + display_LoginPage($_SESSION['config']); // Empty password submitted. Return to login page. + exit(); } if (get_magic_quotes_gpc() == 1) { $_POST['passwd'] = stripslashes($_POST['passwd']); } $username = $_POST['username']; - // search user in LDAP if needed - if ($_SESSION['config']->getLoginMethod() == LAMConfig::LOGIN_SEARCH) { - $searchFilter = $_SESSION['config']->getLoginSearchFilter(); - $searchFilter = str_replace('%USER%', $username ,$searchFilter); - $searchSuccess = true; - $searchError = ''; - $searchLDAP = new Ldap($_SESSION['config']); - $searchLDAPResult = $searchLDAP->connect('', '', true); - if (! ($searchLDAPResult == 0)) { - $searchSuccess = false; - $searchError = _('Cannot connect to specified LDAP server. Please try again.') . ' ' . @ldap_error($searchLDAP->server()); - } - else { - $searchResult = @ldap_search($searchLDAP->server(), $_SESSION['config']->getLoginSearchSuffix(), $searchFilter, array('dn'), 0, 0, 0, LDAP_DEREF_NEVER); - if ($searchResult) { - $searchInfo = @ldap_get_entries($searchLDAP->server(), $searchResult); - if ($searchInfo) { - cleanLDAPResult($searchInfo); - if (sizeof($searchInfo) == 0) { - $searchSuccess = false; - $searchError = _('Wrong password/user name combination. Please try again.'); - } - elseif (sizeof($searchInfo) > 1) { - $searchSuccess = false; - $searchError = _('The given user name matches multiple LDAP entries.'); - } - else { - $username = $searchInfo[0]['dn']; - } + $password = $_POST['passwd']; + } + // search user in LDAP if needed + if ($_SESSION['config']->getLoginMethod() == LAMConfig::LOGIN_SEARCH) { + $searchFilter = $_SESSION['config']->getLoginSearchFilter(); + $searchFilter = str_replace('%USER%', $username ,$searchFilter); + $searchSuccess = true; + $searchError = ''; + $searchLDAP = new Ldap($_SESSION['config']); + $searchLDAPResult = $searchLDAP->connect('', '', true); + if (! ($searchLDAPResult == 0)) { + $searchSuccess = false; + $searchError = _('Cannot connect to specified LDAP server. Please try again.') . ' ' . @ldap_error($searchLDAP->server()); + } + else { + $searchResult = @ldap_search($searchLDAP->server(), $_SESSION['config']->getLoginSearchSuffix(), $searchFilter, array('dn'), 0, 0, 0, LDAP_DEREF_NEVER); + if ($searchResult) { + $searchInfo = @ldap_get_entries($searchLDAP->server(), $searchResult); + if ($searchInfo) { + cleanLDAPResult($searchInfo); + if (sizeof($searchInfo) == 0) { + $searchSuccess = false; + $searchError = _('Wrong password/user name combination. Please try again.'); + } + elseif (sizeof($searchInfo) > 1) { + $searchSuccess = false; + $searchError = _('The given user name matches multiple LDAP entries.'); } else { - $searchSuccess = false; - $searchError = _('Unable to find the user name in LDAP.'); - if (ldap_errno($searchLDAP->server()) != 0) $searchError .= ' ' . ldap_error($searchLDAP->server()); + $username = $searchInfo[0]['dn']; } } else { @@ -489,53 +501,58 @@ if(!empty($_POST['checklogin'])) { if (ldap_errno($searchLDAP->server()) != 0) $searchError .= ' ' . ldap_error($searchLDAP->server()); } } - if (!$searchSuccess) { - $error_message = $searchError; - logNewMessage(LOG_ERR, 'User ' . $_POST['username'] . ' (' . $clientSource . ') failed to log in. ' . $searchError . ''); - $searchLDAP->close(); - display_LoginPage($_SESSION['config']); - exit(); - } - $searchLDAP->close(); - } - // try to connect to LDAP - $result = $_SESSION['ldap']->connect($username,$_POST['passwd']); // Connect to LDAP server for verifing username/password - if($result === 0) {// Username/password correct. Do some configuration and load main frame. - $_SESSION['loggedIn'] = true; - // set security settings for session - $_SESSION['sec_session_id'] = session_id(); - $_SESSION['sec_client_ip'] = $_SERVER['REMOTE_ADDR']; - $_SESSION['sec_sessionTime'] = time(); - // logging - logNewMessage(LOG_NOTICE, 'User ' . $_POST['username'] . ' (' . $clientSource . ') successfully logged in.'); - // Load main frame - metaRefresh("./main.php"); - die(); - } - else { - if ($result === False) { - // connection failed - $error_message = _("Cannot connect to specified LDAP server. Please try again."); - logNewMessage(LOG_ERR, 'User ' . $_POST['username'] . ' (' . $clientSource . ') failed to log in (LDAP error: ' . ldap_err2str($result) . ').'); - } - elseif ($result == 81) { - // connection failed - $error_message = _("Cannot connect to specified LDAP server. Please try again."); - logNewMessage(LOG_ERR, 'User ' . $_POST['username'] . ' (' . $clientSource . ') failed to log in (LDAP error: ' . ldap_err2str($result) . ').'); - } - elseif ($result == 49) { - // user name/password invalid. Return to login page. - $error_message = _("Wrong password/user name combination. Please try again."); - logNewMessage(LOG_ERR, 'User ' . $_POST['username'] . ' (' . $clientSource . ') failed to log in (wrong password).'); - } else { - // other errors - $error_message = _("LDAP error, server says:") . "\n
($result) " . ldap_err2str($result); - logNewMessage(LOG_ERR, 'User ' . $_POST['username'] . ' (' . $clientSource . ') failed to log in (LDAP error: ' . ldap_err2str($result) . ').'); + $searchSuccess = false; + $searchError = _('Unable to find the user name in LDAP.'); + if (ldap_errno($searchLDAP->server()) != 0) $searchError .= ' ' . ldap_error($searchLDAP->server()); } + } + if (!$searchSuccess) { + $error_message = $searchError; + logNewMessage(LOG_ERR, 'User ' . $username . ' (' . $clientSource . ') failed to log in. ' . $searchError . ''); + $searchLDAP->close(); display_LoginPage($_SESSION['config']); exit(); } + $searchLDAP->close(); + } + // try to connect to LDAP + $result = $_SESSION['ldap']->connect($username, $password); // Connect to LDAP server for verifing username/password + if($result === 0) {// Username/password correct. Do some configuration and load main frame. + $_SESSION['loggedIn'] = true; + // set security settings for session + $_SESSION['sec_session_id'] = session_id(); + $_SESSION['sec_client_ip'] = $_SERVER['REMOTE_ADDR']; + $_SESSION['sec_sessionTime'] = time(); + // logging + logNewMessage(LOG_NOTICE, 'User ' . $username . ' (' . $clientSource . ') successfully logged in.'); + // Load main frame + metaRefresh("./main.php"); + die(); + } + else { + if ($result === False) { + // connection failed + $error_message = _("Cannot connect to specified LDAP server. Please try again."); + logNewMessage(LOG_ERR, 'User ' . $username . ' (' . $clientSource . ') failed to log in (LDAP error: ' . ldap_err2str($result) . ').'); + } + elseif ($result == 81) { + // connection failed + $error_message = _("Cannot connect to specified LDAP server. Please try again."); + logNewMessage(LOG_ERR, 'User ' . $username . ' (' . $clientSource . ') failed to log in (LDAP error: ' . ldap_err2str($result) . ').'); + } + elseif ($result == 49) { + // user name/password invalid. Return to login page. + $error_message = _("Wrong password/user name combination. Please try again."); + logNewMessage(LOG_ERR, 'User ' . $username . ' (' . $clientSource . ') failed to log in (wrong password).'); + } + else { + // other errors + $error_message = _("LDAP error, server says:") . "\n
($result) " . ldap_err2str($result); + logNewMessage(LOG_ERR, 'User ' . $username . ' (' . $clientSource . ') failed to log in (LDAP error: ' . ldap_err2str($result) . ').'); + } + display_LoginPage($_SESSION['config']); + exit(); } }