tbrehm
2013-02-22 526b997c9891a796b152cdbab8e329b356b1f596
commit | author | age
46c683 1 <?php
T 2
3 /*
cea1e5 4 Copyright (c) 2007 - 2012, Till Brehm, projektfarm Gmbh
46c683 5 All rights reserved.
T 6
7 Redistribution and use in source and binary forms, with or without modification,
8 are permitted provided that the following conditions are met:
9
10     * Redistributions of source code must retain the above copyright notice,
11       this list of conditions and the following disclaimer.
12     * Redistributions in binary form must reproduce the above copyright notice,
13       this list of conditions and the following disclaimer in the documentation
14       and/or other materials provided with the distribution.
15     * Neither the name of ISPConfig nor the names of its contributors
16       may be used to endorse or promote products derived from this software without
17       specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26 OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 class apache2_plugin {
ac933e 32
46c683 33     var $plugin_name = 'apache2_plugin';
T 34     var $class_name = 'apache2_plugin';
ac933e 35
46c683 36     // private variables
T 37     var $action = '';
481c00 38     var $ssl_certificate_changed = false;
ac933e 39
46c683 40     //* This function is called during ispconfig installation to determine
T 41     //  if a symlink shall be created for this plugin.
42     function onInstall() {
43         global $conf;
ac933e 44
46c683 45         if($conf['services']['web'] == true) {
T 46             return true;
47         } else {
48             return false;
49         }
ac933e 50
46c683 51     }
ac933e 52
V 53
46c683 54     /*
T 55          This function is called when the plugin is loaded
56     */
ac933e 57
46c683 58     function onLoad() {
T 59         global $app;
ac933e 60
46c683 61         /*
T 62         Register for the events
63         */
64         $app->plugins->registerEvent('web_domain_insert',$this->plugin_name,'ssl');
65         $app->plugins->registerEvent('web_domain_update',$this->plugin_name,'ssl');
66         $app->plugins->registerEvent('web_domain_delete',$this->plugin_name,'ssl');
ac933e 67
46c683 68         $app->plugins->registerEvent('web_domain_insert',$this->plugin_name,'insert');
T 69         $app->plugins->registerEvent('web_domain_update',$this->plugin_name,'update');
70         $app->plugins->registerEvent('web_domain_delete',$this->plugin_name,'delete');
ac933e 71
46c683 72         $app->plugins->registerEvent('server_ip_insert',$this->plugin_name,'server_ip');
T 73         $app->plugins->registerEvent('server_ip_update',$this->plugin_name,'server_ip');
74         $app->plugins->registerEvent('server_ip_delete',$this->plugin_name,'server_ip');
ac933e 75
V 76         $app->plugins->registerEvent('webdav_user_insert',$this->plugin_name,'webdav');
77         $app->plugins->registerEvent('webdav_user_update',$this->plugin_name,'webdav');
78         $app->plugins->registerEvent('webdav_user_delete',$this->plugin_name,'webdav');
1ca823 79         
T 80         $app->plugins->registerEvent('client_delete',$this->plugin_name,'client_delete');
524077 81         
T 82         $app->plugins->registerEvent('web_folder_user_insert',$this->plugin_name,'web_folder_user');
83         $app->plugins->registerEvent('web_folder_user_update',$this->plugin_name,'web_folder_user');
84         $app->plugins->registerEvent('web_folder_user_delete',$this->plugin_name,'web_folder_user');
85         
2023a7 86         $app->plugins->registerEvent('web_folder_update',$this->plugin_name,'web_folder_update');
524077 87         $app->plugins->registerEvent('web_folder_delete',$this->plugin_name,'web_folder_delete');
T 88         
26c0fc 89         $app->plugins->registerEvent('ftp_user_delete',$this->plugin_name,'ftp_user_delete');
T 90         
126bda 91         $app->plugins->registerAction('php_ini_changed', $this->plugin_name, 'php_ini_changed');
46c683 92     }
126bda 93     
M 94     // check for php.ini changes
95     
96     
97     // Handle php.ini changes
98     function php_ini_changed($event_name, $data) {
99         global $app, $conf;
100         
101         $app->uses('getconf');
102         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
103         $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi');
104         
105         /* $data contains an array with these keys:
106          * file -> full path of changed php_ini
107          * mode -> web_domain php modes to change (mod, fast-cgi, php-fpm or '' for all except 'mod')
108          * php_version -> php ini path that changed (additional php versions)
109          */
110         
111         $qrystr = "SELECT * FROM web_domain WHERE custom_php_ini != ''";
112         if($data['mode'] == 'mod') {
113             $qrystr .= " AND php = 'mod'";
114         } elseif($data['mode'] == 'fast-cgi') {
115             $qrystr .= " AND php = 'fast-cgi'";
116             if($data['php_version']) {
117                 $qrystr .= " AND fastcgi_php_version LIKE '%:" . $app->db->quote($data['php_version']) . "'";
118             }
119         } elseif($data['mode'] == 'php-fpm') {
120             $qrystr .= " AND php = 'php-fpm'";
121             if($data['php_version']) {
122                 $qrystr .= " AND fastcgi_php_version LIKE '%:" . $app->db->quote($data['php_version']) . ":%'";
123             }
124         } else {
125             $qrystr .= " AND php != 'mod' AND php != 'fast-cgi'";
126         }
127         
128         
129         //** Get all the webs
130         $web_domains = $app->db->queryAllRecords($qrystr);
131         foreach($web_domains as $web_data) {
132             $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$web_data['system_user'];
133             $web_folder = 'web';
134             if($web_data['type'] == 'vhostsubdomain') {
135                 $web_folder = $web_data['web_folder'];
136                 $custom_php_ini_dir .= '_' . $web_folder;
137             }
138             if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf');
ac933e 139
126bda 140
M 141             if(!is_dir($custom_php_ini_dir)) $app->system->mkdir($custom_php_ini_dir);
142             $php_ini_content = '';
143             if($web_data['php'] == 'mod') {
144                 $master_php_ini_path = $web_config['php_ini_path_apache'];
145             } else {
146                 if($web_data['php'] == 'fast-cgi' && file_exists($fastcgi_config["fastcgi_phpini_path"])) {
147                     $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"];
148                 } else {
149                     $master_php_ini_path = $web_config['php_ini_path_cgi'];
150                 }
151             }
152             if($master_php_ini_path != '' && substr($master_php_ini_path,-7) == 'php.ini' && is_file($master_php_ini_path)) {
153                 $php_ini_content .= $app->system->file_get_contents($master_php_ini_path)."\n";
154             }
155             $php_ini_content .= str_replace("\r",'',trim($web_data['custom_php_ini']));
156             $app->system->file_put_contents($custom_php_ini_dir.'/php.ini',$php_ini_content);
157             $app->log('Info: rewrote custom php.ini for web ' . $web_data['domain_id'] . ' (' . $web_data['domain'] . ').',LOGLEVEL_DEBUG);
158         }
159         
160         if(count($web_domains) > 0) {
161             //* We do not check the apache config here - we only changed the php.ini
162             //* Check if this is a chrooted setup
163             if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
164                 $apache_chrooted = true;
165                 $app->log('Info: Apache is chrooted.',LOGLEVEL_DEBUG);
166             } else {
167                 $apache_chrooted = false;
168             }
169             
170             $app->log('Info: rewrote all php.ini and reloading apache now.',LOGLEVEL_DEBUG);
171             if($apache_chrooted) {
172                 $app->services->restartServiceDelayed('httpd','restart');
173             } else {
174                 // request a httpd reload when all records have been processed
175                 $app->services->restartServiceDelayed('httpd','reload');
176             }
177         } else {
178             $app->log('Info: No webs affected by php.ini change.',LOGLEVEL_DEBUG);
179         }
180     }
181     
46c683 182     // Handle the creation of SSL certificates
T 183     function ssl($event_name,$data) {
184         global $app, $conf;
c77103 185         
T 186         $app->uses('system');
1a2310 187
L 188         // load the server configuration options
189         $app->uses('getconf');
190         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
191         if ($web_config['CA_path']!='' && !file_exists($web_config['CA_path'].'/openssl.cnf'))
192             $app->log("CA path error, file does not exist:".$web_config['CA_path'].'/openssl.conf',LOGLEVEL_ERROR);    
1ca823 193         
T 194         //* Only vhosts can have a ssl cert
6fb93d 195         if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain") return;
ac933e 196
c77103 197         // if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl');
T 198         if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl');
199         
fb3339 200         $ssl_dir = $data['new']['document_root'].'/ssl';
J 201         $domain = $data['new']['ssl_domain'];
202         $key_file = $ssl_dir.'/'.$domain.'.key.org';
203         $key_file2 = $ssl_dir.'/'.$domain.'.key';
204         $csr_file = $ssl_dir.'/'.$domain.'.csr';
205         $crt_file = $ssl_dir.'/'.$domain.'.crt';
ac933e 206
4bd960 207         //* Create a SSL Certificate, but only if this is not a mirror server.
T 208         if($data['new']['ssl_action'] == 'create' && $conf['mirror_server_id'] == 0) {
481c00 209             
T 210             $this->ssl_certificate_changed = true;
e94a9f 211             
T 212             //* Rename files if they exist
43b345 213             if(file_exists($key_file)){
T 214                 $app->system->rename($key_file,$key_file.'.bak');
215                 $app->system->chmod($key_file.'.bak',0400);
216             }
217             if(file_exists($key_file2)){
218                 $app->system->rename($key_file2,$key_file2.'.bak');
219                 $app->system->chmod($key_file2.'.bak',0400);
220             }
c77103 221             if(file_exists($csr_file)) $app->system->rename($csr_file,$csr_file.'.bak');
T 222             if(file_exists($crt_file)) $app->system->rename($crt_file,$crt_file.'.bak');
e94a9f 223             
fb3339 224             $rand_file = $ssl_dir.'/random_file';
ac933e 225             $rand_data = md5(uniqid(microtime(),1));
V 226             for($i=0; $i<1000; $i++) {
227                 $rand_data .= md5(uniqid(microtime(),1));
228                 $rand_data .= md5(uniqid(microtime(),1));
229                 $rand_data .= md5(uniqid(microtime(),1));
230                 $rand_data .= md5(uniqid(microtime(),1));
231             }
c77103 232             $app->system->file_put_contents($rand_file, $rand_data);
46c683 233
ac933e 234             $ssl_password = substr(md5(uniqid(microtime(),1)), 0, 15);
V 235
46c683 236             $ssl_cnf = "        RANDFILE               = $rand_file
T 237
238         [ req ]
6d80f5 239         default_bits           = 2048
46c683 240         default_keyfile        = keyfile.pem
T 241         distinguished_name     = req_distinguished_name
242         attributes             = req_attributes
243         prompt                 = no
244         output_password        = $ssl_password
245
246         [ req_distinguished_name ]
e94a9f 247         C                      = ".trim($data['new']['ssl_country'])."
T 248         ST                     = ".trim($data['new']['ssl_state'])."
249         L                      = ".trim($data['new']['ssl_locality'])."
250         O                      = ".trim($data['new']['ssl_organisation'])."
251         OU                     = ".trim($data['new']['ssl_organisation_unit'])."
46c683 252         CN                     = $domain
T 253         emailAddress           = webmaster@".$data['new']['domain']."
254
255         [ req_attributes ]
256         challengePassword              = A challenge password";
ac933e 257
fb3339 258             $ssl_cnf_file = $ssl_dir.'/openssl.conf';
c77103 259             $app->system->file_put_contents($ssl_cnf_file,$ssl_cnf);
ac933e 260
46c683 261             $rand_file = escapeshellcmd($rand_file);
T 262             $key_file = escapeshellcmd($key_file);
10b4c8 263             if(substr($domain, 0, 2) == '*.' && strpos($key_file, '/ssl/\*.') != false) $key_file = str_replace('/ssl/\*.', '/ssl/*.', $key_file); // wildcard certificate
46c683 264             $key_file2 = escapeshellcmd($key_file2);
10b4c8 265             if(substr($domain, 0, 2) == '*.' && strpos($key_file2, '/ssl/\*.') != false) $key_file2 = str_replace('/ssl/\*.', '/ssl/*.', $key_file2); // wildcard certificate
46c683 266             $ssl_days = 3650;
T 267             $csr_file = escapeshellcmd($csr_file);
10b4c8 268             if(substr($domain, 0, 2) == '*.' && strpos($csr_file, '/ssl/\*.') != false) $csr_file = str_replace('/ssl/\*.', '/ssl/*.', $csr_file); // wildcard certificate
46c683 269             $config_file = escapeshellcmd($ssl_cnf_file);
T 270             $crt_file = escapeshellcmd($crt_file);
10b4c8 271             if(substr($domain, 0, 2) == '*.' && strpos($crt_file, '/ssl/\*.') != false) $crt_file = str_replace('/ssl/\*.', '/ssl/*.', $crt_file); // wildcard certificate
46c683 272
c77103 273             if(is_file($ssl_cnf_file) && !is_link($ssl_cnf_file)) {
1a2310 274                 
5c4d55 275                 exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $key_file 2048");
L 276                 exec("openssl req -new -passin pass:$ssl_password -passout pass:$ssl_password -key $key_file -out $csr_file -days $ssl_days -config $config_file");
1a2310 277                 exec("openssl rsa -passin pass:$ssl_password -in $key_file -out $key_file2");
L 278
279                 if(file_exists($web_config['CA_path'].'/openssl.cnf'))
5c4d55 280                 {
1a2310 281                     exec("openssl ca -batch -out $crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $csr_file");
5c4d55 282                     $app->log("Creating CA-signed SSL Cert for: $domain",LOGLEVEL_DEBUG);
1a2310 283                     if (filesize($crt_file)==0 || !file_exists($crt_file)) $app->log("CA-Certificate signing failed.  openssl ca -out $crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $csr_file",LOGLEVEL_ERROR);
L 284                 };
723662 285                 if (@filesize($crt_file)==0 || !file_exists($crt_file)){
5c4d55 286                     exec("openssl req -x509 -passin pass:$ssl_password -passout pass:$ssl_password -key $key_file -in $csr_file -out $crt_file -days $ssl_days -config $config_file ");
L 287                     $app->log("Creating self-signed SSL Cert for: $domain",LOGLEVEL_DEBUG);
288                 };
1a2310 289             
ac933e 290             }
46c683 291
43b345 292             $app->system->chmod($key_file,0400);
c77103 293             $app->system->chmod($key_file2,0400);
T 294             @$app->system->unlink($config_file);
295             @$app->system->unlink($rand_file);
296             $ssl_request = $app->db->quote($app->system->file_get_contents($csr_file));
297             $ssl_cert = $app->db->quote($app->system->file_get_contents($crt_file));
0d20af 298             $ssl_key2 = $app->db->quote($app->system->file_get_contents($key_file2));
d1086f 299             /* Update the DB of the (local) Server */
0d20af 300             $app->db->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert', ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'");
fb3339 301             $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
d1086f 302             /* Update also the master-DB of the Server-Farm */
0d20af 303             $app->dbmaster->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert', ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'");
fb3339 304             $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
46c683 305         }
ac933e 306
46c683 307         //* Save a SSL certificate to disk
9f56bd 308         if($data["new"]["ssl_action"] == 'save') {
481c00 309             $this->ssl_certificate_changed = true;
9f56bd 310             $ssl_dir = $data["new"]["document_root"]."/ssl";
edf806 311             $domain = ($data["new"]["ssl_domain"] != '')?$data["new"]["ssl_domain"]:$data["new"]["domain"];
481c00 312             $key_file = $ssl_dir.'/'.$domain.'.key.org';
0d20af 313             $key_file2 = $ssl_dir.'/'.$domain.'.key';
9f56bd 314             $csr_file = $ssl_dir.'/'.$domain.".csr";
T 315             $crt_file = $ssl_dir.'/'.$domain.".crt";
316             $bundle_file = $ssl_dir.'/'.$domain.".bundle";
481c00 317             
T 318             //* Backup files
43b345 319             if(file_exists($key_file)){
T 320                 $app->system->copy($key_file,$key_file.'~');
321                 $app->system->chmod($key_file.'~',0400);
322             }
323             if(file_exists($key_file2)){
324                 $app->system->copy($key_file2,$key_file2.'~');
325                 $app->system->chmod($key_file2.'~',0400);
326             }
c77103 327             if(file_exists($csr_file)) $app->system->copy($csr_file,$csr_file.'~');
T 328             if(file_exists($crt_file)) $app->system->copy($crt_file,$crt_file.'~');
329             if(file_exists($bundle_file)) $app->system->copy($bundle_file,$bundle_file.'~');
481c00 330             
T 331             //* Write new ssl files
c77103 332             if(trim($data["new"]["ssl_request"]) != '') $app->system->file_put_contents($csr_file,$data["new"]["ssl_request"]);
T 333             if(trim($data["new"]["ssl_cert"]) != '') $app->system->file_put_contents($crt_file,$data["new"]["ssl_cert"]);
334             if(trim($data["new"]["ssl_bundle"]) != '') $app->system->file_put_contents($bundle_file,$data["new"]["ssl_bundle"]);
72695f 335             
T 336             //* Write the key file, if field is empty then import the key into the db
337             if(trim($data["new"]["ssl_key"]) != '') {
338                 $app->system->file_put_contents($key_file2,$data["new"]["ssl_key"]);
339             } else {
340                 $ssl_key2 = $app->db->quote($app->system->file_get_contents($key_file2));
341                 /* Update the DB of the (local) Server */
342                 $app->db->query("UPDATE web_domain SET ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'");
343                 /* Update also the master-DB of the Server-Farm */
344                 $app->dbmaster->query("UPDATE web_domain SET ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'");
345             }
481c00 346             
d1086f 347             /* Update the DB of the (local) Server */
fb3339 348             $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
481c00 349             
d1086f 350             /* Update also the master-DB of the Server-Farm */
fb3339 351             $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
J 352             $app->log('Saving SSL Cert for: '.$domain,LOGLEVEL_DEBUG);
46c683 353         }
ac933e 354
46c683 355         //* Delete a SSL certificate
fb3339 356         if($data['new']['ssl_action'] == 'del') {
J 357             $ssl_dir = $data['new']['document_root'].'/ssl';
edf806 358             $domain = ($data["new"]["ssl_domain"] != '')?$data["new"]["ssl_domain"]:$data["new"]["domain"];
fb3339 359             $csr_file = $ssl_dir.'/'.$domain.'.csr';
J 360             $crt_file = $ssl_dir.'/'.$domain.'.crt';
361             $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
c77103 362             if(file_exists($web_config['CA_path'].'/openssl.cnf') && !is_link($web_config['CA_path'].'/openssl.cnf'))
5c4d55 363                 {
1a2310 364                     exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke $crt_file");
5c4d55 365                     $app->log("Revoking CA-signed SSL Cert for: $domain",LOGLEVEL_DEBUG);
L 366                 };
c77103 367             $app->system->unlink($csr_file);
T 368             $app->system->unlink($crt_file);
369             $app->system->unlink($bundle_file);
d1086f 370             /* Update the DB of the (local) Server */
fb3339 371             $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = '".$data['new']['domain']."'");
J 372             $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
d1086f 373             /* Update also the master-DB of the Server-Farm */
fb3339 374             $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = '".$data['new']['domain']."'");
J 375             $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
376             $app->log('Deleting SSL Cert for: '.$domain,LOGLEVEL_DEBUG);
46c683 377         }
ac933e 378
46c683 379     }
ac933e 380
V 381
46c683 382     function insert($event_name,$data) {
T 383         global $app, $conf;
ac933e 384
46c683 385         $this->action = 'insert';
T 386         // just run the update function
387         $this->update($event_name,$data);
ac933e 388
V 389
46c683 390     }
ac933e 391
V 392
46c683 393     function update($event_name,$data) {
T 394         global $app, $conf;
ac933e 395
46c683 396         if($this->action != 'insert') $this->action = 'update';
ac933e 397
6fb93d 398         if($data['new']['type'] != 'vhost' && $data['new']['type'] != 'vhostsubdomain' && $data['new']['parent_domain_id'] > 0) {
ac933e 399
fb3339 400             $old_parent_domain_id = intval($data['old']['parent_domain_id']);
J 401             $new_parent_domain_id = intval($data['new']['parent_domain_id']);
ac933e 402
1ca823 403             // If the parent_domain_id has been changed, we will have to update the old site as well.
fb3339 404             if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) {
J 405                 $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$old_parent_domain_id." AND active = 'y'");
406                 $data['new'] = $tmp;
407                 $data['old'] = $tmp;
46c683 408                 $this->action = 'update';
T 409                 $this->update($event_name,$data);
410             }
ac933e 411
46c683 412             // This is not a vhost, so we need to update the parent record instead.
fb3339 413             $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$new_parent_domain_id." AND active = 'y'");
J 414             $data['new'] = $tmp;
415             $data['old'] = $tmp;
46c683 416             $this->action = 'update';
T 417         }
ac933e 418
46c683 419         // load the server configuration options
fb3339 420         $app->uses('getconf');
J 421         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
ac933e 422
2bbc4c 423         //* Check if this is a chrooted setup
155cc0 424         if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
2bbc4c 425             $apache_chrooted = true;
fb3339 426             $app->log('Info: Apache is chrooted.',LOGLEVEL_DEBUG);
2bbc4c 427         } else {
T 428             $apache_chrooted = false;
429         }
ac933e 430
fb3339 431         if($data['new']['document_root'] == '') {
526b99 432             if($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain') $app->log('document_root not set',LOGLEVEL_WARN);
46c683 433             return 0;
T 434         }
fb3339 435         if($data['new']['system_user'] == 'root' or $data['new']['system_group'] == 'root') {
J 436             $app->log('Websites cannot be owned by the root user or group.',LOGLEVEL_WARN);
46c683 437             return 0;
T 438         }
e94a9f 439         if(trim($data['new']['domain']) == '') {
T 440             $app->log('domain is empty',LOGLEVEL_WARN);
441             return 0;
442         }
dba68f 443         
6fb93d 444         $web_folder = 'web';
M 445         $log_folder = 'log';
446         if($data['new']['type'] == 'vhostsubdomain') {
c3bf39 447             $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = '.intval($data['new']['parent_domain_id']));
M 448             $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']);
449             if($subdomain_host == '') $subdomain_host = 'web'.$data['new']['domain_id'];
6fb93d 450             $web_folder = $data['new']['web_folder'];
c3bf39 451             $log_folder .= '/' . $subdomain_host;
M 452             unset($tmp);
6fb93d 453         }
M 454
dba68f 455         // Create group and user, if not exist
T 456         $app->uses('system');
8cf78b 457         
T 458         if($web_config['connect_userid_to_webid'] == 'y') {
459             //* Calculate the uid and gid
460             $connect_userid_to_webid_start = ($web_config['connect_userid_to_webid_start'] < 1000)?1000:intval($web_config['connect_userid_to_webid_start']);
461             $fixed_uid_gid = intval($connect_userid_to_webid_start + $data['new']['domain_id']);
462             $fixed_uid_param = '--uid '.$fixed_uid_gid;
463             $fixed_gid_param = '--gid '.$fixed_uid_gid;
464             
465             //* Check if a ispconfigend user and group exists and create them
466             if(!$app->system->is_group('ispconfigend')) {
467                 exec('groupadd --gid '.($connect_userid_to_webid_start + 10000).' ispconfigend');
468             }
469             if(!$app->system->is_user('ispconfigend')) {
470                 exec('useradd -g ispconfigend -d /usr/local/ispconfig --uid '.($connect_userid_to_webid_start + 10000).' ispconfigend');
471             }
472         } else {
473             $fixed_uid_param = '';
474             $fixed_gid_param = '';
475         }
dba68f 476
T 477         $groupname = escapeshellcmd($data['new']['system_group']);
478         if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) {
8cf78b 479             exec('groupadd '.$fixed_gid_param.' '.$groupname);
dba68f 480             if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' groupadd '.$groupname);
T 481             $app->log('Adding the group: '.$groupname,LOGLEVEL_DEBUG);
482         }
483
484         $username = escapeshellcmd($data['new']['system_user']);
485         if($data['new']['system_user'] != '' && !$app->system->is_user($data['new']['system_user'])) {
8cf78b 486             if($web_config['add_web_users_to_sshusers_group'] == 'y') {
T 487                 exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false");
488                 if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false");
489             } else {
490                 exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false");
491                 if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false");
492             }
dba68f 493             $app->log('Adding the user: '.$username,LOGLEVEL_DEBUG);
T 494         }
ac933e 495
46c683 496         //* If the client of the site has been changed, we have a change of the document root
fb3339 497         if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) {
ac933e 498
46c683 499             //* Get the old client ID
fb3339 500             $old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['old']['sys_groupid']));
J 501             $old_client_id = intval($old_client['client_id']);
46c683 502             unset($old_client);
ac933e 503
46c683 504             //* Remove the old symlinks
fb3339 505             $tmp_symlinks_array = explode(':',$web_config['website_symlinks']);
46c683 506             if(is_array($tmp_symlinks_array)) {
T 507                 foreach($tmp_symlinks_array as $tmp_symlink) {
fb3339 508                     $tmp_symlink = str_replace('[client_id]',$old_client_id,$tmp_symlink);
J 509                     $tmp_symlink = str_replace('[website_domain]',$data['old']['domain'],$tmp_symlink);
46c683 510                     // Remove trailing slash
T 511                     if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
512                     // create the symlinks, if not exist
436975 513                     if(is_link($tmp_symlink)) {
fb3339 514                         exec('rm -f '.escapeshellcmd($tmp_symlink));
J 515                         $app->log('Removed symlink: rm -f '.$tmp_symlink,LOGLEVEL_DEBUG);
46c683 516                     }
T 517                 }
518             }
4b9329 519             
T 520             //* Remove protection of old folders
521             $app->system->web_folder_protection($data['old']['document_root'],false);
72695f 522             
T 523             if($data["new"]["type"] != "vhostsubdomain") {
524                 //* Move the site data
525                 $tmp_docroot = explode('/',$data['new']['document_root']);
526                 unset($tmp_docroot[count($tmp_docroot)-1]);
527                 $new_dir = implode('/',$tmp_docroot);
ac933e 528
72695f 529                 $tmp_docroot = explode('/',$data['old']['document_root']);
T 530                 unset($tmp_docroot[count($tmp_docroot)-1]);
531                 $old_dir = implode('/',$tmp_docroot);
ac933e 532
72695f 533                 //* Check if there is already some data in the new docroot and rename it as we need a clean path to move the existing site to the new path
T 534                 if(@is_dir($data['new']['document_root'])) {
535                     $app->system->web_folder_protection($data['new']['document_root'],false);
536                     $app->system->rename($data['new']['document_root'],$data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'));
537                     $app->log('Renaming existing directory in new docroot location. mv '.$data['new']['document_root'].' '.$data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'),LOGLEVEL_DEBUG);
538                 }
539                 
540                 //* Create new base directory, if it does not exist yet
541                 if(!is_dir($new_dir)) $app->system->mkdirpath($new_dir);
542                 $app->system->web_folder_protection($data['old']['document_root'],false);
543                 exec('mv '.escapeshellarg($data['old']['document_root']).' '.escapeshellarg($new_dir));
544                 //$app->system->rename($data['old']['document_root'],$new_dir);
545                 $app->log('Moving site to new document root: mv '.$data['old']['document_root'].' '.$new_dir,LOGLEVEL_DEBUG);
ac933e 546
72695f 547                 // Handle the change in php_open_basedir
T 548                 $data['new']['php_open_basedir'] = str_replace($data['old']['document_root'],$data['new']['document_root'],$data['old']['php_open_basedir']);
ac933e 549
72695f 550                 //* Change the owner of the website files to the new website owner
T 551                 exec('chown --recursive --from='.escapeshellcmd($data['old']['system_user']).':'.escapeshellcmd($data['old']['system_group']).' '.escapeshellcmd($data['new']['system_user']).':'.escapeshellcmd($data['new']['system_group']).' '.$new_dir);
0930f5 552
72695f 553                 //* Change the home directory and group of the website user
526b99 554                 $command = 'killall -u '.escapeshellcmd($data['new']['system_user']).' && usermod';
72695f 555                 $command .= ' --home '.escapeshellcmd($data['new']['document_root']);
T 556                 $command .= ' --gid '.escapeshellcmd($data['new']['system_group']);
526b99 557                 $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null';
72695f 558                 exec($command);
T 559             }
560             
fb3339 561             if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
10b4c8 562             
T 563             //* Change the log mount
564             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.'    none    bind';
565             $app->system->removeLine('/etc/fstab',$fstab_line);
566             $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait    0 0';
567             $app->system->replaceLine('/etc/fstab',$fstab_line,$fstab_line,1,1);
ac933e 568
46c683 569         }
ac933e 570
46c683 571         //print_r($data);
ac933e 572
fb3339 573         // Check if the directories are there and create them if necessary.
d87f76 574         $app->system->web_folder_protection($data['new']['document_root'],false);
T 575         
6fb93d 576         if(!is_dir($data['new']['document_root'].'/' . $web_folder)) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder);
M 577         if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/error') and $data['new']['errordocs']) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/error');
578         //if(!is_dir($data['new']['document_root'].'/'.$log_folder)) exec('mkdir -p '.$data['new']['document_root'].'/'.$log_folder);
c77103 579         if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl');
T 580         if(!is_dir($data['new']['document_root'].'/cgi-bin')) $app->system->mkdirpath($data['new']['document_root'].'/cgi-bin');
581         if(!is_dir($data['new']['document_root'].'/tmp')) $app->system->mkdirpath($data['new']['document_root'].'/tmp');
582         if(!is_dir($data['new']['document_root'].'/webdav')) $app->system->mkdirpath($data['new']['document_root'].'/webdav');
d87f76 583         
T 584         //* Create the new private directory
585         if(!is_dir($data['new']['document_root'].'/private')) {
586             $app->system->mkdirpath($data['new']['document_root'].'/private');
587             $app->system->chmod($data['new']['document_root'].'/private',0710);
588             $app->system->chown($data['new']['document_root'].'/private',$username);
589             $app->system->chgrp($data['new']['document_root'].'/private',$groupname);
590         }
591         
4b9329 592         
46c683 593         // Remove the symlink for the site, if site is renamed
fb3339 594         if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
J 595             if(is_dir('/var/log/ispconfig/httpd/'.$data['old']['domain'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']);
6fb93d 596             if(is_link($data['old']['document_root'].'/'.$log_folder)) $app->system->unlink($data['old']['document_root'].'/'.$log_folder);
10b4c8 597             
T 598             //* remove old log mount
599             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.'    none    bind';
600             $app->system->removeLine('/etc/fstab',$fstab_line);
601             
602             //* Unmount log directory
603             exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder));
46c683 604         }
d5a517 605         
T 606         //* Create the log dir if nescessary and mount it
10b4c8 607         if(!is_dir($data['new']['document_root'].'/'.$log_folder) || !is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain']) || is_link($data['new']['document_root'].'/'.$log_folder)) {
6fb93d 608             if(is_link($data['new']['document_root'].'/'.$log_folder)) unlink($data['new']['document_root'].'/'.$log_folder);
10b4c8 609             if(!is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain'])) exec('mkdir -p /var/log/ispconfig/httpd/'.$data['new']['domain']);
c3bf39 610             $app->system->mkdirpath($data['new']['document_root'].'/'.$log_folder);
6fb93d 611             $app->system->chown($data['new']['document_root'].'/'.$log_folder,'root');
M 612             $app->system->chgrp($data['new']['document_root'].'/'.$log_folder,'root');
613             $app->system->chmod($data['new']['document_root'].'/'.$log_folder,0755);
614             exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder));
d5a517 615             //* add mountpoint to fstab
10b4c8 616             $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait    0 0';
d5a517 617             $app->system->replaceLine('/etc/fstab',$fstab_line,$fstab_line,1,1);
T 618         }
619         
620         $app->system->web_folder_protection($data['new']['document_root'],true);
ac933e 621
46c683 622         // Get the client ID
fb3339 623         $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['new']['sys_groupid']));
J 624         $client_id = intval($client['client_id']);
46c683 625         unset($client);
ac933e 626
46c683 627         // Remove old symlinks, if site is renamed
fb3339 628         if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
J 629             $tmp_symlinks_array = explode(':',$web_config['website_symlinks']);
46c683 630             if(is_array($tmp_symlinks_array)) {
T 631                 foreach($tmp_symlinks_array as $tmp_symlink) {
fb3339 632                     $tmp_symlink = str_replace('[client_id]',$client_id,$tmp_symlink);
J 633                     $tmp_symlink = str_replace('[website_domain]',$data['old']['domain'],$tmp_symlink);
46c683 634                     // Remove trailing slash
T 635                     if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
636                     // remove the symlinks, if not exist
637                     if(is_link($tmp_symlink)) {
fb3339 638                         exec('rm -f '.escapeshellcmd($tmp_symlink));
J 639                         $app->log('Removed symlink: rm -f '.$tmp_symlink,LOGLEVEL_DEBUG);
46c683 640                     }
T 641                 }
642             }
643         }
ac933e 644
46c683 645         // Create the symlinks for the sites
fb3339 646         $tmp_symlinks_array = explode(':',$web_config['website_symlinks']);
46c683 647         if(is_array($tmp_symlinks_array)) {
T 648             foreach($tmp_symlinks_array as $tmp_symlink) {
fb3339 649                 $tmp_symlink = str_replace('[client_id]',$client_id,$tmp_symlink);
J 650                 $tmp_symlink = str_replace('[website_domain]',$data['new']['domain'],$tmp_symlink);
46c683 651                 // Remove trailing slash
T 652                 if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
653                 //* Remove symlink if target folder has been changed.
fb3339 654                 if($data['old']['document_root'] != '' && $data['old']['document_root'] != $data['new']['document_root'] && is_link($tmp_symlink)) {
c77103 655                     $app->system->unlink($tmp_symlink);
46c683 656                 }
T 657                 // create the symlinks, if not exist
658                 if(!is_link($tmp_symlink)) {
552178 659 //                    exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink));
M 660                     if ($web_config["website_symlinks_rel"] == 'y') {
661                         $this->create_relative_link(escapeshellcmd($data["new"]["document_root"]), escapeshellcmd($tmp_symlink));
662                     } else {
663                         exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink));
664                     }
665
fb3339 666                     $app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/ '.$tmp_symlink,LOGLEVEL_DEBUG);
46c683 667                 }
T 668             }
669         }
ac933e 670
V 671
3e41e8 672
L 673         // Install the Standard or Custom Error, Index and other related files
674         // /usr/local/ispconfig/server/conf is for the standard files
675         // /usr/local/ispconfig/server/conf-custom is for the custom files
676         // setting a local var here
677            
678         // normally $conf['templates'] = "/usr/local/ispconfig/server/conf";
6fb93d 679         if($this->action == 'insert' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain')) {
M 680             
681             // Copy the error pages
fb3339 682             if($data['new']['errordocs']) {
6fb93d 683                 $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/';
4ffb51 684                 if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']),0,2))) {
F 685                     exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']),0,2).'/* '.$error_page_path);
46c683 686                 }
T 687                 else {
4ffb51 688                     if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) {
F 689                         exec('cp '. $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path);
46c683 690                     }
T 691                     else {
4ffb51 692                         exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']),0,2).'/* '.$error_page_path);
46c683 693                     }
T 694                 }
fb3339 695                 exec('chmod -R a+r '.$error_page_path);
46c683 696             }
T 697
4ffb51 698             if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']),0,2))) {
6fb93d 699                 exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']),0,2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
3e41e8 700             
4ffb51 701             if(is_file($conf['rootpath'] . '/conf-custom/index/favicon.ico')) {
6fb93d 702                 exec('cp ' . $conf['rootpath'] . '/conf-custom/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
3e41e8 703             }
4ffb51 704             if(is_file($conf['rootpath'] . '/conf-custom/index/robots.txt')) {
6fb93d 705                 exec('cp ' . $conf['rootpath'] . '/conf-custom/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
3e41e8 706                 }
4ffb51 707                 if(is_file($conf['rootpath'] . '/conf-custom/index/.htaccess')) {
6fb93d 708                     exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
3e41e8 709                 }
L 710             }
46c683 711             else {
4ffb51 712                 if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html')) {
6fb93d 713                     exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
46c683 714                 }
T 715                 else {
6fb93d 716                     exec('cp ' . $conf['rootpath'] . '/conf/index/standard_index.html_'.substr(escapeshellcmd($conf['language']),0,2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
M 717                     if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
718                     if(is_file($conf['rootpath'] . '/conf/index/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
719                     if(is_file($conf['rootpath'] . '/conf/index/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
46c683 720                 }
T 721             }
6fb93d 722             exec('chmod -R a+r '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
ac933e 723
V 724             //** Copy the error documents on update when the error document checkbox has been activated and was deactivated before
6fb93d 725         } elseif ($this->action == 'update' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain') && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) {
M 726             
727             $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/';
4ffb51 728             if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']),0,2))) {
F 729                 exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']),0,2).'/* '.$error_page_path);
46c683 730             }
T 731             else {
4ffb51 732                 if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) {
F 733                     exec('cp ' . $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path);
46c683 734                 }
T 735                 else {
4ffb51 736                     exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']),0,2).'/* '.$error_page_path);
46c683 737                 }
T 738             }
fb3339 739             exec('chmod -R a+r '.$error_page_path);
5d5d88 740             exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path);
46c683 741         }  // end copy error docs
ac933e 742
46c683 743         // Set the quota for the user
T 744         if($username != '' && $app->system->is_user($username)) {
fb3339 745             if($data['new']['hd_quota'] > 0) {
J 746                 $blocks_soft = $data['new']['hd_quota'] * 1024;
ac933e 747                 $blocks_hard = $blocks_soft + 1024;
V 748             } else {
749                 $blocks_soft = $blocks_hard = 0;
750             }
46c683 751             exec("setquota -u $username $blocks_soft $blocks_hard 0 0 -a &> /dev/null");
fb3339 752             exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null');
46c683 753         }
ac933e 754
1ca823 755         if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) {
46c683 756             // Chown and chmod the directories below the document root
6fb93d 757             $this->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder);
8db8f3 758             // The document root itself has to be owned by root in normal level and by the web owner in security level 20
T 759             if($web_config['security_level'] == 20) {
6fb93d 760                 $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder);
8db8f3 761             } else {
6fb93d 762                 $this->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder);
8db8f3 763             }
46c683 764         }
ac933e 765
8db8f3 766         //* If the security level is set to high
8cf78b 767         if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost')) {
4b9329 768             
T 769             $app->system->web_folder_protection($data['new']['document_root'],false);
770             
d87f76 771             //* Check if we have the new private folder and create it if nescessary
T 772             if(!is_dir($data['new']['document_root'].'/private')) $app->system->mkdir($data['new']['document_root'].'/private');
773             
edf806 774             if($web_config['security_level'] == 20) {
c77103 775                 
d87f76 776                 $app->system->chmod($data['new']['document_root'],0755);
c77103 777                 $app->system->chmod($data['new']['document_root'].'/web',0710);
T 778                 $app->system->chmod($data['new']['document_root'].'/webdav',0710);
d87f76 779                 $app->system->chmod($data['new']['document_root'].'/private',0710);
c77103 780                 $app->system->chmod($data['new']['document_root'].'/ssl',0755);
ac933e 781
edf806 782                 // make tmp directory writable for Apache and the website users
c77103 783                 $app->system->chmod($data['new']['document_root'].'/tmp',0777);
1ca823 784             
cea1e5 785                 // Set Log directory to 755 to make the logs accessible by the FTP user
418b41 786                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
6fb93d 787                     $app->system->chmod($data['new']['document_root'].'/'.$log_folder,0755);
c77103 788                 }
8cf78b 789                 
T 790                 if($web_config['add_web_users_to_sshusers_group'] == 'y') {
791                     $command = 'usermod';
792                     $command .= ' --groups sshusers';
526b99 793                     $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null';
8cf78b 794                     $this->_exec($command);
T 795                 }
ac933e 796
edf806 797                 //* if we have a chrooted Apache environment
T 798                 if($apache_chrooted) {
799                     $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
ac933e 800
edf806 801                     //* add the apache user to the client group in the chroot environment
T 802                     $tmp_groupfile = $app->system->server_conf['group_datei'];
803                     $app->system->server_conf['group_datei'] = $web_config['website_basedir'].'/etc/group';
804                     $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user']));
805                     $app->system->server_conf['group_datei'] = $tmp_groupfile;
806                     unset($tmp_groupfile);
807                 }
808
809                 //* add the Apache user to the client group
2bbc4c 810                 $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user']));
8cf78b 811                 
T 812                 //* Chown all default directories
d87f76 813                 $app->system->chown($data['new']['document_root'],'root');
T 814                 $app->system->chgrp($data['new']['document_root'],'root');
c77103 815                 $app->system->chown($data['new']['document_root'].'/cgi-bin',$username);
T 816                 $app->system->chgrp($data['new']['document_root'].'/cgi-bin',$groupname);
418b41 817                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
6fb93d 818                     $app->system->chown($data['new']['document_root'].'/'.$log_folder,'root',false);
M 819                     $app->system->chgrp($data['new']['document_root'].'/'.$log_folder,$groupname,false);
c77103 820                 }
T 821                 $app->system->chown($data['new']['document_root'].'/ssl','root');
822                 $app->system->chgrp($data['new']['document_root'].'/ssl','root');
823                 $app->system->chown($data['new']['document_root'].'/tmp',$username);
824                 $app->system->chgrp($data['new']['document_root'].'/tmp',$groupname);
825                 $app->system->chown($data['new']['document_root'].'/web',$username);
826                 $app->system->chgrp($data['new']['document_root'].'/web',$groupname);
827                 $app->system->chown($data['new']['document_root'].'/web/error',$username);
828                 $app->system->chgrp($data['new']['document_root'].'/web/error',$groupname);
829                 $app->system->chown($data['new']['document_root'].'/web/stats',$username);
830                 $app->system->chgrp($data['new']['document_root'].'/web/stats',$groupname);
831                 $app->system->chown($data['new']['document_root'].'/webdav',$username);
832                 $app->system->chgrp($data['new']['document_root'].'/webdav',$groupname);
d87f76 833                 $app->system->chown($data['new']['document_root'].'/private',$username);
T 834                 $app->system->chgrp($data['new']['document_root'].'/private',$groupname);
ac933e 835
edf806 836                 // If the security Level is set to medium
T 837             } else {
838
c77103 839                 $app->system->chmod($data['new']['document_root'],0755);
T 840                 $app->system->chmod($data['new']['document_root'].'/web',0755);
841                 $app->system->chmod($data['new']['document_root'].'/webdav',0755);
842                 $app->system->chmod($data['new']['document_root'].'/ssl',0755);
843                 $app->system->chmod($data['new']['document_root'].'/cgi-bin',0755);
8cf78b 844                 
edf806 845                 // make temp directory writable for Apache and the website users
c77103 846                 $app->system->chmod($data['new']['document_root'].'/tmp',0777);
8cf78b 847                 
6fb93d 848                 // Set Log directory to 755 to make the logs accessible by the FTP user
418b41 849                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
6fb93d 850                     $app->system->chmod($data['new']['document_root'].'/'.$log_folder,0755);
M 851                 }
852                 
c77103 853                 $app->system->chown($data['new']['document_root'],'root');
T 854                 $app->system->chgrp($data['new']['document_root'],'root');
855                 $app->system->chown($data['new']['document_root'].'/cgi-bin',$username);
856                 $app->system->chgrp($data['new']['document_root'].'/cgi-bin',$groupname);
418b41 857                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
6fb93d 858                     $app->system->chown($data['new']['document_root'].'/'.$log_folder,'root',false);
M 859                     $app->system->chgrp($data['new']['document_root'].'/'.$log_folder,$groupname,false);
c77103 860                 }
6fb93d 861                 
M 862                 $app->system->chown($data['new']['document_root'].'/ssl','root');
c77103 863                 $app->system->chgrp($data['new']['document_root'].'/ssl','root');
T 864                 $app->system->chown($data['new']['document_root'].'/tmp',$username);
865                 $app->system->chgrp($data['new']['document_root'].'/tmp',$groupname);
866                 $app->system->chown($data['new']['document_root'].'/web',$username);
867                 $app->system->chgrp($data['new']['document_root'].'/web',$groupname);
868                 $app->system->chown($data['new']['document_root'].'/web/error',$username);
869                 $app->system->chgrp($data['new']['document_root'].'/web/error',$groupname);
870                 $app->system->chown($data['new']['document_root'].'/web/stats',$username);
871                 $app->system->chgrp($data['new']['document_root'].'/web/stats',$groupname);
872                 $app->system->chown($data['new']['document_root'].'/webdav',$username);
873                 $app->system->chgrp($data['new']['document_root'].'/webdav',$groupname);
8db8f3 874             }
6fb93d 875         } elseif(($this->action == 'insert' && $data['new']['type'] == 'vhostsubdomain') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhostsubdomain')) {
M 876             if($web_config['security_level'] == 20) {
877                 $app->system->chmod($data['new']['document_root'].'/' . $web_folder,0710);
878                 $app->system->chown($data['new']['document_root'].'/' . $web_folder,$username);
879                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder,$groupname);
880                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error',$username);
881                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error',$groupname);
882                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats',$username);
883                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats',$groupname);
884             } else {
885                 $app->system->chmod($data['new']['document_root'].'/' . $web_folder,0755);
886                 $app->system->chown($data['new']['document_root'].'/' . $web_folder,$username);
887                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder,$groupname);
888                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error',$username);
889                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error',$groupname);
890                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats',$username);
891                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats',$groupname);
892             }
893         }
4b9329 894         
T 895         //* Protect web folders
896         $app->system->web_folder_protection($data['new']['document_root'],true);
ac933e 897
6fb93d 898         if($data['new']['type'] == 'vhost') {
M 899             // Change the ownership of the error log to the root user
900             if(!@is_file('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')) exec('touch '.escapeshellcmd('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log'));
901             $app->system->chown('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log','root');
902             $app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log','root');
903         }
ac933e 904
26c0fc 905         //* Write the custom php.ini file, if custom_php_ini fieled is not empty
fb3339 906         $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user'];
6fb93d 907         if($data['new']['type'] == 'vhostsubdomain') $custom_php_ini_dir .= '_' . $web_folder;
c77103 908         if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf');
26c0fc 909         
T 910         //* add open_basedir restriction to custom php.ini content, required for suphp only
911         if(!stristr($data['new']['custom_php_ini'],'open_basedir') && $data['new']['php'] == 'suphp') {
912             $data['new']['custom_php_ini'] .= "\nopen_basedir = '".$data['new']['php_open_basedir']."'\n";
913         }
914         //* Create custom php.ini
fb3339 915         if(trim($data['new']['custom_php_ini']) != '') {
7fddfe 916             $has_custom_php_ini = true;
c77103 917             if(!is_dir($custom_php_ini_dir)) $app->system->mkdir($custom_php_ini_dir);
7fddfe 918             $php_ini_content = '';
fb3339 919             if($data['new']['php'] == 'mod') {
7fddfe 920                 $master_php_ini_path = $web_config['php_ini_path_apache'];
T 921             } else {
9f56bd 922                 if($data["new"]['php'] == 'fast-cgi' && file_exists($fastcgi_config["fastcgi_phpini_path"])) {
T 923                     $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"];
924                 } else {
925                     $master_php_ini_path = $web_config['php_ini_path_cgi'];
926                 }
7fddfe 927             }
72695f 928             
T 929             //* Add php.ini to the path in case that the master_php_ini_path is a directory
930             if($master_php_ini_path != '' && is_dir($master_php_ini_path) && is_file($master_php_ini_path.'/php.ini')) {
931                 if(substr($master_php_ini_path,-1) == '/') $master_php_ini_path = substr($master_php_ini_path,0,-1);
932                 $master_php_ini_path .= '/php.ini';
933             }
934             
7fddfe 935             if($master_php_ini_path != '' && substr($master_php_ini_path,-7) == 'php.ini' && is_file($master_php_ini_path)) {
c77103 936                 $php_ini_content .= $app->system->file_get_contents($master_php_ini_path)."\n";
7fddfe 937             }
8cf78b 938             $php_ini_content .= str_replace("\r",'',trim($data['new']['custom_php_ini']));
c77103 939             $app->system->file_put_contents($custom_php_ini_dir.'/php.ini',$php_ini_content);
7fddfe 940         } else {
T 941             $has_custom_php_ini = false;
c77103 942             if(is_file($custom_php_ini_dir.'/php.ini')) $app->system->unlink($custom_php_ini_dir.'/php.ini');
7fddfe 943         }
T 944
945
946         //* Create the vhost config file
46c683 947         $app->load('tpl');
ac933e 948
46c683 949         $tpl = new tpl();
fb3339 950         $tpl->newTemplate('vhost.conf.master');
ac933e 951
fb3339 952         $vhost_data = $data['new'];
a7bdf8 953         //unset($vhost_data['ip_address']);
6fb93d 954         $vhost_data['web_document_root'] = $data['new']['document_root'].'/' . $web_folder;
M 955         $vhost_data['web_document_root_www'] = $web_config['website_basedir'].'/'.$data['new']['domain'].'/' . $web_folder;
fb3339 956         $vhost_data['web_basedir'] = $web_config['website_basedir'];
J 957         $vhost_data['security_level'] = $web_config['security_level'];
958         $vhost_data['allow_override'] = ($data['new']['allow_override'] == '')?'All':$data['new']['allow_override'];
959         $vhost_data['php_open_basedir'] = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
960         $vhost_data['ssl_domain'] = $data['new']['ssl_domain'];
961         $vhost_data['has_custom_php_ini'] = $has_custom_php_ini;
962         $vhost_data['custom_php_ini_dir'] = escapeshellcmd($custom_php_ini_dir);
02bf99 963         
T 964         // Custom Apache directives
965         // Make sure we only have Unix linebreaks
966         $vhost_data['apache_directives'] = str_replace("\r\n", "\n", $vhost_data['apache_directives']);
967         $vhost_data['apache_directives'] = str_replace("\r", "\n", $vhost_data['apache_directives']);
ac933e 968
46c683 969         // Check if a SSL cert exists
fb3339 970         $ssl_dir = $data['new']['document_root'].'/ssl';
J 971         $domain = $data['new']['ssl_domain'];
972         $key_file = $ssl_dir.'/'.$domain.'.key';
973         $crt_file = $ssl_dir.'/'.$domain.'.crt';
974         $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
ac933e 975
a7bdf8 976         /*
1a2310 977         if($domain!='' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0)  && (@filesize($key_file)>0)) {
fb3339 978             $vhost_data['ssl_enabled'] = 1;
J 979             $app->log('Enable SSL for: '.$domain,LOGLEVEL_DEBUG);
46c683 980         } else {
fb3339 981             $vhost_data['ssl_enabled'] = 0;
1a2310 982             $app->log('SSL Disabled. '.$domain,LOGLEVEL_DEBUG);
46c683 983         }
a7bdf8 984         */
ac933e 985
46c683 986         if(@is_file($bundle_file)) $vhost_data['has_bundle_cert'] = 1;
ac933e 987
6fb93d 988         //$vhost_data['document_root'] = $data['new']['document_root'].'/' . $web_folder;
e64fbb 989         
F 990         // Set SEO Redirect
bfcdef 991         if($data['new']['seo_redirect'] != ''){
e64fbb 992             $vhost_data['seo_redirect_enabled'] = 1;
bfcdef 993             $tmp_seo_redirects = $this->get_seo_redirects($data['new']);
T 994             if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){
995                 foreach($tmp_seo_redirects as $key => $val){
996                     $vhost_data[$key] = $val;
997                 }
998             } else {
999                 $vhost_data['seo_redirect_enabled'] = 0;
e64fbb 1000             }
F 1001         } else {
1002             $vhost_data['seo_redirect_enabled'] = 0;
1003         }
1004         
46c683 1005         $tpl->setVar($vhost_data);
ac933e 1006
46c683 1007         // Rewrite rules
T 1008         $rewrite_rules = array();
02bf99 1009         if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') {
bfcdef 1010             if(substr($data['new']['redirect_path'],-1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $data['new']['redirect_path'])) $data['new']['redirect_path'] .= '/';
45ee67 1011             if(substr($data['new']['redirect_path'],0,8) == '[scheme]'){
F 1012                 $rewrite_target = 'http'.substr($data['new']['redirect_path'],8);
1013                 $rewrite_target_ssl = 'https'.substr($data['new']['redirect_path'],8);
1014             } else {
1015                 $rewrite_target = $data['new']['redirect_path'];
1016                 $rewrite_target_ssl = $data['new']['redirect_path'];
1017             }
bc2c3e 1018             /* Disabled path extension
fb3339 1019             if($data['new']['redirect_type'] == 'no' && substr($data['new']['redirect_path'],0,4) != 'http') {
J 1020                 $data['new']['redirect_path'] = $data['new']['document_root'].'/web'.realpath($data['new']['redirect_path']).'/';
8388ae 1021             }
bc2c3e 1022             */
ac933e 1023
fb3339 1024             switch($data['new']['subdomain']) {
ac933e 1025                 case 'www':
95e8ce 1026                     $rewrite_rules[] = array(    'rewrite_domain'     => '^'.$this->_rewrite_quote($data['new']['domain']),
e64fbb 1027                         'rewrite_type'         => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
F 1028                         'rewrite_target'     => $rewrite_target,
046d62 1029                         'rewrite_target_ssl' => $rewrite_target_ssl,
68ec43 1030                         'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
T 1031                         'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
95e8ce 1032                     $rewrite_rules[] = array(    'rewrite_domain'     => '^' . $this->_rewrite_quote('www.'.$data['new']['domain']),
fb3339 1033                             'rewrite_type'         => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
e64fbb 1034                             'rewrite_target'     => $rewrite_target,
046d62 1035                             'rewrite_target_ssl' => $rewrite_target_ssl,
68ec43 1036                             'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
T 1037                             'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
ac933e 1038                     break;
V 1039                 case '*':
95e8ce 1040                     $rewrite_rules[] = array(    'rewrite_domain'     => '(^|\.)'.$this->_rewrite_quote($data['new']['domain']),
e64fbb 1041                         'rewrite_type'         => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
F 1042                         'rewrite_target'     => $rewrite_target,
046d62 1043                         'rewrite_target_ssl' => $rewrite_target_ssl,
68ec43 1044                         'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
T 1045                         'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
ac933e 1046                     break;
e64fbb 1047                 default:
95e8ce 1048                     $rewrite_rules[] = array(    'rewrite_domain'     => '^'.$this->_rewrite_quote($data['new']['domain']),
e64fbb 1049                         'rewrite_type'         => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
F 1050                         'rewrite_target'     => $rewrite_target,
046d62 1051                         'rewrite_target_ssl' => $rewrite_target_ssl,
68ec43 1052                         'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
T 1053                         'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
ac933e 1054             }
46c683 1055         }
3501f9 1056         
M 1057         $server_alias = array();
1058         
1059         // get autoalias
1060         $auto_alias = $web_config['website_autoalias'];
1061         if($auto_alias != '') {
1062             // get the client username
1063             $client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = '" . intval($client_id) . "'");
1064             $aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]');
1065             $aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']);
1066             $auto_alias = str_replace($aa_search, $aa_replace, $auto_alias);
1067             unset($client);
1068             unset($aa_search);
1069             unset($aa_replace);
cece69 1070             $server_alias[] .= $auto_alias.' ';
3501f9 1071         }
M 1072         
46c683 1073         // get alias domains (co-domains and subdomains)
6fb93d 1074         $aliases = $app->db->queryAllRecords('SELECT * FROM web_domain WHERE parent_domain_id = '.$data['new']['domain_id']." AND active = 'y' AND type != 'vhostsubdomain'");
bfcdef 1075         $alias_seo_redirects = array();
fb3339 1076         switch($data['new']['subdomain']) {
ac933e 1077             case 'www':
fb3339 1078                 $server_alias[] .= 'www.'.$data['new']['domain'].' ';
ac933e 1079                 break;
V 1080             case '*':
fb3339 1081                 $server_alias[] .= '*.'.$data['new']['domain'].' ';
ac933e 1082                 break;
V 1083         }
46c683 1084         if(is_array($aliases)) {
T 1085             foreach($aliases as $alias) {
fb3339 1086                 switch($alias['subdomain']) {
ac933e 1087                     case 'www':
fb3339 1088                         $server_alias[] .= 'www.'.$alias['domain'].' '.$alias['domain'].' ';
ac933e 1089                         break;
V 1090                     case '*':
fb3339 1091                         $server_alias[] .= '*.'.$alias['domain'].' '.$alias['domain'].' ';
ac933e 1092                         break;
V 1093                     default:
fb3339 1094                         $server_alias[] .= $alias['domain'].' ';
ac933e 1095                         break;
V 1096                 }
fb3339 1097                 $app->log('Add server alias: '.$alias['domain'],LOGLEVEL_DEBUG);
bfcdef 1098                 
T 1099                 // Add SEO redirects for alias domains
1100                 if($alias['seo_redirect'] != '' && $data['new']['seo_redirect'] != '*_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_to_domain_tld' && ($alias['type'] == 'alias' || ($alias['type'] == 'subdomain' && $data['new']['seo_redirect'] != '*_domain_tld_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_domain_tld_to_domain_tld'))){
1101                     $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_');
1102                     if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){
1103                         $alias_seo_redirects[] = $tmp_seo_redirects;
1104                     }
1105                 }
1106                     
46c683 1107                 // Rewriting
02bf99 1108                 if($alias['redirect_type'] != '' && $alias['redirect_path'] != '') {
bfcdef 1109                     if(substr($alias['redirect_path'],-1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $data['new']['redirect_path'])) $alias['redirect_path'] .= '/';
e64fbb 1110                     if(substr($alias['redirect_path'],0,8) == '[scheme]'){
F 1111                         $rewrite_target = 'http'.substr($alias['redirect_path'],8);
1112                         $rewrite_target_ssl = 'https'.substr($alias['redirect_path'],8);
1113                     } else {
1114                         $rewrite_target = $alias['redirect_path'];
1115                         $rewrite_target_ssl = $alias['redirect_path'];
1116                     }
bc2c3e 1117                     /* Disabled the path extension
fb3339 1118                     if($data['new']['redirect_type'] == 'no' && substr($data['new']['redirect_path'],0,4) != 'http') {
J 1119                         $data['new']['redirect_path'] = $data['new']['document_root'].'/web'.realpath($data['new']['redirect_path']).'/';
8388ae 1120                     }
bc2c3e 1121                     */
e64fbb 1122                     
fb3339 1123                     switch($alias['subdomain']) {
ac933e 1124                         case 'www':
95e8ce 1125                             $rewrite_rules[] = array(    'rewrite_domain'     => '^'.$this->_rewrite_quote($alias['domain']),
e64fbb 1126                                 'rewrite_type'         => ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
F 1127                                 'rewrite_target'     => $rewrite_target,
046d62 1128                                 'rewrite_target_ssl' => $rewrite_target_ssl,
68ec43 1129                                 'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
T 1130                                 'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
95e8ce 1131                             $rewrite_rules[] = array(    'rewrite_domain'     => '^' . $this->_rewrite_quote('www.'.$alias['domain']),
fb3339 1132                                     'rewrite_type'         => ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
e64fbb 1133                                     'rewrite_target'     => $rewrite_target,
046d62 1134                                     'rewrite_target_ssl' => $rewrite_target_ssl,
68ec43 1135                                     'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
T 1136                                     'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
ac933e 1137                             break;
V 1138                         case '*':
95e8ce 1139                             $rewrite_rules[] = array(    'rewrite_domain'     => '(^|\.)'.$this->_rewrite_quote($alias['domain']),
e64fbb 1140                                 'rewrite_type'         => ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
F 1141                                 'rewrite_target'     => $rewrite_target,
046d62 1142                                 'rewrite_target_ssl' => $rewrite_target_ssl,
68ec43 1143                                 'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
T 1144                                 'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
ac933e 1145                             break;
e64fbb 1146                         default:
c7d735 1147                             if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '(^|\.)'.$this->_rewrite_quote(substr($alias['domain'], 2));
95e8ce 1148                             else $domain_rule = '^'.$this->_rewrite_quote($alias['domain']);
M 1149                             $rewrite_rules[] = array(    'rewrite_domain'     => $domain_rule,
e64fbb 1150                                 'rewrite_type'         => ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
F 1151                                 'rewrite_target'     => $rewrite_target,
046d62 1152                                 'rewrite_target_ssl' => $rewrite_target_ssl,
68ec43 1153                                 'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
T 1154                                 'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
ac933e 1155                     }
46c683 1156                 }
T 1157             }
1158         }
ac933e 1159
47cca9 1160         //* If we have some alias records
T 1161         if(count($server_alias) > 0) {
1162             $server_alias_str = '';
1163             $n = 0;
ac933e 1164
47cca9 1165             // begin a new ServerAlias line after 30 alias domains
T 1166             foreach($server_alias as $tmp_alias) {
1167                 if($n % 30 == 0) $server_alias_str .= "\n    ServerAlias ";
1168                 $server_alias_str .= $tmp_alias;
1169             }
1170             unset($tmp_alias);
ac933e 1171
47cca9 1172             $tpl->setVar('alias',trim($server_alias_str));
T 1173         } else {
1174             $tpl->setVar('alias','');
1175         }
ac933e 1176
bfcdef 1177         if(count($rewrite_rules) > 0 || $vhost_data['seo_redirect_enabled'] > 0 || count($alias_seo_redirects) > 0) {
46c683 1178             $tpl->setVar('rewrite_enabled',1);
T 1179         } else {
1180             $tpl->setVar('rewrite_enabled',0);
bfcdef 1181         }
8ab3cd 1182
T 1183         //$tpl->setLoop('redirects',$rewrite_rules);
ac933e 1184
V 1185         /**
1186          * install fast-cgi starter script and add script aliasd config
46c683 1187          * first we create the script directory if not already created, then copy over the starter script
T 1188          * settings are copied over from the server ini config for now
1189          * TODO: Create form for fastcgi configs per site.
1190          */
ac933e 1191
fb3339 1192         if ($data['new']['php'] == 'fast-cgi') {
J 1193             $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi');
ac933e 1194
fb3339 1195             $fastcgi_starter_path = str_replace('[system_user]',$data['new']['system_user'],$fastcgi_config['fastcgi_starter_path']);
J 1196             $fastcgi_starter_path = str_replace('[client_id]',$client_id,$fastcgi_starter_path);
ac933e 1197
V 1198             if (!is_dir($fastcgi_starter_path)) {
c77103 1199                 $app->system->mkdirpath($fastcgi_starter_path);
fb3339 1200                 //exec('chown '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($fastcgi_starter_path));
ac933e 1201
V 1202
fb3339 1203                 $app->log('Creating fastcgi starter script directory: '.$fastcgi_starter_path,LOGLEVEL_DEBUG);
46c683 1204             }
ac933e 1205
c77103 1206             //exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($fastcgi_starter_path));
T 1207             $app->system->chown($fastcgi_starter_path,$data['new']['system_user']);
1208             $app->system->chgrp($fastcgi_starter_path,$data['new']['system_group']);
1209             
46c683 1210             $fcgi_tpl = new tpl();
fb3339 1211             $fcgi_tpl->newTemplate('php-fcgi-starter.master');
7fddfe 1212             
62b385 1213             // Support for multiple PHP versions (FastCGI)
F 1214             if(trim($data['new']['fastcgi_php_version']) != ''){
1215                 $default_fastcgi_php = false;
6de0aa 1216                 list($custom_fastcgi_php_name, $custom_fastcgi_php_executable, $custom_fastcgi_php_ini_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
72695f 1217                 if(is_file($custom_fastcgi_php_ini_dir)) $custom_fastcgi_php_ini_dir = dirname($custom_fastcgi_php_ini_dir);
62b385 1218                 if(substr($custom_fastcgi_php_ini_dir,-1) != '/') $custom_fastcgi_php_ini_dir .= '/';
F 1219             } else {
1220                 $default_fastcgi_php = true;
1221             }
1222             
7fddfe 1223             if($has_custom_php_ini) {
T 1224                 $fcgi_tpl->setVar('php_ini_path',escapeshellcmd($custom_php_ini_dir));
1225             } else {
62b385 1226                 if($default_fastcgi_php){
F 1227                     $fcgi_tpl->setVar('php_ini_path',escapeshellcmd($fastcgi_config['fastcgi_phpini_path']));
1228                 } else {
1229                     $fcgi_tpl->setVar('php_ini_path',escapeshellcmd($custom_fastcgi_php_ini_dir));
1230                 }
7fddfe 1231             }
fb3339 1232             $fcgi_tpl->setVar('document_root',escapeshellcmd($data['new']['document_root']));
J 1233             $fcgi_tpl->setVar('php_fcgi_children',escapeshellcmd($fastcgi_config['fastcgi_children']));
1234             $fcgi_tpl->setVar('php_fcgi_max_requests',escapeshellcmd($fastcgi_config['fastcgi_max_requests']));
62b385 1235             if($default_fastcgi_php){
F 1236                 $fcgi_tpl->setVar('php_fcgi_bin',escapeshellcmd($fastcgi_config['fastcgi_bin']));
1237             } else {
1238                 $fcgi_tpl->setVar('php_fcgi_bin',escapeshellcmd($custom_fastcgi_php_executable));
1239             }
fb3339 1240             $fcgi_tpl->setVar('security_level',intval($web_config['security_level']));
ac933e 1241
fb3339 1242             $php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
ff7075 1243             $fcgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir));
ac933e 1244
6fb93d 1245             $fcgi_starter_script = escapeshellcmd($fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : ''));
c77103 1246             $app->system->file_put_contents($fcgi_starter_script,$fcgi_tpl->grab());
46c683 1247             unset($fcgi_tpl);
ac933e 1248
fb3339 1249             $app->log('Creating fastcgi starter script: '.$fcgi_starter_script,LOGLEVEL_DEBUG);
ac933e 1250
c77103 1251             $app->system->chmod($fcgi_starter_script,0755);
T 1252             $app->system->chown($fcgi_starter_script,$data['new']['system_user']);
1253             $app->system->chgrp($fcgi_starter_script,$data['new']['system_group']);
1254                         
fb3339 1255             $tpl->setVar('fastcgi_alias',$fastcgi_config['fastcgi_alias']);
46c683 1256             $tpl->setVar('fastcgi_starter_path',$fastcgi_starter_path);
6fb93d 1257             $tpl->setVar('fastcgi_starter_script',$fastcgi_config['fastcgi_starter_script'].($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : ''));
824780 1258             $tpl->setVar('fastcgi_config_syntax',$fastcgi_config['fastcgi_config_syntax']);
bfcdef 1259             $tpl->setVar('fastcgi_max_requests',$fastcgi_config['fastcgi_max_requests']);
ac933e 1260
62e4b3 1261         } else {
F 1262             //remove the php fastgi starter script if available
1263             if ($data['old']['php'] == 'fast-cgi') {
6fb93d 1264                 $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi');
M 1265                 $fastcgi_starter_path = str_replace('[system_user]',$data['old']['system_user'],$fastcgi_config['fastcgi_starter_path']);
1266                 $fastcgi_starter_path = str_replace('[client_id]',$client_id,$fastcgi_starter_path);
1267                 if($data['old']['type'] == 'vhost') {
1268                     if (is_dir($fastcgi_starter_path)) {
1269                         exec('rm -rf '.$fastcgi_starter_path);
1270                     }
1271                 } else {
1272                     $fcgi_starter_script = $fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].'_web' . $data['old']['domain_id'];
1273                     if (file_exists($fcgi_starter_script)) {
1274                         exec('rm -f '.$fcgi_starter_script);
1275                     }
1276                 }
62e4b3 1277             }
46c683 1278         }
274362 1279         
F 1280         /**
1281         * PHP-FPM
1282         */
1283         // Support for multiple PHP versions
62e4b3 1284         if($data['new']['php'] == 'php-fpm'){
F 1285             if(trim($data['new']['fastcgi_php_version']) != ''){
1286                 $default_php_fpm = false;
1287                 list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
1288                 if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/';
1289             } else {
1290                 $default_php_fpm = true;
1291             }
274362 1292         } else {
62e4b3 1293             if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
F 1294                 $default_php_fpm = false;
1295                 list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version']));
1296                 if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/';
1297             } else {
1298                 $default_php_fpm = true;
1299             }
274362 1300         }
F 1301         
1302         if($default_php_fpm){
1303             $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
1304         } else {
1305             $pool_dir = $custom_php_fpm_pool_dir;
1306         }
1307         if(substr($pool_dir,-1) != '/') $pool_dir .= '/';
1308         $pool_name = 'web'.$data['new']['domain_id'];
1309         $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']);
1310         if(substr($socket_dir,-1) != '/') $socket_dir .= '/';
1311         
1312         if($data['new']['php_fpm_use_socket'] == 'y'){
1313             $use_tcp = 0;
1314             $use_socket = 1;
1315         } else {
1316             $use_tcp = 1;
1317             $use_socket = 0;
1318         }
1319         $tpl->setVar('use_tcp', $use_tcp);
1320         $tpl->setVar('use_socket', $use_socket);
1321         $fpm_socket = $socket_dir.$pool_name.'.sock';
1322         $tpl->setVar('fpm_socket', $fpm_socket);
1323         $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1);
ac933e 1324
46c683 1325         /**
T 1326          * install cgi starter script and add script alias to config.
1327          * This is needed to allow cgi with suexec (to do so, we need a bin in the document-path!)
1328          * first we create the script directory if not already created, then copy over the starter script.
1329          * TODO: we have to fetch the data from the server-settings.
1330          */
1331
fb3339 1332         if ($data['new']['php'] == 'cgi') {
J 1333             //$cgi_config = $app->getconf->get_server_config($conf['server_id'], 'cgi');
46c683 1334
fb3339 1335             $cgi_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/';
6fb93d 1336             $cgi_config['cgi_starter_script'] = 'php-cgi-starter'.($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : '');
fb3339 1337             $cgi_config['cgi_bin'] = '/usr/bin/php-cgi';
46c683 1338
fb3339 1339             $cgi_starter_path = str_replace('[system_user]',$data['new']['system_user'],$cgi_config['cgi_starter_path']);
J 1340             $cgi_starter_path = str_replace('[client_id]',$client_id,$cgi_starter_path);
46c683 1341
ac933e 1342             if (!is_dir($cgi_starter_path)) {
c77103 1343                 $app->system->mkdirpath($cgi_starter_path);
T 1344                 $app->system->chmod($cgi_starter_script,0755);
1345                 $app->system->chown($cgi_starter_script,$data['new']['system_user']);
1346                 $app->system->chgrp($cgi_starter_script,$data['new']['system_group']);
46c683 1347
fb3339 1348                 $app->log('Creating cgi starter script directory: '.$cgi_starter_path,LOGLEVEL_DEBUG);
46c683 1349             }
T 1350
1351             $cgi_tpl = new tpl();
fb3339 1352             $cgi_tpl->newTemplate('php-cgi-starter.master');
46c683 1353
fb3339 1354             // This works because PHP "rewrites" a symlink to the physical path
J 1355             $php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
ac933e 1356             $cgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir));
fb3339 1357             $cgi_tpl->setVar('document_root', escapeshellcmd($data['new']['document_root']));
ac933e 1358
46c683 1359             // This will NOT work!
fb3339 1360             //$cgi_tpl->setVar('open_basedir', '/var/www/' . $data['new']['domain']);
J 1361             $cgi_tpl->setVar('php_cgi_bin',$cgi_config['cgi_bin']);
1362             $cgi_tpl->setVar('security_level',$web_config['security_level']);
7fddfe 1363             
T 1364             $cgi_tpl->setVar('has_custom_php_ini',$has_custom_php_ini);
1365             if($has_custom_php_ini) {
1366                 $cgi_tpl->setVar('php_ini_path',escapeshellcmd($custom_php_ini_dir));
1367             } else {
fb3339 1368                 $cgi_tpl->setVar('php_ini_path',escapeshellcmd($fastcgi_config['fastcgi_phpini_path']));
7fddfe 1369             }
46c683 1370
6fb93d 1371             $cgi_starter_script = escapeshellcmd($cgi_starter_path.$cgi_config['cgi_starter_script'].($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : ''));
c77103 1372             $app->system->file_put_contents($cgi_starter_script,$cgi_tpl->grab());
46c683 1373             unset($cgi_tpl);
T 1374
fb3339 1375             $app->log('Creating cgi starter script: '.$cgi_starter_script,LOGLEVEL_DEBUG);
46c683 1376
T 1377
c77103 1378             $app->system->chmod($cgi_starter_script,0755);
T 1379             $app->system->chown($cgi_starter_script,$data['new']['system_user']);
1380             $app->system->chgrp($cgi_starter_script,$data['new']['system_group']);
46c683 1381
T 1382             $tpl->setVar('cgi_starter_path',$cgi_starter_path);
6fb93d 1383             $tpl->setVar('cgi_starter_script',$cgi_config['cgi_starter_script'].($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : ''));
46c683 1384
T 1385         }
1386
fb3339 1387         $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost');
7ed741 1388         //* Make a backup copy of vhost file
c77103 1389         if(file_exists($vhost_file)) $app->system->copy($vhost_file,$vhost_file.'~');
7ed741 1390         
a7bdf8 1391         //* create empty vhost array
T 1392         $vhosts = array();
1393         
526b99 1394         //* Add vhost for ipv4 IP
T 1395         $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 0, 'port' => 80);
1396         if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
1397         if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects);
1398         $vhosts[] = $tmp_vhost_arr;
1399         unset($tmp_vhost_arr);
a7bdf8 1400         
T 1401         //* Add vhost for ipv4 IP with SSL
481c00 1402         $ssl_dir = $data['new']['document_root'].'/ssl';
T 1403         $domain = $data['new']['ssl_domain'];
1404         $key_file = $ssl_dir.'/'.$domain.'.key';
1405         $crt_file = $ssl_dir.'/'.$domain.'.crt';
1406         
a7bdf8 1407         if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0)  && (@filesize($key_file)>0)) {
526b99 1408             $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 1, 'port' => '443');
T 1409             if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
1410             if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects);
1411             $vhosts[] = $tmp_vhost_arr;
1412             unset($tmp_vhost_arr);
68ec43 1413             $app->log('Enable SSL for: '.$domain,LOGLEVEL_DEBUG);
T 1414         }
1415         
1416     //* Add vhost for IPv6 IP
1417     if($data['new']['ipv6_address'] != '') {
1418         if ($conf['serverconfig']['web']['vhost_rewrite_v6'] == 'y') {
1419             if (isset($conf['serverconfig']['server']['v6_prefix']) && $conf['serverconfig']['server']['v6_prefix'] <> '') {
1420                 $explode_v6prefix=explode(':',$conf['serverconfig']['server']['v6_prefix']);
1421                 $explode_v6=explode(':',$data['new']['ipv6_address']);
1422
1423                 for ( $i = 0; $i <= count($explode_v6prefix)-3; $i++ ) {
1424                         $explode_v6[$i] = $explode_v6prefix[$i];
1425                 }
1426                 $data['new']['ipv6_address'] = implode(':',$explode_v6);
1427             }
1428         }
526b99 1429             
T 1430             $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 0, 'port' => 80);
1431             if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
1432             if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects);
1433             $vhosts[] = $tmp_vhost_arr;
1434             unset($tmp_vhost_arr);
a7bdf8 1435         
T 1436             //* Add vhost for ipv6 IP with SSL
1437             if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0)  && (@filesize($key_file)>0)) {
526b99 1438                 $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 1, 'port' => '443');
T 1439                 if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
1440                 if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects);
1441                 $vhosts[] = $tmp_vhost_arr;
1442                 unset($tmp_vhost_arr);
a7bdf8 1443                 $app->log('Enable SSL for IPv6: '.$domain,LOGLEVEL_DEBUG);
T 1444             }
1445         }
1446         
1447         //* Set the vhost loop
1448         $tpl->setLoop('vhosts',$vhosts);
1449         
7ed741 1450         //* Write vhost file
c77103 1451         $app->system->file_put_contents($vhost_file,$tpl->grab());
fb3339 1452         $app->log('Writing the vhost file: '.$vhost_file,LOGLEVEL_DEBUG);
46c683 1453         unset($tpl);
ac933e 1454
V 1455         /*
1456          * maybe we have some webdav - user. If so, add them...
1457         */
fb3339 1458         $this->_patchVhostWebdav($vhost_file, $data['new']['document_root'] . '/webdav');
ac933e 1459
c6a89c 1460         //* Set the symlink to enable the vhost
T 1461         //* First we check if there is a old type of symlink and remove it
fb3339 1462         $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost');
c77103 1463         if(is_link($vhost_symlink)) $app->system->unlink($vhost_symlink);
c6a89c 1464         
T 1465         //* Remove old or changed symlinks
1466         if($data['new']['subdomain'] != $data['old']['subdomain'] or $data['new']['active'] == 'n') {
1467             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost');
1468             if(is_link($vhost_symlink)) {
c77103 1469                 $app->system->unlink($vhost_symlink);
c6a89c 1470                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
T 1471             }
1472             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost');
1473             if(is_link($vhost_symlink)) {
c77103 1474                 $app->system->unlink($vhost_symlink);
c6a89c 1475                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
T 1476             }
1477         }
1478         
1479         //* New symlink
1480         if($data['new']['subdomain'] == '*') {
1481             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost');
1482         } else {
1483             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost');
1484         }
fb3339 1485         if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) {
46c683 1486             symlink($vhost_file,$vhost_symlink);
fb3339 1487             $app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
46c683 1488         }
ac933e 1489
46c683 1490         // remove old symlink and vhost file, if domain name of the site has changed
fb3339 1491         if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
c6a89c 1492             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost');
T 1493             if(is_link($vhost_symlink)) {
c77103 1494                 $app->system->unlink($vhost_symlink);
c6a89c 1495                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
T 1496             }
1497             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost');
1498             if(is_link($vhost_symlink)) {
c77103 1499                 $app->system->unlink($vhost_symlink);
c6a89c 1500                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
T 1501             }
8cf78b 1502             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost');
T 1503             if(is_link($vhost_symlink)) {
c77103 1504                 $app->system->unlink($vhost_symlink);
8cf78b 1505                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
T 1506             }
fb3339 1507             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost');
c77103 1508             $app->system->unlink($vhost_file);
fb3339 1509             $app->log('Removing file: '.$vhost_file,LOGLEVEL_DEBUG);
46c683 1510         }
ac933e 1511
46c683 1512         //* Create .htaccess and .htpasswd file for website statistics
6fb93d 1513         if(!is_file($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess') or $data['old']['document_root'] != $data['new']['document_root']) {
M 1514             if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/stats')) $app->system->mkdir($data['new']['document_root'].'/' . $web_folder . '/stats');
bfcdef 1515             $ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$data['new']['document_root']."/web/stats/.htpasswd_stats\nrequire valid-user";
6fb93d 1516             $app->system->file_put_contents($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess',$ht_file);
M 1517             $app->system->chmod($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess',0755);
46c683 1518             unset($ht_file);
T 1519         }
ac933e 1520
bfcdef 1521         if(!is_file($data['new']['document_root'].'/web/stats/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) {
fb3339 1522             if(trim($data['new']['stats_password']) != '') {
J 1523                 $htp_file = 'admin:'.trim($data['new']['stats_password']);
4b9329 1524                 $app->system->web_folder_protection($data['new']['document_root'],false);
bfcdef 1525                 $app->system->file_put_contents($data['new']['document_root'].'/web/stats/.htpasswd_stats',$htp_file);
4b9329 1526                 $app->system->web_folder_protection($data['new']['document_root'],true);
72695f 1527                 $app->system->chmod($data['new']['document_root'].'/web/stats/.htpasswd_stats',0755);
46c683 1528                 unset($htp_file);
T 1529             }
1530         }
58c210 1531         
T 1532         //* Create awstats configuration
6fb93d 1533         if($data['new']['stats_type'] == 'awstats' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain')) {
58c210 1534             $this->awstats_update($data,$web_config);
T 1535         }
7ed741 1536         
274362 1537         $this->php_fpm_pool_update($data,$web_config,$pool_dir,$pool_name,$socket_dir);
F 1538         
7ed741 1539         if($web_config['check_apache_config'] == 'y') {
T 1540             //* Test if apache starts with the new configuration file
1541             $apache_online_status_before_restart = $this->_checkTcp('localhost',80);
fb3339 1542             $app->log('Apache status is: '.$apache_online_status_before_restart,LOGLEVEL_DEBUG);
ac933e 1543
7ed741 1544             $app->services->restartService('httpd','restart');
9f56bd 1545             
T 1546             // wait a few seconds, before we test the apache status again
bfcdef 1547             $apache_online_status_after_restart = false;
9f56bd 1548             sleep(2);
bfcdef 1549             for($i = 0; $i < 5; $i++) {
T 1550                 $apache_online_status_after_restart = $this->_checkTcp('localhost',80);
1551                 if($apache_online_status_after_restart) break;
1552                 sleep(1);
1553             }
7ed741 1554             //* Check if apache restarted successfully if it was online before
fb3339 1555             $app->log('Apache online status after restart is: '.$apache_online_status_after_restart,LOGLEVEL_DEBUG);
7ed741 1556             if($apache_online_status_before_restart && !$apache_online_status_after_restart) {
fb3339 1557                 $app->log('Apache did not restart after the configuration change for website '.$data['new']['domain'].' Reverting the configuration. Saved non-working config as '.$vhost_file.'.err',LOGLEVEL_WARN);
c77103 1558                 $app->system->copy($vhost_file,$vhost_file.'.err');
8cf78b 1559                 if(is_file($vhost_file.'~')) {
T 1560                     //* Copy back the last backup file
c77103 1561                     $app->system->copy($vhost_file.'~',$vhost_file);
8cf78b 1562                 } else {
T 1563                     //* There is no backup file, so we create a empty vhost file with a warning message inside
c77103 1564                     $app->system->file_put_contents($vhost_file,"# Apache did not start after modifying this vhost file.\n# Please check file $vhost_file.err for syntax errors.");
8cf78b 1565                 }
481c00 1566                 if($this->ssl_certificate_changed === true) {
T 1567
1568                     $ssl_dir = $data['new']['document_root'].'/ssl';
1569                     $domain = $data['new']['ssl_domain'];
1570                     $key_file = $ssl_dir.'/'.$domain.'.key.org';
1571                     $key_file2 = $ssl_dir.'/'.$domain.'.key';
1572                     $csr_file = $ssl_dir.'/'.$domain.'.csr';
1573                     $crt_file = $ssl_dir.'/'.$domain.'.crt';
1574                     $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
1575                     
1576                     //* Backup the files that might have caused the error
43b345 1577                     if(is_file($key_file)){
T 1578                         $app->system->copy($key_file,$key_file.'.err');
1579                         $app->system->chmod($key_file.'.err',0400);
1580                     }
1581                     if(is_file($key_file2)){
1582                         $app->system->copy($key_file2,$key_file2.'.err');
1583                         $app->system->chmod($key_file2.'.err',0400);
1584                     }
c77103 1585                     if(is_file($csr_file)) $app->system->copy($csr_file,$csr_file.'.err');
T 1586                     if(is_file($crt_file)) $app->system->copy($crt_file,$crt_file.'.err');
1587                     if(is_file($bundle_file)) $app->system->copy($bundle_file,$bundle_file.'.err');
481c00 1588                     
T 1589                     //* Restore the ~ backup files
c77103 1590                     if(is_file($key_file.'~')) $app->system->copy($key_file.'~',$key_file);
T 1591                     if(is_file($key_file2.'~')) $app->system->copy($key_file2.'~',$key_file2);
1592                     if(is_file($crt_file.'~')) $app->system->copy($crt_file.'~',$crt_file);
1593                     if(is_file($csr_file.'~')) $app->system->copy($csr_file.'~',$csr_file);
1594                     if(is_file($bundle_file.'~')) $app->system->copy($bundle_file.'~',$bundle_file);
481c00 1595                     
T 1596                     $app->log('Apache did not restart after the configuration change for website '.$data['new']['domain'].' Reverting the SSL configuration. Saved non-working SSL files with .err extension.',LOGLEVEL_WARN);
1597                 }
1598                 
7ed741 1599                 $app->services->restartService('httpd','restart');
T 1600             }
c82dc7 1601         } else {
7ed741 1602             //* We do not check the apache config after changes (is faster)
T 1603             if($apache_chrooted) {
1604                 $app->services->restartServiceDelayed('httpd','restart');
1605             } else {
1606                 // request a httpd reload when all records have been processed
1607                 $app->services->restartServiceDelayed('httpd','reload');
1608             }
c82dc7 1609         }
7ed741 1610         
481c00 1611         //* The vhost is written and apache has been restarted, so we 
T 1612         // can reset the ssl changed var to false and cleanup some files
1613         $this->ssl_certificate_changed = false;
1614         
1615         $ssl_dir = $data['new']['document_root'].'/ssl';
1616         $domain = $data['new']['ssl_domain'];
1617         $key_file = $ssl_dir.'/'.$domain.'.key.org';
1618         $key_file2 = $ssl_dir.'/'.$domain.'.key';
1619         $csr_file = $ssl_dir.'/'.$domain.'.csr';
1620         $crt_file = $ssl_dir.'/'.$domain.'.crt';
1621         $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
1622         
c77103 1623         if(@is_file($key_file.'~')) $app->system->unlink($key_file.'~');
T 1624         if(@is_file($key2_file.'~')) $app->system->unlink($key2_file.'~');
1625         if(@is_file($crt_file.'~')) $app->system->unlink($crt_file.'~');
1626         if(@is_file($csr_file.'~')) $app->system->unlink($csr_file.'~');
1627         if(@is_file($bundle_file.'~')) $app->system->unlink($bundle_file.'~');
481c00 1628         
7ed741 1629         // Remove the backup copy of the config file.
c77103 1630         if(@is_file($vhost_file.'~')) $app->system->unlink($vhost_file.'~');
ac933e 1631
da1a7c 1632         //* Unset action to clean it for next processed vhost.
T 1633         $this->action = '';
ac933e 1634
46c683 1635     }
ac933e 1636
46c683 1637     function delete($event_name,$data) {
T 1638         global $app, $conf;
ac933e 1639
46c683 1640         // load the server configuration options
fb3339 1641         $app->uses('getconf');
c09f04 1642         $app->uses('system');
fb3339 1643         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
4b9329 1644         
526b99 1645         if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain') $app->system->web_folder_protection($data['old']['document_root'],false);
ac933e 1646
2bbc4c 1647         //* Check if this is a chrooted setup
4b72c5 1648         if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
2bbc4c 1649             $apache_chrooted = true;
T 1650         } else {
1651             $apache_chrooted = false;
1652         }
fea5e7 1653         
T 1654         //* Remove the mounts
1655         $log_folder = 'log';
837d18 1656         $web_folder = '';
fea5e7 1657         if($data['old']['type'] == 'vhostsubdomain') {
3cde19 1658             $tmp = $app->db->queryOneRecord('SELECT `domain`,`document_root` FROM web_domain WHERE domain_id = '.intval($data['old']['parent_domain_id']));
526b99 1659             if($tmp['domain'] != ''){
T 1660                 $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']);
1661             } else {
1662                 // get log folder from /etc/fstab
1663                 /*
1664                 $bind_mounts = $app->system->file_get_contents('/etc/fstab');
1665                 $bind_mount_lines = explode("\n", $bind_mounts);
1666                 if(is_array($bind_mount_lines) && !empty($bind_mount_lines)){
1667                     foreach($bind_mount_lines as $bind_mount_line){
1668                         $bind_mount_line = preg_replace('/\s+/', ' ', $bind_mount_line);
1669                         $bind_mount_parts = explode(' ', $bind_mount_line);
1670                         if(is_array($bind_mount_parts) && !empty($bind_mount_parts)){
1671                             if($bind_mount_parts[0] == '/var/log/ispconfig/httpd/'.$data['old']['domain'] && $bind_mount_parts[2] == 'none' && strpos($bind_mount_parts[3], 'bind') !== false){
1672                                 $subdomain_host = str_replace($data['old']['document_root'].'/log/', '', $bind_mount_parts[1]);
1673                             }
1674                         }
1675                     }
1676                 }
1677                 */
1678                 // we are deleting the parent domain, so we can delete everything in the log directory
1679                 $subdomain_hosts = array();
1680                 $files = array_diff(scandir($data['old']['document_root'].'/'.$log_folder), array('.','..'));
1681                 if(is_array($files) && !empty($files)){
1682                     foreach($files as $file){
1683                         if(is_dir($data['old']['document_root'].'/'.$log_folder.'/'.$file)){
1684                             $subdomain_hosts[] = $file;
1685                         }
1686                     }
1687                 }
1688             }
1689             if(is_array($subdomain_hosts) && !empty($subdomain_hosts)){
1690                 $log_folders = array();
1691                 foreach($subdomain_hosts as $subdomain_host){
1692                     $log_folders[] = $log_folder.'/'.$subdomain_host;
1693                 }
1694             } else {
1695                 if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id'];
1696                 $log_folder .= '/' . $subdomain_host;
1697             }
1698             $web_folder = $data['old']['web_folder'];
fea5e7 1699             unset($tmp);
526b99 1700             unset($subdomain_hosts);
3cde19 1701         }
aadccc 1702         
526b99 1703         if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain'){
T 1704             if(is_array($log_folders) && !empty($log_folders)){
1705                 foreach($log_folders as $log_folder){
1706                     if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder));
1707                 }
1708             } else {
1709                 if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder));
1710             }
1711         }
fea5e7 1712         
T 1713         //* remove mountpoint from fstab
526b99 1714         if(is_array($log_folders) && !empty($log_folders)){
T 1715             foreach($log_folders as $log_folder){
1716                 $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.'    none    bind';
1717                 $app->system->removeLine('/etc/fstab',$fstab_line);
1718             }
1719         } else {
1720             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.'    none    bind';
1721             $app->system->removeLine('/etc/fstab',$fstab_line);
1722         }
1723         unset($log_folders);
ac933e 1724
6fb93d 1725         if($data['old']['type'] != 'vhost' && $data['old']['type'] != 'vhostsubdomain' && $data['old']['parent_domain_id'] > 0) {
46c683 1726             //* This is a alias domain or subdomain, so we have to update the website instead
fb3339 1727             $parent_domain_id = intval($data['old']['parent_domain_id']);
J 1728             $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$parent_domain_id." AND active = 'y'");
1729             $data['new'] = $tmp;
1730             $data['old'] = $tmp;
46c683 1731             $this->action = 'update';
T 1732             // just run the update function
1733             $this->update($event_name,$data);
ac933e 1734
46c683 1735         } else {
T 1736             //* This is a website
1737             // Deleting the vhost file, symlink and the data directory
fb3339 1738             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost');
8ab3cd 1739             
T 1740             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost');
1741             if(is_link($vhost_symlink)){
c77103 1742                 $app->system->unlink($vhost_symlink);
8ab3cd 1743                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
T 1744             }
1745             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost');
1746             if(is_link($vhost_symlink)){
c77103 1747                 $app->system->unlink($vhost_symlink);
8ab3cd 1748                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
T 1749             }
1750             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost');
1751             if(is_link($vhost_symlink)){
c77103 1752                 $app->system->unlink($vhost_symlink);
8ab3cd 1753                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
T 1754             }
1755             
c77103 1756             $app->system->unlink($vhost_file);
fb3339 1757             $app->log('Removing vhost file: '.$vhost_file,LOGLEVEL_DEBUG);
6fb93d 1758             
837d18 1759             if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain') {
6fb93d 1760                 $docroot = escapeshellcmd($data['old']['document_root']);
837d18 1761                 if($docroot != '' && !stristr($docroot,'..')) {
bfcdef 1762                     if($data['old']['type'] == 'vhost') {
T 1763                         // this is a vhost - we delete everything in here.
1764                         exec('rm -rf '.$docroot);
1765                     } elseif(!stristr($data['old']['web_folder'], '..')) {
1766                         // this is a vhost subdomain
1767                         // IMPORTANT: do some folder checks before we delete this!
1768                         $do_delete = true;
1769                         $delete_folder = preg_replace('/[\/]{2,}/', '/', $web_folder); // replace / occuring multiple times
1770                         if(substr($delete_folder, 0, 1) === '/') $delete_folder = substr($delete_folder, 1);
1771                         if(substr($delete_folder, -1) === '/') $delete_folder = substr($delete_folder, 0, -1);
1772                         
1773                         $path_elements = explode('/', $delete_folder);
1774                         
1775                         if($path_elements[0] == 'web' || $path_elements[0] === '') {
1776                             // paths beginning with /web should NEVER EVER be deleted, empty paths should NEVER occur - but for safety reasons we check it here!
1777                             // we use strict check as otherwise directories named '0' may not be deleted
1778                             $do_delete = false;
1779                         } else {
1780                             // read all vhost subdomains with same parent domain
1781                             $used_paths = array();
1782                             $tmp = $app->db->queryAllRecords("SELECT `web_folder` FROM web_domain WHERE type = 'vhostsubdomain' AND parent_domain_id = ".intval($data['old']['parent_domain_id'])." AND domain_id != ".intval($data['old']['domain_id']));
1783                             foreach($tmp as $tmprec) {
1784                                 // we normalize the folder entries because we need to compare them
1785                                 $tmp_folder = preg_replace('/[\/]{2,}/', '/', $tmprec['web_folder']); // replace / occuring multiple times
1786                                 if(substr($tmp_folder, 0, 1) === '/') $tmp_folder = substr($tmp_folder, 1);
1787                                 if(substr($tmp_folder, -1) === '/') $tmp_folder = substr($tmp_folder, 0, -1);
1788                                 
1789                                 // add this path and it's parent paths to used_paths array
1790                                 while(strpos($tmp_folder, '/') !== false) {
1791                                     if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder;
1792                                     $tmp_folder = substr($tmp_folder, 0, strrpos($tmp_folder, '/'));
1793                                 }
1794                                 if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder;
1795                             }
1796                             unset($tmp);
1797                             
1798                             // loop and check if the path is still used and stop at first used one
1799                             // set do_delete to false so nothing gets deleted if the web_folder itself is still used
1800                             $do_delete = false;
1801                             while(count($path_elements) > 0) {
1802                                 $tmp_folder = implode('/', $path_elements);
1803                                 if(in_array($tmp_folder, $used_paths) == true) break;
1804                                 
1805                                 // this path is not used - set it as path to delete, strip the last element from the array and set do_delete to true
1806                                 $delete_folder = $tmp_folder;
1807                                 $do_delete = true;
1808                                 array_pop($path_elements);
1809                             }
1810                             unset($tmp_folder);
1811                             unset($used_paths);
1812                         }
1813                         
1814                         if($do_delete === true && $delete_folder !== '') exec('rm -rf '.$docroot.'/'.$delete_folder);
1815                         
1816                         unset($delete_folder);
1817                         unset($path_elements);
1818                     }
837d18 1819                 }
274362 1820             
6fb93d 1821                 //remove the php fastgi starter script if available
M 1822                 if ($data['old']['php'] == 'fast-cgi') {
1823                     $fastcgi_starter_path = str_replace('[system_user]',$data['old']['system_user'],$web_config['fastcgi_starter_path']);
1824                     if($data['old']['type'] == 'vhost') {
1825                         if (is_dir($fastcgi_starter_path)) {
1826                             exec('rm -rf '.$fastcgi_starter_path);
1827                         }
1828                     } else {
1829                         $fcgi_starter_script = $fastcgi_starter_path.$web_config['fastcgi_starter_script'].'_web'.$data['old']['domain_id'];
1830                         if (file_exists($fcgi_starter_script)) {
1831                             exec('rm -f '.$fcgi_starter_script);
1832                         }
1833                     }
1834                 }
1835                 
1836                 // remove PHP-FPM pool
1837                 if ($data['old']['php'] == 'php-fpm') {
1838                     $this->php_fpm_pool_delete($data,$web_config);
1839                 }
ac933e 1840
6fb93d 1841                 //remove the php cgi starter script if available
M 1842                 if ($data['old']['php'] == 'cgi') {
1843                     // TODO: fetch the date from the server-settings
1844                     $web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/';
46c683 1845
6fb93d 1846                     $cgi_starter_path = str_replace('[system_user]',$data['old']['system_user'],$web_config['cgi_starter_path']);
M 1847                     if($data['old']['type'] == 'vhost') {
1848                         if (is_dir($cgi_starter_path)) {
1849                             exec('rm -rf '.$cgi_starter_path);
1850                         }
1851                     } else {
1852                         $cgi_starter_script = $cgi_starter_path.'php-cgi-starter_web'.$data['old']['domain_id'];
1853                         if (file_exists($cgi_starter_script)) {
1854                             exec('rm -f '.$cgi_starter_script);
1855                         }
1856                     }
1857                 }
1858             
1859                 $app->log('Removing website: '.$docroot,LOGLEVEL_DEBUG);
46c683 1860
6fb93d 1861                 // Delete the symlinks for the sites
M 1862                 $client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['old']['sys_groupid']));
1863                 $client_id = intval($client['client_id']);
1864                 unset($client);
1865                 $tmp_symlinks_array = explode(':',$web_config['website_symlinks']);
1866                 if(is_array($tmp_symlinks_array)) {
1867                     foreach($tmp_symlinks_array as $tmp_symlink) {
1868                         $tmp_symlink = str_replace('[client_id]',$client_id,$tmp_symlink);
1869                         $tmp_symlink = str_replace('[website_domain]',$data['old']['domain'],$tmp_symlink);
1870                         // Remove trailing slash
1871                         if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
bfcdef 1872                         // delete the symlink
6fb93d 1873                         if(is_link($tmp_symlink)) {
M 1874                             $app->system->unlink($tmp_symlink);
1875                             $app->log('Removing symlink: '.$tmp_symlink,LOGLEVEL_DEBUG);
1876                         }
1877                     }
1878                 }
1879                 // end removing symlinks
1880             }
ac933e 1881
6fb93d 1882             // Delete the log file directory
M 1883             $vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data['old']['domain']);
1884             if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir,'..')) exec('rm -rf '.$vhost_logfile_dir);
1885             $app->log('Removing website logfile directory: '.$vhost_logfile_dir,LOGLEVEL_DEBUG);
1886             
1887             if($data['old']['type'] == 'vhost') {
1888                 //delete the web user
526b99 1889                 $command = 'killall -u '.escapeshellcmd($data['old']['system_user']).' && userdel';
T 1890                 $command .= ' '.escapeshellcmd($data['old']['system_user']);
6fb93d 1891                 exec($command);
M 1892                 if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
1893                 
1894             }
1895             
1896             //* Remove the awstats configuration file
1897             if($data['old']['stats_type'] == 'awstats') {
1898                 $this->awstats_delete($data,$web_config);
1899             }
8ab3cd 1900             
3cde19 1901             if($data['old']['type'] == 'vhostsubdomain') {
T 1902                 $app->system->web_folder_protection($parent_web_document_root,true);
1903             }
1904             
8ab3cd 1905             if($apache_chrooted) {
T 1906                 $app->services->restartServiceDelayed('httpd','restart');
1907             } else {
1908                 // request a httpd reload when all records have been processed
1909                 $app->services->restartServiceDelayed('httpd','reload');
58c210 1910             }
ac933e 1911
46c683 1912         }
a39c36 1913         if($data['old']['type'] != 'vhost') $app->system->web_folder_protection($data['old']['document_root'],true);
46c683 1914     }
ac933e 1915
46c683 1916     //* This function is called when a IP on the server is inserted, updated or deleted
T 1917     function server_ip($event_name,$data) {
1918         global $app, $conf;
ac933e 1919
46c683 1920         // load the server configuration options
fb3339 1921         $app->uses('getconf');
J 1922         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
ac933e 1923
46c683 1924         $app->load('tpl');
ac933e 1925
46c683 1926         $tpl = new tpl();
fb3339 1927         $tpl->newTemplate('apache_ispconfig.conf.master');
J 1928         $records = $app->db->queryAllRecords('SELECT * FROM server_ip WHERE server_id = '.$conf['server_id']." AND virtualhost = 'y'");
a2156e 1929         
T 1930         $records_out= array();
1931         if(is_array($records)) {
1932             foreach($records as $rec) {
1933                 if($rec['ip_type'] == 'IPv6') {
1934                     $ip_address = '['.$rec['ip_address'].']';
1935                 } else {
1936                     $ip_address = $rec['ip_address'];
1937                 }
1938                 $ports = explode(',',$rec['virtualhost_port']);
1939                 if(is_array($ports)) {
1940                     foreach($ports as $port) {
1941                         $port = intval($port);
1942                         if($port > 0 && $port < 65536 && $ip_address != '') {
1943                             $records_out[] = array('ip_address' => $ip_address, 'port' => $port);
1944                         }
1945                     }
1946                 }
1947             }
1948         }
1949         
1950         
1951         if(count($records_out) > 0) {
1952             $tpl->setLoop('ip_adresses',$records_out);
46c683 1953         }
ac933e 1954
fb3339 1955         $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/ispconfig.conf');
c77103 1956         $app->system->file_put_contents($vhost_file,$tpl->grab());
fb3339 1957         $app->log('Writing the conf file: '.$vhost_file,LOGLEVEL_DEBUG);
46c683 1958         unset($tpl);
ac933e 1959
46c683 1960     }
524077 1961     
T 1962     //* Create or update the .htaccess folder protection
1963     function web_folder_user($event_name,$data) {
1964         global $app, $conf;
c69439 1965
524077 1966         $app->uses('system');
T 1967         
1968         if($event_name == 'web_folder_user_delete') {
1969             $folder_id = $data['old']['web_folder_id'];
1970         } else {
1971             $folder_id = $data['new']['web_folder_id'];
1972         }
1973         
1974         $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ".intval($folder_id));
1975         $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id']));
1976         
1977         if(!is_array($folder) or !is_array($website)) {
1978             $app->log('Not able to retrieve folder or website record.',LOGLEVEL_DEBUG);
1979             return false;
1980         }
1981         
6fb93d 1982         $web_folder = 'web';
M 1983         if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder'];
1984         
524077 1985         //* Get the folder path.
c69439 1986         if(substr($folder['path'],0,1) == '/') $folder['path'] = substr($folder['path'],1);
T 1987         if(substr($folder['path'],-1) == '/') $folder['path'] = substr($folder['path'],0,-1);
6fb93d 1988         $folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$folder['path']);
8ab3cd 1989         if(substr($folder_path,-1) != '/') $folder_path .= '/';
524077 1990         
T 1991         //* Check if the resulting path is inside the docroot
c69439 1992         if(stristr($folder_path,'..') || stristr($folder_path,'./') || stristr($folder_path,'\\')) {
T 1993             $app->log('Folder path "'.$folder_path.'" contains .. or ./.',LOGLEVEL_DEBUG);
524077 1994             return false;
T 1995         }
1996         
1997         //* Create the folder path, if it does not exist
8cf78b 1998         if(!is_dir($folder_path)) {
c77103 1999             $app->system->mkdirpath($folder_path);
T 2000             $app->system->chown($folder_path,$website['system_user']);
2001             $app->system->chgrp($folder_path,$website['system_group']);
8cf78b 2002         }
524077 2003         
T 2004         //* Create empty .htpasswd file, if it does not exist
2005         if(!is_file($folder_path.'.htpasswd')) {
4bd960 2006             $app->system->touch($folder_path.'.htpasswd');
T 2007             $app->system->chmod($folder_path.'.htpasswd',0750);
c77103 2008             $app->system->chown($folder_path.'.htpasswd',$website['system_user']);
T 2009             $app->system->chgrp($folder_path.'.htpasswd',$website['system_group']);
8ab3cd 2010             $app->log('Created file '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
524077 2011         }
T 2012         
8ab3cd 2013         /*
T 2014         $auth_users = $app->db->queryAllRecords("SELECT * FROM web_folder_user WHERE active = 'y' AND web_folder_id = ".intval($folder_id));
2015         $htpasswd_content = '';
2016         if(is_array($auth_users) && !empty($auth_users)){
2017             foreach($auth_users as $auth_user){
2018                 $htpasswd_content .= $auth_user['username'].':'.$auth_user['password']."\n";
2019             }
2020         }
2021         $htpasswd_content = trim($htpasswd_content);
2022         @file_put_contents($folder_path.'.htpasswd', $htpasswd_content);
2023         $app->log('Changed .htpasswd file: '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
2024         */
2025         
2026         if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') {
c69439 2027             $app->system->removeLine($folder_path.'.htpasswd',$data['old']['username'].':');
T 2028             $app->log('Removed user: '.$data['old']['username'],LOGLEVEL_DEBUG);
2029         }
2030         
524077 2031         //* Add or remove the user from .htpasswd file
T 2032         if($event_name == 'web_folder_user_delete') {
c69439 2033             $app->system->removeLine($folder_path.'.htpasswd',$data['old']['username'].':');
T 2034             $app->log('Removed user: '.$data['old']['username'],LOGLEVEL_DEBUG);
524077 2035         } else {
c69439 2036             if($data['new']['active'] == 'y') {
T 2037                 $app->system->replaceLine($folder_path.'.htpasswd',$data['new']['username'].':',$data['new']['username'].':'.$data['new']['password'],0,1);
2038                 $app->log('Added or updated user: '.$data['new']['username'],LOGLEVEL_DEBUG);
2039             }
524077 2040         }
T 2041         
8ab3cd 2042         
524077 2043         //* Create the .htaccess file
8ab3cd 2044         //if(!is_file($folder_path.'.htaccess')) {
2c08df 2045             $begin_marker = '### ISPConfig folder protection begin ###';
844684 2046             $end_marker = "### ISPConfig folder protection end ###\n\n";
M 2047             $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user\n".$end_marker;
2c08df 2048             
M 2049             if(file_exists($folder_path.'.htaccess')) {
2050                 $old_content = $app->system->file_get_contents($folder_path.'.htaccess');
2051                 
2052                 if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) {
2053                     $ht_file = str_replace($matches[0], $ht_file, $old_content);
2054                 } else {
2055                     $ht_file .= $old_content;
2056                 }
2057             }
2058             unset($old_content);
2059             
2060             $app->system->file_put_contents($folder_path.'.htaccess',$ht_file);
4bd960 2061             $app->system->chmod($folder_path.'.htaccess',0750);
c77103 2062             $app->system->chown($folder_path.'.htaccess',$website['system_user']);
T 2063             $app->system->chgrp($folder_path.'.htaccess',$website['system_group']);
2c08df 2064             $app->log('Created/modified file '.$folder_path.'.htaccess',LOGLEVEL_DEBUG);
8ab3cd 2065         //}
524077 2066         
T 2067     }
2068     
2069     //* Remove .htaccess and .htpasswd file, when folder protection is removed
2070     function web_folder_delete($event_name,$data) {
2071         global $app, $conf;
2072         
2073         $folder_id = $data['old']['web_folder_id'];
2074         
8ab3cd 2075         $folder = $data['old'];
524077 2076         $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id']));
T 2077         
2078         if(!is_array($folder) or !is_array($website)) {
2079             $app->log('Not able to retrieve folder or website record.',LOGLEVEL_DEBUG);
2080             return false;
2081         }
2082         
6fb93d 2083         $web_folder = 'web';
M 2084         if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder'];
2085         
524077 2086         //* Get the folder path.
8ab3cd 2087         if(substr($folder['path'],0,1) == '/') $folder['path'] = substr($folder['path'],1);
T 2088         if(substr($folder['path'],-1) == '/') $folder['path'] = substr($folder['path'],0,-1);
6fb93d 2089         $folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$folder['path']);
8ab3cd 2090         if(substr($folder_path,-1) != '/') $folder_path .= '/';
524077 2091         
T 2092         //* Check if the resulting path is inside the docroot
2093         if(substr($folder_path,0,strlen($website['document_root'])) != $website['document_root']) {
2094             $app->log('Folder path is outside of docroot.',LOGLEVEL_DEBUG);
2095             return false;
2096         }
2097         
2098         //* Remove .htpasswd file
2099         if(is_file($folder_path.'.htpasswd')) {
c77103 2100             $app->system->unlink($folder_path.'.htpasswd');
8ab3cd 2101             $app->log('Removed file '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
524077 2102         }
T 2103         
2104         //* Remove .htaccess file
2105         if(is_file($folder_path.'.htaccess')) {
2c08df 2106             $begin_marker = '### ISPConfig folder protection begin ###';
844684 2107             $end_marker = "### ISPConfig folder protection end ###\n\n";
2c08df 2108             
M 2109             $ht_file = $app->system->file_get_contents($folder_path.'.htaccess');
2110             
2111             if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) {
2112                 $ht_file = str_replace($matches[0], '', $ht_file);
2cb656 2113             } else {
M 2114                 $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user", '', $ht_file);
2c08df 2115             }
M 2116             
2117             if(trim($ht_file) == '') {
2118                 $app->system->unlink($folder_path.'.htaccess');
2119                 $app->log('Removed file '.$folder_path.'.htaccess',LOGLEVEL_DEBUG);
2120             } else {
2121                 $app->system->file_put_contents($folder_path.'.htaccess', $ht_file);
2122                 $app->log('Removed protection content from file '.$folder_path.'.htaccess',LOGLEVEL_DEBUG);
2123             }
524077 2124         }
2023a7 2125     }
T 2126     
2127     //* Update folder protection, when path has been changed
2128     function web_folder_update($event_name,$data) {
2129         global $app, $conf;
2130         
2131         $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($data['new']['parent_domain_id']));
2132     
2133         if(!is_array($website)) {
2134             $app->log('Not able to retrieve folder or website record.',LOGLEVEL_DEBUG);
2135             return false;
2136         }
2137         
6fb93d 2138         $web_folder = 'web';
M 2139         if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder'];
2140         
2023a7 2141         //* Get the folder path.
8ab3cd 2142         if(substr($data['old']['path'],0,1) == '/') $data['old']['path'] = substr($data['old']['path'],1);
T 2143         if(substr($data['old']['path'],-1) == '/') $data['old']['path'] = substr($data['old']['path'],0,-1);
6fb93d 2144         $old_folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$data['old']['path']);
8ab3cd 2145         if(substr($old_folder_path,-1) != '/') $old_folder_path .= '/';
2023a7 2146             
8ab3cd 2147         if(substr($data['new']['path'],0,1) == '/') $data['new']['path'] = substr($data['new']['path'],1);
T 2148         if(substr($data['new']['path'],-1) == '/') $data['new']['path'] = substr($data['new']['path'],0,-1);
6fb93d 2149         $new_folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$data['new']['path']);
8ab3cd 2150         if(substr($new_folder_path,-1) != '/') $new_folder_path .= '/';
2023a7 2151         
T 2152         //* Check if the resulting path is inside the docroot
2153         if(stristr($new_folder_path,'..') || stristr($new_folder_path,'./') || stristr($new_folder_path,'\\')) {
2154             $app->log('Folder path "'.$new_folder_path.'" contains .. or ./.',LOGLEVEL_DEBUG);
2155             return false;
2156         }
2157         if(stristr($old_folder_path,'..') || stristr($old_folder_path,'./') || stristr($old_folder_path,'\\')) {
2158             $app->log('Folder path "'.$old_folder_path.'" contains .. or ./.',LOGLEVEL_DEBUG);
2159             return false;
2160         }
2161         
2162         //* Check if the resulting path is inside the docroot
2163         if(substr($old_folder_path,0,strlen($website['document_root'])) != $website['document_root']) {
2164             $app->log('Old folder path '.$old_folder_path.' is outside of docroot.',LOGLEVEL_DEBUG);
2165             return false;
2166         }
2167         if(substr($new_folder_path,0,strlen($website['document_root'])) != $website['document_root']) {
2168             $app->log('New folder path '.$new_folder_path.' is outside of docroot.',LOGLEVEL_DEBUG);
2169             return false;
2170         }
2171             
2172         //* Create the folder path, if it does not exist
c77103 2173         if(!is_dir($new_folder_path)) $app->system->mkdirpath($new_folder_path);
2023a7 2174         
2c08df 2175         $begin_marker = '### ISPConfig folder protection begin ###';
844684 2176         $end_marker = "### ISPConfig folder protection end ###\n\n";
2c08df 2177         
2023a7 2178         if($data['old']['path'] != $data['new']['path']) {
T 2179
2180         
2181             //* move .htpasswd file
2182             if(is_file($old_folder_path.'.htpasswd')) {
c77103 2183                 $app->system->rename($old_folder_path.'.htpasswd',$new_folder_path.'.htpasswd');
8ab3cd 2184                 $app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd',LOGLEVEL_DEBUG);
2023a7 2185             }
T 2186             
8ab3cd 2187             //* delete old .htaccess file
2023a7 2188             if(is_file($old_folder_path.'.htaccess')) {
2c08df 2189                 $ht_file = $app->system->file_get_contents($old_folder_path.'.htaccess');
M 2190                 
2191                 if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) {
2192                     $ht_file = str_replace($matches[0], '', $ht_file);
2cb656 2193                 } else {
M 2194                     $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$old_folder_path.".htpasswd\nrequire valid-user", '', $ht_file);
2c08df 2195                 }
M 2196                 
2197                 if(trim($ht_file) == '') {
2198                     $app->system->unlink($old_folder_path.'.htaccess');
2199                     $app->log('Removed file '.$old_folder_path.'.htaccess',LOGLEVEL_DEBUG);
2200                 } else {
2201                     $app->system->file_put_contents($old_folder_path.'.htaccess', $ht_file);
2202                     $app->log('Removed protection content from file '.$old_folder_path.'.htaccess',LOGLEVEL_DEBUG);
2203                 }
2023a7 2204             }
T 2205         
2206         }
2207         
2208         //* Create the .htaccess file
8ab3cd 2209         if($data['new']['active'] == 'y') {
844684 2210             $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user\n".$end_marker;
2c08df 2211             
M 2212             if(file_exists($new_folder_path.'.htaccess')) {
2213                 $old_content = $app->system->file_get_contents($new_folder_path.'.htaccess');
2214                 
2215                 if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) {
2216                     $ht_file = str_replace($matches[0], $ht_file, $old_content);
2217                 } else {
2218                     $ht_file .= $old_content;
2219                 }
2220             }
2221             
2222             $app->system->file_put_contents($new_folder_path.'.htaccess',$ht_file);
4bd960 2223             $app->system->chmod($new_folder_path.'.htaccess',0750);
2c08df 2224             $app->system->chown($new_folder_path.'.htaccess',$website['system_user']);
M 2225             $app->system->chgrp($new_folder_path.'.htaccess',$website['system_group']);
2226             $app->log('Created/modified file '.$new_folder_path.'.htaccess',LOGLEVEL_DEBUG);
2023a7 2227         }
T 2228         
2229         //* Remove .htaccess file
2230         if($data['new']['active'] == 'n' && is_file($new_folder_path.'.htaccess')) {
2c08df 2231             $ht_file = $app->system->file_get_contents($new_folder_path.'.htaccess');
M 2232             
2233             if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) {
2234                 $ht_file = str_replace($matches[0], '', $ht_file);
2cb656 2235             } else {
M 2236                 $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user", '', $ht_file);
2c08df 2237             }
M 2238             
2239             if(trim($ht_file) == '') {
2240                 $app->system->unlink($new_folder_path.'.htaccess');
2241                 $app->log('Removed file '.$new_folder_path.'.htaccess',LOGLEVEL_DEBUG);
2242             } else {
2243                 $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file);
2244                 $app->log('Removed protection content from file '.$new_folder_path.'.htaccess',LOGLEVEL_DEBUG);
2245             }
2023a7 2246         }
524077 2247         
T 2248         
2249     }
26c0fc 2250     
T 2251     public function ftp_user_delete($event_name,$data) {
2252         global $app, $conf;
2253         
2254         $ftpquota_file = $data['old']['dir'].'/.ftpquota';
c77103 2255         if(file_exists($ftpquota_file)) $app->system->unlink($ftpquota_file);
26c0fc 2256         
T 2257     }
2258     
2259     
ac933e 2260
V 2261     /**
2262      * This function is called when a Webdav-User is inserted, updated or deleted.
2263      *
2264      * @author Oliver Vogel
2265      * @param string $event_name
2266      * @param array $data
2267      */
2268     public function webdav($event_name,$data) {
2269         global $app, $conf;
52a04e 2270         
T 2271         /*
2272          * load the server configuration options
2273         */
fb3339 2274         $app->uses('getconf');
J 2275         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
ac933e 2276
V 2277         if (($event_name == 'webdav_user_insert') || ($event_name == 'webdav_user_update')) {
2278
2279             /*
2280              * Get additional informations
2281             */
fb3339 2282             $sitedata = $app->db->queryOneRecord('SELECT document_root, domain, system_user, system_group FROM web_domain WHERE domain_id = ' . $data['new']['parent_domain_id']);
ac933e 2283             $documentRoot = $sitedata['document_root'];
V 2284             $domain = $sitedata['domain'];
ca14fe 2285             $user = $sitedata['system_user'];
V 2286             $group = $sitedata['system_group'];
b67344 2287             $webdav_user_dir = $documentRoot . '/webdav/' . $data['new']['dir'];
ac933e 2288
V 2289             /* Check if this is a chrooted setup */
2290             if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
2291                 $apache_chrooted = true;
fb3339 2292                 $app->log('Info: Apache is chrooted.',LOGLEVEL_DEBUG);
ac933e 2293             } else {
V 2294                 $apache_chrooted = false;
2295             }
b67344 2296             
T 2297             //* We dont want to have relative paths here
2298             if(stristr($webdav_user_dir,'..')  || stristr($webdav_user_dir,'./')) {
2299                 $app->log('Folder path '.$webdav_user_dir.' contains ./ or .. '.$documentRoot,LOGLEVEL_WARN);
2300                 return false;
2301             }
2302             
2303             //* Check if the resulting path exists if yes, if it is inside the docroot
2304             if(is_dir($webdav_user_dir) && substr(realpath($webdav_user_dir),0,strlen($documentRoot)) != $documentRoot) {
2305                 $app->log('Folder path '.$webdav_user_dir.' is outside of docroot '.$documentRoot,LOGLEVEL_WARN);
2306                 return false;
2307             }
ac933e 2308
V 2309             /*
2310              * First the webdav-root - folder has to exist
2311             */
b67344 2312             if(!is_dir($webdav_user_dir)) {
T 2313                 $app->log('Webdav User directory '.$webdav_user_dir.' does not exist. Creating it now.',LOGLEVEL_DEBUG);
c77103 2314                 $app->system->mkdirpath($webdav_user_dir);
ac933e 2315             }
V 2316
2317             /*
ca14fe 2318              * The webdav - Root needs the group/user as owner and the apache as read and write
ac933e 2319             */
c77103 2320             //$this->_exec('chown ' . $user . ':' . $group . ' ' . escapeshellcmd($documentRoot . '/webdav/'));
T 2321             //$this->_exec('chmod 770 ' . escapeshellcmd($documentRoot . '/webdav/'));
2322             $app->system->chown($documentRoot . '/webdav',$user);
2323             $app->system->chgrp($documentRoot . '/webdav',$group);
2324             $app->system->chmod($documentRoot . '/webdav',0770);
ac933e 2325
V 2326             /*
ca14fe 2327              * The webdav folder (not the webdav-root!) needs the same (not in ONE step, because the
V 2328              * pwd-files are owned by root)
ac933e 2329             */
c77103 2330             //$this->_exec('chown ' . $user . ':' . $group . ' ' . escapeshellcmd($webdav_user_dir.' -R'));
T 2331             //$this->_exec('chmod 770 ' . escapeshellcmd($webdav_user_dir.' -R'));
2332             $app->system->chown($webdav_user_dir,$user);
2333             $app->system->chgrp($webdav_user_dir,$group);
2334             $app->system->chmod($webdav_user_dir,0770);
ca14fe 2335
V 2336             /*
2337              * if the user is active, we have to write/update the password - file
2338              * if the user is inactive, we have to inactivate the user by removing the user from the file
2339             */
2340             if ($data['new']['active'] == 'y') {
b67344 2341                 $this->_writeHtDigestFile( $webdav_user_dir . '.htdigest', $data['new']['username'], $data['new']['dir'], $data['new']['password']);
ca14fe 2342             }
V 2343             else {
2344                 /* empty pwd removes the user! */
b67344 2345                 $this->_writeHtDigestFile( $webdav_user_dir . '.htdigest', $data['new']['username'], $data['new']['dir'], '');
ca14fe 2346             }
ac933e 2347
V 2348             /*
2349              * Next step, patch the vhost - file
2350             */
fb3339 2351             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost');
ac933e 2352             $this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav');
ca14fe 2353
ac933e 2354             /*
V 2355              * Last, restart apache
2356             */
2357             if($apache_chrooted) {
2358                 $app->services->restartServiceDelayed('httpd','restart');
2359             } else {
2360                 // request a httpd reload when all records have been processed
2361                 $app->services->restartServiceDelayed('httpd','reload');
2362             }
2363
2364         }
2365
2366         if ($event_name == 'webdav_user_delete') {
2367             /*
2368              * Get additional informations
2369             */
fb3339 2370             $sitedata = $app->db->queryOneRecord('SELECT document_root, domain FROM web_domain WHERE domain_id = ' . $data['old']['parent_domain_id']);
ac933e 2371             $documentRoot = $sitedata['document_root'];
52a04e 2372             $domain = $sitedata['domain'];
ac933e 2373
V 2374             /*
2375              * We dont't want to destroy any (transfer)-Data. So we do NOT delete any dir.
2376              * So the only thing, we have to do, is to delete the user from the password-file
ca14fe 2377             */
ac933e 2378             $this->_writeHtDigestFile( $documentRoot . '/webdav/' . $data['old']['dir'] . '.htdigest', $data['old']['username'], $data['old']['dir'], '');
52a04e 2379             
T 2380             /*
2381              * Next step, patch the vhost - file
2382             */
fb3339 2383             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost');
52a04e 2384             $this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav');
T 2385             
2386             /*
2387              * Last, restart apache
2388             */
2389             if($apache_chrooted) {
2390                 $app->services->restartServiceDelayed('httpd','restart');
2391             } else {
2392                 // request a httpd reload when all records have been processed
2393                 $app->services->restartServiceDelayed('httpd','reload');
2394             }
ac933e 2395         }
V 2396     }
2397
2398
2399     /**
2400      * This function writes the htdigest - files used by webdav and digest
ca14fe 2401      * more info: see http://riceball.com/d/node/424
ac933e 2402      * @author Oliver Vogel
V 2403      * @param string $filename The name of the digest-file
2404      * @param string $username The name of the webdav-user
2405      * @param string $authname The name of the realm
ca14fe 2406      * @param string $pwd      The password-hash of the user
ac933e 2407      */
ca14fe 2408     private function _writeHtDigestFile($filename, $username, $authname, $pwdhash ) {
4bd960 2409         global $app;
T 2410         
ac933e 2411         $changed = false;
c77103 2412         if(is_file($filename) && !is_link($filename)) {
0ff3f1 2413             $in = fopen($filename, 'r');
T 2414             $output = '';
2415             /*
2416             * read line by line and search for the username and authname
2417             */
2418             while (preg_match("/:/", $line = fgets($in))) {
2419                 $line = rtrim($line);
2420                 $tmp = explode(':', $line);
2421                 if ($tmp[0] == $username && $tmp[1] == $authname) {
2422                     /*
2423                     * found the user. delete or change it?
2424                     */
2425                     if ($pwdhash != '') {
2426                         $output .= $tmp[0] . ':' . $tmp[1] . ':' . $pwdhash . "\n";
2427                         }
2428                     $changed = true;
2429                 }
2430                 else {
2431                     $output .= $line . "\n";
2432                 }
ac933e 2433             }
0ff3f1 2434             fclose($in);
ac933e 2435         }
V 2436         /*
2437          * if we didn't change anything, we have to add the new user at the end of the file
2438         */
2439         if (!$changed) {
f17dab 2440             $output .= $username . ':' . $authname . ':' . $pwdhash . "\n";
ac933e 2441         }
0ff3f1 2442         
ac933e 2443
V 2444         /*
2445          * Now lets write the new file
2446         */
52a04e 2447         if(trim($output) == '') {
c77103 2448             $app->system->unlink($filename);
52a04e 2449         } else {
c77103 2450             $app->system->file_put_contents($filename, $output);
52a04e 2451         }
ac933e 2452     }
V 2453
2454     /**
2455      * This function patches the vhost-file and adds all webdav - user.
2456      * This function is written, because the creation of the vhost - file is sophisticated and
2457      * i don't want to make it more "heavy" by also adding this code too...
2458      * @author Oliver Vogel
2459      * @param string $fileName The Name of the .vhost-File (path included)
2460      * @param string $webdavRoot The root of the webdav-folder
2461      */
2462     private function _patchVhostWebdav($fileName, $webdavRoot) {
c77103 2463         global $app;
ac933e 2464         $in = fopen($fileName, 'r');
V 2465         $output = '';
2466         $inWebdavSection = false;
2467
2468         /*
2469          * read line by line and search for the username and authname
2470         */
2471         while ($line = fgets($in)) {
2472             /*
2473              *  is the "replace-comment" found...
2474             */
2475             if (trim($line) == '# WEBDAV BEGIN') {
2476                 /*
2477                  * The begin of the webdav - section is found, so ignore all lines til the end  is found
2478                 */
2479                 $inWebdavSection = true;
2480
2481                 $output .= "      # WEBDAV BEGIN\n";
2482
2483                 /*
2484                  * add all the webdav-dirs to the webdav-section
2485                 */
fb3a98 2486                 $files = @scandir($webdavRoot);
T 2487                 if(is_array($files)) {
ac933e 2488                 foreach($files as $file) {
bfcdef 2489                     if (substr($file, strlen($file) - strlen('.htdigest')) == '.htdigest' && preg_match("/^[a-zA-Z0-9\-_\.]*$/",$file)) {
ac933e 2490                         /*
V 2491                          * found a htdigest - file, so add it to webdav
2492                         */
2493                         $fn = substr($file, 0, strlen($file) - strlen('.htdigest'));
2494                         $output .= "\n";
dd1afa 2495                         // $output .= "      Alias /" . $fn . ' ' . $webdavRoot . '/' . $fn . "\n";
T 2496                         // $output .= "      <Location /" . $fn . ">\n";
9f56bd 2497                         $output .= "      Alias /webdav/" . $fn . ' ' . $webdavRoot . '/' . $fn . "\n";
T 2498                         $output .= "      <Location /webdav/" . $fn . ">\n";
ac933e 2499                         $output .= "        DAV On\n";
b67344 2500                         $output .= '        BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On'."\n";
ac933e 2501                         $output .= "        AuthType Digest\n";
V 2502                         $output .= "        AuthName \"" . $fn . "\"\n";
fb3339 2503                         $output .= "        AuthUserFile " . $webdavRoot . '/' . $file . "\n";
ac933e 2504                         $output .= "        Require valid-user \n";
V 2505                         $output .= "        Options +Indexes \n";
2506                         $output .= "        Order allow,deny \n";
2507                         $output .= "        Allow from all \n";
2508                         $output .= "      </Location> \n";
2509                     }
2510                 }
fb3a98 2511                 }
ac933e 2512             }
V 2513             /*
2514              *  is the "replace-comment-end" found...
2515             */
2516             if (trim($line) == '# WEBDAV END') {
2517                 /*
2518                  * The end of the webdav - section is found, so stop ignoring
2519                 */
2520                 $inWebdavSection = false;
2521             }
2522
2523             /*
2524              * Write the line to the output, if it is not in the section
2525             */
2526             if (!$inWebdavSection) {
2527                 $output .= $line;
2528             }
2529         }
2530         fclose($in);
2531
2532         /*
2533          * Now lets write the new file
2534         */
c77103 2535         $app->system->file_put_contents($fileName, $output);
ac933e 2536
V 2537     }
58c210 2538     
T 2539     //* Update the awstats configuration file
2540     private function awstats_update ($data,$web_config) {
2541         global $app;
2542         
6fb93d 2543         $web_folder = $data['new']['web_folder'];
M 2544         if($data['new']['type'] == 'vhost') $web_folder = 'web';
2a6eac 2545         $awstats_conf_dir = $web_config['awstats_conf_dir'];
T 2546         
6fb93d 2547         if(!is_dir($data['new']['document_root']."/" . $web_folder . "/stats/")) mkdir($data['new']['document_root']."/" . $web_folder . "/stats");
fb3339 2548         if(!@is_file($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf') || ($data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain'])) {
J 2549             if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) {
c77103 2550                 $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf');
58c210 2551             }
T 2552             
2553             $content = '';
2a6eac 2554             $content .= "Include \"".$awstats_conf_dir."/awstats.conf\"\n";
fb3339 2555             $content .= "LogFile=\"/var/log/ispconfig/httpd/".$data['new']['domain']."/access.log\"\n";
J 2556             $content .= "SiteDomain=\"".$data['new']['domain']."\"\n";
2557             $content .= "HostAliases=\"www.".$data['new']['domain']."  localhost 127.0.0.1\"\n";
58c210 2558             
c77103 2559             $app->system->file_put_contents($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf',$content);
fb3339 2560             $app->log('Created AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf',LOGLEVEL_DEBUG);
58c210 2561         }
d81a4c 2562         
6fb93d 2563         if(is_file($data['new']['document_root']."/" . $web_folder . "/stats/index.html")) $app->system->unlink($data['new']['document_root']."/" . $web_folder . "/stats/index.html");
a464e1 2564         if(file_exists("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master")) {
T 2565             $app->system->copy("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master",$data['new']['document_root']."/" . $web_folder . "/stats/index.php");
2566         } else {
2567             $app->system->copy("/usr/local/ispconfig/server/conf/awstats_index.php.master",$data['new']['document_root']."/" . $web_folder . "/stats/index.php");
2568         }
58c210 2569     }
T 2570     
2571     //* Delete the awstats configuration file
2572     private function awstats_delete ($data,$web_config) {
2573         global $app;
2574         
2575         $awstats_conf_dir = $web_config['awstats_conf_dir'];
2576         
fb3339 2577         if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) {
c77103 2578             $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf');
fb3339 2579             $app->log('Removed AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf',LOGLEVEL_DEBUG);
58c210 2580         }
T 2581     }
1ca823 2582     
274362 2583     //* Update the PHP-FPM pool configuration file
F 2584     private function php_fpm_pool_update ($data,$web_config,$pool_dir,$pool_name,$socket_dir) {
2585         global $app, $conf;
2586         //$reload = false;
2587         
62e4b3 2588         if($data['new']['php'] == 'php-fpm'){
F 2589             if(trim($data['new']['fastcgi_php_version']) != ''){
2590                 $default_php_fpm = false;
2591                 list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
2592                 if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/';
2593             } else {
2594                 $default_php_fpm = true;
2595             }
274362 2596         } else {
62e4b3 2597             if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
F 2598                 $default_php_fpm = false;
2599                 list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version']));
2600                 if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/';
2601             } else {
2602                 $default_php_fpm = true;
2603             }
274362 2604         }
F 2605         
2606         $app->uses("getconf");
2607         $web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
2608         
2609         if($data['new']['php'] != 'php-fpm'){
2610             if(@is_file($pool_dir.$pool_name.'.conf')){
c77103 2611                 $app->system->unlink($pool_dir.$pool_name.'.conf');
274362 2612                 //$reload = true;
F 2613             }
2614             if($data['old']['php'] == 'php-fpm'){
2615                 if(!$default_php_fpm){
2616                     $app->services->restartService('php-fpm','reload:'.$custom_php_fpm_init_script);
2617                 } else {
2618                     $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
2619                 }
2620             }
2621             //if($reload == true) $app->services->restartService('php-fpm','reload');
2622             return;
2623         }
2624                 
2625         $app->load('tpl');
2626         $tpl = new tpl();
2627         $tpl->newTemplate('php_fpm_pool.conf.master');
2628
2629         if($data['new']['php_fpm_use_socket'] == 'y'){
2630             $use_tcp = 0;
2631             $use_socket = 1;
c77103 2632             if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir);
274362 2633         } else {
F 2634             $use_tcp = 1;
2635             $use_socket = 0;
2636         }
2637         $tpl->setVar('use_tcp', $use_tcp);
2638         $tpl->setVar('use_socket', $use_socket);
2639             
2640         $fpm_socket = $socket_dir.$pool_name.'.sock';
2641         $tpl->setVar('fpm_socket', $fpm_socket);
2642             
2643         $tpl->setVar('fpm_pool', $pool_name);
2644         $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1);
2645         $tpl->setVar('fpm_user', $data['new']['system_user']);
2646         $tpl->setVar('fpm_group', $data['new']['system_group']);
dd7ce4 2647         $tpl->setVar('pm', $data['new']['pm']);
274362 2648         $tpl->setVar('pm_max_children', $data['new']['pm_max_children']);
F 2649         $tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']);
2650         $tpl->setVar('pm_min_spare_servers', $data['new']['pm_min_spare_servers']);
2651         $tpl->setVar('pm_max_spare_servers', $data['new']['pm_max_spare_servers']);
dd7ce4 2652         $tpl->setVar('pm_process_idle_timeout', $data['new']['pm_process_idle_timeout']);
F 2653         $tpl->setVar('pm_max_requests', $data['new']['pm_max_requests']);
274362 2654         $tpl->setVar('document_root', $data['new']['document_root']);
F 2655         $tpl->setVar('security_level',$web_config['security_level']);
2656         $php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']);
2657         $tpl->setVar('php_open_basedir', $php_open_basedir);
2658         if($php_open_basedir != ''){
2659             $tpl->setVar('enable_php_open_basedir', '');
2660         } else {
2661             $tpl->setVar('enable_php_open_basedir', ';');
2662         }
2663             
2664         // Custom php.ini settings
2665         $final_php_ini_settings = array();
2666         $custom_php_ini_settings = trim($data['new']['custom_php_ini']);
2667         if($custom_php_ini_settings != ''){
2668             // Make sure we only have Unix linebreaks
2669             $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings);
2670             $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings);
2671             $ini_settings = explode("\n", $custom_php_ini_settings);
2672             if(is_array($ini_settings) && !empty($ini_settings)){
2673                 foreach($ini_settings as $ini_setting){
254a4a 2674                     $ini_setting = trim($ini_setting);
F 2675                     if(substr($ini_setting,0,1) == ';') continue;
2676                     if(substr($ini_setting,0,1) == '#') continue;
2677                     if(substr($ini_setting,0,2) == '//') continue;
2678                     list($key, $value) = explode('=', $ini_setting);
2679                     if($value){
2680                         $value = trim($value);
2681                         $key = trim($key);
2682                         switch (strtolower($value)) {
2683                             case '0':
2684                                 // PHP-FPM might complain about invalid boolean value if you use 0
2685                                 $value = 'off';
2686                             case '1':
2687                             case 'on':
2688                             case 'off':
2689                             case 'true':
2690                             case 'false':
2691                             case 'yes':
2692                             case 'no':
2693                                 $final_php_ini_settings[] = array('ini_setting' => 'php_admin_flag['.$key.'] = '.$value);
2694                                 break;
2695                             default:
2696                                 $final_php_ini_settings[] = array('ini_setting' => 'php_admin_value['.$key.'] = '.$value);
274362 2697                         }
254a4a 2698                     }
274362 2699                 }
F 2700             }
2701         }
2702             
2703         $tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings);
2704             
c77103 2705         $app->system->file_put_contents($pool_dir.$pool_name.'.conf',$tpl->grab());
274362 2706         $app->log('Writing the PHP-FPM config file: '.$pool_dir.$pool_name.'.conf',LOGLEVEL_DEBUG);
F 2707         unset($tpl);
2708         
2709         // delete pool in all other PHP versions
2710         $default_pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
2711         if(substr($default_pool_dir,-1) != '/') $default_pool_dir .= '/';
2712         if($default_pool_dir != $pool_dir){
2713             if ( @is_file($default_pool_dir.$pool_name.'.conf') ) {
c77103 2714                     $app->system->unlink($default_pool_dir.$pool_name.'.conf');
274362 2715                     $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf',LOGLEVEL_DEBUG);
F 2716                     $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
2717             }
2718         }
2719         $php_versions = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".$conf["server_id"]);
2720         if(is_array($php_versions) && !empty($php_versions)){
2721             foreach($php_versions as $php_version){
2722                 if(substr($php_version['php_fpm_pool_dir'],-1) != '/') $php_version['php_fpm_pool_dir'] .= '/';
2723                 if($php_version['php_fpm_pool_dir'] != $pool_dir){
2724                     if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) {
c77103 2725                         $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf');
274362 2726                         $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf',LOGLEVEL_DEBUG);
F 2727                         $app->services->restartService('php-fpm','reload:'.$php_version['php_fpm_init_script']);
2728                     }
2729                 }
2730             }
2731         }
2732         // Reload current PHP-FPM after all others
2733         sleep(1);
2734         if(!$default_php_fpm){
2735             $app->services->restartService('php-fpm','reload:'.$custom_php_fpm_init_script);
2736         } else {
2737             $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
2738         }
2739         
2740         //$reload = true;
2741
2742         //if($reload == true) $app->services->restartService('php-fpm','reload');
2743     }
2744     
2745     //* Delete the PHP-FPM pool configuration file
2746     private function php_fpm_pool_delete ($data,$web_config) {
2747         global $app, $conf;
2748         
62e4b3 2749         if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
274362 2750             $default_php_fpm = false;
F 2751             list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version']));
2752             if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/';
2753         } else {
2754             $default_php_fpm = true;
2755         }
2756         
2757         if($default_php_fpm){
2758             $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
2759         } else {
2760             $pool_dir = $custom_php_fpm_pool_dir;
2761         }
2762         
2763         if(substr($pool_dir,-1) != '/') $pool_dir .= '/';
2764         $pool_name = 'web'.$data['old']['domain_id'];
2765         
2766         if ( @is_file($pool_dir.$pool_name.'.conf') ) {
c77103 2767             $app->system->unlink($pool_dir.$pool_name.'.conf');
274362 2768             $app->log('Removed PHP-FPM config file: '.$pool_dir.$pool_name.'.conf',LOGLEVEL_DEBUG);
F 2769             
2770             //$app->services->restartService('php-fpm','reload');
2771         }
2772         
2773         // delete pool in all other PHP versions
2774         $default_pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
2775         if(substr($default_pool_dir,-1) != '/') $default_pool_dir .= '/';
2776         if($default_pool_dir != $pool_dir){
2777             if ( @is_file($default_pool_dir.$pool_name.'.conf') ) {
c77103 2778                     $app->system->unlink($default_pool_dir.$pool_name.'.conf');
274362 2779                     $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf',LOGLEVEL_DEBUG);
F 2780                     $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
2781             }
2782         }    
2783         $php_versions = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".$data['old']['server_id']);
2784         if(is_array($php_versions) && !empty($php_versions)){
2785             foreach($php_versions as $php_version){
2786                 if(substr($php_version['php_fpm_pool_dir'],-1) != '/') $php_version['php_fpm_pool_dir'] .= '/';
2787                 if($php_version['php_fpm_pool_dir'] != $pool_dir){
2788                     if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) {
c77103 2789                         $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf');
274362 2790                         $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf',LOGLEVEL_DEBUG);
F 2791                         $app->services->restartService('php-fpm','reload:'.$php_version['php_fpm_init_script']);
2792                     }
2793                 }
2794             }
2795         }
2796         
2797         // Reload current PHP-FPM after all others
2798         sleep(1);
2799         if(!$default_php_fpm){
2800             $app->services->restartService('php-fpm','reload:'.$custom_php_fpm_init_script);
2801         } else {
2802             $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
2803         }
2804     }
2805     
1ca823 2806     function client_delete($event_name,$data) {
T 2807         global $app, $conf;
2808         
2809         $app->uses("getconf");
2810         $web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
2811         
2812         $client_id = intval($data['old']['client_id']);
2813         if($client_id > 0) {
2814             
2815             $client_dir = $web_config['website_basedir'].'/clients/client'.$client_id;
2816             if(is_dir($client_dir) && !stristr($client_dir,'..')) {
72695f 2817                 // remove symlinks from $client_dir
T 2818                 $files = array_diff(scandir($client_dir), array('.','..'));
2819                 if(is_array($files) && !empty($files)){
2820                     foreach($files as $file){
2821                         if(is_link($client_dir.'/'.$file)){
2822                             unlink($client_dir.'/'.$file);
2823                             $app->log('Removed symlink: '.$client_dir.'/'.$file,LOGLEVEL_DEBUG);
2824                         }
2825                     }
2826                 }
2827                 
1ca823 2828                 @rmdir($client_dir);
T 2829                 $app->log('Removed client directory: '.$client_dir,LOGLEVEL_DEBUG);
2830             }
2831             
2832             $this->_exec('groupdel client'.$client_id);
2833             $app->log('Removed group client'.$client_id,LOGLEVEL_DEBUG);
2834         }
2835         
2836     }
ac933e 2837
1c40af 2838     //* Wrapper for exec function for easier debugging
T 2839     private function _exec($command) {
2840         global $app;
fb3339 2841         $app->log('exec: '.$command,LOGLEVEL_DEBUG);
1c40af 2842         exec($command);
T 2843     }
7ed741 2844     
T 2845     private function _checkTcp ($host,$port) {
2846
2847         $fp = @fsockopen ($host, $port, $errno, $errstr, 2);
2848
2849         if ($fp) {
2850             fclose($fp);
2851             return true;
2852         } else {
2853             return false;
2854         }
2855     }
ac933e 2856
552178 2857     public function create_relative_link($f, $t) {
bfcdef 2858         global $app;
T 2859         
552178 2860         // $from already exists
M 2861         $from = realpath($f);
2862
2863         // realpath requires the traced file to exist - so, lets touch it first, then remove
c77103 2864         @$app->system->unlink($t); touch($t);
552178 2865         $to = realpath($t);
c77103 2866         @$app->system->unlink($t);
552178 2867
M 2868         // Remove from the left side matching path elements from $from and $to
2869         // and get path elements counts
2870         $a1 = explode('/', $from); $a2 = explode('/', $to);
2871         for ($c = 0; $a1[$c] == $a2[$c]; $c++) {
2872             unset($a1[$c]); unset($a2[$c]);
2873         }
2874         $cfrom = implode('/', $a1);
2875
2876         // Check if a path is fully a subpath of another - no way to create symlink in the case
2877         if (count($a1) == 0 || count($a2) == 0) return false;
2878
2879         // Add ($cnt_to-1) number of "../" elements to left side of $cfrom
2880         for ($c = 0; $c < (count($a2)-1); $c++) { $cfrom = '../'.$cfrom; }
2881
2882         return symlink($cfrom, $to);
2883     }
46c683 2884
95e8ce 2885     private function _rewrite_quote($string) {
M 2886         return str_replace(array('.', '*', '?', '+'), array('\\.', '\\*', '\\?', '\\+'), $string);
2887     }
2888     
046d62 2889     private function _is_url($string) {
M 2890         return preg_match('/^(f|ht)tp(s)?:\/\//i', $string);
2891     }
bfcdef 2892     
T 2893     private function get_seo_redirects($web, $prefix = ''){
2894         $seo_redirects = array();
2895         
2896         if(substr($web['domain'], 0, 2) === '*.') $web['subdomain'] = '*';
2897         
2898         if($web['subdomain'] == 'www' || $web['subdomain'] == '*'){
2899             if($web['seo_redirect'] == 'non_www_to_www'){
2900                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = str_replace('.', '\.', $web['domain']);
2901                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain'];
2902                 $seo_redirects[$prefix.'seo_redirect_operator'] = '';
2903             }
2904             if($web['seo_redirect'] == '*_domain_tld_to_www_domain_tld'){
2905                 // ^(example\.com|(?!\bwww\b)\.example\.com)$
2906                 // ^(example\.com|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.example\.com))$
2907                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '('.str_replace('.', '\.', $web['domain']).'|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.'.str_replace('.', '\.', $web['domain']).'))';
2908                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain'];
2909                 $seo_redirects[$prefix.'seo_redirect_operator'] = '';
2910             }
2911             if($web['seo_redirect'] == '*_to_www_domain_tld'){
2912                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www\.'.str_replace('.', '\.', $web['domain']);
2913                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain'];
2914                 $seo_redirects[$prefix.'seo_redirect_operator'] = '!';
2915             }
2916         }
2917         if($web['seo_redirect'] == 'www_to_non_www'){
2918             $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www\.'.str_replace('.', '\.', $web['domain']);
2919             $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain'];
2920             $seo_redirects[$prefix.'seo_redirect_operator'] = '';
2921         }
2922         if($web['seo_redirect'] == '*_domain_tld_to_domain_tld'){
2923             // ^(.+)\.example\.com$
2924             $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '(.+)\.'.str_replace('.', '\.', $web['domain']);
2925             $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain'];
2926             $seo_redirects[$prefix.'seo_redirect_operator'] = '';
2927         }
2928         if($web['seo_redirect'] == '*_to_domain_tld'){
2929             $seo_redirects[$prefix.'seo_redirect_origin_domain'] = str_replace('.', '\.', $web['domain']);
2930             $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain'];
2931             $seo_redirects[$prefix.'seo_redirect_operator'] = '!';
2932         }
2933         return $seo_redirects;
2934     }
046d62 2935     
46c683 2936 } // end class
T 2937
c09f04 2938 ?>