Skip to content

Commit 979e2f9

Browse files
committed
Merge branch '6828-ispconfig-extension-installer' of git.ispconfig.org:ispconfig/ispconfig3 into 6828-ispconfig-extension-installer
2 parents 60e8f6b + 582e24f commit 979e2f9

File tree

96 files changed

+1027
-314
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+1027
-314
lines changed

install/lib/installer_base.lib.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,7 @@ public function grant_master_database_rights($verbose = false) {
775775
$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
776776
}
777777

778-
$query = "GRANT SELECT, INSERT , DELETE ON ?? TO ?@?";
778+
$query = "GRANT SELECT, INSERT, UPDATE, DELETE ON ?? TO ?@?";
779779
if ($verbose){
780780
echo $query ."\n";
781781
}

install/sql/incremental/upd_dev_collection.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,18 @@ ALTER TABLE `server_php` ADD `php_cli_binary` varchar(255) DEFAULT NULL AFTER `p
66
ALTER TABLE `server_php` ADD `php_jk_section` varchar(255) DEFAULT NULL AFTER `php_cli_binary`;
77
ALTER TABLE `mail_domain` ADD `local_delivery` enum('n','y') NOT NULL DEFAULT 'y' AFTER `active`;
88
ALTER TABLE `sys_remoteaction` CHANGE `action_type` `action_type` VARCHAR(64) NOT NULL;
9+
10+
CREATE TABLE IF NOT EXISTS `sys_message` (
11+
`message_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
12+
`sys_userid` int(11) unsigned NOT NULL DEFAULT 0,
13+
`sys_groupid` int(11) unsigned NOT NULL DEFAULT 0,
14+
`sys_perm_user` VARCHAR(5) DEFAULT 'r',
15+
`sys_perm_group` VARCHAR(5) DEFAULT 'r',
16+
`sys_perm_other` VARCHAR(5) DEFAULT '',
17+
`message_state` enum('info','warning','error') NOT NULL DEFAULT 'info',
18+
`message_date` datetime NULL DEFAULT NULL,
19+
`message_ack` enum('y','n') NOT NULL DEFAULT 'n',
20+
`relation` varchar(255) NULL DEFAULT NULL,
21+
`message` TEXT DEFAULT NULL,
22+
PRIMARY KEY (`message_id`)
23+
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

install/sql/ispconfig3.sql

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1771,6 +1771,27 @@ CREATE TABLE `sys_log` (
17711771

17721772
-- --------------------------------------------------------
17731773

1774+
--
1775+
-- Table structure for table `sys_message`
1776+
--
1777+
1778+
CREATE TABLE IF NOT EXISTS `sys_message` (
1779+
`message_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
1780+
`sys_userid` int(11) unsigned NOT NULL DEFAULT 0,
1781+
`sys_groupid` int(11) unsigned NOT NULL DEFAULT 0,
1782+
`sys_perm_user` VARCHAR(5) DEFAULT 'r',
1783+
`sys_perm_group` VARCHAR(5) DEFAULT 'r',
1784+
`sys_perm_other` VARCHAR(5) DEFAULT '',
1785+
`message_state` enum('info','warning','error') NOT NULL DEFAULT 'info',
1786+
`message_date` datetime NULL DEFAULT NULL,
1787+
`message_ack` enum('y','n') NOT NULL DEFAULT 'n',
1788+
`relation` varchar(255) NULL DEFAULT NULL,
1789+
`message` TEXT DEFAULT NULL,
1790+
PRIMARY KEY (`message_id`)
1791+
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
1792+
1793+
-- --------------------------------------------------------
1794+
17741795
--
17751796
-- Table structure for table `sys_remoteaction`
17761797
--

interface/lib/app.inc.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,10 @@ public function log($msg, $priority = 0) {
214214

215215
public function auth_log($msg) {
216216
$authlog_handle = fopen($this->_conf['ispconfig_log_dir'].'/auth.log', 'a');
217-
fwrite($authlog_handle, $msg . PHP_EOL);
218-
fclose($authlog_handle);
217+
if($authlog_handle) {
218+
fwrite($authlog_handle, $msg . PHP_EOL);
219+
fclose($authlog_handle);
220+
}
219221
}
220222

221223
/** Priority values are: 0 = DEBUG, 1 = WARNING, 2 = ERROR */

interface/lib/classes/listform_actions.inc.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ public function prepareDataRow($rec)
189189
//* substitute value for select fields
190190
if(is_array($app->listform->listDef['item']) && count($app->listform->listDef['item']) > 0) {
191191
foreach($app->listform->listDef['item'] as $field) {
192-
if(isset($rec['active']) && $rec['active'] == 'n') $rec['warn_inactive'] = 'y';
192+
if(isset($rec['active']) && strtolower($rec['active']) == 'n') $rec['warn_inactive'] = 'y';
193193
$key = $field['field'];
194194
if(isset($field['formtype']) && $field['formtype'] == 'SELECT') {
195195
if(strtolower($rec[$key]) == 'y' or strtolower($rec[$key]) == 'n') {
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
<?php
2+
3+
/*
4+
Copyright (c) 2025, Falko Timme, Timme Hosting GmbH & Co. KG
5+
All rights reserved.
6+
7+
Redistribution and use in source and binary forms, with or without modification,
8+
are permitted provided that the following conditions are met:
9+
10+
* Redistributions of source code must retain the above copyright notice,
11+
this list of conditions and the following disclaimer.
12+
* Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
* Neither the name of ISPConfig nor the names of its contributors
16+
may be used to endorse or promote products derived from this software without
17+
specific prior written permission.
18+
19+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22+
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24+
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26+
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29+
*/
30+
31+
/*
32+
* This library allows it to display messages on the ISPConfig dashboard which the user
33+
* has to actively acknowledge to hide them. The messages are stored in the sys_message table.
34+
*/
35+
36+
class message {
37+
38+
/*
39+
* This function is used to add a new message
40+
*/
41+
42+
public function add($message, $message_state = 'info', $sys_userid = 0, $sys_groupid = 0, $relation = '') {
43+
global $app, $conf;
44+
45+
if(!in_array($message_state,['info','warning','error'])) $app->debug_log('Unknown message_state in message add function.');
46+
$message_date = date('Y-m-d H:i:s');
47+
$sql = "INSERT INTO `sys_message` (`sys_userid`,`sys_groupid`,`message_state`,`message_date`,`message`,`relation`) VALUES (?,?,?,?,?,?)";
48+
if(is_object($app->dbmaster)) {
49+
// server
50+
if(!$app->dbmaster->query($sql,(int)$sys_userid,(int)$sys_groupid,$message_state,$message_date,$message,$relation)) {
51+
$app->debug_log('Adding '.$message_state.' message to sys_message failed.');
52+
}
53+
} else {
54+
// interface
55+
if(!$app->db->query($sql,(int)$sys_userid,(int)$sys_groupid,$message_state,$message_date,$message,$relation)) {
56+
$app->debug_log('Adding '.$message_state.' message to sys_message failed.');
57+
}
58+
}
59+
}
60+
61+
/*
62+
* This function is used to hide a message by message_id
63+
*/
64+
65+
public function hide_by_id($message_id) {
66+
global $app, $conf;
67+
$sql = "UPDATE `sys_message` SET `message_ack` = 'y' WHERE `message_id` = ?";
68+
if(is_object($app->dbmaster)) {
69+
// server
70+
if(!$app->dbmaster->query($sql,(int)$message_id)) {
71+
$app->debug_log('Hiding message '.$message_id.' in sys_message failed.');
72+
}
73+
} else {
74+
// interface
75+
if(!$app->db->query($sql,(int)$message_id)) {
76+
$app->debug_log('Hiding message '.$message_id.' in sys_message failed.');
77+
}
78+
}
79+
}
80+
81+
/*
82+
* This function is used to hide a message by message_state
83+
*/
84+
85+
public function hide_by_message_state($message_state, $relation = '') {
86+
global $app, $conf;
87+
88+
if(!in_array($message_state,['info','warning','error'])) $app->debug_log('Unknown message_state in message add function.');
89+
90+
if(is_object($app->dbmaster)) {
91+
// server
92+
$sql = "UPDATE `sys_message` SET `message_ack` = 'y' WHERE `message_state` = ?";
93+
if(!empty($relation)) $sql .= " AND relation = ?";
94+
95+
if(!$app->dbmaster->query($sql, $message_state, $relation)) {
96+
$app->debug_log('Hiding message by '.$message_state.' in sys_message failed.');
97+
}
98+
} else {
99+
// interface
100+
$app->uses('tform_base');
101+
$sql = "UPDATE `sys_message` SET `message_ack` = 'y' WHERE `message_state` = ? AND ".$app->tform_base->getAuthSQL('r');
102+
if(!empty($relation)) $sql .= " AND relation = ?";
103+
104+
if(!$app->db->query($sql, $message_state, $relation)) {
105+
$app->debug_log('Hiding message by '.$message_state.' in sys_message failed.');
106+
}
107+
108+
// Do some cleanup
109+
$this->cleanup();
110+
}
111+
}
112+
113+
/*
114+
* This function is used to hide a message by relation
115+
*/
116+
117+
public function hide_by_message_relation($relation) {
118+
global $app, $conf;
119+
120+
if(is_object($app->dbmaster)) {
121+
// server
122+
$sql = "UPDATE `sys_message` SET `message_ack` = 'y' WHERE `relation` = ?";
123+
124+
if(!$app->dbmaster->query($sql, $relation)) {
125+
$app->debug_log('Hiding message by '.$relation.' in sys_message failed.');
126+
}
127+
} else {
128+
// interface
129+
$app->uses('tform_base');
130+
$sql = "UPDATE `sys_message` SET `message_ack` = 'y' WHERE `relation` = ? AND ".$app->tform_base->getAuthSQL('r');
131+
132+
if(!$app->db->query($sql, $relation)) {
133+
$app->debug_log('Hiding message by '.$relation.' in sys_message failed.');
134+
}
135+
136+
// Do some cleanup
137+
$this->cleanup();
138+
}
139+
}
140+
141+
/*
142+
* This function is used to delete a message by message_id
143+
*/
144+
145+
public function delete($message_id) {
146+
global $app, $conf;
147+
$sql = "DELETE FROM `sys_message` WHERE `message_id` = ?";
148+
149+
if(is_object($app->dbmaster)) {
150+
// server
151+
if(!$app->dbmaster->query($sql,(int)$message_id)) {
152+
$app->debug_log('Deleting message '.$message_id.' from sys_message failed.');
153+
}
154+
} else {
155+
// interface
156+
if(!$app->db->query($sql,(int)$message_id)) {
157+
$app->debug_log('Deleting message '.$message_id.' from sys_message failed.');
158+
}
159+
}
160+
}
161+
162+
/*
163+
* This function is used to clean up old messages
164+
*/
165+
166+
private function cleanup() {
167+
global $app, $conf;
168+
$message_cleanup_date = date('Y-m-d H:i:s',strtotime('- 1 month'));
169+
$sql = "DELETE FROM `sys_message` WHERE `message_ack` = 'y' and `message_date` < ?";
170+
if(!$app->db->query($sql,$message_cleanup_date)) {
171+
$app->debug_log('Cleaning up messages from sys_message failed.');
172+
}
173+
}
174+
175+
/*
176+
* This function returns an array with all not acknowledged messages
177+
* for the currently logged-in user (use in interface only)
178+
*/
179+
180+
public function get_current_messages($relation = '') {
181+
global $app, $conf;
182+
183+
$app->uses('tform_base');
184+
if(!is_object($app->tform_base)) {
185+
$app->debug_log('No tform_base object. Do not use this function in server part.');
186+
return false;
187+
}
188+
189+
if($relation != '') {
190+
$sql = "SELECT * FROM `sys_message` WHERE `message_ack` = 'n' AND `relation` = ? AND ".$app->tform_base->getAuthSQL('r');
191+
} else {
192+
$sql = "SELECT * FROM `sys_message` WHERE `message_ack` = 'n' AND ".$app->tform_base->getAuthSQL('r');
193+
}
194+
$messages = $app->db->queryAllRecords($sql,$relation);
195+
196+
// Translate messages
197+
$app->load_language_file('web/dashboard/lib/lang/'.$_SESSION['s']['language'].'_message.lng');
198+
foreach($messages as $key => $msg) {
199+
$messages[$key]['message'] = $app->lng($msg['message']);
200+
}
201+
202+
return $messages;
203+
}
204+
}

interface/lib/classes/validate_database.inc.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ function valid_ip_list($field_name, $field_value, $validator) {
4444
$cur_value = trim($cur_value);
4545
$valid = true;
4646
if(function_exists('filter_var')) {
47-
if(!filter_var($cur_value, FILTER_VALIDATE_IP)) {
47+
// value must be either an IP address or hostname
48+
if(!filter_var($cur_value, FILTER_VALIDATE_IP) && !filter_var($cur_value, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) {
4849
$valid = false;
4950
}
5051
} else return "function filter_var missing <br />\r\n";

interface/web/admin/form/server_php.tform.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,10 @@
261261
'datatype' => 'VARCHAR',
262262
'formtype' => 'TEXT',
263263
'validators' => array(
264-
0 => array (
264+
0 => array('type' => 'NOTEMPTY',
265+
'errmsg' => 'php_cli_binary_empty'
266+
),
267+
1 => array (
265268
'type' => 'REGEX',
266269
'regex' => '/^\/[a-zA-Z0-9\/\-\_\.\s]*$/',
267270
'errmsg'=> 'php_cli_binary_error_regex'
@@ -277,7 +280,10 @@
277280
'formtype' => 'TEXT',
278281
'default' => '',
279282
'validators' => array(
280-
0 => array (
283+
0 => array('type' => 'NOTEMPTY',
284+
'errmsg' => 'php_cli_jk_section_empty'
285+
),
286+
1 => array (
281287
'type' => 'REGEX',
282288
'regex' => '/^[a-zA-Z0-9\-\_]*$/',
283289
'errmsg'=> 'php_cli_jk_section_error_regex'

interface/web/admin/lib/lang/ar_server_php.lng

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,6 @@ $wb['php_jk_section_txt'] = 'PHP Jailkit section';
2727
$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).';
2828
$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section';
2929
$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary';
30+
$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty';
31+
$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty';
3032
?>

interface/web/admin/lib/lang/bg_server_php.lng

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,6 @@ $wb['php_jk_section_txt'] = 'PHP Jailkit section';
2727
$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).';
2828
$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section';
2929
$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary';
30+
$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty';
31+
$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty';
3032
?>

0 commit comments

Comments
 (0)