205 lines
6.4 KiB
PHP
205 lines
6.4 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
|
|
*/
|
|
|
|
/**
|
|
* Changes a password stored in an SQL database.
|
|
*
|
|
* @author Mike Cochrane <mike@graftonhall.co.nz>
|
|
* @author Mattias Webjörn Eriksson <mattias@webjorn.org>
|
|
* @author Ilya Krel <mail@krel.org>
|
|
* @author Ralf Lang <lang@b1-systems.de> (H4 conversion)
|
|
* @author Eric Jon Rostetter <eric.rostetter@physics.utexas.edu>
|
|
* @author Tjeerd van der Zee <admin@xar.nl>
|
|
* @category Horde
|
|
* @copyright 2000-2017 Horde LLC
|
|
* @license http://www.horde.org/licenses/gpl GPL
|
|
* @package Passwd
|
|
*/
|
|
class Passwd_Driver_Sql extends Passwd_Driver
|
|
{
|
|
/**
|
|
* Handle for the current database connection.
|
|
*
|
|
* @var Horde_Db_Adapter
|
|
*/
|
|
protected $_db;
|
|
|
|
/**
|
|
* @param array $params Driver parameters:
|
|
* - db: (Horde_Db_Adapter; REQUIRED) A DB Adapter object.
|
|
* - encryption: (string) The encryption type.
|
|
* - pass_col: (string) The table column for password.
|
|
* - query_lookup: (string) Should we use a custom query for lookup?
|
|
* - query_modify: (string) Should we use a custom query for changing?
|
|
* - show_encryption: (boolean) Prepend the encryption type to the
|
|
* password?
|
|
* - table: (string) The name of the user database table.
|
|
* - user_col: (string) The table column for user name.
|
|
*/
|
|
public function __construct(array $params = array())
|
|
{
|
|
if (isset($params['db'])) {
|
|
$this->_db = $params['db'];
|
|
unset($params['db']);
|
|
} else {
|
|
throw new InvalidArgumentException('Missing required Horde_Db_Adapter object');
|
|
}
|
|
|
|
/* These default to matching the Auth_Sql defaults. */
|
|
parent::__construct(array_merge(array(
|
|
'encryption' => 'ssha',
|
|
'pass_col' => 'user_pass',
|
|
'query_lookup' => false,
|
|
'query_modify' => false,
|
|
'show_encryption' => false,
|
|
'table' => 'horde_users',
|
|
'user_col' => 'user_uid'
|
|
), $params));
|
|
}
|
|
|
|
/**
|
|
* Finds out if a username and password is valid.
|
|
*
|
|
* @param string $userID The userID to check.
|
|
* @param string $oldpass An old password to check.
|
|
*
|
|
* @throws Passwd_Exception
|
|
*/
|
|
protected function _lookup($user, $oldpass)
|
|
{
|
|
if (!empty($this->_params['query_lookup'])) {
|
|
list($sql, $values) = $this->_parseQuery($this->_params['query_lookup'], $user, $oldpass);
|
|
} else {
|
|
/* Build the SQL query. */
|
|
$sql = 'SELECT ' . $this->_params['pass_col'] . ' FROM ' . $this->_params['table'] .
|
|
' WHERE ' . $this->_params['user_col'] . ' = ?';
|
|
$values = array($user);
|
|
}
|
|
|
|
/* Run query. */
|
|
try {
|
|
$result = $this->_db->selectOne($sql, $values);
|
|
} catch (Horde_Db_Exception $e) {
|
|
throw new Passwd_Exception($e);
|
|
}
|
|
|
|
if (!is_array($result)) {
|
|
throw new Passwd_Exception(_("User not found"));
|
|
}
|
|
|
|
/* Check the passwords match. */
|
|
$this->_comparePasswords($result[$this->_params['pass_col']], $oldpass);
|
|
}
|
|
|
|
/**
|
|
* Modifies a SQL password record for a user.
|
|
*
|
|
* @param string $user The user whose record we will udpate.
|
|
* @param string $newpass The new password value to set.
|
|
*
|
|
* @throws Passwd_Exception
|
|
*/
|
|
protected function _modify($user, $newpass)
|
|
{
|
|
if (!empty($this->_params['query_modify'])) {
|
|
list($sql, $values) = $this->_parseQuery($this->_params['query_modify'], $user, $newpass);
|
|
} else {
|
|
/* Encrypt the password. */
|
|
$newpass= $this->_encryptPassword($newpass);
|
|
|
|
/* Build the SQL query. */
|
|
$sql = 'UPDATE ' . $this->_params['table'] .
|
|
' SET ' . $this->_params['pass_col'] . ' = ?' .
|
|
' WHERE ' . $this->_params['user_col'] . ' = ?';
|
|
$values = array($newpass, $user);
|
|
}
|
|
|
|
/* Execute the query. */
|
|
try {
|
|
$this->_db->update($sql, $values);
|
|
} catch (Horde_Db_Exception $e) {
|
|
throw new Passwd_Exception($e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Parses the string as an SQL query substituting placeholders for
|
|
* their values.
|
|
*
|
|
* @param string $string The string to process as a query.
|
|
* @param string $user The user to use for the %u placeholder.
|
|
* @param string $password The password to use for the %p and %e
|
|
* placeholders.
|
|
*
|
|
* @return string The processed SQL query.
|
|
*/
|
|
protected function _parseQuery($string, $user, $password)
|
|
{
|
|
$query = '';
|
|
$values = array();
|
|
$length = strlen($string);
|
|
@list($username, $domain) = explode('@', $user);
|
|
for ($i = 0; $i < $length; $i++) {
|
|
if ($string[$i] == '%' && !empty($string[$i + 1])) {
|
|
switch ($string[++$i]) {
|
|
case 'd':
|
|
$query .= '?';
|
|
$values[] = $domain;
|
|
break;
|
|
|
|
case 'u':
|
|
$query .= '?';
|
|
$values[] = $user;
|
|
break;
|
|
|
|
case 'U':
|
|
$query .= '?';
|
|
$values[] = $username;
|
|
break;
|
|
|
|
case 'p':
|
|
$query .= '?';
|
|
$values[] = $password;
|
|
break;
|
|
|
|
case 'e':
|
|
$query .= '?';
|
|
$values[] = $this->_encryptPassword($password);
|
|
break;
|
|
|
|
case '%':
|
|
$query .= '%';
|
|
break;
|
|
|
|
default:
|
|
$query .= '%' . $string[$i];
|
|
break;
|
|
}
|
|
} else {
|
|
$query .= $string[$i];
|
|
}
|
|
}
|
|
|
|
return array($query, $values);
|
|
}
|
|
|
|
/**
|
|
*/
|
|
protected function _changePassword($user, $oldpass, $newpass)
|
|
{
|
|
$this->_lookup($user, $oldpass);
|
|
$this->_modify($user, $newpass);
|
|
}
|
|
|
|
}
|