Marius Cramer
2014-08-13 42539643c396f9d8865dcf9a51b13dc869709d16
commit | author | age
0b0dc9 1 <?php
M 2
3 /*
4 Copyright (c) 2007 - 2009, Till Brehm, projektfarm Gmbh
5 Modified 2009, Marius Cramer, pixcept KG
6 All rights reserved.
7
8 Redistribution and use in source and binary forms, with or without modification,
9 are permitted provided that the following conditions are met:
10
11     * Redistributions of source code must retain the above copyright notice,
12       this list of conditions and the following disclaimer.
13     * Redistributions in binary form must reproduce the above copyright notice,
14       this list of conditions and the following disclaimer in the documentation
15       and/or other materials provided with the distribution.
16     * Neither the name of ISPConfig nor the names of its contributors
17       may be used to endorse or promote products derived from this software without
18       specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
27 OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 class cron_plugin {
7fe908 33
0b0dc9 34     var $plugin_name = 'cron_plugin';
M 35     var $class_name = 'cron_plugin';
7fe908 36
0b0dc9 37     // private variables
M 38     var $action = '';
7fe908 39
0b0dc9 40     //* This function is called during ispconfig installation to determine
M 41     //  if a symlink shall be created for this plugin.
42     function onInstall() {
43         global $conf;
7fe908 44
0b0dc9 45         if($conf['services']['web'] == true) {
M 46             return true;
47         } else {
48             return false;
49         }
7fe908 50
0b0dc9 51     }
7fe908 52
MC 53
0b0dc9 54     /*
M 55          This function is called when the plugin is loaded
56     */
7fe908 57
0b0dc9 58     function onLoad() {
M 59         global $app;
7fe908 60
0b0dc9 61         /*
M 62         Register for the events
63         */
7fe908 64
MC 65         $app->plugins->registerEvent('cron_insert', $this->plugin_name, 'insert');
66         $app->plugins->registerEvent('cron_update', $this->plugin_name, 'update');
67         $app->plugins->registerEvent('cron_delete', $this->plugin_name, 'delete');
68
0b0dc9 69     }
7fe908 70
MC 71     function insert($event_name, $data) {
0b0dc9 72         global $app, $conf;
7fe908 73
0b0dc9 74         $this->action = 'insert';
M 75         // just run the update function
7fe908 76         $this->update($event_name, $data);
MC 77
0b0dc9 78     }
7fe908 79
MC 80
81     function update($event_name, $data) {
0b0dc9 82         global $app, $conf;
7fe908 83
0b0dc9 84         if($this->action != 'insert') $this->action = 'update';
7fe908 85
0b0dc9 86         // load the server configuration options
M 87         $app->uses("getconf");
7fe908 88
0b0dc9 89         if($data["new"]["parent_domain_id"] == '') {
7fe908 90             $app->log("Parent domain not set", LOGLEVEL_WARN);
0b0dc9 91             return 0;
M 92         }
7fe908 93
MC 94         //* get data from web
95         $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"]));
96         if(!$parent_domain["domain_id"]) {
97             $app->log("Parent domain not found", LOGLEVEL_WARN);
98             return 0;
0b0dc9 99         }
7fe908 100
64ea56 101         if(!$app->system->is_allowed_user($parent_domain['system_user'], true, true)
MC 102             || !$app->system->is_allowed_group($parent_domain['system_group'], true, true)) {
103             $app->log("Websites (and Crons) cannot be owned by the root user or group.", LOGLEVEL_WARN);
104             return false;
105         }
106         
0b0dc9 107         // Get the client ID
M 108         $client = $app->dbmaster->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ".intval($data["new"]["sys_groupid"]));
109         $client_id = intval($client["client_id"]);
110         unset($client);
7fe908 111
0b0dc9 112         // Create group and user, if not exist
M 113         $app->uses("system");
7fe908 114
0b0dc9 115         $groupname = escapeshellcmd($parent_domain["system_group"]);
M 116         if($parent_domain["system_group"] != '' && !$app->system->is_group($parent_domain["system_group"])) {
117             exec("groupadd $groupname");
7fe908 118             $app->log("Adding the group: $groupname", LOGLEVEL_DEBUG);
0b0dc9 119         }
7fe908 120
0b0dc9 121         $username = escapeshellcmd($parent_domain["system_user"]);
M 122         if($parent_domain["system_user"] != '' && !$app->system->is_user($parent_domain["system_user"])) {
123             exec("useradd -d ".escapeshellcmd($parent_domain["document_root"])." -g $groupname $username -s /bin/false");
7fe908 124             $app->log("Adding the user: $username", LOGLEVEL_DEBUG);
0b0dc9 125         }
7fe908 126
0b0dc9 127         // Set the quota for the user
M 128         if($username != '' && $app->system->is_user($username)) {
129             if($parent_domain["hd_quota"] > 0){
7fe908 130                 $blocks_soft = $parent_domain["hd_quota"] * 1024;
MC 131                 $blocks_hard = $blocks_soft + 1024;
132             } else {
133                 $blocks_soft = $blocks_hard = 0;
134             }
0b0dc9 135             exec("setquota -u $username $blocks_soft $blocks_hard 0 0 -a &> /dev/null");
M 136             exec("setquota -T -u $username 604800 604800 -a &> /dev/null");
137         }
7fe908 138
4b88c2 139         //TODO : change this when distribution information has been integrated into server record
7fe908 140         //* Gentoo requires a user to be part of the crontab group.
MC 141         if (file_exists('/etc/gentoo-release')) {
142             if (strpos($app->system->get_user_groups($username), 'crontab') === false) {
143                 $app->system->add_user_to_group('crontab', $username);
144             }
145         }
146
4a6aed 147         // make temp directory writable for the apache and website users
4bd960 148         $app->system->chmod(escapeshellcmd($parent_domain["document_root"].'/tmp'), 0777);
7fe908 149
MC 150         /** TODO READ CRON MASTER **/
151
152
153         $this->parent_domain = $parent_domain;
0b0dc9 154         $this->_write_crontab();
7fe908 155
da1a7c 156         $this->action = '';
7fe908 157
0b0dc9 158     }
7fe908 159
MC 160     function delete($event_name, $data) {
0b0dc9 161         global $app, $conf;
7fe908 162
MC 163         //* get data from web
164         $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"]));
165         if(!$parent_domain["domain_id"]) {
166             $app->log("Parent domain not found", LOGLEVEL_WARN);
167             return 0;
168         }
169
170         // Get the client ID
171         $client = $app->dbmaster->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ".intval($data["old"]["sys_groupid"]));
172         $client_id = intval($client["client_id"]);
173         unset($client);
174
175         $this->parent_domain = $parent_domain;
176         $this->_write_crontab();
0b0dc9 177     }
7fe908 178
MC 179     function _write_crontab() {
180         global $app, $conf;
181
182         //* load the server configuration options
183         $app->uses("getconf");
184
185         $cron_config = $app->getconf->get_server_config($conf["server_id"], 'cron');
186
187         //* try to find customer's mail address
188
189         /** TODO: add possibility for client to choose mail notification! **/
190         $cron_content = "MAILTO=''\n";
b67344 191         $cron_content .= "SHELL='/bin/sh'\n\n";
7fe908 192         $chr_cron_content = "MAILTO=''\n";
MC 193         $chr_cron_content .= "SHELL='/usr/sbin/jk_chrootsh'\n\n";
194
195         $cmd_count = 0;
196         $chr_cmd_count = 0;
197
198         //* read all active cron jobs from database and write them to file
199         $cron_jobs = $app->db->queryAllRecords("SELECT c.`run_min`, c.`run_hour`, c.`run_mday`, c.`run_month`, c.`run_wday`, c.`command`, c.`type`, `web_domain`.`domain` as `domain` FROM `cron` as c INNER JOIN `web_domain` ON `web_domain`.`domain_id` = c.`parent_domain_id` WHERE c.`parent_domain_id` = ".intval($this->parent_domain["domain_id"]) . " AND c.`active` = 'y'");
200         if($cron_jobs && count($cron_jobs) > 0) {
201             foreach($cron_jobs as $job) {
d3687a 202                 if($job['run_month'] == '@reboot') {
T 203                     $command = "@reboot";
204                 } else {
13bfc7 205                     $command = str_replace(" ", "", $job['run_min']) . "\t" . str_replace(" ", "", $job['run_hour']) . "\t" . str_replace(" ", "", $job['run_mday']) . "\t" . str_replace(" ", "", $job['run_month']) . "\t" . str_replace(" ", "", $job['run_wday']);
7fe908 206                 }
d3687a 207                 $command .= "\t{$this->parent_domain['system_user']}"; //* running as user
7fe908 208                 if($job['type'] == 'url') {
MC 209                     $command .= "\t{$cron_config['wget']} -q -t 1 -T 7200 -O /dev/null " . escapeshellarg($job['command']) . " >/dev/null 2>&1";
210                 } else {
211                     if($job['type'] == 'chrooted') {
212                         if(substr($job['command'], 0, strlen($this->parent_domain['document_root'])) == $this->parent_domain['document_root']) {
213                             //* delete the unneeded path part
214                             $job['command'] = substr($job['command'], strlen($this->parent_domain['document_root']));
215                         }
216                     }
217
218                     $command .= "\t";
558b54 219                     //if($job['type'] != 'chrooted' && substr($job['command'], 0, 1) != "/") $command .= $this->parent_domain['document_root'].'/';
7fe908 220                     $command .= $job['command'];
MC 221                 }
222
223                 if($job['type'] == 'chrooted') {
224                     $chr_cron_content .= $command . " #{$job['domain']}\n";
225                     $chr_cmd_count++;
226                 } else {
227                     $cron_content .= $command . " #{$job['domain']}\n";
228                     $cmd_count++;
229                 }
230             }
231         }
232
233         $cron_file = escapeshellcmd($cron_config["crontab_dir"].'/ispc_'.$this->parent_domain["system_user"]);
234         //TODO : change this when distribution information has been integrated into server record
235         //* Gentoo vixie-cron requires files to end with .cron in the cron.d directory
236         if (file_exists('/etc/gentoo-release')) {
237             $cron_file .= '.cron';
238         }
239
240         if($cmd_count > 0) {
241             $app->system->file_put_contents($cron_file, $cron_content);
242             $app->log("Wrote Cron file $cron_file with content:\n$cron_content", LOGLEVEL_DEBUG);
243         } else {
244             $app->system->unlink($cron_file);
245             $app->log("Deleted Cron file $cron_file", LOGLEVEL_DEBUG);
246         }
247
248         $cron_file = escapeshellcmd($cron_config["crontab_dir"].'/ispc_chrooted_'.$this->parent_domain["system_user"]);
249         if($chr_cmd_count > 0) {
250             $app->system->file_put_contents($cron_file, $chr_cron_content);
251             $app->log("Wrote Cron file $cron_file with content:\n$chr_cron_content", LOGLEVEL_DEBUG);
252         } else {
253             $app->system->unlink($cron_file);
254             $app->log("Deleted Cron file $cron_file", LOGLEVEL_DEBUG);
255         }
256
257         return 0;
258     }
0b0dc9 259
M 260 } // end class
261
4a6aed 262 ?>