From 81d79a79e4b29e9314b64b2e4c49b48ae8319767 Mon Sep 17 00:00:00 2001 From: ftimme <ft@falkotimme.com> Date: Tue, 11 Oct 2011 08:50:45 -0400 Subject: [PATCH] - WebDAV Users: show only domains that run on Apache (because nginx does not have full WebDAV support). --- server/plugins-available/nginx_plugin.inc.php | 261 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 245 insertions(+), 16 deletions(-) diff --git a/server/plugins-available/nginx_plugin.inc.php b/server/plugins-available/nginx_plugin.inc.php index 4c9c2ab..640f070 100644 --- a/server/plugins-available/nginx_plugin.inc.php +++ b/server/plugins-available/nginx_plugin.inc.php @@ -79,6 +79,13 @@ */ $app->plugins->registerEvent('client_delete',$this->plugin_name,'client_delete'); + + $app->plugins->registerEvent('web_folder_user_insert',$this->plugin_name,'web_folder_user'); + $app->plugins->registerEvent('web_folder_user_update',$this->plugin_name,'web_folder_user'); + $app->plugins->registerEvent('web_folder_user_delete',$this->plugin_name,'web_folder_user'); + + $app->plugins->registerEvent('web_folder_update',$this->plugin_name,'web_folder_update'); + $app->plugins->registerEvent('web_folder_delete',$this->plugin_name,'web_folder_delete'); } // Handle the creation of SSL certificates @@ -660,7 +667,7 @@ $tpl->setVar('use_socket', $use_socket); $fpm_socket = $socket_dir.$pool_name.'.sock'; $tpl->setVar('fpm_socket', $fpm_socket); - $vhost_data['fpm_port'] = $web_config['php_fpm_start_port'] + $data['new']['domain_id'] + 1; + $vhost_data['fpm_port'] = $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1; // Custom nginx directives $final_nginx_directives = array(); @@ -819,6 +826,9 @@ //* Create basic http auth for website statistics $tpl->setVar('stats_auth_passwd_file', $data['new']['document_root']."/.htpasswd_stats"); + + // Create basic http auth for other directories + $tpl->setLoop('basic_auth_locations', $this->_create_web_folder_auth_configuration($data['new'])); $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost'); //* Make a backup copy of vhost file @@ -940,9 +950,9 @@ //* Check if this is a chrooted setup if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $apache_chrooted = true; + $nginx_chrooted = true; } else { - $apache_chrooted = false; + $nginx_chrooted = false; } if($data['old']['type'] != 'vhost' && $data['old']['parent_domain_id'] > 0) { @@ -957,21 +967,34 @@ } else { //* This is a website - // Deleting the vhost file, symlink and the data directory - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); - unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); - + // Deleting the vhost file, symlink and the data directory $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); + + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)){ + unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)){ + unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)){ + unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); + } + unlink($vhost_file); $app->log('Removing vhost file: '.$vhost_file,LOGLEVEL_DEBUG); $docroot = escapeshellcmd($data['old']['document_root']); if($docroot != '' && !stristr($docroot,'..')) exec('rm -rf '.$docroot); - - //remove the php fastgi starter script if available + //remove the php fastgi starter script and PHP-FPM pool definition if available if ($data['old']['php'] == 'fast-cgi') { + $this->php_fpm_pool_delete($data,$web_config); $fastcgi_starter_path = str_replace('[system_user]',$data['old']['system_user'],$web_config['fastcgi_starter_path']); if (is_dir($fastcgi_starter_path)) { exec('rm -rf '.$fastcgi_starter_path); @@ -1020,16 +1043,14 @@ $command = 'userdel'; $command .= ' '.$data['old']['system_user']; exec($command); - if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); + if($nginx_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); //* Remove the awstats configuration file if($data['old']['stats_type'] == 'awstats') { $this->awstats_delete($data,$web_config); } - if($data['old']['php'] == 'fast-cgi') { - $this->php_fpm_pool_delete($data,$web_config); - } + $app->services->restartServiceDelayed('httpd','reload'); } } @@ -1057,6 +1078,210 @@ $app->log('Writing the conf file: '.$vhost_file,LOGLEVEL_DEBUG); unset($tpl); + } + + //* Create or update the .htaccess folder protection + function web_folder_user($event_name,$data) { + global $app, $conf; + + $app->uses('system'); + + if($event_name == 'web_folder_user_delete') { + $folder_id = $data['old']['web_folder_id']; + } else { + $folder_id = $data['new']['web_folder_id']; + } + + $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ".intval($folder_id)); + $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id'])); + + if(!is_array($folder) or !is_array($website)) { + $app->log('Not able to retrieve folder or website record.',LOGLEVEL_DEBUG); + return false; + } + + //* Get the folder path. + if(substr($folder['path'],0,1) == '/') $folder['path'] = substr($folder['path'],1); + if(substr($folder['path'],-1) == '/') $folder['path'] = substr($folder['path'],0,-1); + $folder_path = escapeshellcmd($website['document_root'].'/web/'.$folder['path']); + if(substr($folder_path,-1 != '/')) $folder_path .= '/'; + + //* Check if the resulting path is inside the docroot + if(stristr($folder_path,'..') || stristr($folder_path,'./') || stristr($folder_path,'\\')) { + $app->log('Folder path "'.$folder_path.'" contains .. or ./.',LOGLEVEL_DEBUG); + return false; + } + + //* Create the folder path, if it does not exist + if(!is_dir($folder_path)) exec('mkdir -p '.$folder_path); + + //* Create empty .htpasswd file, if it does not exist + if(!is_file($folder_path.'.htpasswd')) { + touch($folder_path.'.htpasswd'); + chmod($folder_path.'.htpasswd',0755); + $app->log('Created file'.$folder_path.'.htpasswd',LOGLEVEL_DEBUG); + } + + $auth_users = $app->db->queryAllRecords("SELECT * FROM web_folder_user WHERE active = 'y' AND web_folder_id = ".intval($folder_id)); + $htpasswd_content = ''; + if(is_array($auth_users) && !empty($auth_users)){ + foreach($auth_users as $auth_user){ + $htpasswd_content .= $auth_user['username'].':'.$auth_user['password']."\n"; + } + } + $htpasswd_content = trim($htpasswd_content); + @file_put_contents($folder_path.'.htpasswd', $htpasswd_content); + $app->log('Changed .htpasswd file: '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG); + + /* + if($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') { + $app->system->removeLine($folder_path.'.htpasswd',$data['old']['username'].':'); + $app->log('Removed user: '.$data['old']['username'],LOGLEVEL_DEBUG); + } + + //* Add or remove the user from .htpasswd file + if($event_name == 'web_folder_user_delete') { + $app->system->removeLine($folder_path.'.htpasswd',$data['old']['username'].':'); + $app->log('Removed user: '.$data['old']['username'],LOGLEVEL_DEBUG); + } else { + if($data['new']['active'] == 'y') { + $app->system->replaceLine($folder_path.'.htpasswd',$data['new']['username'].':',$data['new']['username'].':'.$data['new']['password'],0,1); + $app->log('Added or updated user: '.$data['new']['username'],LOGLEVEL_DEBUG); + } + } + */ + + // write basic auth configuration to vhost file because nginx does not support .htaccess + $webdata['new'] = $webdata['old'] = $website; + $this->update('web_domain_update', $webdata); + } + + //* Remove .htpasswd file, when folder protection is removed + function web_folder_delete($event_name,$data) { + global $app, $conf; + + $folder_id = $data['old']['web_folder_id']; + + $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ".intval($folder_id)); + $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id'])); + + if(!is_array($folder) or !is_array($website)) { + $app->log('Not able to retrieve folder or website record.',LOGLEVEL_DEBUG); + return false; + } + + //* Get the folder path. + if(substr($folder['path'],0,1) == '/') $folder['path'] = substr($folder['path'],1); + if(substr($folder['path'],-1) == '/') $folder['path'] = substr($folder['path'],0,-1); + $folder_path = realpath($website['document_root'].'/web/'.$folder['path']); + if(substr($folder_path,-1 != '/')) $folder_path .= '/'; + + //* Check if the resulting path is inside the docroot + if(substr($folder_path,0,strlen($website['document_root'])) != $website['document_root']) { + $app->log('Folder path is outside of docroot.',LOGLEVEL_DEBUG); + return false; + } + + //* Remove .htpasswd file + if(is_file($folder_path.'.htpasswd')) { + unlink($folder_path.'.htpasswd'); + $app->log('Removed file '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG); + } + + // write basic auth configuration to vhost file because nginx does not support .htaccess + $webdata['new'] = $webdata['old'] = $website; + $this->update('web_domain_update', $webdata); + } + + //* Update folder protection, when path has been changed + function web_folder_update($event_name,$data) { + global $app, $conf; + + $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($data['new']['parent_domain_id'])); + + if(!is_array($website)) { + $app->log('Not able to retrieve folder or website record.',LOGLEVEL_DEBUG); + return false; + } + + //* Get the folder path. + if(substr($data['old']['path'],0,1) == '/') $data['old']['path'] = substr($data['old']['path'],1); + if(substr($data['old']['path'],-1) == '/') $data['old']['path'] = substr($data['old']['path'],0,-1); + $old_folder_path = escapeshellcmd($website['document_root'].'/web/'.$data['old']['path']); + if(substr($old_folder_path,-1 != '/')) $old_folder_path .= '/'; + + if(substr($data['new']['path'],0,1) == '/') $data['new']['path'] = substr($data['new']['path'],1); + if(substr($data['new']['path'],-1) == '/') $data['new']['path'] = substr($data['new']['path'],0,-1); + $new_folder_path = escapeshellcmd($website['document_root'].'/web/'.$data['new']['path']); + if(substr($new_folder_path,-1 != '/')) $new_folder_path .= '/'; + + //* Check if the resulting path is inside the docroot + if(stristr($new_folder_path,'..') || stristr($new_folder_path,'./') || stristr($new_folder_path,'\\')) { + $app->log('Folder path "'.$new_folder_path.'" contains .. or ./.',LOGLEVEL_DEBUG); + return false; + } + if(stristr($old_folder_path,'..') || stristr($old_folder_path,'./') || stristr($old_folder_path,'\\')) { + $app->log('Folder path "'.$old_folder_path.'" contains .. or ./.',LOGLEVEL_DEBUG); + return false; + } + + //* Check if the resulting path is inside the docroot + if(substr($old_folder_path,0,strlen($website['document_root'])) != $website['document_root']) { + $app->log('Old folder path '.$old_folder_path.' is outside of docroot.',LOGLEVEL_DEBUG); + return false; + } + if(substr($new_folder_path,0,strlen($website['document_root'])) != $website['document_root']) { + $app->log('New folder path '.$new_folder_path.' is outside of docroot.',LOGLEVEL_DEBUG); + return false; + } + + //* Create the folder path, if it does not exist + if(!is_dir($new_folder_path)) exec('mkdir -p '.$new_folder_path); + + if($data['old']['path'] != $data['new']['path']) { + + + //* move .htpasswd file + if(is_file($old_folder_path.'.htpasswd')) { + rename($old_folder_path.'.htpasswd',$new_folder_path.'.htpasswd'); + $app->log('Moved file '.$new_folder_path.'.htpasswd',LOGLEVEL_DEBUG); + } + + } + + // write basic auth configuration to vhost file because nginx does not support .htaccess + $webdata['new'] = $webdata['old'] = $website; + $this->update('web_domain_update', $webdata); + } + + function _create_web_folder_auth_configuration($website){ + global $app, $conf; + //* Create the domain.auth file which is included in the vhost configuration file + $app->uses('getconf'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + $basic_auth_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$website['domain'].'.auth'); + //$app->load('tpl'); + //$tpl = new tpl(); + //$tpl->newTemplate('nginx_http_authentication.auth.master'); + $website_auth_locations = $app->db->queryAllRecords("SELECT * FROM web_folder WHERE active = 'y' AND parent_domain_id = ".intval($website['domain_id'])); + $basic_auth_locations = array(); + if(is_array($website_auth_locations) && !empty($website_auth_locations)){ + foreach($website_auth_locations as $website_auth_location){ + if(substr($website_auth_location['path'],0,1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'],1); + if(substr($website_auth_location['path'],-1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'],0,-1); + if($website_auth_location['path'] != ''){ + $website_auth_location['path'] .= '/'; + } + $basic_auth_locations[] = array('htpasswd_location' => '/'.$website_auth_location['path'], + 'htpasswd_path' => $website['document_root'].'/web/'.$website_auth_location['path']); + } + } + return $basic_auth_locations; + //$tpl->setLoop('basic_auth_locations', $basic_auth_locations); + //file_put_contents($basic_auth_file,$tpl->grab()); + //$app->log('Writing the http basic authentication file: '.$basic_auth_file,LOGLEVEL_DEBUG); + //unset($tpl); + //$app->services->restartServiceDelayed('httpd','reload'); } //* Update the awstats configuration file @@ -1129,9 +1354,13 @@ $tpl->setVar('fpm_socket', $fpm_socket); $tpl->setVar('fpm_pool', $pool_name); - $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] + 1); + $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1); $tpl->setVar('fpm_user', $data['new']['system_user']); $tpl->setVar('fpm_group', $data['new']['system_group']); + $tpl->setVar('pm_max_children', $data['new']['pm_max_children']); + $tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']); + $tpl->setVar('pm_min_spare_servers', $data['new']['pm_min_spare_servers']); + $tpl->setVar('pm_max_spare_servers', $data['new']['pm_max_spare_servers']); $tpl->setVar('document_root', $data['new']['document_root']); $tpl->setVar('security_level',$web_config['security_level']); $php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']); @@ -1193,7 +1422,7 @@ $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); if(substr($pool_dir,-1) != '/') $pool_dir .= '/'; - $pool_name = 'web'.$data['new']['domain_id']; + $pool_name = 'web'.$data['old']['domain_id']; if ( @is_file($pool_dir.$pool_name.'.conf') ) { unlink($pool_dir.$pool_name.'.conf'); -- Gitblit v1.9.1