From d87f76019fc231ec20d95126a7fee0487e7be5f0 Mon Sep 17 00:00:00 2001
From: tbrehm <t.brehm@ispconfig.org>
Date: Tue, 14 Aug 2012 10:56:20 -0400
Subject: [PATCH] - Added new web folder named private to web folder layout. The folder is intended to store data that shall not be visible in the web directory, it is owned by the user of the web. - Changed ownership of web root directory to root user in all security modes to prevent symlink attacks. - Apache log files are now owned by user root. - Improved functions in system library.

---
 server/plugins-available/shelluser_base_plugin.inc.php |   81 ++++++++++++++++++++++++++++++----------
 1 files changed, 61 insertions(+), 20 deletions(-)

diff --git a/server/plugins-available/shelluser_base_plugin.inc.php b/server/plugins-available/shelluser_base_plugin.inc.php
index 7677778..d63b6b2 100755
--- a/server/plugins-available/shelluser_base_plugin.inc.php
+++ b/server/plugins-available/shelluser_base_plugin.inc.php
@@ -72,7 +72,18 @@
 		
 		$app->uses('system');
 		
+		//* Check if the resulting path is inside the docroot
+		$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($data['new']['parent_domain_id']));
+		if(substr(realpath($data['new']['dir']),0,strlen($web['document_root'])) != $web['document_root']) {
+			$app->log('Directory of the shell user is outside of website docroot.',LOGLEVEL_WARN);
+			return false;
+		}
+		
 		if($app->system->is_user($data['new']['puser'])) {
+			
+			//* Remove webfolder protection
+			$app->system->web_folder_protection($web['document_root'],false);
+			
 			// Get the UID of the parent user
 			$uid = intval($app->system->getuid($data['new']['puser']));
 			if($uid > $this->min_uid) {
@@ -107,6 +118,9 @@
 					exec($command);
 					$app->log("Disabling shelluser temporarily: ".$command,LOGLEVEL_DEBUG);
 				}
+				
+				//* Add webfolder protection again
+				$app->system->web_folder_protection($web['document_root'],true);
 			
 			} else {
 				$app->log("UID = $uid for shelluser:".$data['new']['username']." not allowed.",LOGLEVEL_ERROR);
@@ -121,12 +135,20 @@
 		
 		$app->uses('system');
 		
+		//* Check if the resulting path is inside the docroot
+		$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($data['new']['parent_domain_id']));
+		if(substr(realpath($data['new']['dir']),0,strlen($web['document_root'])) != $web['document_root']) {
+			$app->log('Directory of the shell user is outside of website docroot.',LOGLEVEL_WARN);
+			return false;
+		}
+		
 		if($app->system->is_user($data['new']['puser'])) {
 			// Get the UID of the parent user
 			$uid = intval($app->system->getuid($data['new']['puser']));
 			if($uid > $this->min_uid) {
 				// Check if the user that we want to update exists, if not, we insert it
 				if($app->system->is_user($data['old']['username'])) {
+					/*
 					$command = 'usermod';
 					$command .= ' --home '.escapeshellcmd($data['new']['dir']);
 					$command .= ' --gid '.escapeshellcmd($data['new']['pgroup']);
@@ -139,6 +161,9 @@
 			
 					exec($command);
 					$app->log("Executed command: $command ",LOGLEVEL_DEBUG);
+					*/
+					$groupinfo = posix_getgrnam($data['new']['pgroup']);
+					$app->system->usermod($data['old']['username'],0, $groupinfo[gid], $data['new']['dir'], $data['new']['shell'], $data['new']['password'], $data['new']['username']);
 					$app->log("Updated shelluser: ".$data['old']['username'],LOGLEVEL_DEBUG);
 									
 					// call the ssh-rsa update function
@@ -234,13 +259,13 @@
 
 		if (!file_exists($sshkeys)){
 			// add root's key
-			$app->file->mkdirs($sshdir, '0755');
+			$app->file->mkdirs($sshdir, '0700');
 			if(is_file('/root/.ssh/authorized_keys')) file_put_contents($sshkeys, file_get_contents('/root/.ssh/authorized_keys'));
 		
 			// Remove duplicate keys
-			$existing_keys = file($sshkeys);
+			$existing_keys = @file($sshkeys);
 			$new_keys = explode("\n", $userkey);
-			$final_keys_arr = array_merge($existing_keys, $new_keys);
+			$final_keys_arr = @array_merge($existing_keys, $new_keys);
 			$new_final_keys_arr = array();
 			if(is_array($final_keys_arr) && !empty($final_keys_arr)){
 				foreach($final_keys_arr as $key => $val){
@@ -254,26 +279,42 @@
 			$app->file->remove_blank_lines($sshkeys);
 			$this->app->log("ssh-rsa authorisation keyfile created in ".$sshkeys,LOGLEVEL_DEBUG);
 		}
-		if ($sshrsa != ''){
-			// Remove duplicate keys
-			$existing_keys = file($sshkeys);
-			$new_keys = explode("\n", $sshrsa);
-			$final_keys_arr = array_merge($existing_keys, $new_keys);
-			$new_final_keys_arr = array();
-			if(is_array($final_keys_arr) && !empty($final_keys_arr)){
-				foreach($final_keys_arr as $key => $val){
-					$new_final_keys_arr[$key] = trim($val);
-				}
-			}
-			$final_keys = implode("\n", array_flip(array_flip($new_final_keys_arr)));
 			
-			// add the custom key 
-			file_put_contents($sshkeys, $final_keys);
-			$app->file->remove_blank_lines($sshkeys);
-			$this->app->log("ssh-rsa key updated in ".$sshkeys,LOGLEVEL_DEBUG);
+		//* Get the keys
+		$existing_keys = file($sshkeys);
+		$new_keys = explode("\n", $sshrsa);
+		$old_keys = explode("\n",$this->data['old']['ssh_rsa']);
+			
+		//* Remove all old keys
+		if(is_array($old_keys)) {
+			foreach($old_keys as $key => $val) {
+				$k = array_search(trim($val),$existing_keys);
+				unset($existing_keys[$k]);
+			}
 		}
+			
+		//* merge the remaining keys and the ones fom the ispconfig database.
+		if(is_array($new_keys)) {
+			$final_keys_arr = array_merge($existing_keys, $new_keys);
+		} else {
+			$final_keys_arr = $existing_keys;
+		}
+			
+		$new_final_keys_arr = array();
+		if(is_array($final_keys_arr) && !empty($final_keys_arr)){
+			foreach($final_keys_arr as $key => $val){
+				$new_final_keys_arr[$key] = trim($val);
+			}
+		}
+		$final_keys = implode("\n", array_flip(array_flip($new_final_keys_arr)));
+			
+		// add the custom key 
+		file_put_contents($sshkeys, $final_keys);
+		$app->file->remove_blank_lines($sshkeys);
+		$this->app->log("ssh-rsa key updated in ".$sshkeys,LOGLEVEL_DEBUG);
+		
 		// set proper file permissions
-		// exec("chown -R ".escapeshellcmd($this->data['new']['puser']).":".escapeshellcmd($this->data['new']['pgroup'])." ".$usrdir);
+		exec("chown -R ".escapeshellcmd($this->data['new']['puser']).":".escapeshellcmd($this->data['new']['pgroup'])." ".$sshdir);
 		exec("chmod 600 '$sshkeys'");
 		
 	}

--
Gitblit v1.9.1