285 lines
8.9 KiB
PHP
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;
|
|
}
|
|
|
|
}
|