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