Files
server/usr/share/psa-horde/passwd/lib/Basic.php
2026-01-07 20:52:11 +01:00

285 lines
8.9 KiB
PHP

<?php
/**
* Copyright 2000-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (GPL). If you
* did not receive this file, see http://www.horde.org/licenses/gpl.
*
* @category Horde
* @copyright 2000-2017 Horde LLC
* @license http://www.horde.org/licenses/gpl GPL
* @package Passwd
*/
/**
* Base class for basic view pages.
*
* @author Mike Cochrane <mike@graftonhall.co.nz>
* @author Eric Rostetter <eric.rostetter@physics.utexas.edu>
* @author Jan Schneider <jan@horde.org>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2000-2017 Horde LLC
* @license http://www.horde.org/licenses/gpl GPL
* @package Passwd
*/
class Passwd_Basic
{
/**
* @var array
*/
private $_backends;
/**
* @var string
*/
private $_output;
/**
* User ID.
*
* @var string
*/
private $_userid;
/**
* @var Horde_Variables
*/
private $_vars;
/**
*/
public function __construct(Horde_Variables $vars)
{
global $conf, $injector, $registry;
$this->_userid = $registry->getAuth();
if ($conf['user']['change'] === true) {
$this->_userid = $vars->get('userid', $this->_userid);
} else {
try {
$this->_userid = Horde::callHook('default_username', array(), 'passwd');
} catch (Horde_Exception_HookNotSet $e) {}
}
$this->_backends = $injector->getInstance('Passwd_Factory_Driver')->backends;
$this->_vars = $vars;
$this->_init();
}
/**
*/
public function render()
{
echo $this->_output;
}
/**
*/
public function status()
{
Horde::startBuffer();
$GLOBALS['notification']->notify(array('listeners' => array('status')));
return Horde::endBuffer();
}
/**
*/
private function _init()
{
global $conf, $page_output;
// Get the backend details.
$backend_key = $this->_vars->backend;
if (!isset($this->_backends[$backend_key])) {
$backend_key = null;
}
if ($backend_key && $this->_vars->submit) {
$this->_changePassword($backend_key);
}
// Choose the prefered backend from config/backends.php.
foreach ($this->_backends as $k => $v) {
if (!isset($backend_key) && (substr($k, 0, 1) != '_')) {
$backend_key = $k;
}
if ($this->_isPreferredBackend($v)) {
$backend_key = $k;
break;
}
}
$view = new Horde_View(array(
'templatePath' => PASSWD_TEMPLATES
));
$view->addHelper('FormTag');
$view->addHelper('Horde_Core_View_Helper_Help');
$view->addHelper('Horde_Core_View_Helper_Label');
$view->addHelper('Tag');
$view->formInput = Horde_Util::formInput();
$view->url = $this->_vars->return_to;
$view->userid = $this->_userid;
$view->userChange = $conf['user']['change'];
$view->showlist = ($conf['backend']['backend_list'] == 'shown');
$view->backend = $backend_key;
// Build the <select> widget for the backends list.
if ($view->showlist) {
$view->backends = $this->_backends;
$view->header = _("Change your password");
} else {
$view->header = sprintf(_("Changing password for %s"), htmlspecialchars($this->_backends[$backend_key]['name']));
}
$page_output->sidebar = false;
$page_output->addScriptFile('stripe.js', 'horde');
$page_output->addScriptFile('passwd.js');
$page_output->addInlineJsVars(array(
'var Passwd' => array(
'current_pass' => _("Please provide your current password"),
'new_pass' => _("Please provide a new password"),
'verify_pass' => _("Please verify your new password"),
'no_match' => _("Your passwords do not match"),
)
));
$this->_output = $view->render('index');
}
/**
* @param string $backend_key Backend key.
*/
private function _changePassword($backend_key)
{
global $conf, $injector, $notification, $registry;
// Check for users that cannot change their passwords.
if (in_array($this->_userid, $conf['user']['refused'])) {
$notification->push(sprintf(_("You can't change password for user %s"), $userid), 'horde.error');
return;
}
// We must be passed the old (current) password.
if (!isset($this->_vars->oldpassword)) {
$notification->push(_("You must give your current password"), 'horde.warning');
return;
}
if (!isset($this->_vars->newpassword0)) {
$notification->push(_("You must give your new password"), 'horde.warning');
return;
}
if (!isset($this->_vars->newpassword1)) {
$notification->push(_("You must verify your new password"), 'horde.warning');
return;
}
if ($this->_vars->newpassword0 != $this->_vars->newpassword1) {
$notification->push(_("Your new passwords didn't match"), 'horde.warning');
return;
}
if ($this->_vars->newpassword0 == $this->_vars->oldpassword) {
$notification->push(_("Your new password must be different from your current password"), 'horde.warning');
return;
}
$b_ptr = $this->_backends[$backend_key];
try {
Horde_Auth::checkPasswordPolicy($this->_vars->newpassword0, isset($b_ptr['policy']) ? $b_ptr['policy'] : array());
} catch (Horde_Auth_Exception $e) {
$notification->push($e, 'horde.warning');
return;
}
// Do some simple strength tests, if enabled in the config file.
if (!empty($conf['password']['strengthtests'])) {
try {
Horde_Auth::checkPasswordSimilarity($this->_vars->newpassword0, array($this->_userid, $this->_vars->oldpassword));
} catch (Horde_Auth_Exception $e) {
$notification->push($e, 'horde.warning');
return;
}
}
try {
$driver = $injector->getInstance('Passwd_Factory_Driver')->create($backend_key);
} catch (Passwd_Exception $e) {
Horde::log($e);
$notification->push(_("Password module is not properly configured"), 'horde.error');
return;
}
try {
$driver->changePassword(
$this->_userid,
$this->_vars->oldpassword,
$this->_vars->newpassword0
);
} catch (Exception $e) {
$notification->push(sprintf(_("Failure in changing password for %s: %s"), $b_ptr['name'], $e->getMessage()), 'horde.error');
return;
}
$notification->push(sprintf(_("Password changed on %s."), $b_ptr['name']), 'horde.success');
try {
Horde::callHook('password_changed', array($this->_userid, $this->_vars->oldpassword, $this->_vars->newpassword0), 'passwd');
} catch (Horde_Exception_HookNotSet $e) {}
if (!empty($b_ptr['logout'])) {
$logout_url = $registry->getLogoutUrl(array(
'msg' => _("Your password has been succesfully changed. You need to re-login to the system with your new password."),
'reason' => Horde_Auth::REASON_MESSAGE
));
$registry->clearAuth();
$logout_url->redirect();
}
if ($url = Horde::verifySignedUrl($this->_vars->return_to)) {
$url = new Horde_Url($url);
$url->redirect();
}
}
/**
* Determines if the given backend is the "preferred" backend for this web
* server.
*
* This decision is based on the global 'SERVER_NAME' and 'HTTP_HOST'
* server variables and the contents of the 'preferred' field in the
* backend's definition. The 'preferred' field may take a single value or
* an array of multiple values.
*
* @param array $backend A complete backend entry from the $backends
* hash.
*
* @return boolean True if this entry is "preferred".
*/
private function _isPreferredBackend($backend)
{
if (!empty($backend['preferred'])) {
if (is_array($backend['preferred'])) {
foreach ($backend['preferred'] as $backend) {
if ($backend == $_SERVER['SERVER_NAME'] ||
$backend == $_SERVER['HTTP_HOST']) {
return true;
}
}
} elseif ($backend['preferred'] == $_SERVER['SERVER_NAME'] ||
$backend['preferred'] == $_SERVER['HTTP_HOST']) {
return true;
}
}
return false;
}
}