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