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