From 0b0dc90a467c21513010d62af74a03c952652769 Mon Sep 17 00:00:00 2001
From: mcramer <m.cramer@pixcept.de>
Date: Tue, 23 Jun 2009 10:46:18 -0400
Subject: [PATCH] Added: Cron Jobs for clients (url, chrooted, full) Fixed: Missing server.ini config entries for vlogger and jailkit Added: Admin interface server_config for vlogger and cron
---
interface/web/sites/lib/lang/de_cron.lng | 21
interface/web/sites/lib/module.conf.php | 15
install/dist/conf/debian40.conf.php | 6
interface/web/sites/form/cron.tform.php | 189 +++++
interface/web/sites/cron_edit.php | 226 ++++++
install/tpl/server.ini.master | 9
interface/lib/classes/validate_cron.inc.php | 191 +++++
interface/web/admin/form/server_config.tform.php | 82 ++
interface/web/client/lib/lang/en_client.lng | 5
install/dist/conf/centos52.conf.php | 6
interface/web/admin/lib/lang/de_server_config.lng | 5
install/lib/installer_base.lib.php | 3
install/sql/ispconfig3.sql | 33
interface/web/sites/cron_del.php | 64 +
interface/web/client/lib/lang/en_client_template.lng | 5
install/dist/conf/gentoo.conf.php | 6
interface/web/admin/templates/server_config_jailkit_edit.htm | 4
interface/web/client/templates/client_template_edit_limits.htm | 14
install/dist/conf/centos53.conf.php | 6
interface/web/client/templates/client_edit_limits.htm | 14
interface/web/sites/lib/lang/en_cron.lng | 21
install/dist/conf/fedora9.conf.php | 6
interface/web/client/form/client.tform.php | 34 +
server/plugins-available/cron_jailkit_plugin.inc.php | 272 ++++++++
interface/web/admin/templates/server_config_cron_edit.htm | 30
interface/web/sites/templates/cron_list.htm | 71 ++
interface/web/admin/lib/lang/en_server_config.lng | 5
server/plugins-available/cron_plugin.inc.php | 212 ++++++
interface/web/client/lib/lang/de_client.lng | 5
interface/web/admin/templates/server_config_vlogger_edit.htm | 22
server/mods-available/cron_module.inc.php | 97 ++
interface/web/sites/lib/lang/de_cron_list.lng | 12
interface/web/sites/lib/lang/en_cron_list.lng | 12
interface/web/sites/list/cron.list.php | 152 ++++
install/dist/conf/opensuse110.conf.php | 5
interface/web/client/lib/lang/de_client_template.lng | 5
interface/web/sites/cron_list.php | 23
interface/web/client/form/client_template.tform.php | 34 +
interface/web/sites/templates/cron_edit.htm | 68 ++
interface/web/sites/web_domain_del.php | 6
40 files changed, 1,994 insertions(+), 2 deletions(-)
diff --git a/install/dist/conf/centos52.conf.php b/install/dist/conf/centos52.conf.php
index 0f7cac0..e1ee4be 100644
--- a/install/dist/conf/centos52.conf.php
+++ b/install/dist/conf/centos52.conf.php
@@ -147,8 +147,14 @@
$conf['jailkit']['jk_init'] = 'jk_init.ini';
$conf['jailkit']['jk_chrootsh'] = 'jk_chrootsh.ini';
$conf['jailkit']['jailkit_chroot_app_programs'] = '/usr/bin/groups /usr/bin/id /usr/bin/dircolors /bin/basename /usr/bin/dirname /usr/bin/nano';
+$conf['jailkit']['jailkit_chroot_cron_programs'] = '/usr/bin/php /usr/bin/perl /usr/share/perl /usr/share/php';
//* vlogger
$conf['vlogger']['config_dir'] = '/etc';
+//* cron
+$conf['cron']['init_script'] = 'crond';
+$conf['cron']['crontab_dir'] = '/etc/cron.d';
+$conf['cron']['wget'] = '/usr/bin/wget';
+
?>
\ No newline at end of file
diff --git a/install/dist/conf/centos53.conf.php b/install/dist/conf/centos53.conf.php
index 51a5ba4..260eedb 100644
--- a/install/dist/conf/centos53.conf.php
+++ b/install/dist/conf/centos53.conf.php
@@ -147,8 +147,14 @@
$conf['jailkit']['jk_init'] = 'jk_init.ini';
$conf['jailkit']['jk_chrootsh'] = 'jk_chrootsh.ini';
$conf['jailkit']['jailkit_chroot_app_programs'] = '/usr/bin/groups /usr/bin/id /usr/bin/dircolors /bin/basename /usr/bin/dirname /usr/bin/nano';
+$conf['jailkit']['jailkit_chroot_cron_programs'] = '/usr/bin/php /usr/bin/perl /usr/share/perl /usr/share/php';
//* vlogger
$conf['vlogger']['config_dir'] = '/etc';
+//* cron
+$conf['cron']['init_script'] = 'crond';
+$conf['cron']['crontab_dir'] = '/etc/cron.d';
+$conf['cron']['wget'] = '/usr/bin/wget';
+
?>
\ No newline at end of file
diff --git a/install/dist/conf/debian40.conf.php b/install/dist/conf/debian40.conf.php
index 92fd428..6d10711 100644
--- a/install/dist/conf/debian40.conf.php
+++ b/install/dist/conf/debian40.conf.php
@@ -147,8 +147,14 @@
$conf['jailkit']['jk_init'] = 'jk_init.ini';
$conf['jailkit']['jk_chrootsh'] = 'jk_chrootsh.ini';
$conf['jailkit']['jailkit_chroot_app_programs'] = '/usr/bin/groups /usr/bin/id /usr/bin/dircolors /usr/bin/lesspipe /usr/bin/basename /usr/bin/dirname /usr/bin/nano /usr/bin/pico';
+$conf['jailkit']['jailkit_chroot_cron_programs'] = '/usr/bin/php /usr/bin/perl /usr/share/perl /usr/share/php';
//* vlogger
$conf['vlogger']['config_dir'] = '/etc';
+//* cron
+$conf['cron']['init_script'] = 'cron';
+$conf['cron']['crontab_dir'] = '/etc/cron.d';
+$conf['cron']['wget'] = '/usr/bin/wget';
+
?>
\ No newline at end of file
diff --git a/install/dist/conf/fedora9.conf.php b/install/dist/conf/fedora9.conf.php
index fd41690..c49f133 100644
--- a/install/dist/conf/fedora9.conf.php
+++ b/install/dist/conf/fedora9.conf.php
@@ -147,8 +147,14 @@
$conf['jailkit']['jk_init'] = 'jk_init.ini';
$conf['jailkit']['jk_chrootsh'] = 'jk_chrootsh.ini';
$conf['jailkit']['jailkit_chroot_app_programs'] = '/usr/bin/groups /usr/bin/id /usr/bin/dircolors /bin/basename /usr/bin/dirname /usr/bin/nano';
+$conf['jailkit']['jailkit_chroot_cron_programs'] = '/usr/bin/php /usr/bin/perl /usr/share/perl /usr/share/php';
//* vlogger
$conf['vlogger']['config_dir'] = '/etc';
+//* cron
+$conf['cron']['init_script'] = 'crond';
+$conf['cron']['crontab_dir'] = '/etc/cron.d';
+$conf['cron']['wget'] = '/usr/bin/wget';
+
?>
\ No newline at end of file
diff --git a/install/dist/conf/gentoo.conf.php b/install/dist/conf/gentoo.conf.php
index 4d9a730..9003aeb 100644
--- a/install/dist/conf/gentoo.conf.php
+++ b/install/dist/conf/gentoo.conf.php
@@ -96,8 +96,14 @@
$conf['jailkit']['jk_init'] = 'jk_init.ini';
$conf['jailkit']['jk_chrootsh'] = 'jk_chrootsh.ini';
$conf['jailkit']['jailkit_chroot_app_programs'] = '/usr/bin/groups /usr/bin/id /usr/bin/dircolors /usr/bin/lesspipe /usr/bin/basename /usr/bin/dirname /usr/bin/nano /usr/bin/pico';
+$conf['jailkit']['jailkit_chroot_cron_programs'] = '/usr/bin/php /usr/bin/perl /usr/share/perl /usr/share/php';
//* vlogger
$conf['vlogger']['config_dir'] = '/etc';
+//* cron
+$conf['cron']['init_script'] = 'cron';
+$conf['cron']['crontab_dir'] = '/etc/cron.d';
+$conf['cron']['wget'] = '/usr/bin/wget';
+
?>
\ No newline at end of file
diff --git a/install/dist/conf/opensuse110.conf.php b/install/dist/conf/opensuse110.conf.php
index e46d77e..58b9d38 100644
--- a/install/dist/conf/opensuse110.conf.php
+++ b/install/dist/conf/opensuse110.conf.php
@@ -147,9 +147,14 @@
$conf['jailkit']['jk_init'] = 'jk_init.ini';
$conf['jailkit']['jk_chrootsh'] = 'jk_chrootsh.ini';
$conf['jailkit']['jailkit_chroot_app_programs'] = '/usr/bin/groups /usr/bin/id /usr/bin/dircolors /usr/bin/basename /usr/bin/dirname /usr/bin/nano /usr/bin/pico';
+$conf['jailkit']['jailkit_chroot_cron_programs'] = '/usr/bin/php /usr/bin/perl /usr/share/perl /usr/share/php';
//* vlogger
$conf['vlogger']['config_dir'] = '/etc';
+//* cron
+$conf['cron']['init_script'] = 'cron';
+$conf['cron']['crontab_dir'] = '/etc/cron.d';
+$conf['cron']['wget'] = '/usr/bin/wget';
?>
\ No newline at end of file
diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php
index 8d92e2b..82b5b17 100644
--- a/install/lib/installer_base.lib.php
+++ b/install/lib/installer_base.lib.php
@@ -210,7 +210,8 @@
$tpl_ini_array['web']['website_basedir'] = $conf['web']['website_basedir'];
$tpl_ini_array['web']['website_path'] = $conf['web']['website_path'];
$tpl_ini_array['web']['website_symlinks'] = $conf['web']['website_symlinks'];
-
+ $tpl_ini_array['cron']['crontab_dir'] = $conf['cron']['crontab_dir'];
+
$server_ini_content = array_to_ini($tpl_ini_array);
$server_ini_content = mysql_real_escape_string($server_ini_content);
diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql
index 376ff66..1e1e8e4 100644
--- a/install/sql/ispconfig3.sql
+++ b/install/sql/ispconfig3.sql
@@ -92,6 +92,9 @@
`limit_dns_record` int(11) NOT NULL default '-1',
`default_dbserver` int(11) NOT NULL default '1',
`limit_database` int(11) NOT NULL default '-1',
+ `limit_cron` int(11) NOT NULL default '0',
+ `limit_cron_type` enum('url','chrooted','full') NOT NULL default 'url',
+ `limit_cron_frequency` int(11) NOT NULL default '5',
`limit_client` int(11) NOT NULL default '0',
`parent_client_id` int(11) unsigned NOT NULL default '0',
`username` varchar(64) default NULL,
@@ -140,10 +143,40 @@
`limit_dns_zone` int(11) NOT NULL default '-1',
`limit_dns_record` int(11) NOT NULL default '-1',
`limit_database` int(11) NOT NULL default '-1',
+ `limit_cron` int(11) NOT NULL default '0',
+ `limit_cron_type` enum('url','chrooted','full') NOT NULL default 'url',
+ `limit_cron_frequency` int(11) NOT NULL default '5',
`limit_client` int(11) NOT NULL default '0',
PRIMARY KEY (`template_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `dns_rr`
+--
+CREATE TABLE `cron` (
+ `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) NULL default NULL,
+ `sys_perm_group` varchar(5) NULL default NULL,
+ `sys_perm_other` varchar(5) NULL default NULL,
+ `server_id` int(11) unsigned NOT NULL default '0',
+ `parent_domain_id` int(11) unsigned NOT NULL default '0',
+ `type` enum('url','chrooted','full') NOT NULL default 'url',
+ `command` varchar(255) NOT NULL,
+ `run_min` varchar(100) NULL,
+ `run_hour` varchar(100) NULL,
+ `run_mday` varchar(100) NULL,
+ `run_month` varchar(100) NULL,
+ `run_wday` varchar(100) NULL,
+ `active` enum('n','y') NOT NULL default 'y',
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM AUTO_INCREMENT=1;
+
+
-- --------------------------------------------------------
--
diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master
index 463397e..d33afc7 100644
--- a/install/tpl/server.ini.master
+++ b/install/tpl/server.ini.master
@@ -48,3 +48,12 @@
jailkit_chroot_home=/home/[username]
jailkit_chroot_app_sections=basicshell editors extendedshell netutils ssh sftp scp groups jk_lsh
jailkit_chroot_app_programs=/usr/bin/groups /usr/bin/id /usr/bin/dircolors /usr/bin/lesspipe /usr/bin/basename /usr/bin/dirname /usr/bin/nano /usr/bin/pico
+jailkit_chroot_cron_programs=/usr/bin/php /usr/bin/perl /usr/share/perl /usr/share/php
+
+[vlogger]
+config_dir=/etc
+
+[cron]
+init_script=cron
+crontab_dir=/etc/cron.d
+wget=/usr/bin/wget
diff --git a/interface/lib/classes/validate_cron.inc.php b/interface/lib/classes/validate_cron.inc.php
new file mode 100644
index 0000000..42d9eb6
--- /dev/null
+++ b/interface/lib/classes/validate_cron.inc.php
@@ -0,0 +1,191 @@
+<?php
+
+/*
+Copyright (c) 2007, Till Brehm, projektfarm Gmbh
+Modified 2009, Marius Cramer, pixcept KG
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+class validate_cron {
+
+ function get_error($errmsg) {
+ global $app;
+
+ if(isset($app->tform->wordbook[$errmsg])) {
+ return $app->tform->wordbook[$errmsg]."<br>\r\n";
+ } else {
+ return $errmsg."<br>\r\n";
+ }
+ }
+
+ /*
+ Validator function to check if a given cron command is in correct form (url only).
+ */
+ function command_format($field_name, $field_value, $validator) {
+ if(preg_match("'^(\w+):\/\/'", $field_value, $matches)) {
+
+ $parsed = parse_url($field_value);
+ if($parsed === false) return $this->get_error($validator['errmsg']);
+
+ if($parsed["scheme"] != "http" && $parsed["scheme"] != "https") return $this->get_error($validator['errmsg']);
+
+ if(preg_match("'^([a-z0-9][a-z0-9-]{0,62}\.)+([a-z]{2,4})$'i", $parsed["host"]) == false) return $this->get_error($validator['errmsg']);
+ }
+ }
+
+ /*
+ Validator function to check if a given cron time is in correct form.
+ */
+ function run_time_format($field_name, $field_value, $validator) {
+ global $app;
+
+ //* check general form
+ $is_ok = true;
+ $field_value = str_replace(" ", "", $field_value); // spaces are not needed
+ $used_times = array();
+
+ if(preg_match("'^[0-9\-\,\/\*]+$'", $field_value) == false) return $this->get_error($validator['errmsg']); // allowed characters are 0-9, comma, *, -, /
+ elseif(preg_match("'[\-\,\/][\-\,\/]'", $field_value) == true) return $this->get_error($validator['errmsg']); // comma, - and / never stand together
+ //* now split list and check each entry. store used values in array for later limit-check
+ $time_list = split(",", $field_value);
+ if(count($time_list) < 1) return $this->get_error($validator['errmsg']);
+
+ $max_entry = 0;
+ $min_entry = 0;
+ $in_minutes = 1;
+ //* get maximum value of entry for each field type (name)
+ switch($field_name) {
+ case "run_min":
+ $max_entry = 59;
+ break;
+ case "run_hour":
+ $max_entry = 23;
+ $in_minutes = 60;
+ break;
+ case "run_mday":
+ $max_entry = 31;
+ $min_entry = 1;
+ $in_minutes = 1440;
+ break;
+ case "run_month":
+ $max_entry = 12;
+ $min_entry = 1;
+ $in_minutes = 1440 * 28; // not exactly but enough
+ break;
+ case "run_wday":
+ $max_entry = 7;
+ $in_minutes = 1440;
+ break;
+ }
+
+ if($max_entry == 0) return $this->get_error('unknown_fieldtype_error');
+
+ foreach($time_list as $entry) {
+ //* possible value combinations:
+ //* x => ^(\d+)$
+ //* x-y => ^(\d+)\-(\d+)$
+ //* x/y => ^(\d+)\/([1-9]\d*)$
+ //* x-y/z => ^(\d+)\-(\d+)\/([1-9]\d*)$
+ //* */x => ^\*\/([1-9]\d*)$
+ //* combined regex => ^(\d+|\*)(\-(\d+))?(\/([1-9]\d*))?$
+
+ if(preg_match("'^(((\d+)(\-(\d+))?)|\*)(\/([1-9]\d*))?$'", $entry, $matches) == false) {
+ return $this->get_error($validator['errmsg']);
+ }
+
+ //* matches contains:
+ //* 1 => * or value or x-y range
+ //* 2 => unused
+ //* 3 => value if [1] != *
+ //* 4 => empty if no range was used
+ //* 5 => 2nd value of range if [1] != * and range was used
+ //* 6 => empty if step was not used
+ //* 7 => step
+
+ $loop_step = 1;
+ $loop_from = $min_entry;
+ $loop_to = $max_entry;
+
+ //* calculate used values
+ if($matches[1] == "*") {
+ //* not to check
+ } else {
+ if($matches[3] < $min_entry || $matches[3] > $max_entry) {
+ //* check if value is in allowed range
+ return $this->get_error($validator['errmsg']);
+ } elseif($matches[4] && ($matches[5] < $min_entry || $matches[5] > $max_entry || $matches[5] <= $matches[3])) {
+ //* check if value is in allowed range and not less or equal to first value
+ return $this->get_error($validator['errmsg']);
+ }
+
+ $loop_from = $matches[3];
+ $loop_to = $matches[3];
+ if($matches[4]) $loop_to = $matches[5];
+ }
+ if($matches[6] && ($matches[7] < 2 || $matches[7] > $max_entry - 1)) {
+ //* check if step value is valid
+ return $this->get_error($validator['errmsg']);
+ }
+ if($matches[7]) $loop_step = $matches[7];
+
+ //* loop through values to set used times
+ for($t = $loop_from; $t <= $loop_to; $t = $t + $loop_step) {
+ $used_times[] = $t;
+ }
+ } //* end foreach entry loop
+
+ //* sort used times and erase doubles
+ sort($used_times);
+ $used_times = array_unique($used_times);
+
+ //* get minimum frequency and store it in $app->tform->cron_min_freq for usage in onUpdateSave and onInsertSave!
+ $min_freq = -1;
+ $prev_time = -1;
+ foreach($used_times as $curtime) {
+ if($prev_time != -1) {
+ $freq = $curtime - $prev_time;
+ if($min_freq == -1 || $freq < $min_freq) $min_freq = $freq;
+ }
+ $prev_time = $curtime;
+ }
+
+ //* check last against first (needed because e.g. wday 1,4,7 has diff 1 not 3
+ $prev_time = $used_times[0];
+ $freq = ($prev_time - $min_entry) + ($max_entry - $curtime) + 1;
+ if($min_freq == -1 || $freq < $min_freq) $min_freq = $freq;
+
+ if($min_freq > 0 && $min_freq <= $max_entry) { //* only store if > 1 && < $max_entry!
+ $min_freq = $min_freq * $in_minutes; // we have to overwrite $app->tform->cron_min_freq if this is higher value
+ if(!$app->tform->cron_min_freq || $app->tform->cron_min_freq > $min_freq) $app->tform->cron_min_freq = $min_freq;
+ }
+
+ //return "DEBUG: " . $app->tform->cron_min_freq . " ($min_freq) --- " . var_export($used_times, true) . "<br />";
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php
index 754000b..3e081b4 100644
--- a/interface/web/admin/form/server_config.tform.php
+++ b/interface/web/admin/form/server_config.tform.php
@@ -478,6 +478,17 @@
'width' => '40',
'maxlength' => '1000'
),
+ 'jailkit_chroot_cron_programs' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'default' => '',
+ 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY',
+ 'errmsg'=> 'jailkit_chroot_cron_programs_error_empty'),
+ ),
+ 'value' => '',
+ 'width' => '40',
+ 'maxlength' => '1000'
+ ),
##################################
# ENDE Datatable fields
##################################
@@ -485,10 +496,79 @@
);
+$form["tabs"]['vlogger'] = array (
+ 'title' => "vlogger",
+ 'width' => 80,
+ 'template' => "templates/server_config_vlogger_edit.htm",
+ 'fields' => array (
+ ##################################
+ # Begin Datatable fields
+ ##################################
+ 'config_dir' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'default' => '',
+ 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY',
+ 'errmsg'=> 'vlogger_config_dir_error_empty'),
+ ),
+ 'value' => '',
+ 'width' => '40',
+ 'maxlength' => '255'
+ ),
+ ##################################
+ # ENDE Datatable fields
+ ##################################
+ )
+);
-
+$form["tabs"]['cron'] = array (
+ 'title' => "Cron",
+ 'width' => 80,
+ 'template' => "templates/server_config_cron_edit.htm",
+ 'fields' => array (
+ ##################################
+ # Begin Datatable fields
+ ##################################
+ 'init_script' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'default' => '',
+ 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY',
+ 'errmsg'=> 'cron_init_script_error_empty'),
+ ),
+ 'value' => '',
+ 'width' => '40',
+ 'maxlength' => '255'
+ ),
+ 'crontab_dir' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'default' => '',
+ 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY',
+ 'errmsg'=> 'crontab_dir_error_empty'),
+ ),
+ 'value' => '',
+ 'width' => '40',
+ 'maxlength' => '255'
+ ),
+ 'wget' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'default' => '',
+ 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY',
+ 'errmsg'=> 'cron_wget_error_empty'),
+ ),
+ 'value' => '',
+ 'width' => '40',
+ 'maxlength' => '255'
+ ),
+ ##################################
+ # ENDE Datatable fields
+ ##################################
+ )
+);
diff --git a/interface/web/admin/lib/lang/de_server_config.lng b/interface/web/admin/lib/lang/de_server_config.lng
index 97f3e7f..8c24857 100644
--- a/interface/web/admin/lib/lang/de_server_config.lng
+++ b/interface/web/admin/lib/lang/de_server_config.lng
@@ -2,6 +2,7 @@
$wb['jailkit_chroot_home_txt'] = 'Jailkit chroot home';
$wb['jailkit_chroot_app_sections_txt'] = 'Jailkit chroot app sections';
$wb['jailkit_chroot_app_programs_txt'] = 'Jailkit chrooted applications';
+$wb['jailkit_chroot_cron_programs_txt'] = 'Jailkit cron chrooted applications';
$wb['website_path_txt'] = 'Website path';
$wb['website_symlinks_txt'] = 'Website symlinks';
$wb['vhost_conf_dir_txt'] = 'Vhost config dir';
@@ -38,4 +39,8 @@
$wb['gateway_error_wrong'] = 'Invalid Gateway format.';
$wb['hostname_error_empty'] = 'Hostname is empty.';
$wb['nameservers_error_empty'] = 'Nameserver is empty.';
+$wb["config_dir_txt"] = 'Config directory';
+$wb["init_script_txt"] = 'Cron init script name';
+$wb["crontab_dir_txt"] = 'Path for individual crontabs';
+$wb["wget_txt"] = 'Path to wget program';
?>
diff --git a/interface/web/admin/lib/lang/en_server_config.lng b/interface/web/admin/lib/lang/en_server_config.lng
index 447ae3a..ef736cc 100644
--- a/interface/web/admin/lib/lang/en_server_config.lng
+++ b/interface/web/admin/lib/lang/en_server_config.lng
@@ -2,6 +2,7 @@
$wb["jailkit_chroot_home_txt"] = 'Jailkit chroot home';
$wb["jailkit_chroot_app_sections_txt"] = 'Jailkit chroot app sections';
$wb["jailkit_chroot_app_programs_txt"] = 'Jailkit chrooted applications';
+$wb['jailkit_chroot_cron_programs_txt'] = 'Jailkit cron chrooted applications';
$wb["website_path_txt"] = 'Website path';
$wb["website_symlinks_txt"] = 'Website symlinks';
$wb["website_basedir_txt"] = 'Website basedir';
@@ -38,4 +39,8 @@
$wb["gateway_error_wrong"] = 'Invalid Gateway format.';
$wb["hostname_error_empty"] = 'Hostname is empty.';
$wb["nameservers_error_empty"] = 'Nameserver is empty.';
+$wb["config_dir_txt"] = 'Config directory';
+$wb["init_script_txt"] = 'Cron init script name';
+$wb["crontab_dir_txt"] = 'Path for individual crontabs';
+$wb["wget_txt"] = 'Path to wget program';
?>
\ No newline at end of file
diff --git a/interface/web/admin/templates/server_config_cron_edit.htm b/interface/web/admin/templates/server_config_cron_edit.htm
new file mode 100644
index 0000000..066693e
--- /dev/null
+++ b/interface/web/admin/templates/server_config_cron_edit.htm
@@ -0,0 +1,30 @@
+<h2><tmpl_var name="list_head_txt"></h2>
+<p><tmpl_var name="list_desc_txt"></p>
+
+<div class="panel panel_server_config">
+
+ <div class="pnl_formsarea">
+ <fieldset class="inlineLabels">
+ <div class="ctrlHolder">
+ <label for="init_script">{tmpl_var name='init_script_txt'}</label>
+ <input name="init_script" id="init_script" value="{tmpl_var name='init_script'}" size="40" maxlength="255" type="text" class="textInput" />
+ </div>
+ <div class="ctrlHolder">
+ <label for="crontab_dir">{tmpl_var name='crontab_dir_txt'}</label>
+ <input name="crontab_dir" id="crontab_dir" value="{tmpl_var name='crontab_dir'}" size="40" maxlength="255" type="text" class="textInput" />
+ </div>
+ <div class="ctrlHolder">
+ <label for="wget">{tmpl_var name='wget_txt'}</label>
+ <input name="wget" id="wget" value="{tmpl_var name='wget'}" size="40" maxlength="255" type="text" class="textInput" />
+ </div>
+ </fieldset>
+
+ <input type="hidden" name="id" value="{tmpl_var name='id'}">
+
+ <div class="buttonHolder buttons">
+ <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onClick="submitForm('pageForm','admin/server_config_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button>
+ <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onClick="loadContent('admin/server_config_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button>
+ </div>
+ </div>
+
+</div>
diff --git a/interface/web/admin/templates/server_config_jailkit_edit.htm b/interface/web/admin/templates/server_config_jailkit_edit.htm
index ec2081d..320fb87 100644
--- a/interface/web/admin/templates/server_config_jailkit_edit.htm
+++ b/interface/web/admin/templates/server_config_jailkit_edit.htm
@@ -17,6 +17,10 @@
<label for="jailkit_chroot_app_programs">{tmpl_var name='jailkit_chroot_app_programs_txt'}</label>
<input name="jailkit_chroot_app_programs" id="jailkit_chroot_app_programs" value="{tmpl_var name='jailkit_chroot_app_programs'}" size="40" maxlength="1000" type="text" class="textInput" />
</div>
+ <div class="ctrlHolder">
+ <label for="jailkit_chroot_cron_programs">{tmpl_var name='jailkit_chroot_cron_programs_txt'}</label>
+ <input name="jailkit_chroot_cron_programs" id="jailkit_chroot_cron_programs" value="{tmpl_var name='jailkit_chroot_cron_programs'}" size="40" maxlength="1000" type="text" class="textInput" />
+ </div>
</fieldset>
<input type="hidden" name="id" value="{tmpl_var name='id'}">
diff --git a/interface/web/admin/templates/server_config_vlogger_edit.htm b/interface/web/admin/templates/server_config_vlogger_edit.htm
new file mode 100644
index 0000000..bf6a82a
--- /dev/null
+++ b/interface/web/admin/templates/server_config_vlogger_edit.htm
@@ -0,0 +1,22 @@
+<h2><tmpl_var name="list_head_txt"></h2>
+<p><tmpl_var name="list_desc_txt"></p>
+
+<div class="panel panel_server_config">
+
+ <div class="pnl_formsarea">
+ <fieldset class="inlineLabels">
+ <div class="ctrlHolder">
+ <label for="config_dir">{tmpl_var name='config_dir_txt'}</label>
+ <input name="config_dir" id="config_dir" value="{tmpl_var name='config_dir'}" size="40" maxlength="255" type="text" class="textInput" />
+ </div>
+ </fieldset>
+
+ <input type="hidden" name="id" value="{tmpl_var name='id'}">
+
+ <div class="buttonHolder buttons">
+ <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onClick="submitForm('pageForm','admin/server_config_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button>
+ <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onClick="loadContent('admin/server_config_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button>
+ </div>
+ </div>
+
+</div>
diff --git a/interface/web/client/form/client.tform.php b/interface/web/client/form/client.tform.php
index 288e893..4cc9dd5 100644
--- a/interface/web/client/form/client.tform.php
+++ b/interface/web/client/form/client.tform.php
@@ -663,6 +663,40 @@
'rows' => '',
'cols' => ''
),
+ 'limit_cron' => array (
+ 'datatype' => 'INTEGER',
+ 'formtype' => 'TEXT',
+ 'validators' => array ( 0 => array ( 'type' => 'ISINT',
+ 'errmsg'=> 'limit_cron_error_notint'),
+ ),
+ 'default' => '0',
+ 'value' => '',
+ 'separator' => '',
+ 'width' => '10',
+ 'maxlength' => '10',
+ 'rows' => '',
+ 'cols' => ''
+ ),
+ 'limit_cron_type' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'SELECT',
+ 'default' => '',
+ 'value' => array('full' => 'Full Cron','chrooted' => 'Chrooted Cron','url' => 'URL Cron')
+ ),
+ 'limit_cron_frequency' => array (
+ 'datatype' => 'INTEGER',
+ 'formtype' => 'TEXT',
+ 'validators' => array ( 0 => array ( 'type' => 'ISINT',
+ 'errmsg'=> 'limit_cron_error_frequency'),
+ ),
+ 'default' => '-1',
+ 'value' => '',
+ 'separator' => '',
+ 'width' => '10',
+ 'maxlength' => '10',
+ 'rows' => '',
+ 'cols' => ''
+ ),
##################################
# END Datatable fields
##################################
diff --git a/interface/web/client/form/client_template.tform.php b/interface/web/client/form/client_template.tform.php
index f732faf..e1dd51d 100644
--- a/interface/web/client/form/client_template.tform.php
+++ b/interface/web/client/form/client_template.tform.php
@@ -395,6 +395,40 @@
'rows' => '',
'cols' => ''
),
+ 'limit_cron' => array (
+ 'datatype' => 'INTEGER',
+ 'formtype' => 'TEXT',
+ 'validators' => array ( 0 => array ( 'type' => 'ISINT',
+ 'errmsg'=> 'limit_cron_error_notint'),
+ ),
+ 'default' => '0',
+ 'value' => '',
+ 'separator' => '',
+ 'width' => '10',
+ 'maxlength' => '10',
+ 'rows' => '',
+ 'cols' => ''
+ ),
+ 'limit_cron_type' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'SELECT',
+ 'default' => '',
+ 'value' => array('full' => 'Full Cron','chrooted' => 'Chrooted Cron','url' => 'URL Cron')
+ ),
+ 'limit_cron_frequency' => array (
+ 'datatype' => 'INTEGER',
+ 'formtype' => 'TEXT',
+ 'validators' => array ( 0 => array ( 'type' => 'ISINT',
+ 'errmsg'=> 'limit_cron_error_frequency'),
+ ),
+ 'default' => '-1',
+ 'value' => '',
+ 'separator' => '',
+ 'width' => '10',
+ 'maxlength' => '10',
+ 'rows' => '',
+ 'cols' => ''
+ ),
##################################
# END Datatable fields
##################################
diff --git a/interface/web/client/lib/lang/de_client.lng b/interface/web/client/lib/lang/de_client.lng
index 05fad56..d126fa8 100644
--- a/interface/web/client/lib/lang/de_client.lng
+++ b/interface/web/client/lib/lang/de_client.lng
@@ -39,6 +39,9 @@
$wb['limit_subdomain_txt'] = 'Max. Anzahl an Subdomains';
$wb['limit_webquota_txt'] = 'Max. Webquota';
$wb['limit_database_txt'] = 'Max. Anzahl an Datenbanken';
+$wb["limit_cron_txt"] = 'Max. Anzahl Cron Jobs';
+$wb["limit_cron_type_txt"] = 'Max. erlaubter Typ von Cron Jobs (chrooted und full erlauben auch url)';
+$wb["limit_cron_frequency_txt"] = 'Min. Abstand zwischen Ausführungen';
$wb['ip_address_txt'] = 'IP Adresse';
$wb['limit_client_error_notint'] = 'The sub client limit must be a number.';
$wb['firstname_error_empty'] = 'Vorname ist leer.';
@@ -74,6 +77,8 @@
$wb['limit_dns_zone_error_notint'] = 'Das DNS Einträge Limit muss eine Nummer sein.';
$wb['default_dbserver_txt'] = 'Standarddatenbankserver';
$wb['limit_database_error_notint'] = 'Das Datenbank Limit muss eine Nummer sein.';
+$wb["limit_cron_error_notint"] = 'Das Cron Job Limit muss eine Zahl sein.';
+$wb["limit_cron_error_frequency"] = 'Das Cron Job Intervall-Limit muss eine Zahl sein.';
$wb['username_error_regex'] = 'Der Benutzername enthält ungültige Zeichen.';
$wb['password_strength_txt'] = 'Passwortkomplexität';
$wb['template_master_txt'] = 'Master';
diff --git a/interface/web/client/lib/lang/de_client_template.lng b/interface/web/client/lib/lang/de_client_template.lng
index 8a29d47..cdcce8d 100644
--- a/interface/web/client/lib/lang/de_client_template.lng
+++ b/interface/web/client/lib/lang/de_client_template.lng
@@ -17,6 +17,9 @@
$wb['limit_subdomain_txt'] = 'Max. Anzahl an Subdomains';
$wb['limit_webquota_txt'] = 'Max. Webquota';
$wb['limit_database_txt'] = 'Max. Anzahl an Datenbanken';
+$wb["limit_cron_txt"] = 'Max. Anzahl Cron Jobs';
+$wb["limit_cron_type_txt"] = 'Max. erlaubter Typ von Cron Jobs (chrooted und full erlauben auch url)';
+$wb["limit_cron_frequency_txt"] = 'Min. Abstand zwischen Ausführungen';
$wb['limit_web_domain_txt'] = 'Max. Anzahl an Web Domains';
$wb['limit_web_aliasdomain_txt'] = 'Max. Anzahl an Web Aliasdomains';
$wb['limit_web_subdomain_txt'] = 'Max. Anzahl an Web Subdomains';
@@ -43,5 +46,7 @@
$wb['limit_shell_user_error_notint'] = 'Das Shell Benutzer Limit muss eine Nummer sein.';
$wb['limit_dns_zone_error_notint'] = 'Das DNS Einträge Limit muss eine Nummer sein.';
$wb['limit_database_error_notint'] = 'Das Datenbanken Limit muss eine Nummer sein.';
+$wb["limit_cron_error_notint"] = 'Das Cron Job Limit muss eine Zahl sein.';
+$wb["limit_cron_error_frequency"] = 'Das Cron Job Intervall-Limit muss eine Zahl sein.';
$wb['error_template_name_empty'] = 'Bitte geben sie einen Vorlagenamen ein';
?>
diff --git a/interface/web/client/lib/lang/en_client.lng b/interface/web/client/lib/lang/en_client.lng
index 74c166f..03cec3f 100644
--- a/interface/web/client/lib/lang/en_client.lng
+++ b/interface/web/client/lib/lang/en_client.lng
@@ -39,6 +39,9 @@
$wb["limit_subdomain_txt"] = 'limit_subdomain';
$wb["limit_webquota_txt"] = 'limit_webquota';
$wb["limit_database_txt"] = 'limit_database';
+$wb["limit_cron_txt"] = 'Max. number of cron jobs';
+$wb["limit_cron_type_txt"] = 'Max. type of cron jobs (chrooted and full implies url)';
+$wb["limit_cron_frequency_txt"] = 'Min. delay between executions';
$wb["ip_address_txt"] = 'ip_address';
$wb["limit_client_error_notint"] = 'Client Limit is not a number.';
$wb["firstname_error_empty"] = 'Firstname is empty.';
@@ -78,6 +81,8 @@
$wb["default_dbserver_txt"] = 'Default Database Server';
$wb["limit_database_txt"] = 'Max. number of Databases';
$wb["limit_database_error_notint"] = 'The database limit must be a number.';
+$wb["limit_cron_error_notint"] = 'The cron limit must be a number.';
+$wb["limit_cron_error_frequency"] = 'The cron frequency limit must be a number.';
$wb["username_error_regex"] = 'The Username contains invalid chracaters.';
$wb["template_master_txt"] = 'Master template';
$wb["template_additional_txt"] = 'Addon template';
diff --git a/interface/web/client/lib/lang/en_client_template.lng b/interface/web/client/lib/lang/en_client_template.lng
index c3453a8..6d9ee11 100644
--- a/interface/web/client/lib/lang/en_client_template.lng
+++ b/interface/web/client/lib/lang/en_client_template.lng
@@ -17,6 +17,9 @@
$wb["limit_subdomain_txt"] = 'limit_subdomain';
$wb["limit_webquota_txt"] = 'limit_webquota';
$wb["limit_database_txt"] = 'limit_database';
+$wb["limit_cron_txt"] = 'Max. number of cron jobs';
+$wb["limit_cron_type_txt"] = 'Max. type of cron jobs (chrooted and full implies url)';
+$wb["limit_cron_frequency_txt"] = 'Min. delay between executions';
$wb["limit_web_domain_txt"] = 'Max. number of web domains';
$wb["limit_web_aliasdomain_txt"] = 'Max. number of web aliasdomains';
$wb["limit_web_subdomain_txt"] = 'Max. number of web subdomains';
@@ -46,5 +49,7 @@
$wb["limit_dns_zone_error_notint"] = 'The dns record limit must be a number.';
$wb["limit_database_txt"] = 'Max. number of Databases';
$wb["limit_database_error_notint"] = 'The database limit must be a number.';
+$wb["limit_cron_error_notint"] = 'The cron limit must be a number.';
+$wb["limit_cron_error_frequency"] = 'The cron frequency limit must be a number.';
$wb["error_template_name_empty"] = 'Please enter a Template name';
?>
\ No newline at end of file
diff --git a/interface/web/client/templates/client_edit_limits.htm b/interface/web/client/templates/client_edit_limits.htm
index e12abe9..2085141 100644
--- a/interface/web/client/templates/client_edit_limits.htm
+++ b/interface/web/client/templates/client_edit_limits.htm
@@ -155,6 +155,20 @@
<label for="limit_database">{tmpl_var name='limit_database_txt'}</label>
<input name="limit_database" id="limit_database" value="{tmpl_var name='limit_database'}" size="10" maxlength="10" type="text" class="textInput formLengthLimit" />
</div>
+ <div class="ctrlHolder">
+ <label for="limit_cron">{tmpl_var name='limit_cron_txt'}</label>
+ <input name="limit_cron" id="limit_cron" value="{tmpl_var name='limit_cron'}" size="10" maxlength="10" type="text" class="textInput formLengthLimit" />
+ </div>
+ <div class="ctrlHolder">
+ <label for="limit_cron_type">{tmpl_var name='limit_cron_type_txt'}</label>
+ <select name="limit_cron_type" id="limit_cron_type" class="selectInput formLengthHalf">
+ {tmpl_var name='limit_cron_type'}
+ </select>
+ </div>
+ <div class="ctrlHolder">
+ <label for="limit_cron_frequency">{tmpl_var name='limit_cron_frequency_txt'}</label>
+ <input name="limit_cron_frequency" id="limit_cron_frequency" value="{tmpl_var name='limit_cron_frequency'}" size="10" maxlength="10" type="text" class="textInput formLengthLimit" />
+ </div>
</fieldset>
<input type="hidden" name="id" value="{tmpl_var name='id'}">
diff --git a/interface/web/client/templates/client_template_edit_limits.htm b/interface/web/client/templates/client_template_edit_limits.htm
index bd01dce..2a4374c 100644
--- a/interface/web/client/templates/client_template_edit_limits.htm
+++ b/interface/web/client/templates/client_template_edit_limits.htm
@@ -89,6 +89,20 @@
<label for="limit_database">{tmpl_var name='limit_database_txt'}</label>
<input name="limit_database" id="limit_database" value="{tmpl_var name='limit_database'}" size="10" maxlength="10" type="text" class="textInput formLengthLimit" />
</div>
+ <div class="ctrlHolder">
+ <label for="limit_cron">{tmpl_var name='limit_cron_txt'}</label>
+ <input name="limit_cron" id="limit_cron" value="{tmpl_var name='limit_cron'}" size="10" maxlength="10" type="text" class="textInput formLengthLimit" />
+ </div>
+ <div class="ctrlHolder">
+ <label for="limit_cron_type">{tmpl_var name='limit_cron_type_txt'}</label>
+ <select name="limit_cron_type" id="limit_cron_type" class="selectInput formLengthHalf">
+ {tmpl_var name='limit_cron_type'}
+ </select>
+ </div>
+ <div class="ctrlHolder">
+ <label for="limit_cron_frequency">{tmpl_var name='limit_cron_frequency_txt'}</label>
+ <input name="limit_cron_frequency" id="limit_cron_frequency" value="{tmpl_var name='limit_cron_frequency'}" size="10" maxlength="10" type="text" class="textInput formLengthLimit" />
+ </div>
</fieldset>
<input type="hidden" name="id" value="{tmpl_var name='id'}">
diff --git a/interface/web/sites/cron_del.php b/interface/web/sites/cron_del.php
new file mode 100644
index 0000000..516b447
--- /dev/null
+++ b/interface/web/sites/cron_del.php
@@ -0,0 +1,64 @@
+<?php
+
+/*
+Copyright (c) 2008, Till Brehm, projektfarm Gmbh
+Modified 2009, Marius Cramer, pixcept KG
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/******************************************
+* Begin Form configuration
+******************************************/
+
+$list_def_file = "list/cron.list.php";
+$tform_def_file = "form/cron.tform.php";
+
+/******************************************
+* End Form configuration
+******************************************/
+
+require_once('../../lib/config.inc.php');
+require_once('../../lib/app.inc.php');
+
+//* Check permissions for module
+$app->auth->check_module_permissions('sites');
+
+$app->uses('tpl,tform,tform_actions');
+$app->load('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'));
+ }
+}
+
+$page = new page_action;
+$page->onDelete();
+
+?>
\ No newline at end of file
diff --git a/interface/web/sites/cron_edit.php b/interface/web/sites/cron_edit.php
new file mode 100644
index 0000000..1f0a025
--- /dev/null
+++ b/interface/web/sites/cron_edit.php
@@ -0,0 +1,226 @@
+<?php
+
+/*
+Copyright (c) 2007, Till Brehm, projektfarm Gmbh
+Modified 2009, Marius Cramer, pixcept KG
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/******************************************
+* Begin Form configuration
+******************************************/
+
+$tform_def_file = "form/cron.tform.php";
+
+/******************************************
+* End Form configuration
+******************************************/
+
+require_once('../../lib/config.inc.php');
+require_once('../../lib/app.inc.php');
+
+//* Check permissions for module
+$app->auth->check_module_permissions('sites');
+
+// Loading classes
+$app->uses('tpl,tform,tform_actions,validate_cron');
+$app->load('tform_actions');
+
+class page_action extends tform_actions {
+
+ function onShowNew() {
+ global $app, $conf;
+
+ // we will check only users, not admins
+ if($_SESSION["s"]["user"]["typ"] == 'user') {
+
+ // Get the limits of the client
+ $client_group_id = $_SESSION["s"]["user"]["default_group"];
+ $client = $app->db->queryOneRecord("SELECT limit_cron FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
+
+ // Check if the user may add another cron job.
+ if($client["limit_cron"] >= 0) {
+ $tmp = $app->db->queryOneRecord("SELECT count(id) as number FROM cron WHERE sys_groupid = $client_group_id");
+ if($tmp["number"] >= $client["limit_cron"]) {
+ $app->error($app->tform->wordbook["limit_cron_txt"]);
+ }
+ }
+ }
+
+ parent::onShowNew();
+ }
+
+ function onShowEnd() {
+ global $app, $conf;
+
+ if($this->id > 0) {
+ //* we are editing a existing record
+ $app->tpl->setVar("edit_disabled", 1);
+ $app->tpl->setVar("parent_domain_id_value", $this->dataRecord["parent_domain_id"]);
+ } else {
+ $app->tpl->setVar("edit_disabled", 0);
+ }
+
+ parent::onShowEnd();
+ }
+
+ function onSubmit() {
+ global $app, $conf;
+
+ if($_SESSION["s"]["user"]["typ"] != 'admin') {
+ // Get the limits of the client
+ $client_group_id = $_SESSION["s"]["user"]["default_group"];
+ $client = $app->db->queryOneRecord("SELECT limit_cron, limit_cron_type FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
+
+ // When the record is updated
+ if($this->id > 0) {
+ // When the record is inserted
+ } else {
+ // Check if the user may add another cron job.
+ if($client["limit_cron"] >= 0) {
+ $tmp = $app->db->queryOneRecord("SELECT count(id) as number FROM cron WHERE sys_groupid = $client_group_id");
+ if($tmp["number"] >= $client["limit_cron"]) {
+ $app->error($app->tform->wordbook["limit_cron_txt"]);
+ }
+ }
+ }
+ }
+
+ // Get the record of the parent domain
+ $parent_domain = $app->db->queryOneRecord("select * FROM web_domain WHERE domain_id = ".intval(@$this->dataRecord["parent_domain_id"]));
+
+ // Set fixed values
+ $this->dataRecord["server_id"] = $parent_domain["server_id"];
+
+ //* get type of command
+ $command = $this->dataRecord["command"];
+ if(preg_match("'^http(s)?:\/\/'i", $command)) {
+ $this->dataRecord["type"] = 'url';
+ } else {
+ $domain_owner = $app->db->queryOneRecord("SELECT limit_cron_type FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ".intval($parent_domain["sys_groupid"]));
+ if($domain_owner["limit_cron_type"] == 'full') $this->dataRecord["type"] = 'full';
+ else $this->dataRecord["type"] = 'chrooted';
+ }
+
+ parent::onSubmit();
+ }
+
+ function onUpdateSave($sql) {
+ global $app;
+
+ $has_error = false;
+ //* last chance to stop this, so check frequency limit!
+ if($_SESSION["s"]["user"]["typ"] != 'admin') {
+ // Get the limits of the client
+ $client_group_id = $_SESSION["s"]["user"]["default_group"];
+ $client = $app->db->queryOneRecord("SELECT limit_cron_frequency FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
+
+ if($client["limit_cron_frequency"] > 1) {
+ if($app->tform->cron_min_freq < $client["limit_cron_frequency"]) {
+ $app->error($app->tform->wordbook["limit_cron_frequency_txt"]);
+ $has_error = true;
+ }
+ }
+ }
+
+ if($has_error == true) {
+ parent::onError();
+ exit;
+ }
+ else parent::onUpdateSave($sql);
+ }
+
+ function onInsertSave($sql) {
+ global $app;
+
+ $has_error = false;
+ //* last chance to stop this, so check frequency limit!
+ if($_SESSION["s"]["user"]["typ"] != 'admin') {
+ // Get the limits of the client
+ $client_group_id = $_SESSION["s"]["user"]["default_group"];
+ $client = $app->db->queryOneRecord("SELECT limit_cron_frequency FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
+
+ if($client["limit_cron_frequency"] > 1) {
+ if($app->tform->cron_min_freq < $client["limit_cron_frequency"]) {
+ $app->error($app->tform->wordbook["limit_cron_frequency_txt"]);
+ $has_error = true;
+ }
+ }
+ }
+
+ if($has_error == true) {
+ parent::onError();
+ exit;
+ }
+ else parent::onInsertSave($sql);
+ }
+
+ function onAfterInsert() {
+ global $app, $conf;
+
+ $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($this->dataRecord["parent_domain_id"]));
+ $server_id = $web["server_id"];
+
+ // The cron shall be owned by the same group then the website
+ $sys_groupid = $web['sys_groupid'];
+
+ $sql = "UPDATE shell_user SET server_id = $server_id, sys_groupid = '$sys_groupid' WHERE id = ".$this->id;
+ $app->db->query($sql);
+ }
+
+ function onAfterUpdate() {
+ global $app, $conf;
+
+
+ }
+
+ function getClientName() {
+ global $app, $conf;
+
+ if($_SESSION["s"]["user"]["typ"] != 'admin') {
+ // Get the group-id of the user
+ $client_group_id = $_SESSION["s"]["user"]["default_group"];
+ } else {
+ // Get the group-id from the data itself
+ $web = $app->db->queryOneRecord("SELECT sys_groupid FROM web_domain WHERE domain_id = ".intval($this->dataRecord['parent_domain_id']));
+ $client_group_id = $web['sys_groupid'];
+ }
+ /* get the name of the client */
+ $tmp = $app->db->queryOneRecord("SELECT name FROM sys_group WHERE groupid = " . $client_group_id);
+ $clientName = $tmp['name'];
+ if ($clientName == "") $clientName = 'default';
+ $clientName = convertClientName($clientName);
+
+ return $clientName;
+
+ }
+
+}
+
+$page = new page_action;
+$page->onLoad();
+
+?>
\ No newline at end of file
diff --git a/interface/web/sites/cron_list.php b/interface/web/sites/cron_list.php
new file mode 100644
index 0000000..68e2316
--- /dev/null
+++ b/interface/web/sites/cron_list.php
@@ -0,0 +1,23 @@
+<?php
+require_once('../../lib/config.inc.php');
+require_once('../../lib/app.inc.php');
+
+/******************************************
+* Begin Form configuration
+******************************************/
+
+$list_def_file = "list/cron.list.php";
+
+/******************************************
+* End Form configuration
+******************************************/
+
+//* Check permissions for module
+$app->auth->check_module_permissions('sites');
+
+$app->uses('listform_actions');
+
+$app->listform_actions->onLoad();
+
+
+?>
\ No newline at end of file
diff --git a/interface/web/sites/form/cron.tform.php b/interface/web/sites/form/cron.tform.php
new file mode 100644
index 0000000..4f9f8dd
--- /dev/null
+++ b/interface/web/sites/form/cron.tform.php
@@ -0,0 +1,189 @@
+<?php
+
+/*
+ Form Definition
+
+ Tabledefinition
+
+ Datatypes:
+ - INTEGER (Forces the input to Int)
+ - DOUBLE
+ - CURRENCY (Formats the values to currency notation)
+ - VARCHAR (no format check, maxlength: 255)
+ - TEXT (no format check)
+ - DATE (Dateformat, automatic conversion to timestamps)
+
+ Formtype:
+ - TEXT (Textfield)
+ - TEXTAREA (Textarea)
+ - PASSWORD (Password textfield, input is not shown when edited)
+ - SELECT (Select option field)
+ - RADIO
+ - CHECKBOX
+ - CHECKBOXARRAY
+ - FILE
+
+ VALUE:
+ - Wert oder Array
+
+ Hint:
+ The ID field of the database table is not part of the datafield definition.
+ The ID field must be always auto incement (int or bigint).
+
+
+*/
+
+$form["title"] = "Cron Job";
+$form["description"] = "";
+$form["name"] = "cron";
+$form["action"] = "cron_edit.php";
+$form["db_table"] = "cron";
+$form["db_table_idx"] = "id";
+$form["db_history"] = "yes";
+$form["tab_default"] = "cron";
+$form["list_default"] = "cron_list.php";
+$form["auth"] = 'yes'; // yes / no
+
+$form["auth_preset"]["userid"] = 0; // 0 = id of the user, > 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"]['cron'] = array (
+ 'title' => "Cron Job",
+ 'width' => 100,
+ 'template' => "templates/cron_edit.htm",
+ 'fields' => array (
+ ##################################
+ # Begin Datatable fields
+ ##################################
+ 'server_id' => array (
+ 'datatype' => 'INTEGER',
+ 'formtype' => 'SELECT',
+ 'datasource' => array ( 'type' => 'SQL',
+ 'querystring' => 'SELECT server_id,server_name FROM server WHERE web_server = 1 AND {AUTHSQL} ORDER BY server_name',
+ 'keyfield'=> 'server_id',
+ 'valuefield'=> 'server_name'
+ ),
+ 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY',
+ 'errmsg'=> 'server_id_error_empty'),
+ ),
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'parent_domain_id' => array (
+ 'datatype' => 'INTEGER',
+ 'formtype' => 'SELECT',
+ 'default' => '',
+ 'datasource' => array ( 'type' => 'SQL',
+ 'querystring' => "SELECT domain_id,domain FROM web_domain WHERE type = 'vhost' AND {AUTHSQL} ORDER BY domain",
+ 'keyfield'=> 'domain_id',
+ 'valuefield'=> 'domain'
+ ),
+ 'value' => ''
+ ),
+ 'run_min' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'validators' => array ( 0 => array ( 'type' => 'CUSTOM',
+ 'class' => 'validate_cron',
+ 'function' => 'run_time_format',
+ 'errmsg'=> 'run_min_error_format'),
+ ),
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'run_hour' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'validators' => array ( 0 => array ( 'type' => 'CUSTOM',
+ 'class' => 'validate_cron',
+ 'function' => 'run_time_format',
+ 'errmsg'=> 'run_hour_error_format'),
+ ),
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'run_mday' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'validators' => array ( 0 => array ( 'type' => 'CUSTOM',
+ 'class' => 'validate_cron',
+ 'function' => 'run_time_format',
+ 'errmsg'=> 'run_mday_error_format'),
+ ),
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'run_month' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'validators' => array ( 0 => array ( 'type' => 'CUSTOM',
+ 'class' => 'validate_cron',
+ 'function' => 'run_time_format',
+ 'errmsg'=> 'run_month_error_format'),
+ ),
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'run_wday' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'validators' => array ( 0 => array ( 'type' => 'CUSTOM',
+ 'class' => 'validate_cron',
+ 'function' => 'run_time_format',
+ 'errmsg'=> 'run_wday_error_format'),
+ ),
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'command' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY',
+ 'errmsg'=> 'command_error_empty'),
+ 1 => array ( 'type' => 'CUSTOM',
+ 'class' => 'validate_cron',
+ 'function' => 'command_format',
+ 'errmsg'=> 'command_error_format'),
+ ),
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'type' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'SELECT',
+ 'default' => 'url',
+ 'valuelimit' => 'list:url,full,chrooted',
+ 'value' => array('url' => 'Url', 'full' => 'Full', 'chrooted' => 'Chrooted')
+ ),
+ 'active' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'CHECKBOX',
+ 'default' => 'y',
+ 'value' => array(0 => 'n',1 => 'y')
+ ),
+ ##################################
+ # ENDE Datatable fields
+ ##################################
+ )
+);
+
+
+
+?>
\ No newline at end of file
diff --git a/interface/web/sites/lib/lang/de_cron.lng b/interface/web/sites/lib/lang/de_cron.lng
new file mode 100644
index 0000000..c65bf38
--- /dev/null
+++ b/interface/web/sites/lib/lang/de_cron.lng
@@ -0,0 +1,21 @@
+<?php
+$wb['server_id_txt'] = 'Server';
+$wb['parent_domain_id_txt'] = 'Zugeordnete Website';
+$wb['active_txt'] = 'Aktiv';
+$wb['client_txt'] = 'Kunde';
+$wb['run_min_txt'] = 'Minuten';
+$wb['run_hour_txt'] = 'Stunden';
+$wb['run_mday_txt'] = 'Tage des Monats';
+$wb['run_month_txt'] = 'Monate';
+$wb['run_wday_txt'] = 'Tage der Woche';
+$wb['command_txt'] = 'Auszuführender Befehl (Befehle werden mit sh ausgeführt, urls mit wget)';
+$wb['limit_cron_txt'] = 'Die maximale Anzahl von erlaubten Cron Jobs ist bereits erreicht.';
+$wb['limit_cron_frequency_txt'] = 'Die Ausführungshäufigkeit übersteigt Ihr erlaubtes Limit.';
+$wb['run_min_error_format'] = 'Das Format für Minuten ist nicht korrekt.';
+$wb['run_hour_error_format'] = 'Das Format für Stunden ist nicht korrekt.';
+$wb['run_mday_error_format'] = 'Das Format für Tage des Monats ist nicht korrekt.';
+$wb['run_month_error_format'] = 'Das Format für Monate ist nicht korrekt.';
+$wb['run_wday_error_format'] = 'Das Format für Wochentage ist nicht korrekt.';
+$wb['command_error_format'] = 'Das Format für den Befehl ist nicht korrekt. Beachte, dass bei einem URL Aufruf nur http und https erlaubt ist.';
+$wb['unknown_fieldtype_error'] = 'Es wurde ein unbekanntes Feld verwendet.';
+?>
diff --git a/interface/web/sites/lib/lang/de_cron_list.lng b/interface/web/sites/lib/lang/de_cron_list.lng
new file mode 100644
index 0000000..4f20d8d
--- /dev/null
+++ b/interface/web/sites/lib/lang/de_cron_list.lng
@@ -0,0 +1,12 @@
+<?php
+$wb['list_head_txt'] = 'Cron Jobs';
+$wb['active_txt'] = 'Activ';
+$wb['server_id_txt'] = 'Server';
+$wb['run_min_txt'] = 'Minute';
+$wb["run_hour_txt"] = 'Stunde';
+$wb["run_mday_txt"] = 'Tag des Monats';
+$wb["run_month_txt"] = 'Monat';
+$wb["run_wday_txt"] = 'Tag der Woche';
+$wb['command_txt'] = 'Befehl';
+$wb['add_new_cron_txt'] = 'Neuen Cron Job anlegen';
+?>
diff --git a/interface/web/sites/lib/lang/en_cron.lng b/interface/web/sites/lib/lang/en_cron.lng
new file mode 100644
index 0000000..8cb7f08
--- /dev/null
+++ b/interface/web/sites/lib/lang/en_cron.lng
@@ -0,0 +1,21 @@
+<?php
+$wb["server_id_txt"] = 'Server';
+$wb['parent_domain_id_txt'] = 'Parent website';
+$wb['active_txt'] = 'Active';
+$wb['client_txt'] = 'Client';
+$wb['run_min_txt'] = 'Minutes';
+$wb['run_hour_txt'] = 'Hours';
+$wb['run_mday_txt'] = 'Days of month';
+$wb['run_month_txt'] = 'Months';
+$wb['run_wday_txt'] = 'Days of week';
+$wb['command_txt'] = 'Command to run (commands are executed via sh, urls via wget)';
+$wb['limit_cron_txt'] = 'The maximum number of allowed cron jobs was reached.';
+$wb['limit_cron_frequency_txt'] = 'The cron job frequency exceeds the allowed limit.';
+$wb['run_min_error_format'] = 'Invalid format for minutes.';
+$wb['run_hour_error_format'] = 'Invalid format for hours.';
+$wb['run_mday_error_format'] = 'Invalid format for days of month.';
+$wb['run_month_error_format'] = 'Invalid format for months.';
+$wb['run_wday_error_format'] = 'Invalid format for days of the week.';
+$wb['command_error_format'] = 'Invalid command format. Please note that in case of an url call only http/https is allowed.';
+$wb['unknown_fieldtype_error'] = 'An unknown field type has been used.';
+?>
\ No newline at end of file
diff --git a/interface/web/sites/lib/lang/en_cron_list.lng b/interface/web/sites/lib/lang/en_cron_list.lng
new file mode 100644
index 0000000..b5c8d15
--- /dev/null
+++ b/interface/web/sites/lib/lang/en_cron_list.lng
@@ -0,0 +1,12 @@
+<?php
+$wb["list_head_txt"] = 'Cron Jobs';
+$wb["active_txt"] = 'Active';
+$wb["server_id_txt"] = 'Server';
+$wb["run_min_txt"] = 'Minute';
+$wb["run_hour_txt"] = 'Hour';
+$wb["run_mday_txt"] = 'Day of month';
+$wb["run_month_txt"] = 'Month';
+$wb["run_wday_txt"] = 'Day of week';
+$wb["command_txt"] = 'Command';
+$wb["add_new_cron_txt"] = 'Add new Cron job';
+?>
\ 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 6a437e8..3207caf 100644
--- a/interface/web/sites/lib/module.conf.php
+++ b/interface/web/sites/lib/module.conf.php
@@ -77,6 +77,21 @@
'items' => $items);
+/*
+ Cron menu
+*/
+$items = array();
+
+$items[] = array( 'title' => "Cron Jobs",
+ 'target' => 'content',
+ 'link' => 'sites/cron_list.php');
+
+
+$module["nav"][] = array( 'title' => 'Cron',
+ 'open' => 1,
+ 'items' => $items);
+
+
//**** Statistics menu
$items = array();
diff --git a/interface/web/sites/list/cron.list.php b/interface/web/sites/list/cron.list.php
new file mode 100644
index 0000000..dfa2d4b
--- /dev/null
+++ b/interface/web/sites/list/cron.list.php
@@ -0,0 +1,152 @@
+<?php
+
+/*
+ Datatypes:
+ - INTEGER
+ - DOUBLE
+ - CURRENCY
+ - VARCHAR
+ - TEXT
+ - DATE
+*/
+
+
+
+// Name of the list
+$liste["name"] = "cron";
+
+// Database table
+$liste["table"] = "cron";
+
+// Index index field of the database table
+$liste["table_idx"] = "id";
+
+// Search Field Prefix
+$liste["search_prefix"] = "search_";
+
+// Records per page
+$liste["records_per_page"] = 15;
+
+// Script File of the list
+$liste["file"] = "cron_list.php";
+
+// Script file of the edit form
+$liste["edit_file"] = "cron_edit.php";
+
+// Script File of the delete script
+$liste["delete_file"] = "cron_del.php";
+
+// Paging Template
+$liste["paging_tpl"] = "templates/paging.tpl.htm";
+
+// Enable auth
+$liste["auth"] = "yes";
+
+
+/*****************************************************
+* Suchfelder
+*****************************************************/
+
+
+$liste["item"][] = array( 'field' => "active",
+ 'datatype' => "VARCHAR",
+ 'formtype' => "SELECT",
+ 'op' => "=",
+ 'prefix' => "",
+ 'suffix' => "",
+ 'width' => "",
+ 'value' => array('y' => "<div id=\"ir-Yes\" class=\"swap\"><span>Yes</span></div>",'n' => "<div class=\"swap\" id=\"ir-No\"><span>No</span></div>"));
+
+
+$liste["item"][] = array( 'field' => "server_id",
+ 'datatype' => "VARCHAR",
+ 'formtype' => "SELECT",
+ 'op' => "like",
+ 'prefix' => "%",
+ 'suffix' => "%",
+ 'datasource' => array ( 'type' => 'SQL',
+ 'querystring' => 'SELECT server_id,server_name FROM server WHERE {AUTHSQL} ORDER BY server_name',
+ 'keyfield'=> 'server_id',
+ 'valuefield'=> 'server_name'
+ ),
+ 'width' => "",
+ 'value' => "");
+
+$liste["item"][] = array( 'field' => "parent_domain_id",
+ 'datatype' => "VARCHAR",
+ 'formtype' => "SELECT",
+ 'op' => "like",
+ 'prefix' => "%",
+ 'suffix' => "%",
+ 'datasource' => array ( 'type' => 'SQL',
+ 'querystring' => "SELECT domain_id,domain FROM web_domain WHERE type = 'vhost' AND {AUTHSQL} ORDER BY domain",
+ 'keyfield'=> 'domain_id',
+ 'valuefield'=> 'domain'
+ ),
+ 'width' => "",
+ 'value' => "");
+
+$liste["item"][] = array( 'field' => "run_min",
+ 'datatype' => "VARCHAR",
+ 'formtype' => "TEXT",
+ 'op' => "=",
+ 'prefix' => "",
+ 'suffix' => "",
+ 'width' => "",
+ 'value' => "");
+
+$liste["item"][] = array( 'field' => "run_hour",
+ 'datatype' => "VARCHAR",
+ 'formtype' => "TEXT",
+ 'op' => "=",
+ 'prefix' => "",
+ 'suffix' => "",
+ 'width' => "",
+ 'value' => "");
+
+$liste["item"][] = array( 'field' => "run_mday",
+ 'datatype' => "VARCHAR",
+ 'formtype' => "TEXT",
+ 'op' => "=",
+ 'prefix' => "",
+ 'suffix' => "",
+ 'width' => "",
+ 'value' => "");
+
+$liste["item"][] = array( 'field' => "run_month",
+ 'datatype' => "VARCHAR",
+ 'formtype' => "TEXT",
+ 'op' => "=",
+ 'prefix' => "",
+ 'suffix' => "",
+ 'width' => "",
+ 'value' => "");
+
+$liste["item"][] = array( 'field' => "run_wday",
+ 'datatype' => "VARCHAR",
+ 'formtype' => "TEXT",
+ 'op' => "=",
+ 'prefix' => "",
+ 'suffix' => "",
+ 'width' => "",
+ 'value' => "");
+
+
+$liste["item"][] = array( 'field' => "command",
+ 'datatype' => "VARCHAR",
+ 'formtype' => "TEXT",
+ 'op' => "like",
+ 'prefix' => "%",
+ 'suffix' => "%",
+ 'width' => "",
+ 'value' => "");
+
+
+
+
+
+
+
+
+
+?>
\ No newline at end of file
diff --git a/interface/web/sites/templates/cron_edit.htm b/interface/web/sites/templates/cron_edit.htm
new file mode 100644
index 0000000..39f9bc6
--- /dev/null
+++ b/interface/web/sites/templates/cron_edit.htm
@@ -0,0 +1,68 @@
+<h2><tmpl_var name="list_head_txt"></h2>
+<p><tmpl_var name="list_desc_txt"></p>
+
+<div class="panel panel_cron">
+
+ <div class="pnl_formsarea">
+ <fieldset class="inlineLabels"><legend>Cron Job</legend>
+ <div class="ctrlHolder">
+ <tmpl_if name="edit_disabled">
+ <label for="parent_domain_id">{tmpl_var name='parent_domain_id_txt'}</label>
+ <select name="parent_domain_id" id="parent_domain_id" class="selectInput" disabled="disabled">
+ {tmpl_var name='parent_domain_id'}
+ </select>
+ <input type="hidden" name="parent_domain_id" value="{tmpl_var name='parent_domain_id_value'}" />
+ <tmpl_else>
+ <label for="parent_domain_id">{tmpl_var name='parent_domain_id_txt'}</label>
+ <select name="parent_domain_id" id="parent_domain_id" class="selectInput">
+ {tmpl_var name='parent_domain_id'}
+ </select>
+ </tmpl_if>
+ </div>
+ <div class="ctrlHolder">
+ <label for="run_min">{tmpl_var name='run_min_txt'}</label>
+ <input name="run_min" id="run_min" value="{tmpl_var name='run_min'}" size="10" maxlength="255" type="text" class="textInput" />
+ <p class="formHint">e.g. *, */3, 10-20</p>
+ </div>
+ <div class="ctrlHolder">
+ <label for="run_hour">{tmpl_var name='run_hour_txt'}</label>
+ <input name="run_hour" id="run_hour" value="{tmpl_var name='run_hour'}" size="10" maxlength="255" type="text" class="textInput" />
+ <p class="formHint">e.g. *, */2, 0, 10-12</p>
+ </div>
+ <div class="ctrlHolder">
+ <label for="run_mday">{tmpl_var name='run_mday_txt'}</label>
+ <input name="run_mday" id="run_mday" value="{tmpl_var name='run_mday'}" size="10" maxlength="255" type="text" class="textInput" />
+ <p class="formHint">e.g. *, */4, 1-5</p>
+ </div>
+ <div class="ctrlHolder">
+ <label for="run_month">{tmpl_var name='run_month_txt'}</label>
+ <input name="run_month" id="run_month" value="{tmpl_var name='run_month'}" size="10" maxlength="255" type="text" class="textInput" />
+ <p class="formHint">e.g. *, 1-6</p>
+ </div>
+ <div class="ctrlHolder">
+ <label for="run_wday">{tmpl_var name='run_wday_txt'}</label>
+ <input name="run_wday" id="run_wday" value="{tmpl_var name='run_wday'}" size="10" maxlength="255" type="text" class="textInput" />
+ <p class="formHint">e.g. *, 0, 1-5</p>
+ </div>
+ <div class="ctrlHolder">
+ <label for="command">{tmpl_var name='command_txt'}</label>
+ <input name="command" id="command" value="{tmpl_var name='command'}" size="30" maxlength="255" type="text" class="textInput" />
+ <p class="formHint">e.g. /var/www/clients/client1/myscript.sh or http://www.mydomain.com/path/script.php</p>
+ </div>
+ <div class="ctrlHolder">
+ <p class="label">{tmpl_var name='active_txt'}</p>
+ <div class="multiField">
+ {tmpl_var name='active'}
+ </div>
+ </div>
+ </fieldset>
+
+ <input type="hidden" name="id" value="{tmpl_var name='id'}">
+
+ <div class="buttonHolder buttons">
+ <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onClick="submitForm('pageForm','sites/cron_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button>
+ <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onClick="loadContent('sites/cron_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button>
+ </div>
+ </div>
+
+</div>
diff --git a/interface/web/sites/templates/cron_list.htm b/interface/web/sites/templates/cron_list.htm
new file mode 100644
index 0000000..e2e8ca9
--- /dev/null
+++ b/interface/web/sites/templates/cron_list.htm
@@ -0,0 +1,71 @@
+<h2><tmpl_var name="list_head_txt"></h2>
+<p><tmpl_var name="list_desc_txt"></p>
+
+<div class="panel panel_list_cron">
+
+ <div class="pnl_toolsarea">
+ <fieldset><legend>Tools</legend>
+ <div class="buttons">
+ <button class="iconstxt icoAdd" type="button" onClick="loadContent('sites/cron_edit.php');">
+ <span>{tmpl_var name="add_new_cron_txt"}</span>
+ </button>
+ </div>
+ </fieldset>
+ </div>
+
+ <div class="pnl_listarea">
+ <fieldset><legend><tmpl_var name="list_head_txt"></legend>
+ <table class="list">
+ <thead>
+ <tr>
+ <th class="tbl_col_active" scope="col"><tmpl_var name="active_txt"></th>
+ <th class="tbl_col_server_id" scope="col"><tmpl_var name="server_id_txt"></th>
+ <th class="tbl_col_run_min" scope="col"><tmpl_var name="run_min_txt"></th>
+ <th class="tbl_col_run_hour" scope="col"><tmpl_var name="run_hour_txt"></th>
+ <th class="tbl_col_run_mday" scope="col"><tmpl_var name="run_mday_txt"></th>
+ <th class="tbl_col_run_month" scope="col"><tmpl_var name="run_month_txt"></th>
+ <th class="tbl_col_run_wday" scope="col"><tmpl_var name="run_wday_txt"></th>
+ <th class="tbl_col_command" scope="col"><tmpl_var name="command_txt"></th>
+ <th class="tbl_col_buttons" scope="col"> </th>
+ </tr>
+ <tr>
+ <td class="tbl_col_active"><select name="search_active" onChange="submitForm('pageForm','sites/cron_list.php');">{tmpl_var name='search_active'}</select></td>
+ <td class="tbl_col_server_id"><select name="search_server_id" onChange="submitForm('pageForm','sites/cron_list.php');">{tmpl_var name='search_server_id'}</select></td>
+ <td class="tbl_col_run_min"><input type="text" name="search_run_min" size="3" value="{tmpl_var name='search_run_min'}" /></td>
+ <td class="tbl_col_run_hour"><input type="text" name="search_run_hour" size="3" value="{tmpl_var name='search_run_hour'}" /></td>
+ <td class="tbl_col_run_mday"><input type="text" name="search_run_mday" size="3" value="{tmpl_var name='search_run_mday'}" /></td>
+ <td class="tbl_col_run_month"><input type="text" name="search_run_month" size="3" value="{tmpl_var name='search_run_month'}" /></td>
+ <td class="tbl_col_run_wday"><input type="text" name="search_run_wday" size="3" value="{tmpl_var name='search_run_wday'}" /></td>
+ <td class="tbl_col_command"><input type="text" name="search_command" value="{tmpl_var name='search_command'}" /></td>
+ <td class="tbl_col_buttons"><div class="buttons"><button type="button" class="icons16 icoFilter" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" onClick="submitForm('pageForm','sites/cron_list.php');"><span>{tmpl_var name="filter_txt"}</span></button></div></td>
+ </tr>
+ </thead>
+ <tbody>
+ <tmpl_loop name="records">
+ <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
+ <td class="tbl_col_active"><a href="#" onClick="loadContent('sites/cron_edit.php?id={tmpl_var name='id'}');"><img src="themes/{tmpl_var name='theme'}/icons/{tmpl_var name='_active_'}" border="0" /></a></td>
+ <td class="tbl_col_server_id"><a href="#" onClick="loadContent('sites/cron_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="server_id"}</a></td>
+ <td class="tbl_col_run_min"><a href="#" onClick="loadContent('sites/cron_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="run_min"}</a></td>
+ <td class="tbl_col_run_hour"><a href="#" onClick="loadContent('sites/cron_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="run_hour"}</a></td>
+ <td class="tbl_col_run_mday"><a href="#" onClick="loadContent('sites/cron_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="run_mday"}</a></td>
+ <td class="tbl_col_run_month"><a href="#" onClick="loadContent('sites/cron_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="run_month"}</a></td>
+ <td class="tbl_col_run_wday"><a href="#" onClick="loadContent('sites/cron_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="run_wday"}</a></td>
+ <td class="tbl_col_commnd"><a href="#" onClick="loadContent('sites/cron_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="command"}</a></td>
+ <td class="tbl_col_buttons">
+ <div class="buttons icons16">
+ <a class="icons16 icoDelete" href="javascript: del_record('sites/cron_del.php?id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');"><span>{tmpl_var name='delete_txt'}</span></a>
+ </div>
+ </td>
+ </tr>
+ </tmpl_loop>
+ </tbody>
+ <tfoot>
+ <tr>
+ <td class="tbl_footer tbl_paging" colspan="9"><tmpl_var name="paging"></td>
+ </tr>
+ </tfoot>
+ </table>
+ </fieldset>
+ </div>
+
+</div>
diff --git a/interface/web/sites/web_domain_del.php b/interface/web/sites/web_domain_del.php
index 867d1f4..e5614cf 100644
--- a/interface/web/sites/web_domain_del.php
+++ b/interface/web/sites/web_domain_del.php
@@ -72,6 +72,12 @@
foreach($records as $rec) {
$app->db->datalogDelete('shell_user','shell_user_id',$rec['shell_user_id']);
}
+
+ // Delete all records that belog to this zone.
+ $records = $app->db->queryAllRecords("SELECT id FROM cron WHERE parent_domain_id = '".intval($this->id)."'");
+ foreach($records as $rec) {
+ $app->db->datalogDelete('cron','id',$rec['id']);
+ }
}
}
diff --git a/server/mods-available/cron_module.inc.php b/server/mods-available/cron_module.inc.php
new file mode 100644
index 0000000..778585c
--- /dev/null
+++ b/server/mods-available/cron_module.inc.php
@@ -0,0 +1,97 @@
+<?php
+
+/*
+Copyright (c) 2007, Till Brehm, projektfarm Gmbh
+Modified 2009, Marius Cramer, pixcept KG
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+class cron_module {
+
+ var $module_name = 'cron_module';
+ var $class_name = 'cron_module';
+ var $actions_available = array( 'cron_insert',
+ 'cron_update',
+ 'cron_delete');
+
+ //* This function is called during ispconfig installation to determine
+ // if a symlink shall be created for this plugin.
+ function onInstall() {
+ global $conf;
+
+ return true;
+
+ }
+
+ /*
+ This function is called when the module is loaded
+ */
+
+ function onLoad() {
+ global $app;
+
+ /*
+ Annonce the actions that where provided by this module, so plugins
+ can register on them.
+ */
+
+ $app->plugins->announceEvents($this->module_name,$this->actions_available);
+
+ /*
+ As we want to get notified of any changes on several database tables,
+ we register for them.
+
+ The following function registers the function "functionname"
+ to be executed when a record for the table "dbtable" is
+ processed in the sys_datalog. "classname" is the name of the
+ class that contains the function functionname.
+ */
+
+ $app->modules->registerTableHook('cron',$this->module_name,'process');
+
+ }
+
+ /*
+ This function is called when a change in one of the registered tables is detected.
+ The function then raises the events for the plugins.
+ */
+
+ function process($tablename,$action,$data) {
+ global $app;
+
+ switch ($tablename) {
+ case 'cron':
+ if($action == 'i') $app->plugins->raiseEvent('cron_insert',$data);
+ if($action == 'u') $app->plugins->raiseEvent('cron_update',$data);
+ if($action == 'd') $app->plugins->raiseEvent('cron_delete',$data);
+ break;
+ } // end switch
+ } // end function
+
+
+} // end class
+
+?>
\ No newline at end of file
diff --git a/server/plugins-available/cron_jailkit_plugin.inc.php b/server/plugins-available/cron_jailkit_plugin.inc.php
new file mode 100644
index 0000000..fc19db6
--- /dev/null
+++ b/server/plugins-available/cron_jailkit_plugin.inc.php
@@ -0,0 +1,272 @@
+<?php
+
+/*
+Copyright (c) 2007, Till Brehm, projektfarm Gmbh
+Modified 2009, Marius Cramer, pixcept KG
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+class cron_jailkit_plugin {
+
+ //* $plugin_name and $class_name have to be the same then the name of this class
+ var $plugin_name = 'cron_jailkit_plugin';
+ var $class_name = 'cron_jailkit_plugin';
+
+ //* This function is called during ispconfig installation to determine
+ // if a symlink shall be created for this plugin.
+ function onInstall() {
+ global $conf;
+
+ if($conf['services']['web'] == true) {
+ return true;
+ } else {
+ return false;
+ }
+
+ }
+
+
+ /*
+ This function is called when the plugin is loaded
+ */
+
+ function onLoad() {
+ global $app;
+
+ /*
+ Register for the events
+ */
+
+ $app->plugins->registerEvent('cron_insert', $this->plugin_name, 'insert');
+ $app->plugins->registerEvent('cron_update', $this->plugin_name, 'update');
+ $app->plugins->registerEvent('cron_delete', $this->plugin_name, 'delete');
+
+ }
+
+ //* This function is called, when a cron job is inserted in the database
+ function insert($event_name,$data) {
+ global $app, $conf;
+
+ if($data["new"]["parent_domain_id"] == '') {
+ $app->log("Parent domain not set",LOGLEVEL_WARN);
+ return 0;
+ }
+
+ //* get data from web
+ $parent_domain = $app->db->queryOneRecord("SELECT `domain_id`, `system_user`, `system_group`, `document_root`, `domain` FROM `web_domain` WHERE `domain_id` = ".intval($data["new"]["parent_domain_id"]));
+ if(!$parent_domain["domain_id"]) {
+ $app->log("Parent domain not found",LOGLEVEL_WARN);
+ return 0;
+ } elseif($parent_domain["system_user"] == 'root' or $parent_domain["system_group"] == 'root') {
+ $app->log("Websites (and Crons) can not be owned by the root user or group.",LOGLEVEL_WARN);
+ return 0;
+ }
+
+ $app->uses('system');
+
+ if($app->system->is_user($parent_domain['system_user'])) {
+
+ /**
+ * Setup Jailkit Chroot System If Enabled
+ */
+ if ($data['new']['type'] == "chrooted")
+ {
+ // load the server configuration options
+ $app->uses("getconf");
+ $this->data = $data;
+ $this->app = $app;
+ $this->jailkit_config = $app->getconf->get_server_config($conf["server_id"], 'jailkit');
+ $this->parent_domain = $parent_domain;
+
+ $this->_setup_jailkit_chroot();
+
+ //$command .= 'usermod -U '.escapeshellcmd($parent_domain['system_user']);
+ //exec($command);
+
+ $this->_add_jailkit_user();
+ }
+
+ $app->log("Jailkit Plugin (Cron) -> insert username:".$parent_domain['system_user'],LOGLEVEL_DEBUG);
+
+ } else {
+ $app->log("Jailkit Plugin (Cron) -> insert username:".$parent_domain['system_user']." skipped, the user does not exist.",LOGLEVEL_WARN);
+ }
+
+ }
+
+ //* This function is called, when a cron job is updated in the database
+ function update($event_name,$data) {
+ global $app, $conf;
+
+ if($data["new"]["parent_domain_id"] == '') {
+ $app->log("Parent domain not set",LOGLEVEL_WARN);
+ return 0;
+ }
+ //* get data from web
+ $parent_domain = $app->db->queryOneRecord("SELECT `domain_id`, `system_user`, `system_group`, `document_root`, `domain` FROM `web_domain` WHERE `domain_id` = ".intval($data["new"]["parent_domain_id"]));
+
+ if(!$parent_domain["domain_id"]) {
+ $app->log("Parent domain not found",LOGLEVEL_WARN);
+ return 0;
+ } elseif($parent_domain["system_user"] == 'root' or $parent_domain["system_group"] == 'root') {
+ $app->log("Websites (and Crons) can not be owned by the root user or group.",LOGLEVEL_WARN);
+ return 0;
+ }
+
+ $app->uses('system');
+
+ if($app->system->is_user($parent_domain['system_user'])) {
+
+ /**
+ * Setup Jailkit Chroot System If Enabled
+ */
+ if ($data['new']['type'] == "chrooted")
+ {
+ $app->log("Jailkit Plugin (Cron) -> setting up jail", LOGLEVEL_DEBUG);
+ // load the server configuration options
+ $app->uses("getconf");
+ $this->data = $data;
+ $this->app = $app;
+ $this->jailkit_config = $app->getconf->get_server_config($conf["server_id"], 'jailkit');
+ $this->parent_domain = $parent_domain;
+
+ $this->_setup_jailkit_chroot();
+ $this->_add_jailkit_user();
+ }
+
+ $app->log("Jailkit Plugin (Cron) -> update username:".$parent_domain['system_user'],LOGLEVEL_DEBUG);
+
+ } else {
+ $app->log("Jailkit Plugin (Cron) -> update username:".$parent_domain['system_user']." skipped, the user does not exist.",LOGLEVEL_WARN);
+ }
+
+ }
+
+ //* This function is called, when a cron job is deleted in the database
+ function delete($event_name,$data) {
+ global $app, $conf;
+
+ //* nothing to do here!
+
+ }
+
+ function _setup_jailkit_chroot()
+ {
+ //check if the chroot environment is created yet if not create it with a list of program sections from the config
+ if (!is_dir($this->parent_domain['document_root'].'/etc/jailkit'))
+ {
+ $command = '/usr/local/ispconfig/server/scripts/create_jailkit_chroot.sh';
+ $command .= ' '.escapeshellcmd($this->parent_domain['document_root']);
+ $command .= ' \''.$this->jailkit_config['jailkit_chroot_app_sections'].'\'';
+ exec($command);
+
+ $this->app->log("Added jailkit chroot with command: ".$command,LOGLEVEL_DEBUG);
+
+ //$this->_add_jailkit_programs(); // done later on
+
+ $this->app->load('tpl');
+
+ $tpl = new tpl();
+ $tpl->newTemplate("bash.bashrc.master");
+
+ $tpl->setVar('jailkit_chroot',true);
+ $tpl->setVar('domain',$this->parent_domain['domain']);
+ $tpl->setVar('home_dir',$this->_get_home_dir(""));
+
+ $bashrc = escapeshellcmd($this->parent_domain['document_root']).'/etc/bash.bashrc';
+ if(@is_file($bashrc)) exec('rm '.$bashrc);
+
+ file_put_contents($bashrc,$tpl->grab());
+ unset($tpl);
+
+ $this->app->log("Added bashrc scrpt : ".$bashrc,LOGLEVEL_DEBUG);
+
+ $tpl = new tpl();
+ $tpl->newTemplate("motd.master");
+
+ $tpl->setVar('domain',$this->parent_domain['domain']);
+
+ $motd = escapeshellcmd($this->parent_domain['document_root']).'/var/run/motd';
+ if(@is_file($motd)) exec('rm '.$motd);
+
+ file_put_contents($motd,$tpl->grab());
+
+ }
+ $this->_add_jailkit_programs();
+ }
+
+ function _add_jailkit_programs()
+ {
+ //copy over further programs and its libraries
+ $command = '/usr/local/ispconfig/server/scripts/create_jailkit_programs.sh';
+ $command .= ' '.escapeshellcmd($this->parent_domain['document_root']);
+ $command .= ' \''.$this->jailkit_config['jailkit_chroot_app_programs'].'\'';
+ exec($command);
+
+ $this->app->log("Added programs to jailkit chroot with command: ".$command,LOGLEVEL_DEBUG);
+
+ $command = '/usr/local/ispconfig/server/scripts/create_jailkit_programs.sh';
+ $command .= ' '.escapeshellcmd($this->parent_domain['document_root']);
+ $command .= ' \''.$this->jailkit_config['jailkit_chroot_cron_programs'].'\'';
+ exec($command);
+
+ $this->app->log("Added cron programs to jailkit chroot with command: ".$command,LOGLEVEL_DEBUG);
+ }
+
+ function _add_jailkit_user()
+ {
+ //add the user to the chroot
+ $jailkit_chroot_userhome = $this->_get_home_dir($this->parent_domain['system_user']);
+
+ if(!is_dir($this->parent_domain['document_root'].'/etc')) mkdir($this->parent_domain['document_root'].'/etc');
+ if(!is_file($this->parent_domain['document_root'].'/etc/passwd')) exec('touch '.$this->parent_domain['document_root'].'/etc/passwd');
+
+ // IMPORTANT!
+ // ALWAYS create the user. Even if the user was created before
+ // if we check if the user exists, then a update (no shell -> jailkit) will not work
+ // and the user has FULL ACCESS to the root of the server!
+ $command = '/usr/local/ispconfig/server/scripts/create_jailkit_user.sh';
+ $command .= ' '.escapeshellcmd($this->parent_domain['system_user']);
+ $command .= ' '.escapeshellcmd($this->parent_domain['document_root']);
+ $command .= ' '.$jailkit_chroot_userhome;
+ $command .= ' '.escapeshellcmd("/bin/bash");
+ exec($command);
+
+ $this->app->log("Added jailkit user to chroot with command: ".$command,LOGLEVEL_DEBUG);
+
+ exec("mkdir -p ".escapeshellcmd($this->parent_domain['document_root'].$jailkit_chroot_userhome));
+ }
+
+ function _get_home_dir($username)
+ {
+ return str_replace("[username]",escapeshellcmd($username),$this->jailkit_config["jailkit_chroot_home"]);
+ }
+
+
+
+} // end class
+
+?>
\ No newline at end of file
diff --git a/server/plugins-available/cron_plugin.inc.php b/server/plugins-available/cron_plugin.inc.php
new file mode 100644
index 0000000..d923d1b
--- /dev/null
+++ b/server/plugins-available/cron_plugin.inc.php
@@ -0,0 +1,212 @@
+<?php
+
+/*
+Copyright (c) 2007 - 2009, Till Brehm, projektfarm Gmbh
+Modified 2009, Marius Cramer, pixcept KG
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+class cron_plugin {
+
+ var $plugin_name = 'cron_plugin';
+ var $class_name = 'cron_plugin';
+
+ // private variables
+ var $action = '';
+
+ //* This function is called during ispconfig installation to determine
+ // if a symlink shall be created for this plugin.
+ function onInstall() {
+ global $conf;
+
+ if($conf['services']['web'] == true) {
+ return true;
+ } else {
+ return false;
+ }
+
+ }
+
+
+ /*
+ This function is called when the plugin is loaded
+ */
+
+ function onLoad() {
+ global $app;
+
+ /*
+ Register for the events
+ */
+
+ $app->plugins->registerEvent('cron_insert',$this->plugin_name,'insert');
+ $app->plugins->registerEvent('cron_update',$this->plugin_name,'update');
+ $app->plugins->registerEvent('cron_delete',$this->plugin_name,'delete');
+
+ }
+
+ function insert($event_name,$data) {
+ global $app, $conf;
+
+ $this->action = 'insert';
+ // just run the update function
+ $this->update($event_name,$data);
+
+ }
+
+
+ function update($event_name,$data) {
+ global $app, $conf;
+
+ if($this->action != 'insert') $this->action = 'update';
+
+ // load the server configuration options
+ $app->uses("getconf");
+
+ if($data["new"]["parent_domain_id"] == '') {
+ $app->log("Parent domain not set",LOGLEVEL_WARN);
+ return 0;
+ }
+
+ //* get data from web
+ $parent_domain = $app->db->queryOneRecord("SELECT `domain_id`, `system_user`, `system_group`, `document_root`, `hd_quota` FROM `web_domain` WHERE `domain_id` = ".intval($data["new"]["parent_domain_id"]));
+ if(!$parent_domain["domain_id"]) {
+ $app->log("Parent domain not found",LOGLEVEL_WARN);
+ return 0;
+ } elseif($parent_domain["system_user"] == 'root' or $parent_domain["system_group"] == 'root') {
+ $app->log("Websites (and Crons) can not be owned by the root user or group.",LOGLEVEL_WARN);
+ return 0;
+ }
+
+ // Get the client ID
+ $client = $app->dbmaster->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ".intval($data["new"]["sys_groupid"]));
+ $client_id = intval($client["client_id"]);
+ unset($client);
+
+ // Create group and user, if not exist
+ $app->uses("system");
+
+ $groupname = escapeshellcmd($parent_domain["system_group"]);
+ if($parent_domain["system_group"] != '' && !$app->system->is_group($parent_domain["system_group"])) {
+ exec("groupadd $groupname");
+ $app->log("Adding the group: $groupname",LOGLEVEL_DEBUG);
+ }
+
+ $username = escapeshellcmd($parent_domain["system_user"]);
+ if($parent_domain["system_user"] != '' && !$app->system->is_user($parent_domain["system_user"])) {
+ exec("useradd -d ".escapeshellcmd($parent_domain["document_root"])." -g $groupname $username -s /bin/false");
+ $app->log("Adding the user: $username",LOGLEVEL_DEBUG);
+ }
+
+ // Set the quota for the user
+ if($username != '' && $app->system->is_user($username)) {
+ if($parent_domain["hd_quota"] > 0){
+ $blocks_soft = $parent_domain["hd_quota"] * 1024;
+ $blocks_hard = $blocks_soft + 1024;
+ } else {
+ $blocks_soft = $blocks_hard = 0;
+ }
+ exec("setquota -u $username $blocks_soft $blocks_hard 0 0 -a &> /dev/null");
+ exec("setquota -T -u $username 604800 604800 -a &> /dev/null");
+ }
+
+ // make temp direcory writable for the apache user and the website user
+ exec("chmod 777 ".escapeshellcmd($parent_domain["document_root"]."/tmp"));
+
+ /** TODO READ CRON MASTER **/
+
+ $this->parent_domain = $parent_domain;
+ $this->_write_crontab();
+
+
+ }
+
+ function delete($event_name,$data) {
+ global $app, $conf;
+
+ //* get data from web
+ $parent_domain = $app->db->queryOneRecord("SELECT `domain_id`, `system_user`, `system_group`, `document_root`, `hd_quota` FROM `web_domain` WHERE `domain_id` = ".intval($data["old"]["parent_domain_id"]));
+ if(!$parent_domain["domain_id"]) {
+ $app->log("Parent domain not found",LOGLEVEL_WARN);
+ return 0;
+ }
+
+ // Get the client ID
+ $client = $app->dbmaster->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ".intval($data["old"]["sys_groupid"]));
+ $client_id = intval($client["client_id"]);
+ unset($client);
+
+ /** TODO remove deleted record **/
+ $this->parent_domain = $parent_domain;
+ $this->_write_crontab();
+ }
+
+ function _write_crontab() {
+ global $app, $conf;
+
+ //* load the server configuration options
+ $app->uses("getconf");
+
+ $cron_config = $app->getconf->get_server_config($conf["server_id"], 'cron');
+
+ //* try to find customer's mail address
+
+ $cron_content = "MAILTO=''\n\n";
+
+ //* read all active cron jobs from database and write them to file
+ $cron_jobs = $app->db->queryAllRecords("SELECT `run_min`, `run_hour`, `run_mday`, `run_month`, `run_wday`, `command`, `type` FROM `cron` WHERE `parent_domain_id` = ".intval($this->parent_domain["domain_id"]) . " AND `active` = 'y'");
+ if($cron_jobs && count($cron_jobs) > 0) {
+ foreach($cron_jobs as $job) {
+ $command = "{$job['run_min']}\t{$job['run_hour']}\t{$job['run_mday']}\t{$job['run_month']}\t{$job['run_wday']}";
+ $command .= "\t{$this->parent_domain['system_user']}"; //* running as user
+ if($job['type'] == 'url') {
+ $command .= "\t{$cron_config['wget']} -q -O /dev/null " . escapeshellarg($job['command']) . " >/dev/null 2>&1";
+ } else {
+ if($job['type'] == 'chrooted') {
+ if(substr($job['command'], 0, strlen($this->parent_domain['document_root'])) == $this->parent_domain['document_root']) {
+ //* delete the unneeded path part
+ $job['command'] = substr($job['command'], strlen($this->parent_domain['document_root']));
+ }
+ }
+
+ $command .= "\t";
+ if(substr($job['command'], 0, 1) != "/") $command .= $this->parent_domain['document_root'];
+ $command .= $job['command'];
+ }
+ $cron_content .= $command . "\n";
+ }
+ }
+
+ $cron_file = escapeshellcmd($cron_config["crontab_dir"].'/ispc_'.$this->parent_domain["system_user"]);
+ file_put_contents($cron_file, $cron_content);
+
+ $app->log("Wrote Cron file $cron_file with content:\n$cron_content",LOGLEVEL_DEBUG);
+ return 0;
+ }
+
+} // end class
+
+?>
\ No newline at end of file
--
Gitblit v1.9.1