diff --git a/install/sql/incremental/upd_0039.sql b/install/sql/incremental/upd_0039.sql new file mode 100644 index 0000000000000000000000000000000000000000..b5f64636ecefb5f1809790b02545f4f4b380843b --- /dev/null +++ b/install/sql/incremental/upd_0039.sql @@ -0,0 +1,36 @@ +-- -------------------------------------------------------- + +-- +-- Tabellenstruktur für Tabelle `web_database_user` +-- + +CREATE TABLE IF NOT EXISTS `web_database_user` ( + `database_user_id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `sys_userid` int(11) unsigned NOT NULL DEFAULT '0', + `sys_groupid` int(11) unsigned NOT NULL DEFAULT '0', + `sys_perm_user` varchar(5) DEFAULT NULL, + `sys_perm_group` varchar(5) DEFAULT NULL, + `sys_perm_other` varchar(5) DEFAULT NULL, + `server_id` int(11) UNSIGNED NOT NULL DEFAULT '0', + `database_user` varchar(64) DEFAULT NULL, + `database_password` varchar(64) DEFAULT NULL, + PRIMARY KEY (`database_user_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +ALTER TABLE `web_database` ADD `database_user_id` INT( 11 ) UNSIGNED NULL DEFAULT NULL AFTER `database_password` , +ADD `database_ro_user_id` INT( 11 ) UNSIGNED NULL DEFAULT NULL AFTER `database_user_id`, +ADD INDEX ( `database_user_id` ), +ADD INDEX ( `database_ro_user_id` ) ; + +-- -------------------------------------------------------- + +UPDATE `web_database`, `web_database_user` SET `web_database`.`database_user_id` = `web_database_user`.`database_user_id` WHERE `web_database_user`.`database_user` = `web_database`.`database_user`; + +-- -------------------------------------------------------- + +ALTER TABLE `web_database` +DROP `database_user`, +DROP `database_password`; + diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index 58e017845f4b57532f6f7e1038cd40a6f18a60a7..5777459ce8fa45308b46e36ea1e1b17d7ea2b136 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -1616,19 +1616,39 @@ CREATE TABLE `web_database` ( `parent_domain_id` int(11) unsigned NOT NULL DEFAULT '0', `type` varchar(16) NOT NULL DEFAULT 'y', `database_name` varchar(64) DEFAULT NULL, - `database_user` varchar(64) DEFAULT NULL, - `database_password` varchar(64) DEFAULT NULL, + `database_user_id` int(11) unsigned DEFAULT NULL, + `database_ro_user_id` int(11) unsigned DEFAULT NULL, `database_charset` varchar(64) DEFAULT NULL, `remote_access` enum('n','y') NOT NULL DEFAULT 'y', `remote_ips` text NOT NULL, `backup_interval` VARCHAR( 255 ) NOT NULL DEFAULT 'none', `backup_copies` INT NOT NULL DEFAULT '1', `active` enum('n','y') NOT NULL DEFAULT 'y', - PRIMARY KEY (`database_id`) + PRIMARY KEY (`database_id`), + KEY `database_user_id` (`database_user_id`), + KEY `database_ro_user_id` (`database_ro_user_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; -- -------------------------------------------------------- +-- +-- Tabellenstruktur für Tabelle `web_database_user` +-- + +CREATE TABLE IF NOT EXISTS `web_database_user` ( + `database_user_id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `sys_userid` int(11) unsigned NOT NULL DEFAULT '0', + `sys_groupid` int(11) unsigned NOT NULL DEFAULT '0', + `sys_perm_user` varchar(5) DEFAULT NULL, + `sys_perm_group` varchar(5) DEFAULT NULL, + `sys_perm_other` varchar(5) DEFAULT NULL, + `database_user` varchar(64) DEFAULT NULL, + `database_password` varchar(64) DEFAULT NULL, + PRIMARY KEY (`database_user_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + -- -- Table structure for table `web_domain` -- diff --git a/interface/lib/classes/db_mysql.inc.php b/interface/lib/classes/db_mysql.inc.php index 8354be6d0865c91febd5de621c36a7a7875ed8dc..e2232e886756ad675bcd52c2f04019006d0d88a2 100644 --- a/interface/lib/classes/db_mysql.inc.php +++ b/interface/lib/classes/db_mysql.inc.php @@ -299,7 +299,7 @@ public function toLower($record) { $update_data_str = $update_data; } - $this->query("UPDATE $tablename SET $update_data WHERE $index_field = '$index_value'"); + $this->query("UPDATE $tablename SET $update_data_str WHERE $index_field = '$index_value'"); $new_rec = $this->queryOneRecord("SELECT * FROM $tablename WHERE $index_field = '$index_value'"); $this->datalogSave($tablename, 'UPDATE', $index_field, $index_value, $old_rec, $new_rec, $force_update); diff --git a/interface/web/sites/database_del.php b/interface/web/sites/database_del.php index f5f8dbce1770db37973d109d91a9b123afcec11d..b1263b3073b9a1bbfe7dbd5d70b786216ec2bf48 100644 --- a/interface/web/sites/database_del.php +++ b/interface/web/sites/database_del.php @@ -46,6 +46,41 @@ require_once('../../lib/app.inc.php'); $app->auth->check_module_permissions('sites'); $app->uses("tform_actions"); -$app->tform_actions->onDelete(); +class page_action extends tform_actions { + function onBeforeDelete() { + global $app; $conf; + if($app->tform->checkPerm($this->id,'d') == false) $app->error($app->lng('error_no_delete_permission')); + + $old_record = $app->tform->getDataRecord($this->id); + if($old_record['database_user_id']) { + // check if any database on the server still uses this one + $check = $app->db->queryOneRecord("SELECT COUNT(*) as `cnt` FROM `web_database` WHERE `server_id` = '" . intval($old_record['server_id']) . "' AND (`database_user_id` = '" . intval($old_record['database_user_id']) . "' OR `database_ro_user_id` = '" . intval($old_record['database_user_id']) . "') AND `sys_groupid` = '" . intval($old_record['sys_groupid']) . "' AND `database_id` != '" . intval($this->id) . "'"); + if($check['cnt'] < 1) { + // send a datalog delete + $db_user = $app->db->queryOneRecord("SELECT * FROM `web_database_user` WHERE `database_user_id` = '" . intval($old_record['database_user_id']) . "' AND `sys_groupid` = '" . intval($old_record['sys_groupid']) . "'"); + if($db_user) { + $db_user['server_id'] = $old_record['server_id']; + $app->db->datalogSave('web_database_user', 'DELETE', 'database_user_id', $db_user['database_user_id'], $db_user, array()); + } + } + } + if($old_record['database_ro_user_id']) { + // check if any database on the server still uses this one + $check = $app->db->queryOneRecord("SELECT COUNT(*) as `cnt` FROM `web_database` WHERE `server_id` = '" . intval($old_record['server_id']) . "' AND (`database_user_id` = '" . intval($old_record['database_ro_user_id']) . "' OR `database_ro_user_id` = '" . intval($old_record['database_ro_user_id']) . "') AND `sys_groupid` = '" . intval($old_record['sys_groupid']) . "' AND `database_id` != '" . intval($this->id) . "'"); + if($check['cnt'] < 1) { + // send a datalog delete + $db_user = $app->db->queryOneRecord("SELECT * FROM `web_database_user` WHERE `database_user_id` = '" . intval($old_record['database_ro_user_id']) . "' AND `sys_groupid` = '" . intval($old_record['sys_groupid']) . "'"); + if($db_user) { + $db_user['server_id'] = $old_record['server_id']; + $app->db->datalogSave('web_database_user', 'DELETE', 'database_user_id', $db_user['database_user_id'], $db_user, array()); + } + } + } + + } +} + +$page = new page_action; +$page->onDelete(); ?> \ No newline at end of file diff --git a/interface/web/sites/database_edit.php b/interface/web/sites/database_edit.php index 7f675fa6756428e453472769060dfba853e5104b..d098625e7dc8df949e3d3a5b7ac2c8662eebf1d1 100644 --- a/interface/web/sites/database_edit.php +++ b/interface/web/sites/database_edit.php @@ -114,20 +114,16 @@ class page_action extends tform_actions { $app->uses('getconf'); $global_config = $app->getconf->get_global_config('sites'); $dbname_prefix = replacePrefix($global_config['dbname_prefix'], $this->dataRecord); - $dbuser_prefix = replacePrefix($global_config['dbuser_prefix'], $this->dataRecord); if ($this->dataRecord['database_name'] != ""){ /* REMOVE the restriction */ $app->tpl->setVar("database_name", str_replace($dbname_prefix , '', $this->dataRecord['database_name'])); - $app->tpl->setVar("database_user", str_replace($dbuser_prefix , '', $this->dataRecord['database_user'])); } if($_SESSION["s"]["user"]["typ"] == 'admin' || $app->auth->has_clients($_SESSION['s']['user']['userid'])) { $app->tpl->setVar("database_name_prefix", $global_config['dbname_prefix']); - $app->tpl->setVar("database_user_prefix", $global_config['dbuser_prefix']); } else { $app->tpl->setVar("database_name_prefix", $dbname_prefix); - $app->tpl->setVar("database_user_prefix", $dbuser_prefix); } if($this->id > 0) { @@ -187,8 +183,7 @@ class page_action extends tform_actions { $app->uses('getconf'); $global_config = $app->getconf->get_global_config('sites'); $dbname_prefix = replacePrefix($global_config['dbname_prefix'], $this->dataRecord); - $dbuser_prefix = replacePrefix($global_config['dbuser_prefix'], $this->dataRecord); - + //* Prevent that the database name and charset is changed $old_record = $app->tform->getDataRecord($this->id); if($old_record["database_name"] != $dbname_prefix . $this->dataRecord["database_name"]) { @@ -200,8 +195,7 @@ class page_action extends tform_actions { //* Database username and database name shall not be empty if($this->dataRecord['database_name'] == '') $app->tform->errorMessage .= $app->tform->wordbook["database_name_error_empty"].'
'; - if($this->dataRecord['database_user'] == '') $app->tform->errorMessage .= $app->tform->wordbook["database_user_error_empty"].'
'; - + //* Check if the server has been changed // We do this only for the admin or reseller users, as normal clients can not change the server ID anyway if($_SESSION["s"]["user"]["typ"] == 'admin' || $app->auth->has_clients($_SESSION['s']['user']['userid'])) { @@ -214,7 +208,6 @@ class page_action extends tform_actions { unset($old_record); if(strlen($dbname_prefix . $this->dataRecord['database_name']) > 64) $app->tform->errorMessage .= str_replace('{db}',$dbname_prefix . $this->dataRecord['database_name'],$app->tform->wordbook["database_name_error_len"]).'
'; - if(strlen($dbuser_prefix . $this->dataRecord['database_user']) > 16) $app->tform->errorMessage .= str_replace('{user}',$dbuser_prefix . $this->dataRecord['database_user'],$app->tform->wordbook["database_user_error_len"]).'
'; //* Check database name and user against blacklist $dbname_blacklist = array($conf['db_database'],'mysql'); @@ -222,16 +215,10 @@ class page_action extends tform_actions { $app->tform->errorMessage .= $app->lng('Database name not allowed.').'
'; } - $dbuser_blacklist = array($conf['db_user'],'mysql','root'); - if(in_array($dbname_prefix . $this->dataRecord['database_user'],$dbname_blacklist)) { - $app->tform->errorMessage .= $app->lng('Database user not allowed.').'
'; - } - if ($app->tform->errorMessage == ''){ /* restrict the names if there is no error */ /* crop user and db names if they are too long -> mysql: user: 16 chars / db: 64 chars */ $this->dataRecord['database_name'] = substr($dbname_prefix . $this->dataRecord['database_name'], 0, 64); - $this->dataRecord['database_user'] = substr($dbuser_prefix . $this->dataRecord['database_user'], 0, 16); } //* Check for duplicates @@ -244,8 +231,11 @@ class page_action extends tform_actions { // we need remote access rights for this server, so get it's ip address $server_config = $app->getconf->get_server_config($tmp['server_id'], 'server'); if($server_config['ip_address']!='') { + if($this->dataRecord['remote_access'] != 'y') $this->dataRecord['remote_ips'] = ''; $this->dataRecord['remote_access'] = 'y'; - $this->dataRecord['remote_ips'] .= ($this->dataRecord['remote_ips'] != '' ? ',' : '') . $server_config['ip_address']; + if(preg_match('/(^|,)' . preg_quote($server_config['ip_address'], '/') . '(,|$)/', $this->dataRecord['remote_ips']) == false) { + $this->dataRecord['remote_ips'] .= ($this->dataRecord['remote_ips'] != '' ? ',' : '') . $server_config['ip_address']; + } } } @@ -261,16 +251,13 @@ class page_action extends tform_actions { //* Database username and database name shall not be empty if($this->dataRecord['database_name'] == '') $app->tform->errorMessage .= $app->tform->wordbook["database_name_error_empty"].'
'; - if($this->dataRecord['database_user'] == '') $app->tform->errorMessage .= $app->tform->wordbook["database_user_error_empty"].'
'; //* Get the database name and database user prefix $app->uses('getconf'); $global_config = $app->getconf->get_global_config('sites'); $dbname_prefix = replacePrefix($global_config['dbname_prefix'], $this->dataRecord); - $dbuser_prefix = replacePrefix($global_config['dbuser_prefix'], $this->dataRecord); if(strlen($dbname_prefix . $this->dataRecord['database_name']) > 64) $app->tform->errorMessage .= str_replace('{db}',$dbname_prefix . $this->dataRecord['database_name'],$app->tform->wordbook["database_name_error_len"]).'
'; - if(strlen($dbuser_prefix . $this->dataRecord['database_user']) > 16) $app->tform->errorMessage .= str_replace('{user}',$dbuser_prefix . $this->dataRecord['database_user'],$app->tform->wordbook["database_user_error_len"]).'
'; //* Check database name and user against blacklist $dbname_blacklist = array($conf['db_database'],'mysql'); @@ -278,16 +265,10 @@ class page_action extends tform_actions { $app->tform->errorMessage .= $app->lng('Database name not allowed.').'
'; } - $dbuser_blacklist = array($conf['db_user'],'mysql','root'); - if(in_array($dbname_prefix . $this->dataRecord['database_user'],$dbname_blacklist)) { - $app->tform->errorMessage .= $app->lng('Database user not allowed.').'
'; - } - /* restrict the names */ /* crop user and db names if they are too long -> mysql: user: 16 chars / db: 64 chars */ if ($app->tform->errorMessage == ''){ $this->dataRecord['database_name'] = substr($dbname_prefix . $this->dataRecord['database_name'], 0, 64); - $this->dataRecord['database_user'] = substr($dbuser_prefix . $this->dataRecord['database_user'], 0, 16); } //* Check for duplicates @@ -300,14 +281,139 @@ class page_action extends tform_actions { // we need remote access rights for this server, so get it's ip address $server_config = $app->getconf->get_server_config($tmp['server_id'], 'server'); if($server_config['ip_address']!='') { + if($this->dataRecord['remote_access'] != 'y') $this->dataRecord['remote_ips'] = ''; $this->dataRecord['remote_access'] = 'y'; - $this->dataRecord['remote_ips'] .= (trim($this->dataRecord['remote_ips']) != '' ? ',' : '') . $server_config['ip_address']; + if(preg_match('/(^|,)' . preg_quote($server_config['ip_address'], '/') . '(,|$)/', $this->dataRecord['remote_ips']) == false) { + $this->dataRecord['remote_ips'] .= ($this->dataRecord['remote_ips'] != '' ? ',' : '') . $server_config['ip_address']; + } } } parent::onBeforeInsert(); } + function onInsertSave($sql) { + global $app, $conf; + + if($this->dataRecord["parent_domain_id"] > 0) { + $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($this->dataRecord["parent_domain_id"])); + + //* The Database user shall be owned by the same group then the website + $sys_groupid = $web['sys_groupid']; + } else { + $sys_groupid = $this->dataRecord['sys_groupid']; + } + + + if($this->dataRecord['database_user_id']) { + // check if there has already been a database on this server with that user + $check = $app->db->queryOneRecord("SELECT COUNT(*) as `cnt` FROM `web_database` WHERE `server_id` = '" . intval($this->dataRecord['server_id']) . "' AND (`database_user_id` = '" . intval($this->dataRecord['database_user_id']) . "' OR `database_ro_user_id` = '" . intval($this->dataRecord['database_user_id']) . "') AND `sys_groupid` = '" . intval($sys_groupid) . "'"); + + if($check && $check['cnt'] < 1) { + // we need to make a datalog insert for the database users that are connected to this database + $db_user = $app->db->queryOneRecord("SELECT * FROM `web_database_user` WHERE `database_user_id` = '" . intval($this->dataRecord['database_user_id']) . "' AND `sys_groupid` = '" . intval($sys_groupid) . "'"); + if($db_user) { + $db_user['server_id'] = $this->dataRecord['server_id']; + $app->db->datalogSave('web_database_user', 'INSERT', 'database_user_id', $db_user['database_user_id'], array(), $db_user); + } + } + } + + if($this->dataRecord['database_ro_user_id']) { + // check if there has already been a database on this server with that user + $check = $app->db->queryOneRecord("SELECT COUNT(*) as `cnt` FROM `web_database` WHERE `server_id` = '" . intval($this->dataRecord['server_id']) . "' AND (`database_user_id` = '" . intval($this->dataRecord['database_ro_user_id']) . "' OR `database_ro_user_id` = '" . intval($this->dataRecord['database_ro_user_id']) . "') AND `sys_groupid` = '" . intval($sys_groupid) . "'"); + + if($check && $check['cnt'] < 1) { + // we need to make a datalog insert for the database users that are connected to this database + $db_user = $app->db->queryOneRecord("SELECT * FROM `web_database_user` WHERE `database_user_id` = '" . intval($this->dataRecord['database_ro_user_id']) . "' AND `sys_groupid` = '" . intval($sys_groupid) . "'"); + if($db_user) { + $db_user['server_id'] = $this->dataRecord['server_id']; + $app->db->datalogSave('web_database_user', 'INSERT', 'database_user_id', $db_user['database_user_id'], array(), $db_user); + } + } + } + + $app->db->query($sql); + if($app->db->errorMessage != '') die($app->db->errorMessage); + $new_id = $app->db->insertID(); + + return $new_id; + } + + function onUpdateSave($sql) { + global $app; + if(!empty($sql) && !$app->tform->isReadonlyTab($app->tform->getCurrentTab(),$this->id)) { + $old_record = $app->tform->getDataRecord($this->id); + + if($this->dataRecord["parent_domain_id"] > 0) { + $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($this->dataRecord["parent_domain_id"])); + + //* The Database user shall be owned by the same group then the website + $sys_groupid = $web['sys_groupid']; + } else { + $sys_groupid = $this->dataRecord['sys_groupid']; + } + + // check if database user has changed + if($old_record['database_user_id'] && $old_record['database_user_id'] != $this->dataRecord['database_user_id'] && $old_record['database_user_id'] != $this->dataRecord['database_ro_user_id']) { + // check if any database on the server still uses this one + $check = $app->db->queryOneRecord("SELECT COUNT(*) as `cnt` FROM `web_database` WHERE `server_id` = '" . intval($this->dataRecord['server_id']) . "' AND (`database_user_id` = '" . intval($old_record['database_user_id']) . "' OR `database_ro_user_id` = '" . intval($old_record['database_user_id']) . "') AND `sys_groupid` = '" . intval($sys_groupid) . "' AND `database_id` != '" . intval($this->id) . "'"); + if($check['cnt'] < 1) { + // send a datalog delete + $db_user = $app->db->queryOneRecord("SELECT * FROM `web_database_user` WHERE `database_user_id` = '" . intval($old_record['database_user_id']) . "' AND `sys_groupid` = '" . intval($sys_groupid) . "'"); + if($db_user) { + $db_user['server_id'] = $this->dataRecord['server_id']; + $app->db->datalogSave('web_database_user', 'DELETE', 'database_user_id', $db_user['database_user_id'], $db_user, array()); + } + } + } + // check if readonly database user has changed + if($old_record['database_ro_user_id'] && $old_record['database_ro_user_id'] != $this->dataRecord['database_ro_user_id'] && $old_record['database_ro_user_id'] != $this->dataRecord['database_user_id']) { + // check if any database on the server still uses this one + $check = $app->db->queryOneRecord("SELECT COUNT(*) as `cnt` FROM `web_database` WHERE `server_id` = '" . intval($this->dataRecord['server_id']) . "' AND (`database_user_id` = '" . intval($old_record['database_ro_user_id']) . "' OR `database_ro_user_id` = '" . intval($old_record['database_ro_user_id']) . "') AND `sys_groupid` = '" . intval($sys_groupid) . "' AND `database_id` != '" . intval($this->id) . "'"); + if($check['cnt'] < 1) { + // send a datalog delete + $db_user = $app->db->queryOneRecord("SELECT * FROM `web_database_user` WHERE `database_user_id` = '" . intval($old_record['database_ro_user_id']) . "' AND `sys_groupid` = '" . intval($sys_groupid) . "'"); + if($db_user) { + $db_user['server_id'] = $this->dataRecord['server_id']; + $app->db->datalogSave('web_database_user', 'DELETE', 'database_user_id', $db_user['database_user_id'], $db_user, array()); + } + } + } + + if($this->dataRecord['database_user_id']) { + // check if there has already been a database on this server with that user + $check = $app->db->queryOneRecord("SELECT COUNT(*) as `cnt` FROM `web_database` WHERE `server_id` = '" . intval($this->dataRecord['server_id']) . "' AND (`database_user_id` = '" . intval($this->dataRecord['database_user_id']) . "' OR `database_ro_user_id` = '" . intval($this->dataRecord['database_user_id']) . "') AND `sys_groupid` = '" . intval($sys_groupid) . "'"); + + if($check && $check['cnt'] < 1) { + // we need to make a datalog insert for the database users that are connected to this database + $db_user = $app->db->queryOneRecord("SELECT * FROM `web_database_user` WHERE `database_user_id` = '" . intval($this->dataRecord['database_user_id']) . "' AND `sys_groupid` = '" . intval($sys_groupid) . "'"); + if($db_user) { + $db_user['server_id'] = $this->dataRecord['server_id']; + $app->db->datalogSave('web_database_user', 'INSERT', 'database_user_id', $db_user['database_user_id'], array(), $db_user); + } + } + } + + if($this->dataRecord['database_ro_user_id']) { + // check if there has already been a database on this server with that user + $check = $app->db->queryOneRecord("SELECT COUNT(*) as `cnt` FROM `web_database` WHERE `server_id` = '" . intval($this->dataRecord['server_id']) . "' AND (`database_user_id` = '" . intval($this->dataRecord['database_ro_user_id']) . "' OR `database_ro_user_id` = '" . intval($this->dataRecord['database_ro_user_id']) . "') AND `sys_groupid` = '" . intval($sys_groupid) . "'"); + + if($check && $check['cnt'] < 1) { + // we need to make a datalog insert for the database users that are connected to this database + $db_user = $app->db->queryOneRecord("SELECT * FROM `web_database_user` WHERE `database_user_id` = '" . intval($this->dataRecord['database_ro_user_id']) . "' AND `sys_groupid` = '" . intval($sys_groupid) . "'"); + if($db_user) { + $db_user['server_id'] = $this->dataRecord['server_id']; + $app->db->datalogSave('web_database_user', 'INSERT', 'database_user_id', $db_user['database_user_id'], array(), $db_user); + } + } + } + + $app->db->query($sql); + if($app->db->errorMessage != '') die($app->db->errorMessage); + } + } + function onAfterInsert() { global $app, $conf; diff --git a/interface/web/sites/database_user_del.php b/interface/web/sites/database_user_del.php new file mode 100644 index 0000000000000000000000000000000000000000..5ecdde5abfc98bd0551add4408d70468fed77d90 --- /dev/null +++ b/interface/web/sites/database_user_del.php @@ -0,0 +1,78 @@ +auth->check_module_permissions('sites'); + +$app->uses("tform_actions"); + +class page_action extends tform_actions { + function onBeforeDelete() { + global $app; $conf; + if($app->tform->checkPerm($this->id,'d') == false) $app->error($app->lng('error_no_delete_permission')); + + $old_record = $app->tform->getDataRecord($this->id); + $app->db->datalogDelete('web_database_user', 'database_user_id', $this->id); + } + + function onAfterDelete() { // this has to be done on AFTER delete, because we need the db user still in the database when the server plugin processes the datalog + global $app; $conf; + + //* Update all records that belog to this user + $records = $app->db->queryAllRecords("SELECT database_id FROM web_database WHERE database_user_id = '".intval($this->id)."'"); + foreach($records as $rec) { + $app->db->datalogUpdate('web_database','database_user_id=NULL','database_id', $rec['database_id']); + + } + $records = $app->db->queryAllRecords("SELECT database_id FROM web_database WHERE database_ro_user_id = '".intval($this->id)."'"); + foreach($records as $rec) { + $app->db->datalogUpdate('web_database','database_ro_user_id=NULL','database_id', $rec['database_id']); + } + } +} + +$page = new page_action; +$page->onDelete(); + +?> \ No newline at end of file diff --git a/interface/web/sites/database_user_edit.php b/interface/web/sites/database_user_edit.php new file mode 100644 index 0000000000000000000000000000000000000000..65bf2553d0c7e92314994e05b631eee348c9e0ef --- /dev/null +++ b/interface/web/sites/database_user_edit.php @@ -0,0 +1,212 @@ +auth->check_module_permissions('sites'); + +// Loading classes +$app->uses('tpl,tform,tform_actions'); +$app->load('tform_actions'); + +class page_action extends tform_actions { + + function onShowEnd() { + global $app, $conf, $interfaceConf; + + /* + * If the names are restricted -> remove the restriction, so that the + * data can be edited + */ + + //* Get the database user prefix + $app->uses('getconf'); + $global_config = $app->getconf->get_global_config('sites'); + $dbuser_prefix = replacePrefix($global_config['dbuser_prefix'], $this->dataRecord); + + if ($_SESSION["s"]["user"]["typ"] != 'admin' && $app->auth->has_clients($_SESSION['s']['user']['userid'])) { + // Get the limits of the client + $client_group_id = $_SESSION["s"]["user"]["default_group"]; + $client = $app->db->queryOneRecord("SELECT client.contactname, client.name, client.client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); + + // Fill the client select field + $sql = "SELECT sys_group.groupid, sys_group.name, CONCAT(client.company_name,' :: ',client.contact_name) as contactname FROM sys_group, client WHERE sys_group.client_id = client.client_id AND client.parent_client_id = ".$client['client_id']." ORDER BY sys_group.name"; + $records = $app->db->queryAllRecords($sql); + $tmp = $app->db->queryOneRecord("SELECT groupid FROM sys_group WHERE client_id = ".$client['client_id']); + $client_select = ''; + //$tmp_data_record = $app->tform->getDataRecord($this->id); + if(is_array($records)) { + foreach( $records as $rec) { + $selected = @(is_array($this->dataRecord) && ($rec["groupid"] == $this->dataRecord['client_group_id'] || $rec["groupid"] == $this->dataRecord['sys_groupid']))?'SELECTED':''; + $client_select .= "\r\n"; + } + } + $app->tpl->setVar("client_group_id",$client_select); + } elseif($_SESSION["s"]["user"]["typ"] == 'admin') { + // Fill the client select field + $sql = "SELECT sys_group.groupid, sys_group.name, CONCAT(client.company_name,' :: ',client.contact_name) as contactname FROM sys_group, client WHERE sys_group.client_id = client.client_id AND sys_group.client_id > 0 ORDER BY sys_group.name"; + $clients = $app->db->queryAllRecords($sql); + $client_select = ""; + //$tmp_data_record = $app->tform->getDataRecord($this->id); + if(is_array($clients)) { + foreach( $clients as $client) { + //$selected = @($client["groupid"] == $tmp_data_record["sys_groupid"])?'SELECTED':''; + $selected = @(is_array($this->dataRecord) && ($client["groupid"] == $this->dataRecord['client_group_id'] || $client["groupid"] == $this->dataRecord['sys_groupid']))?'SELECTED':''; + $client_select .= "\r\n"; + } + } + $app->tpl->setVar("client_group_id",$client_select); + } + + + if ($this->dataRecord['database_user'] != ""){ + /* REMOVE the restriction */ + $app->tpl->setVar("database_user", str_replace($dbuser_prefix , '', $this->dataRecord['database_user'])); + } + + if($_SESSION["s"]["user"]["typ"] == 'admin' || $app->auth->has_clients($_SESSION['s']['user']['userid'])) { + $app->tpl->setVar("database_user_prefix", $global_config['dbuser_prefix']); + } else { + $app->tpl->setVar("database_user_prefix", $dbuser_prefix); + } + + parent::onShowEnd(); + } + + function onSubmit() { + global $app; + + if($_SESSION['s']['user']['typ'] != 'admin' && !$app->auth->has_clients($_SESSION['s']['user']['userid'])) unset($this->dataRecord["client_group_id"]); + + parent::onSubmit(); + } + + function onBeforeUpdate() { + global $app, $conf, $interfaceConf; + + //* Get the database user prefix + $app->uses('getconf'); + $global_config = $app->getconf->get_global_config('sites'); + $dbuser_prefix = replacePrefix($global_config['dbuser_prefix'], $this->dataRecord); + + //* Database username shall not be empty + if($this->dataRecord['database_user'] == '') $app->tform->errorMessage .= $app->tform->wordbook["database_user_error_empty"].'
'; + + if(strlen($dbuser_prefix . $this->dataRecord['database_user']) > 16) $app->tform->errorMessage .= str_replace('{user}',$dbuser_prefix . $this->dataRecord['database_user'],$app->tform->wordbook["database_user_error_len"]).'
'; + + //* Check database user against blacklist + $dbuser_blacklist = array($conf['db_user'],'mysql','root'); + if(in_array($dbname_prefix . $this->dataRecord['database_user'],$dbname_blacklist)) { + $app->tform->errorMessage .= $app->lng('Database user not allowed.').'
'; + } + + if ($app->tform->errorMessage == ''){ + /* restrict the names if there is no error */ + /* crop user and db names if they are too long -> mysql: user: 16 chars / db: 64 chars */ + $this->dataRecord['database_user'] = substr($dbuser_prefix . $this->dataRecord['database_user'], 0, 16); + } + + parent::onBeforeUpdate(); + } + + function onBeforeInsert() { + global $app, $conf, $interfaceConf; + + //* Database username shall not be empty + if($this->dataRecord['database_user'] == '') $app->tform->errorMessage .= $app->tform->wordbook["database_user_error_empty"].'
'; + + //* Get the database name and database user prefix + $app->uses('getconf'); + $global_config = $app->getconf->get_global_config('sites'); + $dbuser_prefix = replacePrefix($global_config['dbuser_prefix'], $this->dataRecord); + + if(strlen($dbuser_prefix . $this->dataRecord['database_user']) > 16) $app->tform->errorMessage .= str_replace('{user}',$dbuser_prefix . $this->dataRecord['database_user'],$app->tform->wordbook["database_user_error_len"]).'
'; + + //* Check database user against blacklist + $dbuser_blacklist = array($conf['db_user'],'mysql','root'); + if(in_array($dbname_prefix . $this->dataRecord['database_user'],$dbname_blacklist)) { + $app->tform->errorMessage .= $app->lng('Database user not allowed.').'
'; + } + + /* restrict the names */ + /* crop user names if they are too long -> mysql: user: 16 chars / db: 64 chars */ + if ($app->tform->errorMessage == ''){ + $this->dataRecord['database_user'] = substr($dbuser_prefix . $this->dataRecord['database_user'], 0, 16); + } + + parent::onBeforeInsert(); + } + + function onAfterInsert() { + global $app, $conf; + + if($_SESSION["s"]["user"]["typ"] == 'admin' && isset($this->dataRecord["client_group_id"])) { + $client_group_id = intval($this->dataRecord["client_group_id"]); + $app->db->query("UPDATE web_database_user SET sys_groupid = $client_group_id, sys_perm_group = 'riud' WHERE database_user_id = ".$this->id); + } + if($app->auth->has_clients($_SESSION['s']['user']['userid']) && isset($this->dataRecord["client_group_id"])) { + $client_group_id = intval($this->dataRecord["client_group_id"]); + $app->db->query("UPDATE web_database_user SET sys_groupid = $client_group_id, sys_perm_group = 'riud' WHERE database_user_id = ".$this->id); + } + } + + function onAfterUpdate() { + global $app, $conf; + + if($_SESSION["s"]["user"]["typ"] == 'admin' && isset($this->dataRecord["client_group_id"])) { + $client_group_id = intval($this->dataRecord["client_group_id"]); + $app->db->query("UPDATE web_database_user SET sys_groupid = $client_group_id, sys_perm_group = 'riud' WHERE database_user_id = ".$this->id); + } + if($app->auth->has_clients($_SESSION['s']['user']['userid']) && isset($this->dataRecord["client_group_id"])) { + $client_group_id = intval($this->dataRecord["client_group_id"]); + $app->db->query("UPDATE web_database_user SET sys_groupid = $client_group_id, sys_perm_group = 'riud' WHERE database_user_id = ".$this->id); + } + + } + +} + +$page = new page_action; +$page->onLoad(); + +?> \ No newline at end of file diff --git a/interface/web/sites/database_user_list.php b/interface/web/sites/database_user_list.php new file mode 100644 index 0000000000000000000000000000000000000000..52a48e4cb431f1f82e7f6deb3e887ace794f16bf --- /dev/null +++ b/interface/web/sites/database_user_list.php @@ -0,0 +1,65 @@ +auth->check_module_permissions('sites'); + +$app->load('listform_actions'); + + +class list_action extends listform_actions { + + function onShow() { + global $app,$conf; + + parent::onShow(); + } + +} + +$list = new list_action; +$list->SQLOrderBy = 'ORDER BY database_user'; +$list->onLoad(); + + +?> \ No newline at end of file diff --git a/interface/web/sites/form/database.tform.php b/interface/web/sites/form/database.tform.php index b26a1e4d539903022d3d6e6b89d6aeebe178ea82..c8a7ac9b82a08929b7296f3cb9185b61e3843677 100644 --- a/interface/web/sites/form/database.tform.php +++ b/interface/web/sites/form/database.tform.php @@ -106,31 +106,27 @@ $form["tabs"]['database'] = array ( 'maxlength' => '255', 'searchable' => 1 ), - 'database_user' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY', - 'errmsg'=> 'database_user_error_empty'), - 1 => array ( 'type' => 'UNIQUE', - 'errmsg'=> 'database_user_error_unique'), - 2 => array ( 'type' => 'REGEX', - 'regex' => '/^[a-zA-Z0-9_]{2,64}$/', - 'errmsg'=> 'database_user_error_regex'), - ), + 'database_user_id' => array ( + 'datatype' => 'INTEGER', + 'formtype' => 'SELECT', 'default' => '', - 'value' => '', - 'width' => '30', - 'maxlength' => '255', - 'searchable' => 2 + 'datasource' => array ( 'type' => 'SQL', + 'querystring' => "SELECT database_user_id,database_user FROM web_database_user WHERE {AUTHSQL} ORDER BY database_user", + 'keyfield'=> 'database_user_id', + 'valuefield'=> 'database_user' + ), + 'value' => array('0' => $app->tform->lng('select_dbuser_txt')) ), - 'database_password' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'PASSWORD', - 'encryption' => 'MYSQL', + 'database_ro_user_id' => array ( + 'datatype' => 'INTEGER', + 'formtype' => 'SELECT', 'default' => '', - 'value' => '', - 'width' => '30', - 'maxlength' => '255' + 'datasource' => array ( 'type' => 'SQL', + 'querystring' => "SELECT database_user_id,database_user FROM web_database_user WHERE {AUTHSQL} ORDER BY database_user", + 'keyfield'=> 'database_user_id', + 'valuefield'=> 'database_user' + ), + 'value' => array('0' => $app->tform->lng('no_dbuser_txt')) ), 'database_charset' => array ( 'datatype' => 'VARCHAR', diff --git a/interface/web/sites/form/database_user.tform.php b/interface/web/sites/form/database_user.tform.php new file mode 100644 index 0000000000000000000000000000000000000000..f8cd38c95b7fe25eb28b34c41b835c89f4a52e4b --- /dev/null +++ b/interface/web/sites/form/database_user.tform.php @@ -0,0 +1,99 @@ + 0 id must match with id of current user +$form["auth_preset"]["groupid"] = 0; // 0 = default groupid of the user, > 0 id must match with groupid of current user +$form["auth_preset"]["perm_user"] = 'riud'; //r = read, i = insert, u = update, d = delete +$form["auth_preset"]["perm_group"] = 'riud'; //r = read, i = insert, u = update, d = delete +$form["auth_preset"]["perm_other"] = ''; //r = read, i = insert, u = update, d = delete + +$form["tabs"]['database_user'] = array ( + 'title' => "Database User", + 'width' => 100, + 'template' => "templates/database_user_edit.htm", + 'fields' => array ( + ################################## + # Begin Datatable fields + ################################## + 'database_user' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY', + 'errmsg'=> 'database_user_error_empty'), + 1 => array ( 'type' => 'UNIQUE', + 'errmsg'=> 'database_user_error_unique'), + 2 => array ( 'type' => 'REGEX', + 'regex' => '/^[a-zA-Z0-9_]{2,64}$/', + 'errmsg'=> 'database_user_error_regex'), + ), + 'default' => '', + 'value' => '', + 'width' => '30', + 'maxlength' => '255', + 'searchable' => 2 + ), + 'database_password' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'PASSWORD', + 'encryption' => 'MYSQL', + 'default' => '', + 'value' => '', + 'width' => '30', + 'maxlength' => '255' + ), + ################################## + # ENDE Datatable fields + ################################## + ) +); + + +?> \ No newline at end of file diff --git a/interface/web/sites/lib/lang/de_database.lng b/interface/web/sites/lib/lang/de_database.lng index a10771f91f63bc6ecd1edb569eb6ee8602953914..36ac6194ad1e8c7cabb1ea8e597357487f369816 100644 --- a/interface/web/sites/lib/lang/de_database.lng +++ b/interface/web/sites/lib/lang/de_database.lng @@ -3,10 +3,14 @@ $wb['server_id_txt'] = 'Server'; $wb['type_txt'] = 'Typ'; $wb['database_name_txt'] = 'Datenbankname'; $wb['database_user_txt'] = 'Datenbank-Benutzer'; +$wb['database_ro_user_txt'] = 'Nur-Lesen Datenbank-Benutzer'; +$wb['optional_txt'] = 'optional'; $wb['database_password_txt'] = 'Datenbank-Passwort'; $wb['database_charset_txt'] = 'Datenbank Zeichensatz'; -$wb['remote_access_txt'] = 'Remotezugang'; -$wb['remote_ips_txt'] = 'Remotezugang-IPs (mit Komma trennen, keine Eingabe für alle)'; +$wb['select_dbuser_txt'] = 'Datenbank User auswählen'; +$wb['no_dbuser_txt'] = 'Keiner'; +$wb['remote_access_txt'] = 'Remotezugriff'; +$wb['remote_ips_txt'] = 'Remotezugriff-IPs (mit Komma trennen, keine Eingabe für alle)'; $wb['database_remote_error_ips'] = 'Mindestens eine der eingegebenen IP-Adressen ist ungültig.'; $wb['client_txt'] = 'Kunde'; $wb['active_txt'] = 'Aktiv'; diff --git a/interface/web/sites/lib/lang/de_database_list.lng b/interface/web/sites/lib/lang/de_database_list.lng index 62086c999c8d9ddc7d969a579f7fdee9b0931d73..bae444c42b7b7b9de244ea31e2f227e70ccad174 100644 --- a/interface/web/sites/lib/lang/de_database_list.lng +++ b/interface/web/sites/lib/lang/de_database_list.lng @@ -1,7 +1,7 @@ diff --git a/interface/web/sites/lib/lang/de_database_user_admin_list.lng b/interface/web/sites/lib/lang/de_database_user_admin_list.lng new file mode 100644 index 0000000000000000000000000000000000000000..cac37121e1312d0b8cb3ca5e961a1d51617b8209 --- /dev/null +++ b/interface/web/sites/lib/lang/de_database_user_admin_list.lng @@ -0,0 +1,6 @@ + diff --git a/interface/web/sites/lib/lang/de_database_user_list.lng b/interface/web/sites/lib/lang/de_database_user_list.lng new file mode 100644 index 0000000000000000000000000000000000000000..ac800770cc986a1f0311c6d09fd39c2a054fad22 --- /dev/null +++ b/interface/web/sites/lib/lang/de_database_user_list.lng @@ -0,0 +1,5 @@ + diff --git a/interface/web/sites/lib/lang/en_database.lng b/interface/web/sites/lib/lang/en_database.lng index 8a470c708a14ca8c0118b38393d33d9c03b1e17b..a494efcef33703d233c8757bfcfec951980517a1 100644 --- a/interface/web/sites/lib/lang/en_database.lng +++ b/interface/web/sites/lib/lang/en_database.lng @@ -3,9 +3,13 @@ $wb["server_id_txt"] = 'Server'; $wb["type_txt"] = 'Type'; $wb["database_name_txt"] = 'Database name'; $wb["database_user_txt"] = 'Database user'; +$wb['database_ro_user_txt'] = 'Read-only database user'; +$wb['optional_txt'] = 'optional'; $wb["database_password_txt"] = 'Database password'; $wb["password_strength_txt"] = 'Password strength'; $wb["database_charset_txt"] = 'Database charset'; +$wb['select_dbuser_txt'] = 'Select database user'; +$wb['no_dbuser_txt'] = 'None'; $wb["remote_access_txt"] = 'Remote Access'; $wb["remote_ips_txt"] = 'Remote Access IPs (separate by , and leave blank for any)'; $wb["database_remote_error_ips"] = 'At least one of the entered ip addresses is invalid.'; diff --git a/interface/web/sites/lib/lang/en_database_user.lng b/interface/web/sites/lib/lang/en_database_user.lng new file mode 100644 index 0000000000000000000000000000000000000000..6c4ee7c6961d6af78fb0116804561486da511893 --- /dev/null +++ b/interface/web/sites/lib/lang/en_database_user.lng @@ -0,0 +1,23 @@ + diff --git a/interface/web/sites/lib/lang/en_database_user_admin_list.lng b/interface/web/sites/lib/lang/en_database_user_admin_list.lng new file mode 100644 index 0000000000000000000000000000000000000000..4c17da126bcf81122bf0e322150bc0314768ce4b --- /dev/null +++ b/interface/web/sites/lib/lang/en_database_user_admin_list.lng @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/interface/web/sites/lib/lang/en_database_user_list.lng b/interface/web/sites/lib/lang/en_database_user_list.lng new file mode 100644 index 0000000000000000000000000000000000000000..549374b6aca3bd60f10521d585aee5f51918391b --- /dev/null +++ b/interface/web/sites/lib/lang/en_database_user_list.lng @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/interface/web/sites/lib/module.conf.php b/interface/web/sites/lib/module.conf.php index 1e11450f8130df660e31c45ae01fd4ab41c31dec..d79d3f45f235fa5b93cdabf23620d59cbc9496ef 100644 --- a/interface/web/sites/lib/module.conf.php +++ b/interface/web/sites/lib/module.conf.php @@ -62,15 +62,12 @@ $items[] = array( 'title' => "Database", 'link' => 'sites/database_list.php', 'html_id' => 'database_list'); -/* -Database User (for future development) $items[] = array( 'title' => "Database User", 'target' => 'content', 'link' => 'sites/database_user_list.php', 'html_id' => 'database_user_list' ); -*/ $module["nav"][] = array( 'title' => 'Database', 'open' => 1, diff --git a/interface/web/sites/lib/remote.conf.php b/interface/web/sites/lib/remote.conf.php index b2d6ff6083a323136258ff7d294b4c9926fb67c7..4cdc6fc3a3bfca5e80a64926abaa5279c4e8a457 100644 --- a/interface/web/sites/lib/remote.conf.php +++ b/interface/web/sites/lib/remote.conf.php @@ -1,6 +1,6 @@ "server_id", 'width' => "", 'value' => ""); -$liste["item"][] = array( 'field' => "database_user", - 'datatype' => "VARCHAR", - 'formtype' => "TEXT", - 'op' => "like", - 'prefix' => "%", - 'suffix' => "%", +$liste["item"][] = array( 'field' => "database_user_id", + 'datatype' => "INTEGER", + 'formtype' => "SELECT", + 'op' => "=", + 'prefix' => "", + 'suffix' => "", + 'datasource' => array ( 'type' => 'SQL', + 'querystring' => 'SELECT database_user_id, database_user FROM web_database_user WHERE {AUTHSQL} ORDER BY database_user', + 'keyfield'=> 'database_user_id', + 'valuefield'=> 'database_user' + ), 'width' => "", 'value' => ""); diff --git a/interface/web/sites/list/database_user.list.php b/interface/web/sites/list/database_user.list.php new file mode 100644 index 0000000000000000000000000000000000000000..67796a8374fa1eafaf3d828bedc2ea0776116be2 --- /dev/null +++ b/interface/web/sites/list/database_user.list.php @@ -0,0 +1,81 @@ + "sys_groupid", + 'datatype' => "INTEGER", + 'formtype' => "SELECT", + 'op' => "=", + 'prefix' => "", + 'suffix' => "", + 'datasource' => array ( 'type' => 'SQL', + 'querystring' => 'SELECT groupid, name FROM sys_group WHERE groupid != 1 ORDER BY name', + 'keyfield'=> 'groupid', + 'valuefield'=> 'name' + ), + 'width' => "", + 'value' => ""); +} + +$liste["item"][] = array( 'field' => "database_user", + 'datatype' => "VARCHAR", + 'formtype' => "TEXT", + 'op' => "like", + 'prefix' => "%", + 'suffix' => "%", + 'width' => "", + 'value' => ""); + + +?> \ No newline at end of file diff --git a/interface/web/sites/templates/database_admin_list.htm b/interface/web/sites/templates/database_admin_list.htm index b6c90b5652abd799b0230ceced250228271716e2..fda3ba70c8a1a047cb6c68e5168f3f104ded4cd4 100644 --- a/interface/web/sites/templates/database_admin_list.htm +++ b/interface/web/sites/templates/database_admin_list.htm @@ -30,7 +30,7 @@ - +
@@ -42,7 +42,7 @@ {tmpl_var name="remote_access"} {tmpl_var name="sys_groupid"} {tmpl_var name="server_id"} - {tmpl_var name="database_user"} + {tmpl_var name="database_user_id"} {tmpl_var name="database_name"}
diff --git a/interface/web/sites/templates/database_edit.htm b/interface/web/sites/templates/database_edit.htm index b8b4b3fe5ece55f45dc7930ab5473efd9624a236..4207a789ff724b95cb3a71e82bf88ad768fb3349 100644 --- a/interface/web/sites/templates/database_edit.htm +++ b/interface/web/sites/templates/database_edit.htm @@ -44,25 +44,17 @@
- -

{tmpl_var name='database_user_prefix'}

- -
-
- -  {tmpl_var name='generate_password_txt'} -
-
-

{tmpl_var name='password_strength_txt'}

-
-

 

+ +
- - + +  {tmpl_var name='optional_txt'}
- -
diff --git a/interface/web/sites/templates/database_list.htm b/interface/web/sites/templates/database_list.htm index d3b9ac5f90f8e6b5dcae385def69f8c5a4dcc44d..7b49e87044fc2f2618026bddd7c776aca947c844 100644 --- a/interface/web/sites/templates/database_list.htm +++ b/interface/web/sites/templates/database_list.htm @@ -21,7 +21,7 @@ - + {tmpl_var name='search_limit'} @@ -29,7 +29,7 @@ - +
@@ -40,7 +40,7 @@ {tmpl_var name="active"} {tmpl_var name="remote_access"} {tmpl_var name="server_id"} - {tmpl_var name="database_user"} + {tmpl_var name="database_user_id"} {tmpl_var name="database_name"}
diff --git a/interface/web/sites/templates/database_user_admin_list.htm b/interface/web/sites/templates/database_user_admin_list.htm new file mode 100644 index 0000000000000000000000000000000000000000..c1bee6768841907bb495189a0fc4b29e5dd2712b --- /dev/null +++ b/interface/web/sites/templates/database_user_admin_list.htm @@ -0,0 +1,50 @@ +

+ +
+ +
+
{tmpl_var name="toolsarea_head_txt"} +
+ +
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
{tmpl_var name='search_limit'}
{tmpl_var name="database_user"} + +
+
+
+ +
\ No newline at end of file diff --git a/interface/web/sites/templates/database_user_edit.htm b/interface/web/sites/templates/database_user_edit.htm new file mode 100644 index 0000000000000000000000000000000000000000..40e8c96e826fd64ed7ca414ad9da05724b8992c8 --- /dev/null +++ b/interface/web/sites/templates/database_user_edit.htm @@ -0,0 +1,54 @@ +

+

+ +
+ +
+
+ +
+ + +
+
+ +
+ + +
+
+
+ +

{tmpl_var name='database_user_prefix'}

+ +
+
+ +  {tmpl_var name='generate_password_txt'} +
+
+

{tmpl_var name='password_strength_txt'}

+
+

 

+
+
+ + +
+ + +
+ + + +
+ + +
+
+ +
\ No newline at end of file diff --git a/interface/web/sites/templates/database_user_list.htm b/interface/web/sites/templates/database_user_list.htm new file mode 100644 index 0000000000000000000000000000000000000000..0a0ea1a63779a0182d966490bdc99cf22c9b589e --- /dev/null +++ b/interface/web/sites/templates/database_user_list.htm @@ -0,0 +1,51 @@ +

+

+ +
+ +
+
{tmpl_var name="toolsarea_head_txt"} +
+ +
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
{tmpl_var name='search_limit'}
{tmpl_var name="database_user"} + +
+
+
+ +
\ No newline at end of file diff --git a/server/mods-available/database_module.inc.php b/server/mods-available/database_module.inc.php index 199a6c714852247590f9fd9a8790c682ea49bfbf..c3a99b63f18c60b51cc9d1a526af0c09b2242782 100644 --- a/server/mods-available/database_module.inc.php +++ b/server/mods-available/database_module.inc.php @@ -34,7 +34,10 @@ class database_module { var $class_name = 'database_module'; var $actions_available = array( 'database_insert', 'database_update', - 'database_delete' + 'database_delete', + 'database_user_insert', + 'database_user_update', + 'database_user_delete' ); //* This function is called during ispconfig installation to determine @@ -75,7 +78,7 @@ class database_module { */ $app->modules->registerTableHook('web_database','database_module','process'); - //$app->modules->registerTableHook('web_database_user','database_module','process'); + $app->modules->registerTableHook('web_database_user','database_module','process'); // Register service //$app->services->registerService('httpd','web_module','restartHttpd'); @@ -96,13 +99,13 @@ class database_module { if($action == 'u') $app->plugins->raiseEvent('database_update',$data); if($action == 'd') $app->plugins->raiseEvent('database_delete',$data); break; - /* + case 'web_database_user': if($action == 'i') $app->plugins->raiseEvent('database_user_insert',$data); if($action == 'u') $app->plugins->raiseEvent('database_user_update',$data); if($action == 'd') $app->plugins->raiseEvent('database_user_delete',$data); break; - */ + } // end switch } // end function diff --git a/server/plugins-available/mysql_clientdb_plugin.inc.php b/server/plugins-available/mysql_clientdb_plugin.inc.php index df8749afb14a3ee7358a05bafd9bbad3483aef63..98efd8c35cea89bb63bfcf2ae68cb1c24b503eb5 100644 --- a/server/plugins-available/mysql_clientdb_plugin.inc.php +++ b/server/plugins-available/mysql_clientdb_plugin.inc.php @@ -64,14 +64,14 @@ class mysql_clientdb_plugin { $app->plugins->registerEvent('database_delete',$this->plugin_name,'db_delete'); //* Database users - //$app->plugins->registerEvent('database_user_insert',$this->plugin_name,'db_user_insert'); - //$app->plugins->registerEvent('database_user_update',$this->plugin_name,'db_user_update'); - //$app->plugins->registerEvent('database_user_delete',$this->plugin_name,'db_user_delete'); + $app->plugins->registerEvent('database_user_insert',$this->plugin_name,'db_user_insert'); + $app->plugins->registerEvent('database_user_update',$this->plugin_name,'db_user_update'); + $app->plugins->registerEvent('database_user_delete',$this->plugin_name,'db_user_delete'); } - function process_host_list($action, $database_name, $database_user, $database_password, $host_list, $link, $database_rename_user = '') { + function process_host_list($action, $database_name, $database_user, $database_password, $host_list, $link, $database_rename_user = '', $user_read_only = false) { global $app; $action = strtoupper($action); @@ -105,9 +105,9 @@ class mysql_clientdb_plugin { if($valid == false) continue; if($action == 'GRANT') { - if(!$link->query("GRANT ALL ON ".$link->escape_string($database_name).".* TO '".$link->escape_string($database_user)."'@'$db_host' IDENTIFIED BY PASSWORD '".$link->escape_string($database_password)."';")) $success = false; + if(!$link->query("GRANT " . ($user_read_only ? "SELECT" : "ALL") . " ON ".$link->escape_string($database_name).".* TO '".$link->escape_string($database_user)."'@'$db_host' IDENTIFIED BY PASSWORD '".$link->escape_string($database_password)."';")) $success = false; } elseif($action == 'REVOKE') { - //mysql_query("REVOKE ALL PRIVILEGES ON ".mysql_real_escape_string($database_name,$link).".* FROM '".mysql_real_escape_string($database_user,$link)."';",$link); + if(!$link->query("REVOKE ALL PRIVILEGES ON ".$link->escape_string($database_name).".* FROM '".$link->escape_string($database_user)."'@'$db_host' IDENTIFIED BY PASSWORD '".$link->escape_string($database_password)."';")) $success = false; } elseif($action == 'DROP') { if(!$link->query("DROP USER '".$link->escape_string($database_user)."'@'$db_host';")) $success = false; } elseif($action == 'RENAME') { @@ -129,11 +129,6 @@ class mysql_clientdb_plugin { return; } - if($data['new']['database_user'] == 'root') { - $app->log('User root not allowed for Client databases',LOGLEVEL_WARNING); - return; - } - //* Connect to the database $link = new mysqli($clientdb_host, $clientdb_user, $clientdb_password); if ($link->connect_error) { @@ -158,13 +153,26 @@ class mysql_clientdb_plugin { // Create the database user if database is active if($data['new']['active'] == 'y') { - if($data['new']['remote_access'] == 'y') { - $this->process_host_list('GRANT', $data['new']['database_name'], $data['new']['database_user'], $data['new']['database_password'], $data['new']['remote_ips'], $link); - } - - $db_host = 'localhost'; - $link->query("GRANT ALL ON `".str_replace(array('_','%'),array('\\_','\\%'),$link->escape_string($data['new']['database_name']))."`.* TO '".$link->escape_string($data['new']['database_user'])."'@'$db_host' IDENTIFIED BY PASSWORD '".$link->escape_string($data['new']['database_password'])."';"); - + // get the users for this database + $db_user = $app->db->queryOneRecord("SELECT `database_user`, `database_password` FROM `web_database_user` WHERE `database_user_id` = '" . intval($data['new']['database_user_id']) . "'"); + + $db_ro_user = $app->db->queryOneRecord("SELECT `database_user`, `database_password` FROM `web_database_user` WHERE `database_user_id` = '" . intval($data['new']['database_ro_user_id']) . "'"); + + $host_list = ''; + if($data['new']['remote_access'] == 'y') { + $host_list = $data['new']['remote_ips']; + } + if($host_list != '') $host_list .= ','; + $host_list .= 'localhost'; + + if($db_user) { + if($db_user['database_user'] == 'root') $app->log('User root not allowed for Client databases',LOGLEVEL_WARNING); + else $this->process_host_list('GRANT', $data['new']['database_name'], $db_user['database_user'], $db_user['database_password'], $host_list, $link); + } + if($db_ro_user && $data['new']['database_user_id'] != $data['new']['database_ro_user_id']) { + if($db_ro_user['database_user'] == 'root') $app->log('User root not allowed for Client databases',LOGLEVEL_WARNING); + else $this->process_host_list('GRANT', $data['new']['database_name'], $db_ro_user['database_user'], $db_ro_user['database_password'], $host_list, $link, '', true); + } } @@ -182,11 +190,6 @@ class mysql_clientdb_plugin { return; } - if($data['new']['database_user'] == 'root') { - $app->log('User root not allowed for Client databases',LOGLEVEL_WARNING); - return; - } - //* Connect to the database $link = new mysqli($clientdb_host, $clientdb_user, $clientdb_password); if ($link->connect_error) { @@ -194,41 +197,66 @@ class mysql_clientdb_plugin { return; } - // Create the database user if database was disabled before + // get the users for this database + $db_user = $app->db->queryOneRecord("SELECT `database_user`, `database_password` FROM `web_database_user` WHERE `database_user_id` = '" . intval($data['new']['database_user_id']) . "'"); + + $db_ro_user = $app->db->queryOneRecord("SELECT `database_user`, `database_password` FROM `web_database_user` WHERE `database_user_id` = '" . intval($data['new']['database_ro_user_id']) . "'"); + + $host_list = ''; + if($data['new']['remote_access'] == 'y') { + $host_list = $data['new']['remote_ips']; + } + if($host_list != '') $host_list .= ','; + $host_list .= 'localhost'; + + // Create the database user if database was disabled before if($data['new']['active'] == 'y' && $data['old']['active'] == 'n') { - - if($data['new']['remote_access'] == 'y') { - $this->process_host_list('GRANT', $data['new']['database_name'], $data['new']['database_user'], $data['new']['database_password'], $data['new']['remote_ips'], $link); - } - - $db_host = 'localhost'; - $link->query("GRANT ALL ON `".str_replace(array('_','%'),array('\\_','\\%'),$link->escape_string($data['new']['database_name']))."`.* TO '".$link->escape_string($data['new']['database_user'])."'@'$db_host' IDENTIFIED BY PASSWORD '".$link->escape_string($data['new']['database_password'])."';"); - - // mysql_query("GRANT ALL ON ".mysql_real_escape_string($data["new"]["database_name"],$link).".* TO '".mysql_real_escape_string($data["new"]["database_user"],$link)."'@'$db_host' IDENTIFIED BY '".mysql_real_escape_string($data["new"]["database_password"],$link)."';",$link); - //echo "GRANT ALL ON ".mysql_real_escape_string($data["new"]["database_name"]).".* TO '".mysql_real_escape_string($data["new"]["database_user"])."'@'$db_host' IDENTIFIED BY '".mysql_real_escape_string($data["new"]["database_password"])."';"; - } - - // Remove database user, if inactive - if($data['new']['active'] == 'n' && $data['old']['active'] == 'y') { - - if($data['old']['remote_access'] == 'y') { - $this->process_host_list('DROP', '', $data['old']['database_user'], '', $data['old']['remote_ips'], $link); - } - - $db_host = 'localhost'; - $link->query("DROP USER '".$link->escape_string($data['old']['database_user'])."'@'$db_host';"); - //mysql_query("REVOKE ALL PRIVILEGES ON ".mysql_real_escape_string($data["new"]["database_name"],$link).".* FROM '".mysql_real_escape_string($data["new"]["database_user"],$link)."';",$link); - } - - //* Rename User - if($data['new']['database_user'] != $data['old']['database_user']) { - $db_host = 'localhost'; - $link->query("RENAME USER '".$link->escape_string($data['old']['database_user'])."'@'$db_host' TO '".$link->escape_string($data['new']['database_user'])."'@'$db_host'"); - if($data['old']['remote_access'] == 'y') { - $this->process_host_list('RENAME', '', $data['old']['database_user'], '', $data['new']['remote_ips'], $link, $data['new']['database_user']); - } - $app->log('Renaming MySQL user: '.$data['old']['database_user'].' to '.$data['new']['database_user'],LOGLEVEL_DEBUG); + if($db_user) { + if($db_user['database_user'] == 'root') $app->log('User root not allowed for Client databases',LOGLEVEL_WARNING); + else $this->process_host_list('GRANT', $data['new']['database_name'], $db_user['database_user'], $db_user['database_password'], $host_list, $link); + } + if($db_ro_user && $data['new']['database_user_id'] != $data['new']['database_ro_user_id']) { + if($db_ro_user['database_user'] == 'root') $app->log('User root not allowed for Client databases',LOGLEVEL_WARNING); + else $this->process_host_list('GRANT', $data['new']['database_name'], $db_ro_user['database_user'], $db_ro_user['database_password'], $host_list, $link, '', true); + } + } else if($data['new']['active'] == 'n' && $data['old']['active'] == 'y') { // revoke database user, if inactive + if($db_user) { + if($db_user['database_user'] == 'root') $app->log('User root not allowed for Client databases',LOGLEVEL_WARNING); + else $this->process_host_list('REVOKE', $data['new']['database_name'], $db_user['database_user'], $db_user['database_password'], $host_list, $link); + } + if($db_ro_user && $data['new']['database_user_id'] != $data['new']['database_ro_user_id']) { + if($db_ro_user['database_user'] == 'root') $app->log('User root not allowed for Client databases',LOGLEVEL_WARNING); + else $this->process_host_list('REVOKE', $data['new']['database_name'], $db_ro_user['database_user'], $db_ro_user['database_password'], $host_list, $link); + } } + + //* selected Users have changed + if($data['new']['database_user_id'] != $data['old']['database_user_id']) { + if($data['old']['database_user_id'] && $data['old']['database_user_id'] != $data['new']['database_ro_user_id']) { + $old_db_user = $app->db->queryOneRecord("SELECT `database_user`, `database_password` FROM `web_database_user` WHERE `database_user_id` = '" . intval($data['old']['database_user_id']) . "'"); + if($old_db_user) { + if($old_db_user['database_user'] == 'root') $app->log('User root not allowed for Client databases',LOGLEVEL_WARNING); + else $this->process_host_list('REVOKE', $data['new']['database_name'], $old_db_user['database_user'], $old_db_user['database_password'], $host_list, $link); + } + } + if($db_user) { + if($db_user['database_user'] == 'root') $app->log('User root not allowed for Client databases',LOGLEVEL_WARNING); + else $this->process_host_list('GRANT', $data['new']['database_name'], $db_user['database_user'], $db_user['database_password'], $host_list, $link); + } + } + if($data['new']['database_ro_user_id'] != $data['old']['database_ro_user_id']) { + if($data['old']['database_ro_user_id'] && $data['old']['database_ro_user_id'] != $data['new']['database_user_id']) { + $old_db_user = $app->db->queryOneRecord("SELECT `database_user`, `database_password` FROM `web_database_user` WHERE `database_user_id` = '" . intval($data['old']['database_ro_user_id']) . "'"); + if($old_db_user) { + if($old_db_user['database_user'] == 'root') $app->log('User root not allowed for Client databases',LOGLEVEL_WARNING); + else $this->process_host_list('REVOKE', $data['new']['database_name'], $old_db_user['database_user'], $old_db_user['database_password'], $host_list, $link); + } + } + if($db_ro_user && $data['new']['database_user_id'] != $data['new']['database_ro_user_id']) { + if($db_ro_user['database_user'] == 'root') $app->log('User root not allowed for Client databases',LOGLEVEL_WARNING); + else $this->process_host_list('GRANT', $data['new']['database_name'], $db_ro_user['database_user'], $db_ro_user['database_password'], $host_list, $link, '', true); + } + } //* Remote access option has changed. if($data['new']['remote_access'] != $data['old']['remote_access']) { @@ -238,27 +266,43 @@ class mysql_clientdb_plugin { //* set new priveliges if($data['new']['remote_access'] == 'y') { - $this->process_host_list('GRANT', $data['new']['database_name'], $data['new']['database_user'], $data['new']['database_password'], $data['new']['remote_ips'], $link); + if($db_user) { + if($db_user['database_user'] == 'root') $app->log('User root not allowed for Client databases',LOGLEVEL_WARNING); + else $this->process_host_list('GRANT', $data['new']['database_name'], $db_user['database_user'], $db_user['database_password'], $data['new']['remote_ips'], $link); + } + if($db_ro_user && $data['new']['database_user_id'] != $data['new']['database_ro_user_id']) { + if($db_ro_user['database_user'] == 'root') $app->log('User root not allowed for Client databases',LOGLEVEL_WARNING); + else $this->process_host_list('GRANT', $data['new']['database_name'], $db_ro_user['database_user'], $db_ro_user['database_password'], $data['new']['remote_ips'], $link, '', true); + } } else { - $this->process_host_list('DROP', '', $data['old']['database_user'], '', $data['old']['remote_ips'], $link); + if($db_user) { + if($db_user['database_user'] == 'root') $app->log('User root not allowed for Client databases',LOGLEVEL_WARNING); + else $this->process_host_list('REVOKE', $data['new']['database_name'], $db_user['database_user'], $db_user['database_password'], $data['new']['remote_ips'], $link); + } + if($db_ro_user && $data['new']['database_user_id'] != $data['new']['database_ro_user_id']) { + if($db_ro_user['database_user'] == 'root') $app->log('User root not allowed for Client databases',LOGLEVEL_WARNING); + else $this->process_host_list('REVOKE', $data['new']['database_name'], $db_ro_user['database_user'], $db_ro_user['database_password'], $data['new']['remote_ips'], $link); + } } $app->log('Changing MySQL remote access privileges for database: '.$data['new']['database_name'],LOGLEVEL_DEBUG); } elseif($data['new']['remote_access'] == 'y' && $data['new']['remote_ips'] != $data['old']['remote_ips']) { - //* Change remote access list - $this->process_host_list('DROP', '', $data['old']['database_user'], '', $data['old']['remote_ips'], $link); - $this->process_host_list('GRANT', $data['new']['database_name'], $data['new']['database_user'], $data['new']['database_password'], $data['new']['remote_ips'], $link); - } + //* Change remote access list + if($db_user) { + if($db_user['database_user'] == 'root') $app->log('User root not allowed for Client databases',LOGLEVEL_WARNING); + else { + $this->process_host_list('REVOKE', $data['new']['database_name'], $db_user['database_user'], $db_user['database_password'], $data['old']['remote_ips'], $link); + $this->process_host_list('GRANT', $data['new']['database_name'], $db_user['database_user'], $db_user['database_password'], $data['new']['remote_ips'], $link); + } + } + if($db_ro_user && $data['new']['database_user_id'] != $data['new']['database_ro_user_id']) { + if($db_ro_user['database_user'] == 'root') $app->log('User root not allowed for Client databases',LOGLEVEL_WARNING); + else { + $this->process_host_list('REVOKE', $data['new']['database_name'], $db_ro_user['database_user'], $db_ro_user['database_password'], $data['old']['remote_ips'], $link); + $this->process_host_list('GRANT', $data['new']['database_name'], $db_ro_user['database_user'], $db_ro_user['database_password'], $data['new']['remote_ips'], $link, '', true); + } + } + } - //* Change password - if($data['new']['database_password'] != $data['old']['database_password']) { - $db_host = 'localhost'; - $link->query("SET PASSWORD FOR '".$link->escape_string($data['new']['database_user'])."'@'$db_host' = '".$link->escape_string($data['new']['database_password'])."';"); - - if($data['new']['remote_access'] == 'y') { - $this->process_host_list('PASSWORD', '', $data['new']['database_user'], $data['new']['database_password'], $data['new']['remote_ips'],$link); - } - $app->log('Changing MySQL user password for: '.$data['new']['database_user'],LOGLEVEL_DEBUG); - } $link->query('FLUSH PRIVILEGES;'); $link->close(); @@ -282,21 +326,6 @@ class mysql_clientdb_plugin { return; } - //* Get the db host setting for the access priveliges - if($data['old']['remote_access'] == 'y') { - if($this->process_host_list('DROP', '', $data['old']['database_user'], '', $data['old']['remote_ips'], $link)) { - $app->log('Dropping MySQL user: '.$data['old']['database_user'],LOGLEVEL_DEBUG); - } else { - $app->log('Error while dropping MySQL user: '.$data['old']['database_user'].' '.$link->error,LOGLEVEL_WARNING); - } - } - $db_host = 'localhost'; - if($link->query("DROP USER '".$link->escape_string($data['old']['database_user'])."'@'$db_host';")) { - $app->log('Dropping MySQL user: '.$data['old']['database_user'],LOGLEVEL_DEBUG); - } else { - $app->log('Error while dropping MySQL user: '.$data['old']['database_user'].' '.$link->error,LOGLEVEL_WARNING); - } - if($link->query('DROP DATABASE '.$link->escape_string($data['old']['database_name']))) { $app->log('Dropping MySQL database: '.$data['old']['database_name'],LOGLEVEL_DEBUG); } else { @@ -310,24 +339,100 @@ class mysql_clientdb_plugin { } - /* + function db_user_insert($event_name,$data) { global $app, $conf; - + // we have nothing to do here, stale user accounts are useless ;) } function db_user_update($event_name,$data) { global $app, $conf; + if(!include(ISPC_LIB_PATH.'/mysql_clientdb.conf')) { + $app->log('Unable to open'.ISPC_LIB_PATH.'/mysql_clientdb.conf',LOGLEVEL_ERROR); + return; + } + + //* Connect to the database + $link = new mysqli($clientdb_host, $clientdb_user, $clientdb_password); + if ($link->connect_error) { + $app->log('Unable to connect to mysql'.$link->connect_error,LOGLEVEL_ERROR); + return; + } + + + if($data['old']['database_user'] == $data['new']['database_user'] && $data['old']['database_password'] == $data['new']['database_password']) { + return; + } + + + $host_list = array('localhost'); + // get all databases this user was active for + $db_list = $app->db->queryAllRecords("SELECT `remote_access`, `remote_ips` FROM `web_database` WHERE `database_user_id` = '" . intval($data['old']['database_user_id']) . "'"); + foreach($db_list as $database) { + if($database['remote_access'] != 'y') continue; + + if($database['remote_ips'] != '') $ips = explode(',', $database['remote_ips']); + else $ips = array('%'); + + foreach($ips as $ip) { + $ip = trim($ip); + if(!in_array($ip, $host_list)) $host_list[] = $ip; + } + } + + foreach($host_list as $db_host) { + if($data['new']['database_user'] != $data['old']['database_user']) { + $link->query("RENAME USER '".$link->escape_string($data['old']['database_user'])."'@'$db_host' TO '".$link->escape_string($data['new']['database_user'])."'@'$db_host'"); + $app->log('Renaming MySQL user: '.$data['old']['database_user'].' to '.$data['new']['database_user'],LOGLEVEL_DEBUG); + } + + if($data['new']['database_password'] != $data['old']['database_password']) { + $db_host = 'localhost'; + $link->query("SET PASSWORD FOR '".$link->escape_string($data['new']['database_user'])."'@'$db_host' = '".$link->escape_string($data['new']['database_password'])."';"); + $app->log('Changing MySQL user password for: '.$data['new']['database_user'],LOGLEVEL_DEBUG); + } + } + + $link->query('FLUSH PRIVILEGES;'); + $link->close(); + } function db_user_delete($event_name,$data) { global $app, $conf; + if(!include(ISPC_LIB_PATH.'/mysql_clientdb.conf')) { + $app->log('Unable to open'.ISPC_LIB_PATH.'/mysql_clientdb.conf',LOGLEVEL_ERROR); + return; + } + + //* Connect to the database + $link = new mysqli($clientdb_host, $clientdb_user, $clientdb_password); + if ($link->connect_error) { + $app->log('Unable to connect to mysql'.$link->connect_error,LOGLEVEL_ERROR); + return; + } + + $host_list = array(); + // read all mysql users with this username + $result = $link->query("SELECT `User`, `Host` FROM `mysql`.`user` WHERE `User` = '" . $link->escape_string($data['old']['database_user']) . "' AND `Create_user_priv` = 'N'"); // basic protection against accidently deleting system users like debian-sys-maint + if($result) { + while($row = $result->fetch_assoc()) { + $host_list[] = $row['Host']; + } + $result->free(); + } + + foreach($host_list as $db_host) { + if($link->query("DROP USER '".$link->escape_string($data['old']['database_user'])."'@'$db_host';")) { + $app->log('Dropping MySQL user: '.$data['old']['database_user'],LOGLEVEL_DEBUG); + } + } + + $link->query('FLUSH PRIVILEGES;'); + $link->close(); } - */ - - } // end class ?>