Merge pull request #19 from gpgmailencrypt/master

Nextcloud 13 support
This commit is contained in:
Marcin Łojewski
2018-01-29 11:43:05 +01:00
committed by GitHub
11 changed files with 631 additions and 332 deletions

View File

@@ -21,14 +21,11 @@
* *
*/ */
require_once __DIR__ . '/../user_sql.php'; require_once(__DIR__ . '/../lib/user_sql.php');
require_once __DIR__ . '/../group_sql.php'; require_once __DIR__ . '/../lib/group_sql.php';
\OCP\App::registerAdmin('user_sql','settings');
$backend = new \OCA\user_sql\OC_USER_SQL; $backend = new \OCA\user_sql\OC_USER_SQL;
$group_backend = new \OCA\user_sql\OC_GROUP_SQL; $group_backend = new \OCA\user_sql\OC_GROUP_SQL;
\OC::$server->getUserManager()->registerBackend($backend);
// register user backend
\OC_User::useBackend($backend);
\OC::$server->getGroupManager()->addBackend($group_backend); \OC::$server->getGroupManager()->addBackend($group_backend);
?>

View File

@@ -1,22 +1,24 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<info> <info>
<id>user_sql</id> <id>user_sql</id>
<name>SQL user backend</name> <name>SQL user backend</name>
<summary>Authenticate users by SQL queries.</summary> <summary>Authenticate Users by SQL</summary>
<description>Authenticate users by SQL queries.</description> <description>Authenticate Users by SQL</description>
<version>2.4.0</version> <version>3.1.0</version>
<licence>agpl</licence> <licence>agpl</licence>
<author>Andreas Boehler &lt;dev (at) aboehler (dot) at &gt;</author> <author>Andreas Boehler &lt;dev (at) aboehler (dot) at &gt;</author>
<namespace>user_sql</namespace> <namespace>user_sql</namespace>
<bugs>https://github.com/nextcloud/user_sql/issues</bugs> <types>
<repository>https://github.com/nextcloud/user_sql</repository> <authentication/>
<screenshot>https://raw.githubusercontent.com/nextcloud/user_sql/v2.4.0/screenshot.png</screenshot> </types>
<types> <category>auth</category>
<authentication/> <dependencies>
</types> <nextcloud min-version="12" max-version="13"/>
<category>auth</category> <database>mysql</database>
<dependencies> <database>pgsql</database>
<nextcloud min-version="12" max-version="12"/> </dependencies>
<owncloud min-version="10" max-version="10"/> <settings>
</dependencies> <admin>\OCA\user_sql\Settings\Admin</admin>
<admin-section>OCA\user_sql\Settings\Section</admin-section>
</settings>
</info> </info>

4
img/app-dark.svg Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.0" viewBox="0 0 16 16">
<path style="block-progression:tb;color:#000000;text-transform:none;text-indent:0" fill="#000" d="m8.4036 1c-1.7312 0-3.1998 1.2661-3.1998 2.9 0.012287 0.51643 0.058473 1.1532 0.36664 2.5v0.033333l0.033328 0.033333c0.098928 0.28338 0.24289 0.44549 0.4333 0.66666s0.41742 0.48149 0.63328 0.69999c0.025397 0.025708 0.041676 0.041633 0.066656 0.066677 0.04281 0.18631 0.094672 0.38681 0.13332 0.56666 0.10284 0.47851 0.092296 0.81737 0.066668 0.93332-0.74389 0.26121-1.6694 0.57228-2.4998 0.93332-0.46622 0.2027-0.8881 0.3837-1.2332 0.59999-0.34513 0.2163-0.68837 0.37971-0.79994 0.86666-0.16004 0.63293-0.19866 0.7539-0.39997 1.5333-0.027212 0.20914 0.083011 0.42961 0.26665 0.53333 1.5078 0.81451 3.824 1.1423 6.1329 1.1333s4.6066-0.35609 6.0662-1.1333c0.11739-0.07353 0.14304-0.10869 0.13332-0.2333-0.04365-0.68908-0.08154-1.3669-0.13332-1.7666-0.01807-0.09908-0.06492-0.19275-0.13332-0.26666-0.46366-0.5537-1.1564-0.89218-1.9665-1.2333-0.7396-0.31144-1.6067-0.63486-2.4665-0.99999-0.048123-0.10721-0.095926-0.41912 0-0.89999 0.025759-0.12912 0.066096-0.26742 0.099994-0.4 0.0808-0.090507 0.14378-0.16447 0.23332-0.26666 0.19096-0.21796 0.39614-0.44661 0.56662-0.66666s0.30996-0.40882 0.39997-0.66666l0.03333-0.033333c0.34839-1.4062 0.34857-1.9929 0.36664-2.5v-0.033333c0-1.6339-1.4686-2.9-3.1998-2.9z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

100
lib/Settings/Admin.php Normal file
View File

@@ -0,0 +1,100 @@
<?php
/**
* @copyright Copyright (c)
*
* @author
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\user_sql\Settings;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\Defaults;
use OCP\IConfig;
use OCP\IL10N;
use OCP\Settings\ISettings;
use OCA\user_sql\lib\Helper;
class Admin implements ISettings {
/** @var IL10N */
private $l10n;
/** @var Defaults */
private $defaults;
/** @var IConfig */
private $config;
/**
* @param IL10N $l10n
* @param Defaults $defaults
* @param IConfig $config
*/
public function __construct(IL10N $l10n,
Defaults $defaults,
IConfig $config) {
$this->l10n = $l10n;
$this->defaults = $defaults;
$this->config = $config;
$this->helper = new \OCA\user_sql\lib\Helper();
$this->params = $this->helper->getParameterArray();
$this->settings = $this->helper -> loadSettingsForDomain('default');
}
/**
* @return TemplateResponse
*/
public function getForm() {
$type = $this->config->getAppValue('user_sql', 'type');
$trusted_domains = \OC::$server->getConfig()->getSystemValue('trusted_domains');
$inserted = array('default');
array_splice($trusted_domains, 0, 0, $inserted);
$params = [
'type' => $type,
];
$params['allowed_domains']= array_unique($trusted_domains);
foreach($this->params as $key)
{
$value = $this->settings[$key];
$params[$key]=$value;
}
$params["config"]=$this->config;
return new TemplateResponse('user_sql', 'admin', $params);
}
/**
* @return string the section ID, e.g. 'sharing'
*/
public function getSection() {
return 'usersql';
}
/**
* @return int whether the form should be rather on the top or bottom of
* the admin section. The forms are arranged in ascending order of the
* priority values. It is required to return a value between 0 and 100.
*
* keep the server setting at the top, right after "server settings"
*/
public function getPriority() {
return 0;
}
}

68
lib/Settings/Section.php Normal file
View File

@@ -0,0 +1,68 @@
<?php
/**
* @copyright Copyright (c)
*
* @author
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\user_sql\Settings;
use OCP\IL10N;
use OCP\Settings\IIconSection;
use OCP\IURLGenerator;
class Section implements IIconSection {
/** @var IL10N */
private $l;
/**
* @param IL10N $l
*/
public function __construct(IURLGenerator $url,IL10N $l) {
$this->l = $l;
$this->url = $url;
}
/**
* {@inheritdoc}
*/
public function getID() {
return 'usersql';
}
/**
* {@inheritdoc}
*/
public function getName() {
return $this->l->t('User SQL');
}
/**
* {@inheritdoc}
*/
public function getPriority() {
return 75;
}
/**
* {@inheritdoc}
*/
public function getIcon() {
return $this->url->imagePath('user_sql', 'app-dark.svg');
}
}

View File

@@ -3,6 +3,7 @@
namespace OCA\user_sql; namespace OCA\user_sql;
use \OCA\user_sql\lib\Helper; use \OCA\user_sql\lib\Helper;
use OCP\Util;
class OC_GROUP_SQL extends \OC_Group_Backend implements \OCP\GroupInterface class OC_GROUP_SQL extends \OC_Group_Backend implements \OCP\GroupInterface
{ {
@@ -21,13 +22,13 @@ class OC_GROUP_SQL extends \OC_Group_Backend implements \OCP\GroupInterface
public function getUserGroups($uid) { public function getUserGroups($uid) {
if(empty($this -> settings['sql_group_table'])) if(empty($this -> settings['sql_group_table']))
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Group table not configured", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Group table not configured", Util::DEBUG);
return []; return [];
} }
$rows = $this -> helper -> runQuery('getUserGroups', array('uid' => $uid), false, true); $rows = $this -> helper -> runQuery('getUserGroups', array('uid' => $uid), false, true);
if($rows === false) if($rows === false)
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Found no group", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Found no group", Util::DEBUG);
return []; return [];
} }
$groups = array(); $groups = array();
@@ -60,13 +61,13 @@ class OC_GROUP_SQL extends \OC_Group_Backend implements \OCP\GroupInterface
public function usersInGroup($gid, $search = '', $limit = null, $offset = null) { public function usersInGroup($gid, $search = '', $limit = null, $offset = null) {
if(empty($this -> settings['sql_group_table'])) if(empty($this -> settings['sql_group_table']))
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Group table not configured", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Group table not configured", Util::DEBUG);
return []; return [];
} }
$rows = $this -> helper -> runQuery('getGroupUsers', array('gid' => $gid), false, true); $rows = $this -> helper -> runQuery('getGroupUsers', array('gid' => $gid), false, true);
if($rows === false) if($rows === false)
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Found no users for group", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Found no users for group", Util::DEBUG);
return []; return [];
} }
$users = array(); $users = array();

View File

@@ -1,7 +1,7 @@
<?php <?php
/** /**
* ownCloud - user_sql * nextCloud - user_sql
* *
* @author Andreas Böhler and contributors * @author Andreas Böhler and contributors
* @copyright 2012-2015 Andreas Böhler <dev (at) aboehler (dot) at> * @copyright 2012-2015 Andreas Böhler <dev (at) aboehler (dot) at>
@@ -22,6 +22,8 @@
*/ */
namespace OCA\user_sql\lib; namespace OCA\user_sql\lib;
use OCP\IConfig;
use OCP\Util;
class Helper { class Helper {
@@ -83,7 +85,7 @@ class Helper {
*/ */
public function loadSettingsForDomain($domain) public function loadSettingsForDomain($domain)
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Trying to load settings for domain: " . $domain, \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Trying to load settings for domain: " . $domain, Util::DEBUG);
$settings = array(); $settings = array();
$sql_host = \OC::$server->getConfig()->getAppValue('user_sql', 'sql_hostname_'.$domain, ''); $sql_host = \OC::$server->getConfig()->getAppValue('user_sql', 'sql_hostname_'.$domain, '');
if($sql_host === '') if($sql_host === '')
@@ -95,7 +97,7 @@ class Helper {
{ {
$settings[$param] = \OC::$server->getConfig()->getAppValue('user_sql', $param.'_'.$domain, ''); $settings[$param] = \OC::$server->getConfig()->getAppValue('user_sql', $param.'_'.$domain, '');
} }
\OCP\Util::writeLog('OC_USER_SQL', "Loaded settings for domain: " . $domain, \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Loaded settings for domain: " . $domain, Util::DEBUG);
return $settings; return $settings;
} }
@@ -110,7 +112,7 @@ class Helper {
*/ */
public function runQuery($type, $params, $execOnly = false, $fetchArray = false, $limits = array()) public function runQuery($type, $params, $execOnly = false, $fetchArray = false, $limits = array())
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Entering runQuery for type: " . $type, \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Entering runQuery for type: " . $type, Util::DEBUG);
if(!$this -> db_conn) if(!$this -> db_conn)
return false; return false;
@@ -208,24 +210,24 @@ class Helper {
$query .= " OFFSET ".$offset; $query .= " OFFSET ".$offset;
} }
\OCP\Util::writeLog('OC_USER_SQL', "Preparing query: $query", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Preparing query: $query", Util::DEBUG);
$result = $this -> db -> prepare($query); $result = $this -> db -> prepare($query);
foreach($params as $param => $value) foreach($params as $param => $value)
{ {
$result -> bindValue(":".$param, $value); $result -> bindValue(":".$param, $value);
} }
\OCP\Util::writeLog('OC_USER_SQL', "Executing query...", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Executing query...", Util::DEBUG);
if(!$result -> execute()) if(!$result -> execute())
{ {
$err = $result -> errorInfo(); $err = $result -> errorInfo();
\OCP\Util::writeLog('OC_USER_SQL', "Query failed: " . $err[2], \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Query failed: " . $err[2], Util::DEBUG);
return false; return false;
} }
if($execOnly === true) if($execOnly === true)
{ {
return true; return true;
} }
\OCP\Util::writeLog('OC_USER_SQL', "Fetching result...", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Fetching result...", Util::DEBUG);
if($fetchArray === true) if($fetchArray === true)
$row = $result -> fetchAll(); $row = $result -> fetchAll();
else else
@@ -262,7 +264,7 @@ class Helper {
} }
catch (\Exception $e) catch (\Exception $e)
{ {
\OCP\Util::writeLog('OC_USER_SQL', 'Failed to connect to the database: ' . $e -> getMessage(), \OCP\Util::ERROR); Util::writeLog('OC_USER_SQL', 'Failed to connect to the database: ' . $e -> getMessage(), Util::ERROR);
$this -> db_conn = false; $this -> db_conn = false;
return false; return false;
} }
@@ -286,7 +288,7 @@ class Helper {
if(!in_array($col, $columns, true)) if(!in_array($col, $columns, true))
{ {
$res = false; $res = false;
$err .= $table.'.'.$col.' '; $err .= $col.' ';
} }
} }
if($res) if($res)

View File

@@ -1,7 +1,7 @@
<?php <?php
/** /**
* ownCloud - user_sql * nextCloud - user_sql
* *
* @author Andreas Böhler and contributors * @author Andreas Böhler and contributors
* @copyright 2012-2015 Andreas Böhler <dev (at) aboehler (dot) at> * @copyright 2012-2015 Andreas Böhler <dev (at) aboehler (dot) at>
@@ -28,16 +28,30 @@
*/ */
namespace OCA\user_sql; namespace OCA\user_sql;
use OC\User\Backend;
use \OCA\user_sql\lib\Helper; use \OCA\user_sql\lib\Helper;
use OCP\IConfig;
use OCP\IUser;
use OCP\IUserSession;
use OCP\Notification\IManager as INotificationManager;
use OCP\Util;
if(!interface_exists('OCP\\User\\IProvidesEMailBackend')) abstract class BackendUtility {
{ protected $access;
// hack for nextcloud
eval("namespace OCP\User; interface IProvidesEMailBackend {}"); /**
* constructor, make sure the subclasses call this one!
* @param Access $access an instance of Access for LDAP interaction
*/
public function __construct(Access $access) {
$this->access = $access;
}
} }
class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\UserInterface, \OCP\User\IProvidesEMailBackend
class OC_USER_SQL extends BackendUtility implements \OCP\IUserBackend,
\OCP\UserInterface
{ {
protected $cache; protected $cache;
protected $settings; protected $settings;
@@ -51,11 +65,11 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
*/ */
public function __construct() public function __construct()
{ {
$memcache = \OC::$server->getMemCacheFactory(); $memcache = \OC::$server->getMemCacheFactory();
if ( $memcache -> isAvailable()) if ( $memcache -> isAvailable())
{ {
$this -> cache = $memcache -> create(); $this -> cache = $memcache -> create();
} }
$this -> helper = new \OCA\user_sql\lib\Helper(); $this -> helper = new \OCA\user_sql\lib\Helper();
$domain = \OC::$server->getRequest()->getServerHost(); $domain = \OC::$server->getRequest()->getServerHost();
$this -> settings = $this -> helper -> loadSettingsForDomain($domain); $this -> settings = $this -> helper -> loadSettingsForDomain($domain);
@@ -78,7 +92,8 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
*/ */
private function doEmailSync($uid) private function doEmailSync($uid)
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Entering doEmailSync for UID: $uid", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Entering doEmailSync for UID: $uid",
Util::DEBUG);
if($this -> settings['col_email'] === '') if($this -> settings['col_email'] === '')
return false; return false;
@@ -94,26 +109,40 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
return false; return false;
} }
$newMail = $row[$this -> settings['col_email']]; $newMail = $row[$this -> settings['col_email']];
$currMail = $this->ocConfig->getUserValue($ocUid, 'settings', 'email', '');
$currMail = $this->ocConfig->getUserValue( $ocUid,
'settings',
'email', '');
switch($this -> settings['set_mail_sync_mode']) switch($this -> settings['set_mail_sync_mode'])
{ {
case 'initial': case 'initial':
if($currMail === '') if($currMail === '')
$this->ocConfig->setUserValue($ocUid, 'settings', 'email', $newMail); $this->ocConfig->setUserValue( $ocUid,
'settings',
'email',
$newMail);
break; break;
case 'forcesql': case 'forcesql':
if($currMail !== $newMail) //if($currMail !== $newMail)
$this->ocConfig->setUserValue($ocUid, 'settings', 'email', $newMail); $this->ocConfig->setUserValue( $ocUid,
'settings',
'email',
$newMail);
break; break;
case 'forceoc': case 'forceoc':
if(($currMail !== '') && ($currMail !== $newMail)) if(($currMail !== '') && ($currMail !== $newMail))
{ {
$row = $this -> helper -> runQuery('setMail', array('uid' => $uid, 'currMail' => $currMail), true); $row = $this -> helper -> runQuery('setMail',
array('uid' => $uid,
'currMail' => $currMail)
, true);
if($row === false) if($row === false)
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Could not update E-Mail address in SQL database!", \OCP\Util::ERROR); Util::writeLog('OC_USER_SQL',
"Could not update E-Mail address in SQL database!",
\OCP\Util::ERROR);
} }
} }
break; break;
@@ -122,15 +151,6 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
return true; return true;
} }
/**
* Only used by OwnCloud to get the email address
*/
public function getEMailAddress($uid) {
$this->doEmailSync($uid);
$email = $this->ocConfig->getUserValue($uid, 'settings', 'email', '');
return $email;
}
/** /**
* This maps the username to the specified domain name. * This maps the username to the specified domain name.
* It can only append a default domain name. * It can only append a default domain name.
@@ -144,7 +164,8 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
if($this -> settings['set_default_domain'] !== '') if($this -> settings['set_default_domain'] !== '')
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Append default domain: ".$this -> settings['set_default_domain'], \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Append default domain: ".
$this -> settings['set_default_domain'], Util::DEBUG);
if(strpos($uid, '@') === false) if(strpos($uid, '@') === false)
{ {
$uid .= "@" . $this -> settings['set_default_domain']; $uid .= "@" . $this -> settings['set_default_domain'];
@@ -152,7 +173,8 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
} }
$uid = strtolower($uid); $uid = strtolower($uid);
\OCP\Util::writeLog('OC_USER_SQL', 'Returning mapped UID: ' . $uid, \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', 'Returning mapped UID: ' . $uid,
Util::DEBUG);
return $uid; return $uid;
} }
@@ -161,14 +183,16 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
* @param $actions * @param $actions
* @return bool * @return bool
*/ */
public function implementsAction($actions) public function implementsActions($actions)
{ {
return (bool)((\OC_User_Backend::CHECK_PASSWORD return (bool)((Backend::CHECK_PASSWORD
| \OC_User_Backend::GET_DISPLAYNAME | Backend::GET_DISPLAYNAME
| \OC_User_Backend::COUNT_USERS | Backend::COUNT_USERS
| $this -> settings['set_allow_pwchange'] === 'true' ? \OC_User_Backend::SET_PASSWORD : 0 | ($this -> settings['set_allow_pwchange'] === 'true' ?
| $this -> settings['set_enable_gethome'] === 'true' ? \OC_User_Backend::GET_HOME : 0 Backend::SET_PASSWORD : 0)
) & $actions); | ($this -> settings['set_enable_gethome'] === 'true' ?
Backend::GET_HOME : 0)
) & $actions);
} }
/** /**
@@ -187,7 +211,8 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
*/ */
public function getHome($uid) public function getHome($uid)
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Entering getHome for UID: $uid", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Entering getHome for UID: $uid",
Util::DEBUG);
if($this -> settings['set_enable_gethome'] !== 'true') if($this -> settings['set_enable_gethome'] !== 'true')
return false; return false;
@@ -198,25 +223,36 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
switch($this->settings['set_gethome_mode']) switch($this->settings['set_gethome_mode'])
{ {
case 'query': case 'query':
\OCP\Util::writeLog('OC_USER_SQL', "getHome with Query selected, running Query...", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL',
$row = $this -> helper -> runQuery('getHome', array('uid' => $uidMapped)); "getHome with Query selected, running Query...",
Util::DEBUG);
$row = $this -> helper -> runQuery('getHome',
array('uid' => $uidMapped));
if($row === false) if($row === false)
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Got no row, return false", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL',
"Got no row, return false",
Util::DEBUG);
return false; return false;
} }
$home = $row[$this -> settings['col_gethome']]; $home = $row[$this -> settings['col_gethome']];
break; break;
case 'static': case 'static':
\OCP\Util::writeLog('OC_USER_SQL', "getHome with static selected", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL',
"getHome with static selected",
Util::DEBUG);
$home = $this -> settings['set_gethome']; $home = $this -> settings['set_gethome'];
$home = str_replace('%ud', $uidMapped, $home); $home = str_replace('%ud', $uidMapped, $home);
$home = str_replace('%u', $uid, $home); $home = str_replace('%u', $uid, $home);
$home = str_replace('%d', $this -> settings['set_default_domain'], $home); $home = str_replace('%d',
$this -> settings['set_default_domain'],
$home);
break; break;
} }
\OCP\Util::writeLog('OC_USER_SQL', "Returning getHome for UID: $uid with Home $home", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL',
"Returning getHome for UID: $uid with Home $home",
Util::DEBUG);
return $home; return $home;
} }
@@ -227,7 +263,9 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
public function createUser() public function createUser()
{ {
// Can't create user // Can't create user
\OCP\Util::writeLog('OC_USER_SQL', 'Not possible to create local users from web frontend using SQL user backend', \OCP\Util::ERROR); Util::writeLog('OC_USER_SQL',
'Not possible to create local users from web'.
' frontend using SQL user backend', \OCP\Util::ERROR);
return false; return false;
} }
@@ -239,7 +277,8 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
public function deleteUser($uid) public function deleteUser($uid)
{ {
// Can't delete user // Can't delete user
\OCP\Util::writeLog('OC_USER_SQL', 'Not possible to delete local users from web frontend using SQL user backend', \OCP\Util::ERROR); Util::writeLog('OC_USER_SQL', 'Not possible to delete local users'.
' from web frontend using SQL user backend', \OCP\Util::ERROR);
return false; return false;
} }
@@ -255,7 +294,8 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
{ {
// Update the user's password - this might affect other services, that // Update the user's password - this might affect other services, that
// use the same database, as well // use the same database, as well
\OCP\Util::writeLog('OC_USER_SQL', "Entering setPassword for UID: $uid", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Entering setPassword for UID: $uid",
Util::DEBUG);
if($this -> settings['set_allow_pwchange'] !== 'true') if($this -> settings['set_allow_pwchange'] !== 'true')
return false; return false;
@@ -275,29 +315,61 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
$hasher = new \PasswordHash(10, true); $hasher = new \PasswordHash(10, true);
$enc_password = $hasher -> HashPassword($password); $enc_password = $hasher -> HashPassword($password);
} }
// Redmine stores the salt separatedly, this doesn't play nice with the way // Redmine stores the salt separatedly, this doesn't play nice with
// we check passwords // the way we check passwords
elseif($this -> settings['set_crypt_type'] === 'redmine') elseif($this -> settings['set_crypt_type'] === 'redmine')
{ {
$salt = $this -> helper -> runQuery('getRedmineSalt', array('uid' => $uid)); $salt = $this -> helper -> runQuery('getRedmineSalt',
if(!$salt) array('uid' => $uid));
return false; if(!$salt)
$enc_password = sha1($salt['salt'].sha1($password)); return false;
$enc_password = sha1($salt['salt'].sha1($password));
} }
elseif($this -> settings['set_crypt_type'] === 'sha1') elseif($this -> settings['set_crypt_type'] === 'sha1')
{ {
$enc_password = sha1($password); $enc_password = sha1($password);
} else }
elseif($this -> settings['set_crypt_type'] === 'system')
{
$prefix=substr($old_password,0,2);
if ($prefix==="$2")
{
$enc_password = $this->pw_hash($password);
}
else
{
if (($prefix==="$1") or ($prefix[0] != "$")) //old md5 or DES
{
//Update encryption algorithm
$prefix="$6"; //change to sha512
}
$newsalt=$this->create_systemsalt();
$enc_password=crypt($password,$prefix ."$" . $newsalt);
}
}
elseif($this -> settings['set_crypt_type'] === 'password_hash')
{
$enc_password = $this->pw_hash($password);
}
else
{ {
$enc_password = $this -> pacrypt($password, $old_password); $enc_password = $this -> pacrypt($password, $old_password);
} }
$res = $this -> helper -> runQuery('setPass', array('uid' => $uid, 'enc_password' => $enc_password), true); $res = $this -> helper -> runQuery('setPass',
array('uid' => $uid, 'enc_password' => $enc_password),
true);
if($res === false) if($res === false)
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Could not update password!", \OCP\Util::ERROR); Util::writeLog('OC_USER_SQL', "Could not update password!",
\OCP\Util::ERROR);
return false; return false;
} }
\OCP\Util::writeLog('OC_USER_SQL', "Updated password successfully, return true", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL',
"Updated password successfully, return true",
Util::DEBUG);
return true; return true;
} }
@@ -311,7 +383,9 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
*/ */
public function checkPassword($uid, $password) public function checkPassword($uid, $password)
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Entering checkPassword() for UID: $uid", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL',
"Entering checkPassword() for UID: $uid",
Util::DEBUG);
$uid = $this -> doUserDomainMapping($uid); $uid = $this -> doUserDomainMapping($uid);
@@ -339,9 +413,10 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
$db_pass = $row[$this -> settings['col_password']]; $db_pass = $row[$this -> settings['col_password']];
} }
\OCP\Util::writeLog('OC_USER_SQL', "Encrypting and checking password", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Encrypting and checking password",
// Joomla 2.5.18 switched to phPass, which doesn't play nice with the way Util::DEBUG);
// we check passwords // Joomla 2.5.18 switched to phPass, which doesn't play nice with the
// way we check passwords
if($this -> settings['set_crypt_type'] === 'joomla2') if($this -> settings['set_crypt_type'] === 'joomla2')
{ {
if(!class_exists('\PasswordHash')) if(!class_exists('\PasswordHash'))
@@ -349,25 +424,36 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
$hasher = new \PasswordHash(10, true); $hasher = new \PasswordHash(10, true);
$ret = $hasher -> CheckPassword($password, $db_pass); $ret = $hasher -> CheckPassword($password, $db_pass);
} }
// Redmine stores the salt separatedly, this doesn't play nice with the way elseif($this -> settings['set_crypt_type'] === 'password_hash')
// we check passwords {
$ret = password_verify($password,$db_pass);
}
// Redmine stores the salt separatedly, this doesn't play nice with the
// way we check passwords
elseif($this -> settings['set_crypt_type'] === 'redmine') elseif($this -> settings['set_crypt_type'] === 'redmine')
{ {
$salt = $this -> helper -> runQuery('getRedmineSalt', array('uid' => $uid)); $salt = $this -> helper -> runQuery('getRedmineSalt',
if(!$salt) array('uid' => $uid));
return false; if(!$salt)
$ret = sha1($salt['salt'].sha1($password)) === $db_pass; return false;
$ret = sha1($salt['salt'].sha1($password)) === $db_pass;
} }
elseif($this -> settings['set_crypt_type'] == 'sha1') elseif($this -> settings['set_crypt_type'] == 'sha1')
{ {
$ret = sha1($password) === $db_pass; $ret = $this->hash_equals(sha1($password) , $db_pass);
} else } else
{ {
$ret = $this -> pacrypt($password, $db_pass) === $db_pass; // $ret = $this -> pacrypt($password, $db_pass) === $db_pass;
$ret = $this->hash_equals($this -> pacrypt($password, $db_pass),
$db_pass);
} }
if($ret) if($ret)
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Passwords matching, return true", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL',
"Passwords matching, return true",
Util::DEBUG);
if($this -> settings['set_strip_domain'] === 'true') if($this -> settings['set_strip_domain'] === 'true')
{ {
$uid = explode("@", $uid); $uid = explode("@", $uid);
@@ -376,7 +462,9 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
return $uid; return $uid;
} else } else
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Passwords do not match, return false", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL',
"Passwords do not match, return false",
Util::DEBUG);
return false; return false;
} }
} }
@@ -385,12 +473,14 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
* Count the number of users * Count the number of users
* @return int The user count * @return int The user count
*/ */
public function countUsers() public function countUsers()
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Entering countUsers()", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Entering countUsers()",
Util::DEBUG);
$search = "%".$this -> doUserDomainMapping(""); $search = "%".$this -> doUserDomainMapping("");
$userCount = $this -> helper -> runQuery('countUsers', array('search' => $search)); $userCount = $this -> helper -> runQuery('countUsers',
array('search' => $search));
if($userCount === false) if($userCount === false)
{ {
$userCount = 0; $userCount = 0;
@@ -399,9 +489,10 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
$userCount = reset($userCount); $userCount = reset($userCount);
} }
\OCP\Util::writeLog('OC_USER_SQL', "Return usercount: ".$userCount, \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Return usercount: ".$userCount,
Util::DEBUG);
return $userCount; return $userCount;
} }
/** /**
* Get a list of all users * Get a list of all users
@@ -412,7 +503,9 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
*/ */
public function getUsers($search = '', $limit = null, $offset = null) public function getUsers($search = '', $limit = null, $offset = null)
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Entering getUsers() with Search: $search, Limit: $limit, Offset: $offset", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL',
"Entering getUsers() with Search: $search, ".
"Limit: $limit, Offset: $offset", Util::DEBUG);
$users = array(); $users = array();
if($search !== '') if($search !== '')
@@ -421,10 +514,15 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
} }
else else
{ {
$search = "%".$this -> doUserDomainMapping("")."%"; $search = "%".$this -> doUserDomainMapping("")."%";
} }
$rows = $this -> helper -> runQuery('getUsers', array('search' => $search), false, true, array('limit' => $limit, 'offset' => $offset)); $rows = $this -> helper -> runQuery('getUsers',
array('search' => $search),
false,
true,
array('limit' => $limit,
'offset' => $offset));
if($rows === false) if($rows === false)
return array(); return array();
@@ -438,7 +536,8 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
} }
$users[] = strtolower($uid); $users[] = strtolower($uid);
} }
\OCP\Util::writeLog('OC_USER_SQL', "Return list of results", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Return list of results",
Util::DEBUG);
return $users; return $users;
} }
@@ -452,11 +551,15 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
$cacheKey = 'sql_user_exists_' . $uid; $cacheKey = 'sql_user_exists_' . $uid;
$cacheVal = $this -> getCache ($cacheKey); $cacheVal = $this -> getCache ($cacheKey);
\OCP\Util::writeLog('OC_USER_SQL', "userExists() for UID: $uid cacheVal: $cacheVal", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL',
"userExists() for UID: $uid cacheVal: $cacheVal",
Util::DEBUG);
if(!is_null($cacheVal)) if(!is_null($cacheVal))
return (bool)$cacheVal; return (bool)$cacheVal;
\OCP\Util::writeLog('OC_USER_SQL', "Entering userExists() for UID: $uid", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL',
"Entering userExists() for UID: $uid",
Util::DEBUG);
// Only if the domain is removed for internal user handling, // Only if the domain is removed for internal user handling,
// we should add the domain back when checking existance // we should add the domain back when checking existance
@@ -465,16 +568,20 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
$uid = $this -> doUserDomainMapping($uid); $uid = $this -> doUserDomainMapping($uid);
} }
$exists = (bool)$this -> helper -> runQuery('userExists', array('uid' => $uid));; $exists = (bool)$this -> helper -> runQuery('userExists',
array('uid' => $uid));;
$this -> setCache ($cacheKey, $exists, 60); $this -> setCache ($cacheKey, $exists, 60);
if(!$exists) if(!$exists)
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Empty row, user does not exists, return false", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL',
"Empty row, user does not exists, return false",
Util::DEBUG);
return false; return false;
} else } else
{ {
\OCP\Util::writeLog('OC_USER_SQL', "User exists, return true", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "User exists, return true",
Util::DEBUG);
return true; return true;
} }
@@ -487,7 +594,9 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
*/ */
public function getDisplayName($uid) public function getDisplayName($uid)
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Entering getDisplayName() for UID: $uid", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL',
"Entering getDisplayName() for UID: $uid",
Util::DEBUG);
$this -> doEmailSync($uid); $this -> doEmailSync($uid);
$uid = $this -> doUserDomainMapping($uid); $uid = $this -> doUserDomainMapping($uid);
@@ -497,15 +606,21 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
return false; return false;
} }
$row = $this -> helper -> runQuery('getDisplayName', array('uid' => $uid)); $row = $this -> helper -> runQuery('getDisplayName',
array('uid' => $uid));
if(!$row) if(!$row)
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Empty row, user has no display name or does not exist, return false", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL',
"Empty row, user has no display name or ".
"does not exist, return false",
Util::DEBUG);
return false; return false;
} else } else
{ {
\OCP\Util::writeLog('OC_USER_SQL', "User exists, return true", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL',
"User exists, return true",
Util::DEBUG);
$displayName = $row[$this -> settings['col_displayname']]; $displayName = $row[$this -> settings['col_displayname']];
return $displayName; ; return $displayName; ;
} }
@@ -523,20 +638,20 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
return $displayNames; return $displayNames;
} }
/** /**
* Returns the backend name * Returns the backend name
* @return string * @return string
*/ */
public function getBackendName() public function getBackendName()
{ {
return 'SQL'; return 'SQL';
} }
/** /**
* The following functions were directly taken from PostfixAdmin and just * The following functions were directly taken from PostfixAdmin and just
* slightly modified * slightly modified
* to suit our needs. * to suit our needs.
* Encrypt a password, using the apparopriate hashing mechanism as defined in * Encrypt a password,using the apparopriate hashing mechanism as defined in
* config.inc.php ($this->crypt_type). * config.inc.php ($this->crypt_type).
* When wanting to compare one pw to another, it's necessary to provide the * When wanting to compare one pw to another, it's necessary to provide the
* salt used - hence * salt used - hence
@@ -548,7 +663,8 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
*/ */
private function pacrypt($pw, $pw_db = "") private function pacrypt($pw, $pw_db = "")
{ {
\OCP\Util::writeLog('OC_USER_SQL', "Entering private pacrypt()", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "Entering private pacrypt()",
Util::DEBUG);
$pw = stripslashes($pw); $pw = stripslashes($pw);
$password = ""; $password = "";
$salt = ""; $salt = "";
@@ -573,19 +689,21 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
$password = $pw; $password = $pw;
} }
// See // See
// https://sourceforge.net/tracker/?func=detail&atid=937966&aid=1793352&group_id=191583 // https://sourceforge.net/tracker/?func=detail&atid=937966&aid=1793352&group_id=191583
// this is apparently useful for pam_mysql etc. // this is apparently useful for pam_mysql etc.
elseif($this -> settings['set_crypt_type'] === 'mysql_encrypt') elseif($this -> settings['set_crypt_type'] === 'mysql_encrypt')
{ {
if($pw_db !== "") if($pw_db !== "")
{ {
$salt = substr($pw_db, 0, 2); $salt = substr($pw_db, 0, 2);
$row = $this -> helper -> runQuery('mysqlEncryptSalt', array('pw' => $pw, 'salt' => $salt)); $row = $this -> helper -> runQuery('mysqlEncryptSalt',
array('pw' => $pw, 'salt' => $salt));
} else } else
{ {
$row = $this -> helper -> runQuery('mysqlEncrypt', array('pw' => $pw)); $row = $this -> helper -> runQuery('mysqlEncrypt',
array('pw' => $pw));
} }
if($row === false) if($row === false)
@@ -595,7 +713,8 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
$password = $row[0]; $password = $row[0];
} elseif($this -> settings['set_crypt_type'] === 'mysql_password') } elseif($this -> settings['set_crypt_type'] === 'mysql_password')
{ {
$row = $this -> helper -> runQuery('mysqlPassword', array('pw' => $pw)); $row = $this -> helper -> runQuery('mysqlPassword',
array('pw' => $pw));
if($row === false) if($row === false)
{ {
@@ -614,19 +733,25 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
} }
$password = ($salt) ? md5($pw . $salt) : md5($pw); $password = ($salt) ? md5($pw . $salt) : md5($pw);
$password .= ':' . $salt; $password .= ':' . $salt;
} }
elseif($this-> settings['set_crypt_type'] === 'ssha256') elseif($this-> settings['set_crypt_type'] === 'ssha256')
{ {
$salted_password = base64_decode(preg_replace('/{SSHA256}/i','',$pw_db)); $salted_password = base64_decode(
$salt = substr($salted_password,-(strlen($salted_password)-32)); preg_replace('/{SSHA256}/i','',$pw_db));
$password = $this->ssha256($pw,$salt); $salt = substr($salted_password,-(strlen($salted_password)-32));
$password = $this->ssha256($pw,$salt);
} else } else
{ {
\OCP\Util::writeLog('OC_USER_SQL', "unknown/invalid crypt_type settings: ".$this->settings['set_crypt_type'], \OCP\Util::ERROR); Util::writeLog('OC_USER_SQL',
die('unknown/invalid Encryption type setting: ' . $this -> settings['set_crypt_type']); "unknown/invalid crypt_type settings: ".
$this->settings['set_crypt_type'],
\OCP\Util::ERROR);
die('unknown/invalid Encryption type setting: ' .
$this -> settings['set_crypt_type']);
} }
\OCP\Util::writeLog('OC_USER_SQL', "pacrypt() done, return", \OCP\Util::DEBUG); Util::writeLog('OC_USER_SQL', "pacrypt() done, return",
Util::DEBUG);
return $password; return $password;
} }
@@ -646,7 +771,7 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
if($magic === "") if($magic === "")
$magic = $MAGIC; $magic = $MAGIC;
if($salt === "") if($salt === "")
$salt = $this -> create_salt(); $salt = $this -> create_md5salt();
$slist = explode("$", $salt); $slist = explode("$", $salt);
if($slist[0] === "1") if($slist[0] === "1")
$salt = $slist[1]; $salt = $slist[1];
@@ -701,11 +826,16 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
$final = $this -> pahex2bin(md5($ctx1)); $final = $this -> pahex2bin(md5($ctx1));
} }
$passwd = ""; $passwd = "";
$passwd .= $this -> to64(((ord($final[0])<<16) | (ord($final[6])<<8) | (ord($final[12]))), 4); $passwd .= $this -> to64(((ord($final[0])<<16) |
$passwd .= $this -> to64(((ord($final[1])<<16) | (ord($final[7])<<8) | (ord($final[13]))), 4); (ord($final[6])<<8) | (ord($final[12]))), 4);
$passwd .= $this -> to64(((ord($final[2])<<16) | (ord($final[8])<<8) | (ord($final[14]))), 4); $passwd .= $this -> to64(((ord($final[1])<<16) |
$passwd .= $this -> to64(((ord($final[3])<<16) | (ord($final[9])<<8) | (ord($final[15]))), 4); (ord($final[7])<<8) | (ord($final[13]))), 4);
$passwd .= $this -> to64(((ord($final[4])<<16) | (ord($final[10])<<8) | (ord($final[5]))), 4); $passwd .= $this -> to64(((ord($final[2])<<16) |
(ord($final[8])<<8) | (ord($final[14]))), 4);
$passwd .= $this -> to64(((ord($final[3])<<16) |
(ord($final[9])<<8) | (ord($final[15]))), 4);
$passwd .= $this -> to64(((ord($final[4])<<16) |
(ord($final[10])<<8) | (ord($final[5]))), 4);
$passwd .= $this -> to64(ord($final[11]), 2); $passwd .= $this -> to64(ord($final[11]), 2);
return "$magic$salt\$$passwd"; return "$magic$salt\$$passwd";
} }
@@ -714,7 +844,7 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
* Create a new salte * Create a new salte
* @return string The salt * @return string The salt
*/ */
private function create_salt() private function create_md5salt()
{ {
srand((double) microtime() * 1000000); srand((double) microtime() * 1000000);
$salt = substr(md5(rand(0, 9999999)), 0, 8); $salt = substr(md5(rand(0, 9999999)), 0, 8);
@@ -728,9 +858,9 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
* @return string The hashed password, prefixed by {SSHA256} * @return string The hashed password, prefixed by {SSHA256}
*/ */
private function ssha256($pw, $salt) private function ssha256($pw, $salt)
{ {
return '{SSHA256}'.base64_encode(hash('sha256',$pw.$salt,true).$salt); return '{SSHA256}'.base64_encode(hash('sha256',$pw.$salt,true).$salt);
} }
/** /**
* PostfixAdmin's hex2bin function * PostfixAdmin's hex2bin function
@@ -760,7 +890,8 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
*/ */
private function to64($v, $n) private function to64($v, $n)
{ {
$ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; $ITOA64 =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
$ret = ""; $ret = "";
while(($n - 1) >= 0) while(($n - 1) >= 0)
{ {
@@ -771,52 +902,95 @@ class OC_USER_SQL extends \OC_User_Backend implements \OCP\IUserBackend, \OCP\Us
return $ret; return $ret;
} }
/** /**
* Store a value in memcache or the session, if no memcache is available * Store a value in memcache or the session, if no memcache is available
* @param string $key The key * @param string $key The key
* @param mixed $value The value to store * @param mixed $value The value to store
* @param int $ttl (optional) defaults to 3600 seconds. * @param int $ttl (optional) defaults to 3600 seconds.
*/ */
private function setCache($key, $value, $ttl=3600) private function setCache($key, $value, $ttl=3600)
{ {
if ($this -> cache === NULL) if ($this -> cache === NULL)
{ {
$_SESSION[$this -> session_cache_name][$key] = array( $_SESSION[$this -> session_cache_name][$key] = array(
'value' => $value, 'value' => $value,
'time' => time(), 'time' => time(),
'ttl' => $ttl, 'ttl' => $ttl,
); );
} else } else
{ {
$this -> cache -> set($key,$value,$ttl); $this -> cache -> set($key,$value,$ttl);
} }
} }
/** /**
* Fetch a value from memcache or session, if memcache is not available. * Fetch a value from memcache or session, if memcache is not available.
* Returns NULL if there's no value stored or the value expired. * Returns NULL if there's no value stored or the value expired.
* @param string $key * @param string $key
* @return mixed|NULL * @return mixed|NULL
*/ */
private function getCache($key) private function getCache($key)
{ {
$retVal = NULL; $retVal = NULL;
if ($this -> cache === NULL) if ($this -> cache === NULL)
{ {
if (isset($_SESSION[$this -> session_cache_name],$_SESSION[$this -> session_cache_name][$key])) if (isset($_SESSION[$this -> session_cache_name],
{ $_SESSION[$this -> session_cache_name][$key]))
$value = $_SESSION[$this -> session_cache_name][$key]; {
if (time() < $value['time'] + $value['ttl']) $value = $_SESSION[$this -> session_cache_name][$key];
{ if (time() < $value['time'] + $value['ttl'])
$retVal = $value['value']; {
} $retVal = $value['value'];
} }
} else }
{ } else
$retVal = $this -> cache -> get ($key); {
} $retVal = $this -> cache -> get ($key);
return $retVal; }
} return $retVal;
}
private function create_systemsalt($length=20)
{
$fp = fopen('/dev/urandom', 'r');
$randomString = fread($fp, $length);
fclose($fp);
$salt = base64_encode($randomString);
return $salt;
}
private function pw_hash($password)
{
$options = [
'cost' => 10,
];
return password_hash($password, PASSWORD_BCRYPT, $options);
}
function hash_equals( $a, $b ) {
$a_length = strlen( $a );
if ( $a_length !== strlen( $b ) ) {
return false;
}
$result = 0;
// Do not attempt to "optimize" this.
for ( $i = 0; $i < $a_length; $i++ ) {
$result |= ord( $a[ $i ] ) ^ ord( $b[ $i ] );
}
//Hide the length of the string
$additional_length=200-($a_length % 200);
$tmp=0;
$c="abCD";
for ( $i = 0; $i < $additional_length; $i++ ) {
$tmp |= ord( $c[ 0 ] ) ^ ord( $c[ 0 ] );
}
return $result === 0;
}
} }
?>

View File

@@ -1,52 +0,0 @@
<?php
/**
* ownCloud - user_sql
*
* @author Andreas Böhler
* @copyright 2012 Andreas Böhler <andreas (at) aboehler (dot) at>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\user_sql;
use OCA\user_sql\lib\Helper;
$helper = new \OCA\user_sql\lib\Helper();
$params = $helper -> getParameterArray();
$settings = $helper -> loadSettingsForDomain('default');
\OCP\Util::addStyle('user_sql', 'settings');
\OCP\Util::addScript('user_sql', 'settings');
\OCP\User::checkAdminUser();
// fill template
$tmpl = new \OCP\Template('user_sql', 'settings');
foreach($params as $param)
{
$value = htmlentities($settings[$param]);
$tmpl -> assign($param, $value);
}
$trusted_domains = \OC::$server->getConfig()->getSystemValue('trusted_domains');
$inserted = array('default');
array_splice($trusted_domains, 0, 0, $inserted);
$tmpl -> assign('allowed_domains', array_unique($trusted_domains));
// workaround to detect OC version
$ocVersion = @reset(\OCP\Util::getVersion());
$tmpl -> assign('ocVersion', $ocVersion);
return $tmpl -> fetchPage();

View File

@@ -1,5 +1,7 @@
<?php $ocVersion = $_['ocVersion']; <?php
$cfgClass = $ocVersion >= 7 ? 'section' : 'personalblock'; script('user_sql', 'settings');
style('user_sql', 'settings');
$cfgClass = 'section';
?> ?>
<div class="<?php p($cfgClass); ?>"> <div class="<?php p($cfgClass); ?>">
@@ -43,10 +45,10 @@ $cfgClass = $ocVersion >= 7 ? 'section' : 'personalblock';
<p><label for="sql_hostname"><?php p($l -> t('Host')); ?></label><input type="text" id="sql_hostname" name="sql_hostname" value="<?php p($_['sql_hostname']); ?>"></p> <p><label for="sql_hostname"><?php p($l -> t('Host')); ?></label><input type="text" id="sql_hostname" name="sql_hostname" value="<?php p($_['sql_hostname']); ?>"></p>
<p><label for="sql_username"><?php p($l -> t('Username')); ?></label><input type="text" id="sql_username" name="sql_username" value="<?php p($_['sql_username']); ?>" /></p>
<p><label for="sql_database"><?php p($l -> t('Database')); ?></label><input type="text" id="sql_database" name="sql_database" value="<?php p($_['sql_database']); ?>" /></p> <p><label for="sql_database"><?php p($l -> t('Database')); ?></label><input type="text" id="sql_database" name="sql_database" value="<?php p($_['sql_database']); ?>" /></p>
<p><label for="sql_username"><?php p($l -> t('Username')); ?></label><input type="text" id="sql_username" name="sql_username" value="<?php p($_['sql_username']); ?>" /></p>
<p><label for="sql_password"><?php p($l -> t('Password')); ?></label><input type="password" id="sql_password" name="sql_password" value="<?php p($_['sql_password']); ?>" /></p> <p><label for="sql_password"><?php p($l -> t('Password')); ?></label><input type="password" id="sql_password" name="sql_password" value="<?php p($_['sql_password']); ?>" /></p>
<p><input type="submit" id="sqlVerify" value="<?php p($l -> t('Verify Settings')); ?>"></p> <p><input type="submit" id="sqlVerify" value="<?php p($l -> t('Verify Settings')); ?>"></p>
@@ -63,12 +65,13 @@ $cfgClass = $ocVersion >= 7 ? 'section' : 'personalblock';
if($_['set_allow_pwchange']) if($_['set_allow_pwchange'])
p(' checked'); p(' checked');
?>><br> ?>><br>
<em><?php p($l -> t('Allow changing passwords. Imposes a security risk as password salts are not recreated')); ?></em></p> <em><?php p($l -> t('Allow changing passwords. Imposes a security risk if password salts are not recreated.')); ?></em></p>
<em><?php p($l -> t('Only the encryption types "System","password_hash" and "Joomla2" are safe.')); ?></em></p>
<p><label for="col_displayname"><?php p($l -> t('Real Name Column')); ?></label><input type="text" id="col_displayname" name="col_displayname" value="<?php p($_['col_displayname']); ?>" /></p> <p><label for="col_displayname"><?php p($l -> t('Real Name Column')); ?></label><input type="text" id="col_displayname" name="col_displayname" value="<?php p($_['col_displayname']); ?>" /></p>
<p><label for="set_crypt_type"><?php p($l -> t('Encryption Type')); ?></label> <p><label for="set_crypt_type"><?php p($l -> t('Encryption Type')); ?></label>
<?php $crypt_types = array('md5' => 'MD5', 'md5crypt' => 'MD5 Crypt', 'cleartext' => 'Cleartext', 'mysql_encrypt' => 'mySQL ENCRYPT()', 'system' => 'System (crypt)', 'mysql_password' => 'mySQL PASSWORD()', 'joomla' => 'Joomla MD5 Encryption', 'joomla2' => 'Joomla > 2.5.18 phpass', 'ssha256' => 'Salted SSHA256', 'redmine' => 'Redmine', 'sha1' => 'SHA1'); ?> <?php $crypt_types = array('md5' => 'MD5', 'md5crypt' => 'MD5 Crypt', 'cleartext' => 'Cleartext', 'mysql_encrypt' => 'mySQL ENCRYPT()', 'system' => 'System (crypt)', 'password_hash' => 'password_hash','mysql_password' => 'mySQL PASSWORD()', 'joomla' => 'Joomla MD5 Encryption', 'joomla2' => 'Joomla > 2.5.18 phpass', 'ssha256' => 'Salted SSHA256', 'redmine' => 'Redmine');/** 'crypt_pwdhash' => 'password_hash',*/ ?>
<select id="set_crypt_type" name="set_crypt_type"> <select id="set_crypt_type" name="set_crypt_type">
<?php <?php
foreach ($crypt_types as $driver => $name): foreach ($crypt_types as $driver => $name):