From ff6a68388bcf9524f5dc7380c44f826aa9e1bf19 Mon Sep 17 00:00:00 2001
From: tbrehm <t.brehm@ispconfig.org>
Date: Tue, 14 Aug 2012 14:15:52 +0000
Subject: [PATCH] Fixed: FS#2287 - Changing chroot shell option doesnt work

---
 server/lib/classes/monitor_tools.inc.php      |  3 +-
 server/lib/classes/system.inc.php             | 98 +++++++++++++++++++
 .../shelluser_base_plugin.inc.php             |  4 +
 .../shelluser_jailkit_plugin.inc.php          | 27 +++--
 server/server.php                             |  2 +-
 5 files changed, 124 insertions(+), 10 deletions(-)

diff --git a/server/lib/classes/monitor_tools.inc.php b/server/lib/classes/monitor_tools.inc.php
index b5ca043d09..d1ed1297be 100644
--- a/server/lib/classes/monitor_tools.inc.php
+++ b/server/lib/classes/monitor_tools.inc.php
@@ -117,7 +117,6 @@ class monitor_tools {
 					$relname = "UNKNOWN";
 				}
 				$distver = $ver.$lts." ".$relname;
-				swriteln("Operating System: ".$distver."\n");
 			} elseif(trim(file_get_contents('/etc/debian_version')) == '4.0') {
 				$distname = 'Debian';
 				$distver = '4.0';
@@ -1149,6 +1148,7 @@ class monitor_tools {
 			$data['output'] = shell_exec('tw_cli info c0');
 
 			$state = 'ok';
+			if(is_array($data['output'])) {
 			foreach ($data['output'] as $item) {
 				if (strpos($item, 'RAID') !== false) {
 					if (strpos($item, ' VERIFYING ') !== false) {
@@ -1192,6 +1192,7 @@ class monitor_tools {
 					}
 				}
 			}
+			}
 		}
 
 
diff --git a/server/lib/classes/system.inc.php b/server/lib/classes/system.inc.php
index 410a895e85..7a78a2b040 100644
--- a/server/lib/classes/system.inc.php
+++ b/server/lib/classes/system.inc.php
@@ -737,6 +737,7 @@ class system{
 	  	}
 	}
 	
+	/*
 	function usermod($user, $groups){
 		global $app;
 	  	if($this->is_user($user)){
@@ -776,6 +777,7 @@ class system{
 		    return false;
 	  	}
 	}
+	*/
 	
 	/**boot autostart etc
 	 *
@@ -1396,6 +1398,102 @@ class system{
 			if($document_root != '' && $document_root != '/' && strlen($document_root) > 6 && !stristr($document_root,'..')) exec('chattr -i '.escapeshellcmd($document_root));
 		}
 	}
+	
+	function usermod($username, $uid = 0, $gid = 0, $home = '', $shell = '', $password = '', $login = '') {
+		global $app;
+		
+		if($login == '') $login = $username;
+		
+		//* Change values in /etc/passwd
+		$passwd_file_array = file('/etc/passwd');
+		if(is_array($passwd_file_array)) {
+			foreach($passwd_file_array as $line) {
+				$line = trim($line);
+				$parts = explode(':',$line);
+				if($parts[0] == $username) {
+					if(trim($login) != '' && trim($login) != trim($username)) $parts[0] = trim($login);
+					if(!empty($uid)) $parts[2] = trim($uid);
+					if(!empty($gid)) $parts[3] = trim($gid);
+					if(trim($home) != '') $parts[5] = trim($home);
+					if(trim($shell) != '') $parts[6] = trim($shell);
+					$new_line = implode(':',$parts);
+					copy('/etc/passwd','/etc/passwd~');
+					chmod('/etc/passwd~',0600);
+					$app->uses('system');
+					$app->system->replaceLine('/etc/passwd',$line,$new_line,1,0);
+				}
+			}
+			unset($passwd_file_array);
+		}
+		
+		//* If username != login, change username in group and gshadow file
+		if($username  != $login) {
+			$group_file_array = file('/etc/group');
+			if(is_array($group_file_array)) {
+				foreach($group_file_array as $line) {
+					$line = trim($line);
+					$parts = explode(':',$line);
+					if(strstr($parts[3],$username)) {
+						$uparts = explode(',',$parts[3]);
+						if(is_array($uparts)) {
+							foreach($uparts as $key => $val) {
+								if($val == $username) $uparts[$key] = $login;
+							}
+						}
+						$parts[3] = implode(',',$uparts);
+						$new_line = implode(':',$parts);
+						copy('/etc/group','/etc/group~');
+						chmod('/etc/group~',0600);
+						$app->system->replaceLine('/etc/group',$line,$new_line,1,0);
+					}
+				}
+			}
+			unset($group_file_array);
+			
+			$gshadow_file_array = file('/etc/gshadow');
+			if(is_array($gshadow_file_array)) {
+				foreach($gshadow_file_array as $line) {
+					$line = trim($line);
+					$parts = explode(':',$line);
+					if(strstr($parts[3],$username)) {
+						$uparts = explode(',',$parts[3]);
+						if(is_array($uparts)) {
+							foreach($uparts as $key => $val) {
+								if($val == $username) $uparts[$key] = $login;
+							}
+						}
+						$parts[3] = implode(',',$uparts);
+						$new_line = implode(':',$parts);
+						copy('/etc/gshadow','/etc/gshadow~');
+						chmod('/etc/gshadow~',0600);
+						$app->system->replaceLine('/etc/gshadow',$line,$new_line,1,0);
+					}
+				}
+			}
+			unset($group_file_array);
+		}
+		
+		
+		//* When password or login name has been changed
+		if($password != '' || $username  != $login) {
+			$shadow_file_array = file('/etc/shadow');
+			if(is_array($shadow_file_array)) {
+				foreach($shadow_file_array as $line) {
+					$line = trim($line);
+					$parts = explode(':',$line);
+					if($parts[0] == $username) {
+						if(trim($login) != '' && trim($login) != trim($username)) $parts[0] = trim($login);
+						if(trim($password) != '') $parts[1] = trim($password);
+						$new_line = implode(':',$parts);
+						copy('/etc/shadow','/etc/shadow~');
+						chmod('/etc/shadow~',0600);
+						$app->system->replaceLine('/etc/shadow',$line,$new_line,1,0);
+					}
+				}
+			}
+			unset($shadow_file_array);
+		}
+	}
 
 }
 ?>
diff --git a/server/plugins-available/shelluser_base_plugin.inc.php b/server/plugins-available/shelluser_base_plugin.inc.php
index a56ec6d72d..d63b6b2219 100755
--- a/server/plugins-available/shelluser_base_plugin.inc.php
+++ b/server/plugins-available/shelluser_base_plugin.inc.php
@@ -148,6 +148,7 @@ class shelluser_base_plugin {
 			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']);
@@ -160,6 +161,9 @@ class shelluser_base_plugin {
 			
 					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
diff --git a/server/plugins-available/shelluser_jailkit_plugin.inc.php b/server/plugins-available/shelluser_jailkit_plugin.inc.php
index 6ffe8e87a2..322b1ba341 100755
--- a/server/plugins-available/shelluser_jailkit_plugin.inc.php
+++ b/server/plugins-available/shelluser_jailkit_plugin.inc.php
@@ -71,7 +71,7 @@ class shelluser_jailkit_plugin {
 		global $app, $conf;
 		
 		$app->uses('system');
-		$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$this->data['new']['parent_domain_id']);
+		$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$data['new']['parent_domain_id']);
 		
 		if($app->system->is_user($data['new']['username'])) {
 		
@@ -97,7 +97,12 @@ class shelluser_jailkit_plugin {
 				//* call the ssh-rsa update function
 				$this->_setup_ssh_rsa();
 				
-				$command .= 'usermod -s /usr/sbin/jk_chrootsh -U '.escapeshellcmd($data['new']['username']);
+				//$command .= 'usermod -s /usr/sbin/jk_chrootsh -U '.escapeshellcmd($data['new']['username']);
+				//exec($command);
+				$app->system->usermod($data['new']['username'], 0, 0, '', '/usr/sbin/jk_chrootsh', '', '');
+				
+				//* Unlock user
+				$command = 'usermod -U '.escapeshellcmd($data['new']['username']);
 				exec($command);
 				
 				$this->_update_website_security_level();
@@ -117,7 +122,7 @@ class shelluser_jailkit_plugin {
 		global $app, $conf;
 		
 		$app->uses('system');
-		$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$this->data['new']['parent_domain_id']);
+		$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$data['new']['parent_domain_id']);
 		
 		if($app->system->is_user($data['new']['username'])) {
 		
@@ -164,7 +169,7 @@ class shelluser_jailkit_plugin {
 		
 		$app->uses('system');
 		
-		$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$this->data['old']['parent_domain_id']);
+		$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$data['old']['parent_domain_id']);
 		
 		if ($data['old']['chroot'] == "jailkit")
 		{
@@ -285,6 +290,7 @@ class shelluser_jailkit_plugin {
 			//* Change the homedir of the shell user and parent user
 			//* We have to do this manually as the usermod command fails 
 			//* when the user is logged in or a command is running under that user
+			/*
 			$passwd_file_array = file('/etc/passwd');
 			$passwd_out = '';
 			if(is_array($passwd_file_array)) {
@@ -301,8 +307,10 @@ class shelluser_jailkit_plugin {
 						$app->system->replaceLine('/etc/passwd',$line,$new_line,1,0);
 					}
 				}
-			}
+			}*/
 			
+			$app->system->usermod($this->data['new']['username'], 0, 0, $this->data['new']['dir'].'/.'.$jailkit_chroot_userhome, '/usr/sbin/jk_chrootsh');
+			$app->system->usermod($this->data['new']['puser'], 0, 0, $this->data['new']['dir'].'/.'.$jailkit_chroot_userhome, '/usr/sbin/jk_chrootsh');
 				
 			$this->app->log("Added jailkit user to chroot with command: ".$command,LOGLEVEL_DEBUG);
 						
@@ -333,9 +341,12 @@ class shelluser_jailkit_plugin {
 		$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$this->data['new']['parent_domain_id']);
 		
 		//* If the security level is set to high
-		if($web_config['security_level'] == 20) {
-			$this->_exec('chmod 755 '.escapeshellcmd($web["document_root"]));
-			$this->_exec('chown root:root '.escapeshellcmd($web["document_root"]));
+		if($web_config['security_level'] == 20 && is_array($web)) {
+			$app->system->web_folder_protection($web["document_root"],false);
+			$app->system->chmod($web["document_root"],0755);
+			$app->system->chown($web["document_root"],'root');
+			$app->system->chgrp($web["document_root"],'root');
+			$app->system->web_folder_protection($web["document_root"],true);
 		}
 		
 	}
diff --git a/server/server.php b/server/server.php
index d371dcf57b..54a4b5b5ee 100644
--- a/server/server.php
+++ b/server/server.php
@@ -148,7 +148,7 @@ if ($app->db->connect_error == NULL && $app->dbmaster->connect_error == NULL) {
 	unset($tmp_rec);
 	
 	//** Load required base-classes
-	$app->uses('modules,plugins,file,services');
+	$app->uses('modules,plugins,file,services,system');
 	//** Load the modules that are in the mods-enabled folder
 	$app->modules->loadModules('all');
 	//** Load the plugins that are in the plugins-enabled folder
-- 
GitLab