Marius Cramer
2014-08-13 31230cb7cda673db7a96fb14d93dfaf9262c74cf
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;
99         } elseif($parent_domain["system_user"] == 'root' or $parent_domain["system_group"] == 'root') {
100             $app->log("Websites (and Crons) cannot be owned by the root user or group.", LOGLEVEL_WARN);
0b0dc9 101             return 0;
M 102         }
7fe908 103
0b0dc9 104         // Get the client ID
M 105         $client = $app->dbmaster->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ".intval($data["new"]["sys_groupid"]));
106         $client_id = intval($client["client_id"]);
107         unset($client);
7fe908 108
0b0dc9 109         // Create group and user, if not exist
M 110         $app->uses("system");
7fe908 111
0b0dc9 112         $groupname = escapeshellcmd($parent_domain["system_group"]);
M 113         if($parent_domain["system_group"] != '' && !$app->system->is_group($parent_domain["system_group"])) {
114             exec("groupadd $groupname");
7fe908 115             $app->log("Adding the group: $groupname", LOGLEVEL_DEBUG);
0b0dc9 116         }
7fe908 117
0b0dc9 118         $username = escapeshellcmd($parent_domain["system_user"]);
M 119         if($parent_domain["system_user"] != '' && !$app->system->is_user($parent_domain["system_user"])) {
120             exec("useradd -d ".escapeshellcmd($parent_domain["document_root"])." -g $groupname $username -s /bin/false");
7fe908 121             $app->log("Adding the user: $username", LOGLEVEL_DEBUG);
0b0dc9 122         }
7fe908 123
0b0dc9 124         // Set the quota for the user
M 125         if($username != '' && $app->system->is_user($username)) {
126             if($parent_domain["hd_quota"] > 0){
7fe908 127                 $blocks_soft = $parent_domain["hd_quota"] * 1024;
MC 128                 $blocks_hard = $blocks_soft + 1024;
129             } else {
130                 $blocks_soft = $blocks_hard = 0;
131             }
0b0dc9 132             exec("setquota -u $username $blocks_soft $blocks_hard 0 0 -a &> /dev/null");
M 133             exec("setquota -T -u $username 604800 604800 -a &> /dev/null");
134         }
7fe908 135
4b88c2 136         //TODO : change this when distribution information has been integrated into server record
7fe908 137         //* Gentoo requires a user to be part of the crontab group.
MC 138         if (file_exists('/etc/gentoo-release')) {
139             if (strpos($app->system->get_user_groups($username), 'crontab') === false) {
140                 $app->system->add_user_to_group('crontab', $username);
141             }
142         }
143
4a6aed 144         // make temp directory writable for the apache and website users
4bd960 145         $app->system->chmod(escapeshellcmd($parent_domain["document_root"].'/tmp'), 0777);
7fe908 146
MC 147         /** TODO READ CRON MASTER **/
148
149
150         $this->parent_domain = $parent_domain;
0b0dc9 151         $this->_write_crontab();
7fe908 152
da1a7c 153         $this->action = '';
7fe908 154
0b0dc9 155     }
7fe908 156
MC 157     function delete($event_name, $data) {
0b0dc9 158         global $app, $conf;
7fe908 159
MC 160         //* get data from web
161         $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"]));
162         if(!$parent_domain["domain_id"]) {
163             $app->log("Parent domain not found", LOGLEVEL_WARN);
164             return 0;
165         }
166
167         // Get the client ID
168         $client = $app->dbmaster->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ".intval($data["old"]["sys_groupid"]));
169         $client_id = intval($client["client_id"]);
170         unset($client);
171
172         $this->parent_domain = $parent_domain;
173         $this->_write_crontab();
0b0dc9 174     }
7fe908 175
MC 176     function _write_crontab() {
177         global $app, $conf;
178
179         //* load the server configuration options
180         $app->uses("getconf");
181
182         $cron_config = $app->getconf->get_server_config($conf["server_id"], 'cron');
183
184         //* try to find customer's mail address
185
186         /** TODO: add possibility for client to choose mail notification! **/
187         $cron_content = "MAILTO=''\n";
b67344 188         $cron_content .= "SHELL='/bin/sh'\n\n";
7fe908 189         $chr_cron_content = "MAILTO=''\n";
MC 190         $chr_cron_content .= "SHELL='/usr/sbin/jk_chrootsh'\n\n";
191
192         $cmd_count = 0;
193         $chr_cmd_count = 0;
194
195         //* read all active cron jobs from database and write them to file
196         $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'");
197         if($cron_jobs && count($cron_jobs) > 0) {
198             foreach($cron_jobs as $job) {
d3687a 199                 if($job['run_month'] == '@reboot') {
T 200                     $command = "@reboot";
201                 } else {
13bfc7 202                     $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 203                 }
d3687a 204                 $command .= "\t{$this->parent_domain['system_user']}"; //* running as user
7fe908 205                 if($job['type'] == 'url') {
MC 206                     $command .= "\t{$cron_config['wget']} -q -t 1 -T 7200 -O /dev/null " . escapeshellarg($job['command']) . " >/dev/null 2>&1";
207                 } else {
208                     if($job['type'] == 'chrooted') {
209                         if(substr($job['command'], 0, strlen($this->parent_domain['document_root'])) == $this->parent_domain['document_root']) {
210                             //* delete the unneeded path part
211                             $job['command'] = substr($job['command'], strlen($this->parent_domain['document_root']));
212                         }
213                     }
214
215                     $command .= "\t";
558b54 216                     //if($job['type'] != 'chrooted' && substr($job['command'], 0, 1) != "/") $command .= $this->parent_domain['document_root'].'/';
7fe908 217                     $command .= $job['command'];
MC 218                 }
219
220                 if($job['type'] == 'chrooted') {
221                     $chr_cron_content .= $command . " #{$job['domain']}\n";
222                     $chr_cmd_count++;
223                 } else {
224                     $cron_content .= $command . " #{$job['domain']}\n";
225                     $cmd_count++;
226                 }
227             }
228         }
229
230         $cron_file = escapeshellcmd($cron_config["crontab_dir"].'/ispc_'.$this->parent_domain["system_user"]);
231         //TODO : change this when distribution information has been integrated into server record
232         //* Gentoo vixie-cron requires files to end with .cron in the cron.d directory
233         if (file_exists('/etc/gentoo-release')) {
234             $cron_file .= '.cron';
235         }
236
237         if($cmd_count > 0) {
238             $app->system->file_put_contents($cron_file, $cron_content);
239             $app->log("Wrote Cron file $cron_file with content:\n$cron_content", LOGLEVEL_DEBUG);
240         } else {
241             $app->system->unlink($cron_file);
242             $app->log("Deleted Cron file $cron_file", LOGLEVEL_DEBUG);
243         }
244
245         $cron_file = escapeshellcmd($cron_config["crontab_dir"].'/ispc_chrooted_'.$this->parent_domain["system_user"]);
246         if($chr_cmd_count > 0) {
247             $app->system->file_put_contents($cron_file, $chr_cron_content);
248             $app->log("Wrote Cron file $cron_file with content:\n$chr_cron_content", LOGLEVEL_DEBUG);
249         } else {
250             $app->system->unlink($cron_file);
251             $app->log("Deleted Cron file $cron_file", LOGLEVEL_DEBUG);
252         }
253
254         return 0;
255     }
0b0dc9 256
M 257 } // end class
258
4a6aed 259 ?>