tbrehm
2013-02-22 526b997c9891a796b152cdbab8e329b356b1f596
commit | author | age
0b0dc9 1 <?php
M 2
3 /*
4 Copyright (c) 2007, 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_jailkit_plugin {
33     
34     //* $plugin_name and $class_name have to be the same then the name of this class
35     var $plugin_name = 'cron_jailkit_plugin';
36     var $class_name = 'cron_jailkit_plugin';
37     
38     //* This function is called during ispconfig installation to determine
39     //  if a symlink shall be created for this plugin.
40     function onInstall() {
41         global $conf;
42         
43         if($conf['services']['web'] == true) {
44             return true;
45         } else {
46             return false;
47         }
48         
49     }
50     
51         
52     /*
53          This function is called when the plugin is loaded
54     */
55     
56     function onLoad() {
57         global $app;
58         
59         /*
60         Register for the events
61         */
62         
63         $app->plugins->registerEvent('cron_insert', $this->plugin_name, 'insert');
64         $app->plugins->registerEvent('cron_update', $this->plugin_name, 'update');
65         $app->plugins->registerEvent('cron_delete', $this->plugin_name, 'delete');
66         
67     }
68     
69     //* This function is called, when a cron job is inserted in the database
70     function insert($event_name,$data) {
71         global $app, $conf;
72         
73         if($data["new"]["parent_domain_id"] == '') {
74             $app->log("Parent domain not set",LOGLEVEL_WARN);
75             return 0;
76         }
77         
78         //* get data from web
79         $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"]));
80         if(!$parent_domain["domain_id"]) {
81             $app->log("Parent domain not found",LOGLEVEL_WARN);
82             return 0;
83         } elseif($parent_domain["system_user"] == 'root' or $parent_domain["system_group"] == 'root') {
c128b1 84             $app->log("Websites (and Crons) cannot be owned by the root user or group.",LOGLEVEL_WARN);
0b0dc9 85             return 0;
M 86         }
87         
e23d19 88         $this->parent_domain = $parent_domain;
T 89         
0b0dc9 90         $app->uses('system');
M 91         
92         if($app->system->is_user($parent_domain['system_user'])) {
93         
94             /**
95              * Setup Jailkit Chroot System If Enabled 
96              */
97             if ($data['new']['type'] == "chrooted")
98             {
99                 // load the server configuration options
e23d19 100                 /*
0b0dc9 101                 $app->uses("getconf");
M 102                 $this->data = $data;
103                 $this->app = $app;
104                 $this->jailkit_config = $app->getconf->get_server_config($conf["server_id"], 'jailkit');
105                 $this->parent_domain = $parent_domain;
106             
107                 $this->_setup_jailkit_chroot();
108                 
109                 //$command .= 'usermod -U '.escapeshellcmd($parent_domain['system_user']);
110                 //exec($command);
111                 
112                 $this->_add_jailkit_user();
e23d19 113                 */
T 114                 $app->uses("getconf");
115                 $this->data = $data;
116                 $this->app = $app;
117                 $this->jailkit_config = $app->getconf->get_server_config($conf["server_id"], 'jailkit');
118                 
119                 $this->_update_website_security_level();
4bd960 120                 
T 121                 $app->system->web_folder_protection($parent_domain['document_root'],false);
e23d19 122             
T 123                 $this->_setup_jailkit_chroot();
124                 
125                 $this->_add_jailkit_user();
126                 
526b99 127                 $command .= 'usermod -U '.escapeshellcmd($parent_domain["system_user"]).' 2>/dev/null';
e23d19 128                 exec($command);
T 129                 
130                 $this->_update_website_security_level();
4b9329 131                 
T 132                 $app->system->web_folder_protection($parent_domain['document_root'],true);
0b0dc9 133             }
M 134         
135             $app->log("Jailkit Plugin (Cron) -> insert username:".$parent_domain['system_user'],LOGLEVEL_DEBUG);
136             
137         } else {
138             $app->log("Jailkit Plugin (Cron) -> insert username:".$parent_domain['system_user']." skipped, the user does not exist.",LOGLEVEL_WARN);
139         }
140         
141     }
142     
143     //* This function is called, when a cron job is updated in the database
144     function update($event_name,$data) {
145         global $app, $conf;
146         
147         if($data["new"]["parent_domain_id"] == '') {
148             $app->log("Parent domain not set",LOGLEVEL_WARN);
149             return 0;
150         }
151         //* get data from web
152         $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"]));
153         if(!$parent_domain["domain_id"]) {
154             $app->log("Parent domain not found",LOGLEVEL_WARN);
155             return 0;
156         } elseif($parent_domain["system_user"] == 'root' or $parent_domain["system_group"] == 'root') {
c128b1 157             $app->log("Websites (and Crons) cannot be owned by the root user or group.",LOGLEVEL_WARN);
0b0dc9 158             return 0;
M 159         }
160         
161         $app->uses('system');
162         
e23d19 163         $this->parent_domain = $parent_domain;
T 164         
0b0dc9 165         if($app->system->is_user($parent_domain['system_user'])) {
M 166         
167             /**
168              * Setup Jailkit Chroot System If Enabled 
169              */
170             if ($data['new']['type'] == "chrooted")
171             {
172                 $app->log("Jailkit Plugin (Cron) -> setting up jail", LOGLEVEL_DEBUG);
173                 // load the server configuration options
e23d19 174                 /*
0b0dc9 175                 $app->uses("getconf");
M 176                 $this->data = $data;
177                 $this->app = $app;
178                 $this->jailkit_config = $app->getconf->get_server_config($conf["server_id"], 'jailkit');
179                 $this->parent_domain = $parent_domain;
180             
181                 $this->_setup_jailkit_chroot();
182                 $this->_add_jailkit_user();
e23d19 183                 */
T 184                 $app->uses("getconf");
185                 $this->data = $data;
186                 $this->app = $app;
187                 $this->jailkit_config = $app->getconf->get_server_config($conf["server_id"], 'jailkit');
4bd960 188
T 189                 $this->_update_website_security_level();
e23d19 190                 
4b9329 191                 $app->system->web_folder_protection($parent_domain['document_root'],false);
e23d19 192             
T 193                 $this->_setup_jailkit_chroot();
194                 $this->_add_jailkit_user();
195                 
196                 $this->_update_website_security_level();
4b9329 197                 $app->system->web_folder_protection($parent_domain['document_root'],true);
0b0dc9 198             }
M 199         
200             $app->log("Jailkit Plugin (Cron) -> update username:".$parent_domain['system_user'],LOGLEVEL_DEBUG);
201             
202         } else {
203             $app->log("Jailkit Plugin (Cron) -> update username:".$parent_domain['system_user']." skipped, the user does not exist.",LOGLEVEL_WARN);
204         }
205         
206     }
207     
208     //* This function is called, when a cron job is deleted in the database
209     function delete($event_name,$data) {
210         global $app, $conf;
211         
212         //* nothing to do here!
213         
214     }
215     
216     function _setup_jailkit_chroot()
217     {
4bd960 218         global $app;    
T 219             
0b0dc9 220             //check if the chroot environment is created yet if not create it with a list of program sections from the config
M 221             if (!is_dir($this->parent_domain['document_root'].'/etc/jailkit'))
222             {
223                 $command = '/usr/local/ispconfig/server/scripts/create_jailkit_chroot.sh';
224                 $command .= ' '.escapeshellcmd($this->parent_domain['document_root']);
225                 $command .= ' \''.$this->jailkit_config['jailkit_chroot_app_sections'].'\'';
526b99 226                 exec($command.' 2>/dev/null');
0b0dc9 227                 
M 228                 $this->app->log("Added jailkit chroot with command: ".$command,LOGLEVEL_DEBUG);
229                 
230                 //$this->_add_jailkit_programs(); // done later on
231                 
232                 $this->app->load('tpl');
233         
234                 $tpl = new tpl();
235                 $tpl->newTemplate("bash.bashrc.master");
236                 
237                 $tpl->setVar('jailkit_chroot',true);
238                 $tpl->setVar('domain',$this->parent_domain['domain']);
239                 $tpl->setVar('home_dir',$this->_get_home_dir(""));
240                 
241                 $bashrc = escapeshellcmd($this->parent_domain['document_root']).'/etc/bash.bashrc';
94d2cf 242                 if(@is_file($bashrc) || @is_link($bashrc)) unlink($bashrc);
0b0dc9 243                 
4bd960 244                 $app->system->file_put_contents($bashrc,$tpl->grab());
0b0dc9 245                 unset($tpl);
M 246                 
8e725d 247                 $this->app->log('Added bashrc script: '.$bashrc,LOGLEVEL_DEBUG);
0b0dc9 248                 
M 249                 $tpl = new tpl();
8e725d 250                 $tpl->newTemplate('motd.master');
0b0dc9 251                 
M 252                 $tpl->setVar('domain',$this->parent_domain['domain']);
253                 
254                 $motd = escapeshellcmd($this->parent_domain['document_root']).'/var/run/motd';
94d2cf 255                 if(@is_file($motd) || @is_link($motd)) unlink($motd);
0b0dc9 256                 
4bd960 257                 $app->system->file_put_contents($motd,$tpl->grab());
0b0dc9 258                 
M 259             }
260             $this->_add_jailkit_programs();
261     }
262     
263     function _add_jailkit_programs()
264     {
43b345 265         global $app;
T 266         
0b0dc9 267         //copy over further programs and its libraries
M 268         $command = '/usr/local/ispconfig/server/scripts/create_jailkit_programs.sh';
269         $command .= ' '.escapeshellcmd($this->parent_domain['document_root']);
270         $command .= ' \''.$this->jailkit_config['jailkit_chroot_app_programs'].'\'';
526b99 271         exec($command.' 2>/dev/null');
0b0dc9 272         
M 273         $this->app->log("Added programs to jailkit chroot with command: ".$command,LOGLEVEL_DEBUG);
274         
275         $command = '/usr/local/ispconfig/server/scripts/create_jailkit_programs.sh';
276         $command .= ' '.escapeshellcmd($this->parent_domain['document_root']);
277         $command .= ' \''.$this->jailkit_config['jailkit_chroot_cron_programs'].'\'';
526b99 278         exec($command.' 2>/dev/null');
0b0dc9 279         
M 280         $this->app->log("Added cron programs to jailkit chroot with command: ".$command,LOGLEVEL_DEBUG);
281     }
282     
283     function _add_jailkit_user()
284     {
43b345 285             global $app;
T 286             
0b0dc9 287             //add the user to the chroot
M 288             $jailkit_chroot_userhome = $this->_get_home_dir($this->parent_domain['system_user']);
289             
290             if(!is_dir($this->parent_domain['document_root'].'/etc')) mkdir($this->parent_domain['document_root'].'/etc');
291             if(!is_file($this->parent_domain['document_root'].'/etc/passwd')) exec('touch '.$this->parent_domain['document_root'].'/etc/passwd');
292             
293             // IMPORTANT!
294             // ALWAYS create the user. Even if the user was created before
295             // if we check if the user exists, then a update (no shell -> jailkit) will not work
296             // and the user has FULL ACCESS to the root of the server!
297             $command = '/usr/local/ispconfig/server/scripts/create_jailkit_user.sh';
298             $command .= ' '.escapeshellcmd($this->parent_domain['system_user']);
299             $command .= ' '.escapeshellcmd($this->parent_domain['document_root']);
300             $command .= ' '.$jailkit_chroot_userhome;
301             $command .= ' '.escapeshellcmd("/bin/bash");
526b99 302             exec($command.' 2>/dev/null');
0b0dc9 303                 
M 304             $this->app->log("Added jailkit user to chroot with command: ".$command,LOGLEVEL_DEBUG);
305                 
4bd960 306             $app->system->mkdir(escapeshellcmd($this->parent_domain['document_root'].$jailkit_chroot_userhome), 0755, true);
T 307             $app->system->chown(escapeshellcmd($this->parent_domain['document_root'].$jailkit_chroot_userhome), escapeshellcmd($this->parent_domain['system_user']));
308             $app->system->chgrp(escapeshellcmd($this->parent_domain['document_root'].$jailkit_chroot_userhome), escapeshellcmd($this->parent_domain['system_group']));
bd36f6 309             
0b0dc9 310     }
M 311     
312     function _get_home_dir($username)
313     {
314         return str_replace("[username]",escapeshellcmd($username),$this->jailkit_config["jailkit_chroot_home"]);
315     }
e23d19 316     
T 317     //* Update the website root directory permissions depending on the security level
318     function _update_website_security_level() {
319         global $app,$conf;
320         
321         // load the server configuration options
322         $app->uses("getconf");
323         $web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
324         
4bd960 325         // Get the parent website of this shell user
T 326         $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$this->data['new']['parent_domain_id']);
327         
328         //* If the security level is set to high
329         if($web_config['security_level'] == 20 && is_array($web)) {
330             $app->system->web_folder_protection($web["document_root"],false);
331             $app->system->chmod($web["document_root"],0755);
332             $app->system->chown($web["document_root"],'root');
333             $app->system->chgrp($web["document_root"],'root');
334             $app->system->web_folder_protection($web["document_root"],true);
335         }
e23d19 336     }
T 337     
338     //* Wrapper for exec function for easier debugging
339     private function _exec($command) {
340         global $app;
8e725d 341         $app->log('exec: '.$command,LOGLEVEL_DEBUG);
e23d19 342         exec($command);
T 343     }
0b0dc9 344     
M 345     
346
347 } // end class
348
c128b1 349 ?>