Pascal Dreissen
2016-07-08 f1193b43f4c9fd132741d30f03f0b35841011989
commit | author | age
396f0e 1 <?php
T 2
3 /*
4 Copyright (c) 2007, Till Brehm, projektfarm Gmbh
5 All rights reserved.
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
31 class shelluser_base_plugin {
7fe908 32
396f0e 33     var $plugin_name = 'shelluser_base_plugin';
T 34     var $class_name = 'shelluser_base_plugin';
35     var $min_uid = 499;
7fe908 36
396f0e 37     //* This function is called during ispconfig installation to determine
T 38     //  if a symlink shall be created for this plugin.
39     function onInstall() {
40         global $conf;
7fe908 41
396f0e 42         if($conf['services']['web'] == true) {
T 43             return true;
44         } else {
45             return false;
46         }
7fe908 47
396f0e 48     }
7fe908 49
MC 50
396f0e 51     /*
T 52          This function is called when the plugin is loaded
53     */
7fe908 54
396f0e 55     function onLoad() {
T 56         global $app;
7fe908 57
396f0e 58         /*
T 59         Register for the events
60         */
9edea9 61         
7fe908 62         $app->plugins->registerEvent('shell_user_insert', $this->plugin_name, 'insert');
MC 63         $app->plugins->registerEvent('shell_user_update', $this->plugin_name, 'update');
64         $app->plugins->registerEvent('shell_user_delete', $this->plugin_name, 'delete');
9edea9 65         
7fe908 66
396f0e 67     }
7fe908 68
MC 69
70     function insert($event_name, $data) {
396f0e 71         global $app, $conf;
9edea9 72         
TB 73         $app->uses('system,getconf');
74         
75         $security_config = $app->getconf->get_security_config('permissions');
76         if($security_config['allow_shell_user'] != 'yes') {
77             $app->log('Shell user plugin disabled by security settings.',LOGLEVEL_WARN);
78             return false;
79         }
7fe908 80
b67344 81         //* Check if the resulting path is inside the docroot
cc7a82 82         $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']);
6d21f1 83         if(substr($data['new']['dir'],0,strlen($web['document_root'])) != $web['document_root']) {
FT 84             $app->log('Directory of the shell user is outside of website docroot.',LOGLEVEL_WARN);
85             return false;
86         }
87         if(strpos($data['new']['dir'], '/../') !== false || substr($data['new']['dir'],-3) == '/..') {
88             $app->log('Directory of the shell user is not valid.',LOGLEVEL_WARN);
b67344 89             return false;
T 90         }
64ea56 91         
MC 92         if(!$app->system->is_allowed_user($data['new']['username'], false, false)
93             || !$app->system->is_allowed_user($data['new']['puser'], true, true)
94             || !$app->system->is_allowed_group($data['new']['pgroup'], true, true)) {
95             $app->log('Shell user must not be root or in group root.',LOGLEVEL_WARN);
96             return false;
97         }
7fe908 98
a52337 99         if($data['new']['active'] != 'y') $data['new']['shell'] = '/bin/false';
MC 100         
396f0e 101         if($app->system->is_user($data['new']['puser'])) {
7fe908 102
396f0e 103             // Get the UID of the parent user
T 104             $uid = intval($app->system->getuid($data['new']['puser']));
105             if($uid > $this->min_uid) {
892d73 106                 //* Remove webfolder protection
MC 107                 $app->system->web_folder_protection($web['document_root'], false);
743330 108                 
TB 109                 //* Home directory of the new shell user
110                 if($data['new']['chroot'] == 'jailkit') {
111                     $homedir = $data['new']['dir'];
112                 } else {
113                     $homedir = $data['new']['dir'].'/home/'.$data['new']['username'];
114                 }
115                 
8216c5 116                 // Create home base directory if it does not exist
743330 117                 if(!is_dir($data['new']['dir'].'/home')){
8216c5 118                     $app->file->mkdirs(escapeshellcmd($data['new']['dir'].'/home'), '0755');
743330 119                 }
8216c5 120                 
TB 121                 // Change ownership of home base dir to root user
122                 $app->system->chown(escapeshellcmd($data['new']['dir'].'/home'),'root');
123                 $app->system->chgrp(escapeshellcmd($data['new']['dir'].'/home'),'root');
124                 $app->system->chmod(escapeshellcmd($data['new']['dir'].'/home'),0755);
743330 125                 
TB 126                 if(!is_dir($homedir)){
127                     $app->file->mkdirs(escapeshellcmd($homedir), '0750');
8216c5 128                     $app->system->chown(escapeshellcmd($homedir),escapeshellcmd($data['new']['puser']),false);
TB 129                     $app->system->chgrp(escapeshellcmd($homedir),escapeshellcmd($data['new']['pgroup']),false);
892d73 130                 }
396f0e 131                 $command = 'useradd';
743330 132                 $command .= ' -d '.escapeshellcmd($homedir);
e47d46 133                 $command .= ' -g '.escapeshellcmd($data['new']['pgroup']);
T 134                 $command .= ' -o '; // non unique
135                 if($data['new']['password'] != '') $command .= ' -p '.escapeshellcmd($data['new']['password']);
136                 $command .= ' -s '.escapeshellcmd($data['new']['shell']);
137                 $command .= ' -u '.escapeshellcmd($uid);
396f0e 138                 $command .= ' '.escapeshellcmd($data['new']['username']);
7fe908 139
396f0e 140                 exec($command);
7fe908 141                 $app->log("Executed command: ".$command, LOGLEVEL_DEBUG);
MC 142                 $app->log("Added shelluser: ".$data['new']['username'], LOGLEVEL_DEBUG);
a71305 143                 
8216c5 144                 $app->system->chown(escapeshellcmd($data['new']['dir']),escapeshellcmd($data['new']['username']),false);
TB 145                 $app->system->chgrp(escapeshellcmd($data['new']['dir']),escapeshellcmd($data['new']['pgroup']),false);
a71305 146                 
7fe908 147
08c588 148                 // call the ssh-rsa update function
L 149                 $app->uses("getconf");
150                 $this->data = $data;
151                 $this->app = $app;
152                 $this->_setup_ssh_rsa();
7fe908 153
12e119 154                 //* Create .bash_history file
743330 155                 $app->system->touch(escapeshellcmd($homedir).'/.bash_history');
8216c5 156                 $app->system->chmod(escapeshellcmd($homedir).'/.bash_history', 0750);
743330 157                 $app->system->chown(escapeshellcmd($homedir).'/.bash_history', $data['new']['username']);
TB 158                 $app->system->chgrp(escapeshellcmd($homedir).'/.bash_history', $data['new']['pgroup']);
7fe908 159
02e7ea 160                 //* Create .profile file
MC 161                 $app->system->touch(escapeshellcmd($homedir).'/.profile');
162                 $app->system->chmod(escapeshellcmd($homedir).'/.profile', 0644);
163                 $app->system->chown(escapeshellcmd($homedir).'/.profile', $data['new']['username']);
164                 $app->system->chgrp(escapeshellcmd($homedir).'/.profile', $data['new']['pgroup']);
165
396f0e 166                 //* Disable shell user temporarily if we use jailkit
T 167                 if($data['new']['chroot'] == 'jailkit') {
526b99 168                     $command = 'usermod -s /bin/false -L '.escapeshellcmd($data['new']['username']).' 2>/dev/null';
396f0e 169                     exec($command);
7fe908 170                     $app->log("Disabling shelluser temporarily: ".$command, LOGLEVEL_DEBUG);
396f0e 171                 }
7fe908 172
4b9329 173                 //* Add webfolder protection again
7fe908 174                 $app->system->web_folder_protection($web['document_root'], true);
396f0e 175             } else {
7fe908 176                 $app->log("UID = $uid for shelluser:".$data['new']['username']." not allowed.", LOGLEVEL_ERROR);
396f0e 177             }
T 178         } else {
7fe908 179             $app->log("Skipping insertion of user:".$data['new']['username'].", parent user ".$data['new']['puser']." does not exist.", LOGLEVEL_WARN);
396f0e 180         }
T 181     }
7fe908 182
MC 183     function update($event_name, $data) {
396f0e 184         global $app, $conf;
7fe908 185
9edea9 186         $app->uses('system,getconf');
TB 187         
188         $security_config = $app->getconf->get_security_config('permissions');
189         if($security_config['allow_shell_user'] != 'yes') {
190             $app->log('Shell user plugin disabled by security settings.',LOGLEVEL_WARN);
191             return false;
192         }
7fe908 193
b67344 194         //* Check if the resulting path is inside the docroot
cc7a82 195         $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']);
6d21f1 196         if(substr($data['new']['dir'],0,strlen($web['document_root'])) != $web['document_root']) {
FT 197             $app->log('Directory of the shell user is outside of website docroot.',LOGLEVEL_WARN);
198             return false;
199         }
200         
201         if(strpos($data['new']['dir'], '/../') !== false || substr($data['new']['dir'],-3) == '/..') {
202             $app->log('Directory of the shell user is not valid.',LOGLEVEL_WARN);
b67344 203             return false;
T 204         }
7fe908 205
64ea56 206         if(!$app->system->is_allowed_user($data['new']['username'], false, false)
MC 207             || !$app->system->is_allowed_user($data['new']['puser'], true, true)
208             || !$app->system->is_allowed_group($data['new']['pgroup'], true, true)) {
209             $app->log('Shell user must not be root or in group root.',LOGLEVEL_WARN);
210             return false;
211         }
212         
a52337 213         if($data['new']['active'] != 'y') $data['new']['shell'] = '/bin/false';
MC 214         
396f0e 215         if($app->system->is_user($data['new']['puser'])) {
T 216             // Get the UID of the parent user
217             $uid = intval($app->system->getuid($data['new']['puser']));
218             if($uid > $this->min_uid) {
743330 219                 
TB 220                 //* Home directory of the shell user
221                 if($data['new']['chroot'] == 'jailkit') {
222                     $homedir = $data['new']['dir'];
223                     $homedir_old = $data['old']['dir'];
224                 } else {
225                     $homedir = $data['new']['dir'].'/home/'.$data['new']['username'];
226                     $homedir_old = $data['old']['dir'].'/home/'.$data['old']['username'];
227                 }
228                 
396f0e 229                 // Check if the user that we want to update exists, if not, we insert it
T 230                 if($app->system->is_user($data['old']['username'])) {
02e7ea 231                     //* Remove webfolder protection
MC 232                     $app->system->web_folder_protection($web['document_root'], false);
233                     
ff6a68 234                     /*
396f0e 235                     $command = 'usermod';
T 236                     $command .= ' --home '.escapeshellcmd($data['new']['dir']);
237                     $command .= ' --gid '.escapeshellcmd($data['new']['pgroup']);
238                     // $command .= ' --non-unique ';
239                     $command .= ' --password '.escapeshellcmd($data['new']['password']);
240                     if($data['new']['chroot'] != 'jailkit') $command .= ' --shell '.escapeshellcmd($data['new']['shell']);
241                     // $command .= ' --uid '.escapeshellcmd($uid);
242                     $command .= ' --login '.escapeshellcmd($data['new']['username']);
243                     $command .= ' '.escapeshellcmd($data['old']['username']);
7fe908 244
396f0e 245                     exec($command);
e47d46 246                     $app->log("Executed command: $command ",LOGLEVEL_DEBUG);
ff6a68 247                     */
3f478f 248                     //$groupinfo = $app->system->posix_getgrnam($data['new']['pgroup']);
743330 249                     if($homedir != $homedir_old && !is_dir($homedir)){
TB 250                         $app->system->web_folder_protection($web['document_root'], false);
251                         if(!is_dir($data['new']['dir'].'/home')){
252                             $app->file->mkdirs(escapeshellcmd($data['new']['dir'].'/home'), '0750');
253                             $app->system->chown(escapeshellcmd($data['new']['dir'].'/home'),escapeshellcmd($data['new']['puser']));
254                             $app->system->chgrp(escapeshellcmd($data['new']['dir'].'/home'),escapeshellcmd($data['new']['pgroup']));
255                         }
8216c5 256                         $app->file->mkdirs(escapeshellcmd($homedir), '0755');
TB 257                         $app->system->chown(escapeshellcmd($homedir),'root');
258                         $app->system->chgrp(escapeshellcmd($homedir),'root');
743330 259                         $app->system->web_folder_protection($web['document_root'], true);
TB 260                     } else {
261                         if(!is_dir($homedir)){
262                             $app->system->web_folder_protection($web['document_root'], false);
263                             if(!is_dir($data['new']['dir'].'/home')){
8216c5 264                                 $app->file->mkdirs(escapeshellcmd($data['new']['dir'].'/home'), '0755');
TB 265                                 $app->system->chown(escapeshellcmd($data['new']['dir'].'/home'),'root');
266                                 $app->system->chgrp(escapeshellcmd($data['new']['dir'].'/home'),'root');
743330 267                             }
TB 268                             $app->file->mkdirs(escapeshellcmd($homedir), '0750');
269                             $app->system->chown(escapeshellcmd($homedir),escapeshellcmd($data['new']['puser']));
270                             $app->system->chgrp(escapeshellcmd($homedir),escapeshellcmd($data['new']['pgroup']));
271                             $app->system->web_folder_protection($web['document_root'], true);
272                         }
6d21f1 273                     }
743330 274                     $app->system->usermod($data['old']['username'], 0, $app->system->getgid($data['new']['pgroup']), $homedir, $data['new']['shell'], $data['new']['password'], $data['new']['username']);
7fe908 275                     $app->log("Updated shelluser: ".$data['old']['username'], LOGLEVEL_DEBUG);
MC 276
08c588 277                     // call the ssh-rsa update function
L 278                     $app->uses("getconf");
279                     $this->data = $data;
280                     $this->app = $app;
281                     $this->_setup_ssh_rsa();
7fe908 282
12e119 283                     //* Create .bash_history file
T 284                     if(!is_file($data['new']['dir']).'/.bash_history') {
743330 285                         $app->system->touch(escapeshellcmd($homedir).'/.bash_history');
8216c5 286                         $app->system->chmod(escapeshellcmd($homedir).'/.bash_history', 0750);
743330 287                         $app->system->chown(escapeshellcmd($homedir).'/.bash_history', escapeshellcmd($data['new']['username']));
TB 288                         $app->system->chgrp(escapeshellcmd($homedir).'/.bash_history', escapeshellcmd($data['new']['pgroup']));
12e119 289                     }
02e7ea 290                     
MC 291                     //* Create .profile file
292                     if(!is_file($data['new']['dir']).'/.profile') {
293                         $app->system->touch(escapeshellcmd($homedir).'/.profile');
294                         $app->system->chmod(escapeshellcmd($homedir).'/.profile', 0644);
295                         $app->system->chown(escapeshellcmd($homedir).'/.profile', escapeshellcmd($data['new']['username']));
296                         $app->system->chgrp(escapeshellcmd($homedir).'/.profile', escapeshellcmd($data['new']['pgroup']));
297                     }
7fe908 298
02e7ea 299                     //* Add webfolder protection again
MC 300                     $app->system->web_folder_protection($web['document_root'], true);
396f0e 301                 } else {
T 302                     // The user does not exist, so we insert it now
7fe908 303                     $this->insert($event_name, $data);
396f0e 304                 }
T 305             } else {
7fe908 306                 $app->log("UID = $uid for shelluser:".$data['new']['username']." not allowed.", LOGLEVEL_ERROR);
396f0e 307             }
T 308         } else {
7fe908 309             $app->log("Skipping update for user:".$data['new']['username'].", parent user ".$data['new']['puser']." does not exist.", LOGLEVEL_WARN);
396f0e 310         }
T 311     }
7fe908 312
MC 313     function delete($event_name, $data) {
396f0e 314         global $app, $conf;
7fe908 315
4664a2 316         $app->uses('system,getconf,services');
9edea9 317         
TB 318         $security_config = $app->getconf->get_security_config('permissions');
319         if($security_config['allow_shell_user'] != 'yes') {
320             $app->log('Shell user plugin disabled by security settings.',LOGLEVEL_WARN);
321             return false;
322         }
7fe908 323
396f0e 324         if($app->system->is_user($data['old']['username'])) {
T 325             // Get the UID of the user
326             $userid = intval($app->system->getuid($data['old']['username']));
327             if($userid > $this->min_uid) {
4664a2 328                 $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($data['old']['parent_domain_id']));
FT 329                     
892d73 330                 // check if we have to delete the dir
cc7a82 331                 $check = $app->db->queryOneRecord('SELECT shell_user_id FROM `shell_user` WHERE `dir` = ?', $data['old']['dir']);
892d73 332                 if(!$check && is_dir($data['old']['dir'])) {
a7e4ec 333                     
cc7a82 334                     $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['old']['parent_domain_id']);
a7e4ec 335                     $app->system->web_folder_protection($web['document_root'], false);
TB 336                     
892d73 337                     // delete dir
743330 338                     if($data['new']['chroot'] == 'jailkit') {
TB 339                         $homedir = $data['old']['dir'];
340                     } else {
341                         $homedir = $data['old']['dir'].'/home/'.$data['old']['username'];
342                     }
343                 
892d73 344                     if(substr($homedir, -1) !== '/') $homedir .= '/';
MC 345                     $files = array('.bash_logout', '.bash_history', '.bashrc', '.profile');
65a0b9 346                     $dirs = array('.ssh', '.cache');
892d73 347                     foreach($files as $delfile) {
MC 348                         if(is_file($homedir . $delfile) && fileowner($homedir . $delfile) == $userid) unlink($homedir . $delfile);
349                     }
350                     foreach($dirs as $deldir) {
351                         if(is_dir($homedir . $deldir) && fileowner($homedir . $deldir) == $userid) exec('rm -rf ' . escapeshellarg($homedir . $deldir));
352                     }
353                     $empty = true;
354                     $dirres = opendir($homedir);
355                     if($dirres) {
356                         while(($entry = readdir($dirres)) !== false) {
357                             if($entry != '.' && $entry != '..') {
358                                 $empty = false;
359                                 break;
360                             }
361                         }
362                         closedir($dirres);
363                     }
364                     if($empty == true) {
365                         rmdir($homedir);
366                     }
367                     unset($files);
368                     unset($dirs);
a7e4ec 369                     
TB 370                     $app->system->web_folder_protection($web['document_root'], true);
892d73 371                 }
MC 372                 
ac32a4 373                 // We delete only non jailkit users, jailkit users will be deleted by the jailkit plugin.
T 374                 if ($data['old']['chroot'] != "jailkit") {
4664a2 375                     // if this web uses PHP-FPM, that PPH-FPM service must be stopped before we can delete this user
FT 376                     if($web['php'] == 'php-fpm'){
377                         if(trim($web['fastcgi_php_version']) != ''){
378                             $default_php_fpm = false;
379                             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']));
380                         } else {
381                             $default_php_fpm = true;
382                         }
383                         $web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
384                         if(!$default_php_fpm){
385                             $app->services->restartService('php-fpm', 'stop:'.$custom_php_fpm_init_script);
386                         } else {
387                             $app->services->restartService('php-fpm', 'stop:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
388                         }
389                     }
c65384 390                     $command = 'killall -u '.escapeshellcmd($data['old']['username']).' ; userdel -f';
526b99 391                     $command .= ' '.escapeshellcmd($data['old']['username']).' &> /dev/null';
ac32a4 392                     exec($command);
7fe908 393                     $app->log("Deleted shelluser: ".$data['old']['username'], LOGLEVEL_DEBUG);
4664a2 394                     // start PHP-FPM again
FT 395                     if($web['php'] == 'php-fpm'){
396                         if(!$default_php_fpm){
397                             $app->services->restartService('php-fpm', 'start:'.$custom_php_fpm_init_script);
398                         } else {
399                             $app->services->restartService('php-fpm', 'start:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
400                         }
401                     }
ac32a4 402                 }
7fe908 403
396f0e 404             } else {
7fe908 405                 $app->log("UID = $userid for shelluser:".$data['old']['username']." not allowed.", LOGLEVEL_ERROR);
396f0e 406             }
T 407         } else {
7fe908 408             $app->log("User:".$data['new']['username']." does not exist in in /etc/passwd, skipping delete.", LOGLEVEL_WARN);
396f0e 409         }
7fe908 410
396f0e 411     }
7fe908 412
00a055 413     private function _setup_ssh_rsa() {
8ab3cd 414         global $app;
7fe908 415         $this->app->log("ssh-rsa setup shelluser_base", LOGLEVEL_DEBUG);
00a055 416         // Get the client ID, username, and the key
cc7a82 417         $domain_data = $this->app->db->queryOneRecord('SELECT sys_groupid FROM web_domain WHERE web_domain.domain_id = ?', $this->data['new']['parent_domain_id']);
MC 418         $sys_group_data = $this->app->db->queryOneRecord('SELECT * FROM sys_group WHERE sys_group.groupid = ?', $domain_data['sys_groupid']);
00a055 419         $id = intval($sys_group_data['client_id']);
L 420         $username= $sys_group_data['name'];
cc7a82 421         $client_data = $this->app->db->queryOneRecord('SELECT * FROM client WHERE client.client_id = ?', $id);
00a055 422         $userkey = $client_data['ssh_rsa'];
L 423         unset($domain_data);
424         unset($client_data);
7fe908 425
00a055 426         // ssh-rsa authentication variables
5c93f0 427         //$sshrsa = $this->data['new']['ssh_rsa'];
TB 428         $sshrsa = '';
cc7a82 429         $ssh_users = $app->db->queryAllRecords("SELECT ssh_rsa FROM shell_user WHERE parent_domain_id = ?", $this->data['new']['parent_domain_id']);
5c93f0 430         if(is_array($ssh_users)) {
TB 431             foreach($ssh_users as $sshu) {
432                 if($sshu['ssh_rsa'] != '') $sshrsa .= "\n".$sshu['ssh_rsa'];
433             }
434         }
435         $sshrsa = trim($sshrsa);
00a055 436         $usrdir = escapeshellcmd($this->data['new']['dir']);
3fb9be 437         //* Home directory of the new shell user
TB 438         if($this->data['new']['chroot'] == 'jailkit') {
439             $usrdir = escapeshellcmd($this->data['new']['dir']);
440         } else {
99e9ac 441             $usrdir = escapeshellcmd($this->data['new']['dir'].'/home/'.$this->data['new']['username']);
3fb9be 442         }
00a055 443         $sshdir = $usrdir.'/.ssh';
L 444         $sshkeys= $usrdir.'/.ssh/authorized_keys';
7fe908 445
8ab3cd 446         $app->uses('file');
T 447         $sshrsa = $app->file->unix_nl($sshrsa);
7fe908 448         $sshrsa = $app->file->remove_blank_lines($sshrsa, 0);
MC 449
00a055 450         // If this user has no key yet, generate a pair
8ab3cd 451         if ($userkey == '' && $id > 0){
00a055 452             //Generate ssh-rsa-keys
L 453             exec('ssh-keygen -t rsa -C '.$username.'-rsa-key-'.time().' -f /tmp/id_rsa -N ""');
7fe908 454
8ab3cd 455             // use the public key that has been generated
4bd960 456             $userkey = $app->system->file_get_contents('/tmp/id_rsa.pub');
7fe908 457
00a055 458             // save keypair in client table
cc7a82 459             $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);
7fe908 460
4bd960 461             $app->system->unlink('/tmp/id_rsa');
T 462             $app->system->unlink('/tmp/id_rsa.pub');
7fe908 463             $this->app->log("ssh-rsa keypair generated for ".$username, LOGLEVEL_DEBUG);
00a055 464         };
8ab3cd 465
T 466         if (!file_exists($sshkeys)){
00a055 467             // add root's key
8cf78b 468             $app->file->mkdirs($sshdir, '0700');
4bd960 469             if(is_file('/root/.ssh/authorized_keys')) $app->system->file_put_contents($sshkeys, $app->system->file_get_contents('/root/.ssh/authorized_keys'));
7fe908 470
8ab3cd 471             // Remove duplicate keys
8cf78b 472             $existing_keys = @file($sshkeys);
8ab3cd 473             $new_keys = explode("\n", $userkey);
8cf78b 474             $final_keys_arr = @array_merge($existing_keys, $new_keys);
8ab3cd 475             $new_final_keys_arr = array();
T 476             if(is_array($final_keys_arr) && !empty($final_keys_arr)){
477                 foreach($final_keys_arr as $key => $val){
478                     $new_final_keys_arr[$key] = trim($val);
479                 }
480             }
481             $final_keys = implode("\n", array_flip(array_flip($new_final_keys_arr)));
7fe908 482
00a055 483             // add the user's key
4bd960 484             $app->system->file_put_contents($sshkeys, $final_keys);
8ab3cd 485             $app->file->remove_blank_lines($sshkeys);
7fe908 486             $this->app->log("ssh-rsa authorisation keyfile created in ".$sshkeys, LOGLEVEL_DEBUG);
00a055 487         }
7fe908 488
8cf78b 489         //* Get the keys
T 490         $existing_keys = file($sshkeys);
491         $new_keys = explode("\n", $sshrsa);
7fe908 492         $old_keys = explode("\n", $this->data['old']['ssh_rsa']);
MC 493
8cf78b 494         //* Remove all old keys
T 495         if(is_array($old_keys)) {
496             foreach($old_keys as $key => $val) {
7fe908 497                 $k = array_search(trim($val), $existing_keys);
8cf78b 498                 unset($existing_keys[$k]);
T 499             }
00a055 500         }
7fe908 501
8cf78b 502         //* merge the remaining keys and the ones fom the ispconfig database.
T 503         if(is_array($new_keys)) {
504             $final_keys_arr = array_merge($existing_keys, $new_keys);
505         } else {
506             $final_keys_arr = $existing_keys;
507         }
7fe908 508
8cf78b 509         $new_final_keys_arr = array();
T 510         if(is_array($final_keys_arr) && !empty($final_keys_arr)){
511             foreach($final_keys_arr as $key => $val){
512                 $new_final_keys_arr[$key] = trim($val);
513             }
514         }
515         $final_keys = implode("\n", array_flip(array_flip($new_final_keys_arr)));
7fe908 516
MC 517         // add the custom key
4bd960 518         $app->system->file_put_contents($sshkeys, $final_keys);
8cf78b 519         $app->file->remove_blank_lines($sshkeys);
7fe908 520         $this->app->log("ssh-rsa key updated in ".$sshkeys, LOGLEVEL_DEBUG);
MC 521
00a055 522         // set proper file permissions
8cf78b 523         exec("chown -R ".escapeshellcmd($this->data['new']['puser']).":".escapeshellcmd($this->data['new']['pgroup'])." ".$sshdir);
00a055 524         exec("chmod 600 '$sshkeys'");
7fe908 525
08c588 526     }
7fe908 527
396f0e 528
T 529 } // end class
530
8e725d 531 ?>