shelluser_base_plugin.inc.php 20.2 KB
Newer Older
tbrehm's avatar
tbrehm committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
<?php

/*
Copyright (c) 2007, Till Brehm, projektfarm Gmbh
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
    * Neither the name of ISPConfig nor the names of its contributors
      may be used to endorse or promote products derived from this software without
      specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

class shelluser_base_plugin {
32

tbrehm's avatar
tbrehm committed
33 34 35
	var $plugin_name = 'shelluser_base_plugin';
	var $class_name = 'shelluser_base_plugin';
	var $min_uid = 499;
36

tbrehm's avatar
tbrehm committed
37 38 39 40
	//* This function is called during ispconfig installation to determine
	//  if a symlink shall be created for this plugin.
	function onInstall() {
		global $conf;
41

tbrehm's avatar
tbrehm committed
42 43 44 45 46
		if($conf['services']['web'] == true) {
			return true;
		} else {
			return false;
		}
47

tbrehm's avatar
tbrehm committed
48
	}
49 50


tbrehm's avatar
tbrehm committed
51 52 53
	/*
	 	This function is called when the plugin is loaded
	*/
54

tbrehm's avatar
tbrehm committed
55 56
	function onLoad() {
		global $app;
57

tbrehm's avatar
tbrehm committed
58 59 60
		/*
		Register for the events
		*/
61
		
62 63 64
		$app->plugins->registerEvent('shell_user_insert', $this->plugin_name, 'insert');
		$app->plugins->registerEvent('shell_user_update', $this->plugin_name, 'update');
		$app->plugins->registerEvent('shell_user_delete', $this->plugin_name, 'delete');
65
		
66

tbrehm's avatar
tbrehm committed
67
	}
68 69 70


	function insert($event_name, $data) {
tbrehm's avatar
tbrehm committed
71
		global $app, $conf;
72 73 74 75 76 77 78 79
		
		$app->uses('system,getconf');
		
		$security_config = $app->getconf->get_security_config('permissions');
		if($security_config['allow_shell_user'] != 'yes') {
			$app->log('Shell user plugin disabled by security settings.',LOGLEVEL_WARN);
			return false;
		}
80

81
		//* Check if the resulting path is inside the docroot
82
		$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']);
83 84 85 86 87 88
		if(substr($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(strpos($data['new']['dir'], '/../') !== false || substr($data['new']['dir'],-3) == '/..') {
			$app->log('Directory of the shell user is not valid.',LOGLEVEL_WARN);
89 90
			return false;
		}
Marius Cramer's avatar
Marius Cramer committed
91 92 93 94 95 96 97
		
		if(!$app->system->is_allowed_user($data['new']['username'], false, false)
			|| !$app->system->is_allowed_user($data['new']['puser'], true, true)
			|| !$app->system->is_allowed_group($data['new']['pgroup'], true, true)) {
			$app->log('Shell user must not be root or in group root.',LOGLEVEL_WARN);
			return false;
		}
98

Marius Cramer's avatar
Marius Cramer committed
99 100
		if($data['new']['active'] != 'y') $data['new']['shell'] = '/bin/false';
		
tbrehm's avatar
tbrehm committed
101
		if($app->system->is_user($data['new']['puser'])) {
102

tbrehm's avatar
tbrehm committed
103 104 105
			// Get the UID of the parent user
			$uid = intval($app->system->getuid($data['new']['puser']));
			if($uid > $this->min_uid) {
106 107
				//* Remove webfolder protection
				$app->system->web_folder_protection($web['document_root'], false);
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
				
				//* Home directory of the new shell user
				if($data['new']['chroot'] == 'jailkit') {
					$homedir = $data['new']['dir'];
				} else {
					$homedir = $data['new']['dir'].'/home/'.$data['new']['username'];
				}
				
				if(!is_dir($data['new']['dir'].'/home')){
					$app->file->mkdirs(escapeshellcmd($data['new']['dir'].'/home'), '0750');
					$app->system->chown(escapeshellcmd($data['new']['dir'].'/home'),escapeshellcmd($data['new']['puser']));
					$app->system->chgrp(escapeshellcmd($data['new']['dir'].'/home'),escapeshellcmd($data['new']['pgroup']));
				}
				
				if(!is_dir($homedir)){
					$app->file->mkdirs(escapeshellcmd($homedir), '0750');
					$app->system->chown(escapeshellcmd($homedir),escapeshellcmd($data['new']['puser']));
					$app->system->chgrp(escapeshellcmd($homedir),escapeshellcmd($data['new']['pgroup']));
126
				}
tbrehm's avatar
tbrehm committed
127
				$command = 'useradd';
128
				$command .= ' -d '.escapeshellcmd($homedir);
tbrehm's avatar
tbrehm committed
129 130 131 132 133
				$command .= ' -g '.escapeshellcmd($data['new']['pgroup']);
				$command .= ' -o '; // non unique
				if($data['new']['password'] != '') $command .= ' -p '.escapeshellcmd($data['new']['password']);
				$command .= ' -s '.escapeshellcmd($data['new']['shell']);
				$command .= ' -u '.escapeshellcmd($uid);
tbrehm's avatar
tbrehm committed
134
				$command .= ' '.escapeshellcmd($data['new']['username']);
135

tbrehm's avatar
tbrehm committed
136
				exec($command);
137 138 139
				$app->log("Executed command: ".$command, LOGLEVEL_DEBUG);
				$app->log("Added shelluser: ".$data['new']['username'], LOGLEVEL_DEBUG);

140 141 142 143 144
				// call the ssh-rsa update function
				$app->uses("getconf");
				$this->data = $data;
				$this->app = $app;
				$this->_setup_ssh_rsa();
145

146
				//* Create .bash_history file
147 148 149 150
				$app->system->touch(escapeshellcmd($homedir).'/.bash_history');
				$app->system->chmod(escapeshellcmd($homedir).'/.bash_history', 0755);
				$app->system->chown(escapeshellcmd($homedir).'/.bash_history', $data['new']['username']);
				$app->system->chgrp(escapeshellcmd($homedir).'/.bash_history', $data['new']['pgroup']);
151

tbrehm's avatar
tbrehm committed
152 153
				//* Disable shell user temporarily if we use jailkit
				if($data['new']['chroot'] == 'jailkit') {
154
					$command = 'usermod -s /bin/false -L '.escapeshellcmd($data['new']['username']).' 2>/dev/null';
tbrehm's avatar
tbrehm committed
155
					exec($command);
156
					$app->log("Disabling shelluser temporarily: ".$command, LOGLEVEL_DEBUG);
tbrehm's avatar
tbrehm committed
157
				}
158

159
				//* Add webfolder protection again
160
				$app->system->web_folder_protection($web['document_root'], true);
tbrehm's avatar
tbrehm committed
161
			} else {
162
				$app->log("UID = $uid for shelluser:".$data['new']['username']." not allowed.", LOGLEVEL_ERROR);
tbrehm's avatar
tbrehm committed
163 164
			}
		} else {
165
			$app->log("Skipping insertion of user:".$data['new']['username'].", parent user ".$data['new']['puser']." does not exist.", LOGLEVEL_WARN);
tbrehm's avatar
tbrehm committed
166 167
		}
	}
168 169

	function update($event_name, $data) {
tbrehm's avatar
tbrehm committed
170
		global $app, $conf;
171

172 173 174 175 176 177 178
		$app->uses('system,getconf');
		
		$security_config = $app->getconf->get_security_config('permissions');
		if($security_config['allow_shell_user'] != 'yes') {
			$app->log('Shell user plugin disabled by security settings.',LOGLEVEL_WARN);
			return false;
		}
179

180
		//* Check if the resulting path is inside the docroot
181
		$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']);
182 183 184 185 186 187 188
		if(substr($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(strpos($data['new']['dir'], '/../') !== false || substr($data['new']['dir'],-3) == '/..') {
			$app->log('Directory of the shell user is not valid.',LOGLEVEL_WARN);
189 190
			return false;
		}
191

Marius Cramer's avatar
Marius Cramer committed
192 193 194 195 196 197 198
		if(!$app->system->is_allowed_user($data['new']['username'], false, false)
			|| !$app->system->is_allowed_user($data['new']['puser'], true, true)
			|| !$app->system->is_allowed_group($data['new']['pgroup'], true, true)) {
			$app->log('Shell user must not be root or in group root.',LOGLEVEL_WARN);
			return false;
		}
		
Marius Cramer's avatar
Marius Cramer committed
199 200
		if($data['new']['active'] != 'y') $data['new']['shell'] = '/bin/false';
		
tbrehm's avatar
tbrehm committed
201 202 203 204
		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) {
205 206 207 208 209 210 211 212 213 214
				
				//* Home directory of the shell user
				if($data['new']['chroot'] == 'jailkit') {
					$homedir = $data['new']['dir'];
					$homedir_old = $data['old']['dir'];
				} else {
					$homedir = $data['new']['dir'].'/home/'.$data['new']['username'];
					$homedir_old = $data['old']['dir'].'/home/'.$data['old']['username'];
				}
				
tbrehm's avatar
tbrehm committed
215 216
				// Check if the user that we want to update exists, if not, we insert it
				if($app->system->is_user($data['old']['username'])) {
217
					/*
tbrehm's avatar
tbrehm committed
218 219 220 221 222 223 224 225 226
					$command = 'usermod';
					$command .= ' --home '.escapeshellcmd($data['new']['dir']);
					$command .= ' --gid '.escapeshellcmd($data['new']['pgroup']);
					// $command .= ' --non-unique ';
					$command .= ' --password '.escapeshellcmd($data['new']['password']);
					if($data['new']['chroot'] != 'jailkit') $command .= ' --shell '.escapeshellcmd($data['new']['shell']);
					// $command .= ' --uid '.escapeshellcmd($uid);
					$command .= ' --login '.escapeshellcmd($data['new']['username']);
					$command .= ' '.escapeshellcmd($data['old']['username']);
227

tbrehm's avatar
tbrehm committed
228
					exec($command);
tbrehm's avatar
tbrehm committed
229
					$app->log("Executed command: $command ",LOGLEVEL_DEBUG);
230
					*/
231
					//$groupinfo = $app->system->posix_getgrnam($data['new']['pgroup']);
232 233 234 235 236 237 238 239
					if($homedir != $homedir_old && !is_dir($homedir)){
						$app->system->web_folder_protection($web['document_root'], false);
						if(!is_dir($data['new']['dir'].'/home')){
							$app->file->mkdirs(escapeshellcmd($data['new']['dir'].'/home'), '0750');
							$app->system->chown(escapeshellcmd($data['new']['dir'].'/home'),escapeshellcmd($data['new']['puser']));
							$app->system->chgrp(escapeshellcmd($data['new']['dir'].'/home'),escapeshellcmd($data['new']['pgroup']));
						}
						$app->file->mkdirs(escapeshellcmd($homedir), '0750');
240
						$app->system->chown(escapeshellcmd($homedir),escapeshellcmd($data['new']['puser']));
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
						$app->system->chgrp(escapeshellcmd($homedir),escapeshellcmd($data['new']['pgroup']));
						$app->system->web_folder_protection($web['document_root'], true);
					} else {
						if(!is_dir($homedir)){
							$app->system->web_folder_protection($web['document_root'], false);
							if(!is_dir($data['new']['dir'].'/home')){
								$app->file->mkdirs(escapeshellcmd($data['new']['dir'].'/home'), '0750');
								$app->system->chown(escapeshellcmd($data['new']['dir'].'/home'),escapeshellcmd($data['new']['puser']));
								$app->system->chgrp(escapeshellcmd($data['new']['dir'].'/home'),escapeshellcmd($data['new']['pgroup']));
							}
							$app->file->mkdirs(escapeshellcmd($homedir), '0750');
							$app->system->chown(escapeshellcmd($homedir),escapeshellcmd($data['new']['puser']));
							$app->system->chgrp(escapeshellcmd($homedir),escapeshellcmd($data['new']['pgroup']));
							$app->system->web_folder_protection($web['document_root'], true);
						}
256
					}
257
					$app->system->usermod($data['old']['username'], 0, $app->system->getgid($data['new']['pgroup']), $homedir, $data['new']['shell'], $data['new']['password'], $data['new']['username']);
258 259
					$app->log("Updated shelluser: ".$data['old']['username'], LOGLEVEL_DEBUG);

260 261 262 263 264
					// call the ssh-rsa update function
					$app->uses("getconf");
					$this->data = $data;
					$this->app = $app;
					$this->_setup_ssh_rsa();
265

266 267
					//* Create .bash_history file
					if(!is_file($data['new']['dir']).'/.bash_history') {
268 269 270 271
						$app->system->touch(escapeshellcmd($homedir).'/.bash_history');
						$app->system->chmod(escapeshellcmd($homedir).'/.bash_history', 0755);
						$app->system->chown(escapeshellcmd($homedir).'/.bash_history', escapeshellcmd($data['new']['username']));
						$app->system->chgrp(escapeshellcmd($homedir).'/.bash_history', escapeshellcmd($data['new']['pgroup']));
272
					}
273

tbrehm's avatar
tbrehm committed
274 275
				} else {
					// The user does not exist, so we insert it now
276
					$this->insert($event_name, $data);
tbrehm's avatar
tbrehm committed
277 278
				}
			} else {
279
				$app->log("UID = $uid for shelluser:".$data['new']['username']." not allowed.", LOGLEVEL_ERROR);
tbrehm's avatar
tbrehm committed
280 281
			}
		} else {
282
			$app->log("Skipping update for user:".$data['new']['username'].", parent user ".$data['new']['puser']." does not exist.", LOGLEVEL_WARN);
tbrehm's avatar
tbrehm committed
283 284
		}
	}
285 286

	function delete($event_name, $data) {
tbrehm's avatar
tbrehm committed
287
		global $app, $conf;
288

289
		$app->uses('system,getconf,services');
290 291 292 293 294 295
		
		$security_config = $app->getconf->get_security_config('permissions');
		if($security_config['allow_shell_user'] != 'yes') {
			$app->log('Shell user plugin disabled by security settings.',LOGLEVEL_WARN);
			return false;
		}
296

tbrehm's avatar
tbrehm committed
297 298 299 300
		if($app->system->is_user($data['old']['username'])) {
			// Get the UID of the user
			$userid = intval($app->system->getuid($data['old']['username']));
			if($userid > $this->min_uid) {
301 302
				$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($data['old']['parent_domain_id']));
					
303
				// check if we have to delete the dir
304
				$check = $app->db->queryOneRecord('SELECT shell_user_id FROM `shell_user` WHERE `dir` = ?', $data['old']['dir']);
305
				if(!$check && is_dir($data['old']['dir'])) {
306
					
307
					$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['old']['parent_domain_id']);
308 309
					$app->system->web_folder_protection($web['document_root'], false);
					
310
					// delete dir
311 312 313 314 315 316
					if($data['new']['chroot'] == 'jailkit') {
						$homedir = $data['old']['dir'];
					} else {
						$homedir = $data['old']['dir'].'/home/'.$data['old']['username'];
					}
				
317 318
					if(substr($homedir, -1) !== '/') $homedir .= '/';
					$files = array('.bash_logout', '.bash_history', '.bashrc', '.profile');
319
					$dirs = array('.ssh', '.cache');
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
					foreach($files as $delfile) {
						if(is_file($homedir . $delfile) && fileowner($homedir . $delfile) == $userid) unlink($homedir . $delfile);
					}
					foreach($dirs as $deldir) {
						if(is_dir($homedir . $deldir) && fileowner($homedir . $deldir) == $userid) exec('rm -rf ' . escapeshellarg($homedir . $deldir));
					}
					$empty = true;
					$dirres = opendir($homedir);
					if($dirres) {
						while(($entry = readdir($dirres)) !== false) {
							if($entry != '.' && $entry != '..') {
								$empty = false;
								break;
							}
						}
						closedir($dirres);
					}
					if($empty == true) {
						rmdir($homedir);
					}
					unset($files);
					unset($dirs);
342 343
					
					$app->system->web_folder_protection($web['document_root'], true);
344 345
				}
				
346 347
				// We delete only non jailkit users, jailkit users will be deleted by the jailkit plugin.
				if ($data['old']['chroot'] != "jailkit") {
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
					// if this web uses PHP-FPM, that PPH-FPM service must be stopped before we can delete this user
					if($web['php'] == 'php-fpm'){
						if(trim($web['fastcgi_php_version']) != ''){
							$default_php_fpm = false;
							list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($web['fastcgi_php_version']));
						} else {
							$default_php_fpm = true;
						}
						$web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
						if(!$default_php_fpm){
							$app->services->restartService('php-fpm', 'stop:'.$custom_php_fpm_init_script);
						} else {
							$app->services->restartService('php-fpm', 'stop:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
						}
					}
363
					$command = 'killall -u '.escapeshellcmd($data['old']['username']).' ; userdel -f';
364
					$command .= ' '.escapeshellcmd($data['old']['username']).' &> /dev/null';
365
					exec($command);
366
					$app->log("Deleted shelluser: ".$data['old']['username'], LOGLEVEL_DEBUG);
367 368 369 370 371 372 373 374
					// start PHP-FPM again
					if($web['php'] == 'php-fpm'){
						if(!$default_php_fpm){
							$app->services->restartService('php-fpm', 'start:'.$custom_php_fpm_init_script);
						} else {
							$app->services->restartService('php-fpm', 'start:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
						}
					}
375
				}
376

tbrehm's avatar
tbrehm committed
377
			} else {
378
				$app->log("UID = $userid for shelluser:".$data['old']['username']." not allowed.", LOGLEVEL_ERROR);
tbrehm's avatar
tbrehm committed
379 380
			}
		} else {
381
			$app->log("User:".$data['new']['username']." does not exist in in /etc/passwd, skipping delete.", LOGLEVEL_WARN);
tbrehm's avatar
tbrehm committed
382
		}
383

tbrehm's avatar
tbrehm committed
384
	}
385

386
	private function _setup_ssh_rsa() {
387
		global $app;
388
		$this->app->log("ssh-rsa setup shelluser_base", LOGLEVEL_DEBUG);
389
		// Get the client ID, username, and the key
390 391
		$domain_data = $this->app->db->queryOneRecord('SELECT sys_groupid FROM web_domain WHERE web_domain.domain_id = ?', $this->data['new']['parent_domain_id']);
		$sys_group_data = $this->app->db->queryOneRecord('SELECT * FROM sys_group WHERE sys_group.groupid = ?', $domain_data['sys_groupid']);
392 393
		$id = intval($sys_group_data['client_id']);
		$username= $sys_group_data['name'];
394
		$client_data = $this->app->db->queryOneRecord('SELECT * FROM client WHERE client.client_id = ?', $id);
395 396 397
		$userkey = $client_data['ssh_rsa'];
		unset($domain_data);
		unset($client_data);
398

399
		// ssh-rsa authentication variables
400 401
		//$sshrsa = $this->data['new']['ssh_rsa'];
		$sshrsa = '';
402
		$ssh_users = $app->db->queryAllRecords("SELECT ssh_rsa FROM shell_user WHERE parent_domain_id = ?", $this->data['new']['parent_domain_id']);
403 404 405 406 407 408
		if(is_array($ssh_users)) {
			foreach($ssh_users as $sshu) {
				if($sshu['ssh_rsa'] != '') $sshrsa .= "\n".$sshu['ssh_rsa'];
			}
		}
		$sshrsa = trim($sshrsa);
409
		$usrdir = escapeshellcmd($this->data['new']['dir']);
410 411 412 413
		//* Home directory of the new shell user
		if($this->data['new']['chroot'] == 'jailkit') {
			$usrdir = escapeshellcmd($this->data['new']['dir']);
		} else {
414
			$usrdir = escapeshellcmd($this->data['new']['dir'].'/home/'.$this->data['new']['username']);
415
		}
416 417
		$sshdir = $usrdir.'/.ssh';
		$sshkeys= $usrdir.'/.ssh/authorized_keys';
418

419 420
		$app->uses('file');
		$sshrsa = $app->file->unix_nl($sshrsa);
421 422
		$sshrsa = $app->file->remove_blank_lines($sshrsa, 0);

423
		// If this user has no key yet, generate a pair
424
		if ($userkey == '' && $id > 0){
425 426
			//Generate ssh-rsa-keys
			exec('ssh-keygen -t rsa -C '.$username.'-rsa-key-'.time().' -f /tmp/id_rsa -N ""');
427

428
			// use the public key that has been generated
429
			$userkey = $app->system->file_get_contents('/tmp/id_rsa.pub');
430

431
			// save keypair in client table
432
			$this->app->db->query("UPDATE client SET created_at = UNIX_TIMESTAMP(), id_rsa = ?, ssh_rsa = ? WHERE client_id = ?", $app->system->file_get_contents('/tmp/id_rsa'), $userkey, $id);
433

434 435
			$app->system->unlink('/tmp/id_rsa');
			$app->system->unlink('/tmp/id_rsa.pub');
436
			$this->app->log("ssh-rsa keypair generated for ".$username, LOGLEVEL_DEBUG);
437
		};
438 439

		if (!file_exists($sshkeys)){
440
			// add root's key
441
			$app->file->mkdirs($sshdir, '0700');
442
			if(is_file('/root/.ssh/authorized_keys')) $app->system->file_put_contents($sshkeys, $app->system->file_get_contents('/root/.ssh/authorized_keys'));
443

444
			// Remove duplicate keys
445
			$existing_keys = @file($sshkeys);
446
			$new_keys = explode("\n", $userkey);
447
			$final_keys_arr = @array_merge($existing_keys, $new_keys);
448 449 450 451 452 453 454
			$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)));
455

456
			// add the user's key
457
			$app->system->file_put_contents($sshkeys, $final_keys);
458
			$app->file->remove_blank_lines($sshkeys);
459
			$this->app->log("ssh-rsa authorisation keyfile created in ".$sshkeys, LOGLEVEL_DEBUG);
460
		}
461

462 463 464
		//* Get the keys
		$existing_keys = file($sshkeys);
		$new_keys = explode("\n", $sshrsa);
465 466
		$old_keys = explode("\n", $this->data['old']['ssh_rsa']);

467 468 469
		//* Remove all old keys
		if(is_array($old_keys)) {
			foreach($old_keys as $key => $val) {
470
				$k = array_search(trim($val), $existing_keys);
471
				unset($existing_keys[$k]);
472
			}
473
		}
474

475 476 477 478 479
		//* 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;
480
		}
481

482 483 484 485 486 487 488
		$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)));
489 490

		// add the custom key
491
		$app->system->file_put_contents($sshkeys, $final_keys);
492
		$app->file->remove_blank_lines($sshkeys);
493 494
		$this->app->log("ssh-rsa key updated in ".$sshkeys, LOGLEVEL_DEBUG);

495
		// set proper file permissions
496
		exec("chown -R ".escapeshellcmd($this->data['new']['puser']).":".escapeshellcmd($this->data['new']['pgroup'])." ".$sshdir);
497
		exec("chmod 600 '$sshkeys'");
498

499
	}
500

tbrehm's avatar
tbrehm committed
501 502 503

} // end class

504
?>