Marius Cramer
2014-03-19 0a0ca4f6a79f15308c6c2c6b4b7d1de9c8454e3b
commit | author | age
e2d6ed 1 <?php
436ed8 2
e2d6ed 3 /*
436ed8 4 Copyright (c) 2007, Till Brehm, projektfarm Gmbh
e2d6ed 5 All rights reserved.
T 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 system{
32
3b4c28 33     var $FILE = '/root/ispconfig/scripts/lib/classes/ispconfig_system.lib.php';
55da90 34     var $server_id;
B 35     var $server_conf;
36     var $data;
7fe908 37
55da90 38     /**
B 39      * Construct for this class
40      *
41      * @return system
42      */
7fe908 43
MC 44
55da90 45     public function system(){
cea1e5 46         //global $go_info;
7fe908 47         //$this->server_id = $go_info['isp']['server_id'];
MC 48         //$this->server_conf = $go_info['isp']['server_conf'];
49         $this->server_conf['passwd_datei'] = '/etc/passwd';
50         $this->server_conf['shadow_datei'] = '/etc/shadow';
51         $this->server_conf['group_datei'] = '/etc/group';
55da90 52     }
7fe908 53
MC 54
55
55da90 56     /**
B 57      * Get the hostname from the server
58      *
59      * @return string
60      */
61     public function hostname(){
3b4c28 62         $dist = $this->server_conf['dist'];
7fe908 63
MC 64         ob_start();
65         passthru('hostname');
66         $hostname = ob_get_contents();
67         ob_end_clean();
55da90 68         $hostname = trim($hostname);
7fe908 69         ob_start();
MC 70         if(!strstr($dist, 'freebsd')){
71             passthru('dnsdomainname');
72         } else {
73             passthru('domainname');
74         }
75         $domainname = ob_get_contents();
76         ob_end_clean();
77         $domainname = trim($domainname);
78         if($domainname != ""){
79             if(!strstr($hostname, $domainname)) $hostname .= ".".$domainname;
80         }
81         return $hostname;
55da90 82     }
7fe908 83
MC 84
85
55da90 86     /**
B 87      * Add an user to the system
7fe908 88      *
55da90 89      */
B 90     public function adduser($user_username, $uid, $gid, $username, $homedir, $shell, $passwort = '*'){
91         global $app;
7fe908 92         if($this->is_user($user_username)){
MC 93             return false;
94         } else {
95             if(trim($user_username) != '') {
96                 $user_datei = $this->server_conf['passwd_datei'];
97                 $shadow_datei = $this->server_conf['shadow_datei'];
98                 $shell = realpath($shell);
99                 if(trim($passwort) == '') $passwort = '*';
100                 $new_user = "\n$user_username:x:$uid:$gid:$username:$homedir:$shell\n";
101                 $app->log->msg('USER: '.$new_user);
102                 $app->file->af($user_datei, $new_user);
103                 if($shadow_datei == '/etc/shadow'){
104                     $datum = time();
105                     $tage = floor($datum/86400);
106                     $new_passwd = "\n$user_username:$passwort:$tage:0:99999:7:::\n";
107                 } else {
108                     $new_passwd = "\n$user_username:$passwort:$uid:$gid::0:0:$username:$homedir:$shell\n";
109                 }
110                 $app->file->af($shadow_datei, $new_passwd);
55da90 111                 // TB: leere Zeilen entfernen
7fe908 112                 $app->file->remove_blank_lines($shadow_datei);
MC 113                 $app->file->remove_blank_lines($user_datei);
114                 // TB: user Sortierung deaktiviert
115                 //$this->order_users_groups();
116                 if($shadow_datei != '/etc/shadow'){
117                     $app->file->af($shadow_datei, "\n");
55da90 118                     // TB: leere Zeilen entfernen
7fe908 119                     $app->file->remove_blank_lines($shadow_datei);
55da90 120                     $app->log->caselog("pwd_mkdb $shadow_datei &> /dev/null", $this->FILE, __LINE__);
7fe908 121                 }
MC 122                 return true;
123             }
124         }
55da90 125     }
7fe908 126
MC 127
128
129
130
55da90 131     /**
B 132      * Update users when someone edit it
133      *
134      */
135     function updateuser($user_username, $uid, $gid, $username, $homedir, $shell, $passwort = '*'){
136         //* First delete the users
137         $this->deluser($user_username);
138         //* Add the user again
7fe908 139         $this->adduser($user_username, $uid, $gid, $username, $homedir, $shell, $passwort);
55da90 140     }
7fe908 141
MC 142
143
144
145
55da90 146     /**
B 147      * Lock the user
148      *
149      */
150     function deactivateuser($user_username){
151         $passwort = str_rot13($this->getpasswd($user_username));
7fe908 152         $user_attr = $this->get_user_attributes($user_username);
MC 153         $uid = $user_attr['uid'];
154         $gid = $user_attr['gid'];
155         $username = $user_attr['name'];
156         $homedir = $user_attr['homedir'];
157         $shell = '/dev/null';
158         $this->deluser($user_username);
159         $this->adduser($user_username, $uid, $gid, $username, $homedir, $shell, $passwort);
55da90 160     }
7fe908 161
MC 162
55da90 163     /**
B 164      * Delete a user from the system
165      *
166      */
167     function deluser($user_username){
168         global $app;
7fe908 169         if($this->is_user($user_username)){
MC 170             $user_datei = $this->server_conf['passwd_datei'];
171             $shadow_datei = $this->server_conf['shadow_datei'];
172             $users = $app->file->rf($user_datei);
173             $lines = explode("\n", $users);
174             if(is_array($lines)){
175                 $num_lines = sizeof($lines);
176                 for($i=0;$i<$num_lines;$i++){
177                     if(trim($lines[$i]) != ''){
178                         list($f1, ) = explode(':', $lines[$i]);
179                         if($f1 != $user_username) $new_lines[] = $lines[$i];
180                     }
181                 }
182                 $new_users = implode("\n", $new_lines);
183                 $app->file->wf($user_datei, $new_users);
184                 unset($new_lines);
185                 unset($lines);
186                 unset($new_users);
187             }
188             $app->file->remove_blank_lines($user_datei);
189
190             $passwds = $app->file->rf($shadow_datei);
191             $lines = explode("\n", $passwds);
192             if(is_array($lines)){
193                 $num_lines = sizeof($lines);
194                 for($i=0;$i<$num_lines;$i++){
195                     if(trim($lines[$i]) != ''){
196                         list($f1, ) = explode(':', $lines[$i]);
197                         if($f1 != $user_username) $new_lines[] = $lines[$i];
198                     }
199                 }
200                 $new_passwds = implode("\n", $new_lines);
201                 $app->file->wf($shadow_datei, $new_passwds);
202                 unset($new_lines);
203                 unset($lines);
204                 unset($new_passwds);
205             }
206             $app->file->remove_blank_lines($shadow_datei);
207
208             $group_file = $app->file->rf($this->server_conf['group_datei']);
209             $group_file_lines = explode("\n", $group_file);
210             foreach($group_file_lines as $group_file_line){
211                 if(trim($group_file_line) != ''){
212                     list($f1, $f2, $f3, $f4) = explode(':', $group_file_line);
213                     $group_users = explode(',', str_replace(' ', '', $f4));
214                     if(in_array($user_username, $group_users)){
215                         $g_users = array();
216                         foreach($group_users as $group_user){
217                             if($group_user != $user_username) $g_users[] = $group_user;
218                         }
219                         $f4 = implode(',', $g_users);
220                     }
221                     $new_group_file[] = $f1.':'.$f2.':'.$f3.':'.$f4;
222                 }
223             }
224             $new_group_file = implode("\n", $new_group_file);
225             $app->file->wf($this->server_conf['group_datei'], $new_group_file);
226             // TB: auskommentiert
227             //$this->order_users_groups();
228
229             if($shadow_datei != '/etc/shadow'){
230                 $app->file->af($shadow_datei, "\n");
231                 $app->log->caselog("pwd_mkdb $shadow_datei &> /dev/null", $this->FILE, __LINE__);
232             }
233             return true;
234         } else {
235             return false;
236         }
55da90 237     }
7fe908 238
MC 239
240
241
242
55da90 243     /**
B 244      * Add a usergroup to the system
245      *
246      */
247     function addgroup($group, $gid, $members = ''){
248         global $app;
7fe908 249         if($this->is_group($group)){
MC 250             return false;
251         } else {
252             $group_datei = $this->server_conf['group_datei'];
253             $shadow_datei = $this->server_conf['shadow_datei'];
254             $new_group = "\n$group:x:$gid:$members\n";
255             $app->file->af($group_datei, $new_group);
256
257             // TB: auskommentiert
258             //$this->order_users_groups();
259             if($shadow_datei != '/etc/shadow'){
260                 $app->log->caselog("pwd_mkdb $shadow_datei &> /dev/null", $this->FILE, __LINE__);
261             }
262             return true;
263         }
55da90 264     }
7fe908 265
MC 266
267
268
269
55da90 270     /**
B 271      * Update usersgroup in way to delete and add it again
272      *
273      */
274     function updategroup($group, $gid, $members = ''){
275         $this->delgroup($group);
7fe908 276         $this->addgroup($group, $gid, $members);
55da90 277     }
7fe908 278
MC 279
280
281
282
55da90 283     /**
B 284      * Delete a usergroup from the system
285      *
286      */
287     function delgroup($group){
288         global $app;
7fe908 289         if($this->is_group($group)){
MC 290             $group_datei = $this->server_conf['group_datei'];
291             $shadow_datei = $this->server_conf['shadow_datei'];
292             $groups = $app->file->rf($group_datei);
293             $lines = explode("\n", $groups);
294             if(is_array($lines)){
295                 $num_lines = sizeof($lines);
296                 for($i=0;$i<$num_lines;$i++){
297                     if(trim($lines[$i]) != ''){
298                         list($f1, ) = explode(':', $lines[$i]);
299                         if($f1 != $group) $new_lines[] = $lines[$i];
300                     }
301                 }
302                 $new_groups = implode("\n", $new_lines);
303                 $app->file->wf($group_datei, $new_groups);
304                 unset($new_lines);
305                 unset($lines);
306                 unset($new_groups);
307             }
308             // TB: auskommentiert
309             //$this->order_users_groups();
310             if($shadow_datei != '/etc/shadow'){
311                 $app->log->caselog("pwd_mkdb $shadow_datei &> /dev/null", $this->FILE, __LINE__);
312             }
313             return true;
314         } else {
315             return false;
316         }
55da90 317     }
7fe908 318
MC 319
55da90 320     /**
B 321      * Order usergroups
322      *
323      */
324     function order_users_groups(){
325         global $app;
7fe908 326         $user_datei = $this->server_conf['passwd_datei'];
MC 327         $shadow_datei = $this->server_conf['shadow_datei'];
328         $group_datei = $this->server_conf['group_datei'];
329
330         $groups = $app->file->no_comments($group_datei);
331         $lines = explode("\n", $groups);
332         if(is_array($lines)){
333             foreach($lines as $line){
334                 if(trim($line) != ''){
335                     list($f1, $f2, $f3, $f4) = explode(':', $line);
336                     $arr[$f3] = $line;
337                 }
338             }
339         }
340         ksort($arr);
341         reset($arr);
342         if($shadow_datei != '/etc/shadow'){
343             $app->file->wf($group_datei, $app->file->remove_blank_lines(implode("\n", $arr), 0)."\n");
344         }else {
345             $app->file->wf($group_datei, $app->file->remove_blank_lines(implode("\n", $arr), 0));
346         }
347         unset($arr);
348
349         $users = $app->file->no_comments($user_datei);
350         $lines = explode("\n", $users);
351         if(is_array($lines)){
352             foreach($lines as $line){
353                 if(trim($line) != ""){
354                     list($f1, $f2, $f3, ) = explode(':', $line);
355                     if($f1 != 'toor'){
356                         $arr[$f3] = $line;
357                     } else {
358                         $arr[70000] = $line;
359                     }
360                 }
361             }
362         }
363         ksort($arr);
364         reset($arr);
365         $app->file->wf($user_datei, $app->file->remove_blank_lines(implode("\n", $arr), 0));
366         unset($arr);
367
368         $passwds = $app->file->no_comments($shadow_datei);
369         $lines = explode("\n", $passwds);
370         if(is_array($lines)){
371             foreach($lines as $line){
372                 if(trim($line) != ''){
373                     list($f1, $f2, $f3, ) = explode(':', $line);
374                     if($f1 != 'toor'){
375                         $uid = $this->getuid($f1);
376                         if(!is_bool($uid)) $arr[$uid] = $line;
377                     } else {
378                         $arr[70000] = $line;
379                     }
380                 }
381             }
382         }
383         ksort($arr);
384         reset($arr);
385         $app->file->wf($shadow_datei, $app->file->remove_blank_lines(implode("\n", $arr), 0));
386         unset($arr);
55da90 387     }
7fe908 388
MC 389
390
391
392
55da90 393     /**
B 394      * Find a user / group id
395      *
396      */
397     function find_uid_gid($min, $max){
398         global $app;
7fe908 399         if($min < $max && $min >= 0 && $max >= 0 && $min <= 65536 && $max <= 65536 && is_int($min) && is_int($max)){
MC 400             for($i=$min;$i<=$max;$i++){
401                 $uid_arr[$i] = $gid_arr[$i] = 1;
402             }
403             $user_datei = $this->server_conf['passwd_datei'];
404             $group_datei = $this->server_conf['group_datei'];
405
406             $users = $app->file->no_comments($user_datei);
407             $lines = explode("\n", $users);
408             if(is_array($lines)){
409                 foreach($lines as $line){
410                     if(trim($line) != ''){
411                         list($f1, $f2, $f3, $f4, $f5, $f6, $f7) = explode(':', $line);
412                         if($f3 >= $min && $f3 <= $max) unset($uid_arr[$f3]);
413                     }
414                 }
415                 if(!empty($uid_arr)){
416                     foreach($uid_arr as $key => $val){
417                         $uids[] = $key;
418                     }
419                     $min_uid = min($uids);
420                     unset($uid_arr);
421                 } else {
422                     return false;
423                 }
424             }
425
426             $groups = $app->file->no_comments($group_datei);
427             $lines = explode("\n", $groups);
428             if(is_array($lines)){
429                 foreach($lines as $line){
430                     if(trim($line) != ''){
431                         list($f1, $f2, $f3, $f4) = explode(':', $line);
432                         if($f3 >= $min && $f3 <= $max) unset($gid_arr[$f3]);
433                     }
434                 }
435                 if(!empty($gid_arr)){
436                     foreach($gid_arr as $key => $val){
437                         $gids[] = $key;
438                     }
439                     $min_gid = min($gids);
440                     unset($gid_arr);
441                 } else {
442                     return false;
443                 }
444             }
445
446             $result = array_intersect($uids, $gids);
447             $new_id = (max($result));
448             unset($uids);
449             unset($gids);
450             unset($result);
451             if($new_id <= $max){
452                 return $new_id;
453             } else {
454                 return false;
455             }
456         } else {
457             return false;
458         }
55da90 459     }
7fe908 460
MC 461
462
463
464
55da90 465     /**
B 466      * Check if the users is really a user into the system
467      *
468      */
469     function is_user($user){
470         global $app;
7fe908 471         $user_datei = $this->server_conf['passwd_datei'];
MC 472         $users = $app->file->no_comments($user_datei);
473         $lines = explode("\n", $users);
474         if(is_array($lines)){
55da90 475             foreach($lines as $line){
7fe908 476                 if(trim($line) != ''){
MC 477                     list($f1, $f2, $f3, $f4, $f5, $f6, $f7) = explode(':', $line);
478                     if($f1 == $user) return true;
479                 }
480             }
481         }
482         return false;
55da90 483     }
7fe908 484
MC 485
486
487
488
55da90 489     /**
B 490      * Check if the group is on this system
491      *
492      */
493     function is_group($group){
494         global $app;
7fe908 495         $group_datei = $this->server_conf['group_datei'];
MC 496         $groups = $app->file->no_comments($group_datei);
497         $lines = explode("\n", $groups);
498         if(is_array($lines)){
499             foreach($lines as $line){
500                 if(trim($line) != ""){
501                     list($f1, $f2, $f3, $f4) = explode(':', $line);
502                     if($f1 == $group) return true;
503                 }
504             }
505         }
506         return false;
55da90 507     }
7fe908 508
89a57f 509     /*
T 510     // Alternative implementation of the is_group function. Should be faster then the old one To be tested.
511     function is_group($group) {
512     $groupfile = '/etc/group';
513     if(is_file($groupfile)) {
514         $handle = fopen ($groupfile, "r");
515         while (!feof($handle)) {
516             $line = trim(fgets($handle, 4096));
517             if($line != ""){
518                 $parts = explode(":", $line);
519                 if($parts[0] == $group) {
520                     fclose ($handle);
521                     return true;
522                 }
523             }
524         }
525         fclose ($handle);
526     }
527     return false;
528     }
529     */
7fe908 530
55da90 531     function root_group(){
B 532         global $app;
7fe908 533         $group_datei = $this->server_conf['group_datei'];
MC 534         $groups = $app->file->no_comments($group_datei);
535         $lines = explode("\n", $groups);
536         if(is_array($lines)){
537             foreach($lines as $line){
538                 if(trim($line) != ''){
539                     list($f1, $f2, $f3, $f4) = explode(':', $line);
540                     if($f3 == 0) return $f1;
541                 }
542             }
543         }
544         return false;
55da90 545     }
7fe908 546
MC 547
548
549
550
55da90 551     /**
B 552      * Get the groups of an user
553      *
554      */
555     function get_user_groups($username){
556         global $app;
7fe908 557         $user_groups = array();
MC 558         $group_datei = $this->server_conf['group_datei'];
559         $groups = $app->file->no_comments($group_datei);
560         $lines = explode("\n", $groups);
561         if(is_array($lines)){
562             foreach($lines as $line){
563                 if(trim($line) != ''){
564                     list($f1, $f2, $f3, $f4) = explode(':', $line);
565                     if(intval($f3) < intval($this->server_conf['groupid_von']) && trim($f1) != 'users'){
566                         $tmp_group_users = explode(',', str_replace(' ', '', $f4));
567                         if(in_array($username, $tmp_group_users) && trim($f1) != '') $user_groups[] = $f1;
568                         unset($tmp_group_users);
569                     }
570                 }
571             }
572         }
573         if(!empty($user_groups)) return implode(',', $user_groups);
574         return '';
55da90 575     }
7fe908 576
MC 577
578
579
580
55da90 581     /**
B 582      * Get a user password
583      *
584      */
585     function getpasswd($user){
586         global $app;
7fe908 587         if($this->is_user($user)){
MC 588             $shadow_datei = $this->server_conf['shadow_datei'];
589             $passwds = $app->file->no_comments($shadow_datei);
590             $lines = explode("\n", $passwds);
591             if(is_array($lines)){
592                 foreach($lines as $line){
593                     if(trim($line) != ''){
594                         list($f1, $f2, ) = explode(':', $line);
595                         if($f1 == $user) return $f2;
596                     }
597                 }
598             }
599         } else {
600             return false;
601         }
55da90 602     }
7fe908 603
MC 604
605
606
607
55da90 608     /**
B 609      * Get the user id from an user
610      *
611      */
612     function getuid($user){
613         global $app;
7fe908 614         if($this->is_user($user)){
MC 615             $user_datei = $this->server_conf['passwd_datei'];
616             $users = $app->file->no_comments($user_datei);
617             $lines = explode("\n", $users);
618             if(is_array($lines)){
619                 foreach($lines as $line){
620                     if(trim($line) != ''){
621                         list($f1, $f2, $f3, ) = explode(':', $line);
622                         if($f1 == $user) return $f3;
623                     }
624                 }
625             }
626         } else {
627             return false;
628         }
55da90 629     }
7fe908 630
MC 631
632
633
634
55da90 635     /**
3f478f 636      * Get the group id from an group
T 637      *
638      */
639     function getgid($group){
640         global $app;
7fe908 641         if($this->is_group($group)){
MC 642             $group_datei = $this->server_conf['group_datei'];
3f478f 643             $groups = $app->file->no_comments($group_datei);
T 644             $lines = explode("\n", $groups);
645             if(is_array($lines)){
7fe908 646                 foreach($lines as $line){
3f478f 647                     if(trim($line) != ""){
T 648                         list($f1, $f2, $f3, $f4) = explode(':', $line);
649                         if($f1 == $group) return $f3;
650                     }
651                 }
652             }
7fe908 653         } else {
MC 654             return false;
655         }
3f478f 656     }
7fe908 657
MC 658
659
660
661
3f478f 662     /**
7fe908 663      * Return info about a group by name
MC 664      *
665      */
3f478f 666     function posix_getgrnam($group) {
T 667         if(!function_exists('posix_getgrnam')){
668             $group_datei = $this->server_conf['group_datei'];
669             $cmd = 'grep -m 1 "^'.$group.':" '.$group_datei;
670             exec($cmd, $output, $return_var);
671             if($return_var != 0 || !$output[0]) return false;
672             list($f1, $f2, $f3, $f4) = explode(':', $output[0]);
673             $f2 = trim($f2);
674             $f3 = trim($f3);
675             $f4 = trim($f4);
676             if($f4 != ''){
677                 $members = explode(',', $f4);
678             } else {
679                 $members = array();
680             }
7fe908 681             $group_details = array( 'name' => $group,
MC 682                 'passwd' => $f2,
683                 'members' => $members,
684                 'gid' => $f3);
685             return $group_details;
3f478f 686         } else {
T 687             return posix_getgrnam($group);
688         }
7fe908 689     }
MC 690
691
692
693
694
3f478f 695     /**
55da90 696      * Get all information from a user
B 697      *
698      */
699     function get_user_attributes($user){
700         global $app;
7fe908 701         if($this->is_user($user)){
MC 702             $user_datei = $this->server_conf['passwd_datei'];
703             $users = $app->file->no_comments($user_datei);
704             $lines = explode("\n", $users);
705             if(is_array($lines)){
706                 foreach($lines as $line){
707                     if(trim($line) != ''){
708                         list($f1, $f2, $f3, $f4, $f5, $f6, $f7) = explode(':', $line);
709                         if($f1 == $user){
710                             $user_attr['username'] = $f1;
711                             $user_attr['x'] = $f2;
712                             $user_attr['uid'] = $f3;
713                             $user_attr['gid'] = $f4;
714                             $user_attr['name'] = $f5;
715                             $user_attr['homedir'] = $f6;
716                             $user_attr['shell'] = $f7;
717                             return $user_attr;
718                         }
719                     }
720                 }
721             }
722         } else {
723             return false;
724         }
55da90 725     }
7fe908 726
MC 727
728
729
730
55da90 731     /**
B 732      * Edit the owner of a file
733      *
734      */
c3ac0a 735     function chown($file, $owner, $allow_symlink = false){
7fe908 736         global $app;
MC 737         if($allow_symlink == false && $this->checkpath($file) == false) {
738             $app->log("Action aborted, file is a symlink: $file", LOGLEVEL_WARN);
d87f76 739             return false;
T 740         }
7fe908 741         if(file_exists($file)) {
MC 742             if(@chown($file, $owner)) {
743                 return true;
744             } else {
745                 $app->log("chown failed: $file : $owner", LOGLEVEL_DEBUG);
746                 return false;
747             }
748         }
c3ac0a 749     }
7fe908 750
c3ac0a 751     function chgrp($file, $group = '', $allow_symlink = false){
7fe908 752         global $app;
MC 753         if($allow_symlink == false && $this->checkpath($file) == false) {
754             $app->log("Action aborted, file is a symlink: $file", LOGLEVEL_WARN);
d87f76 755             return false;
T 756         }
7fe908 757         if(file_exists($file)) {
MC 758             if(@chgrp($file, $group)) {
759                 return true;
760             } else {
761                 $app->log("chgrp failed: $file : $group", LOGLEVEL_DEBUG);
762                 return false;
763             }
764         }
c3ac0a 765     }
7fe908 766
c3ac0a 767     //* Change the mode of a file
T 768     function chmod($file, $mode, $allow_symlink = false) {
c77103 769         global $app;
c3ac0a 770         if($allow_symlink == false && $this->checkpath($file) == false) {
7fe908 771             $app->log("Action aborted, file is a symlink: $file", LOGLEVEL_WARN);
c3ac0a 772             return false;
T 773         }
d87f76 774         if(@chmod($file, $mode)) {
T 775             return true;
776         } else {
7fe908 777             $app->log("chmod failed: $file : $mode", LOGLEVEL_DEBUG);
d87f76 778             return false;
T 779         }
c3ac0a 780     }
7fe908 781
c3ac0a 782     function file_put_contents($filename, $data, $allow_symlink = false) {
c77103 783         global $app;
c3ac0a 784         if($allow_symlink == false && $this->checkpath($filename) == false) {
7fe908 785             $app->log("Action aborted, file is a symlink: $filename", LOGLEVEL_WARN);
c3ac0a 786             return false;
T 787         }
c77103 788         if(file_exists($filename)) unlink($filename);
c3ac0a 789         return file_put_contents($filename, $data);
T 790     }
7fe908 791
c3ac0a 792     function file_get_contents($filename, $allow_symlink = false) {
c77103 793         global $app;
c3ac0a 794         if($allow_symlink == false && $this->checkpath($filename) == false) {
7fe908 795             $app->log("Action aborted, file is a symlink: $filename", LOGLEVEL_WARN);
c3ac0a 796             return false;
T 797         }
b889ed 798         return file_get_contents($filename, $data);
c3ac0a 799     }
7fe908 800
c3ac0a 801     function rename($filename, $new_filename, $allow_symlink = false) {
c77103 802         global $app;
c3ac0a 803         if($allow_symlink == false && $this->checkpath($filename) == false) {
7fe908 804             $app->log("Action aborted, file is a symlink: $filename", LOGLEVEL_WARN);
c3ac0a 805             return false;
T 806         }
807         return rename($filename, $new_filename);
808     }
7fe908 809
c3ac0a 810     function mkdir($dirname, $allow_symlink = false) {
c77103 811         global $app;
c3ac0a 812         if($allow_symlink == false && $this->checkpath($dirname) == false) {
7fe908 813             $app->log("Action aborted, file is a symlink: $dirname", LOGLEVEL_WARN);
c3ac0a 814             return false;
T 815         }
d87f76 816         if(@mkdir($dirname)) {
T 817             return true;
818         } else {
7fe908 819             $app->log("mkdir failed: $dirname", LOGLEVEL_DEBUG);
d87f76 820             return false;
T 821         }
c3ac0a 822     }
7fe908 823
58053e 824     function unlink($filename) {
b889ed 825         if(file_exists($filename) || is_link($filename)) {
c77103 826             return unlink($filename);
T 827         }
c3ac0a 828     }
7fe908 829
MC 830     function copy($file1, $file2) {
831         return copy($file1, $file2);
c3ac0a 832     }
7fe908 833
4bd960 834     function touch($file, $allow_symlink = false){
7fe908 835         global $app;
MC 836         if($allow_symlink == false && @file_exists($file) && $this->checkpath($file) == false) {
837             $this->unlink($file);
838         }
839         if(@touch($file)) {
4bd960 840             return true;
7fe908 841         } else {
MC 842             $app->log("touch failed: $file", LOGLEVEL_DEBUG);
4bd960 843             return false;
7fe908 844         }
4bd960 845     }
7fe908 846
c3ac0a 847     function checkpath($path) {
T 848         $path = trim($path);
849         //* We allow only absolute paths
7fe908 850         if(substr($path, 0, 1) != '/') return false;
MC 851
c3ac0a 852         //* We allow only some characters in the path
992797 853         // * is allowed, for example it is part of wildcard certificates/keys: *.example.com.crt
c6e989 854         if(!preg_match('@^/[-a-zA-Z0-9_/.*]{1,}[~]?$@', $path)) return false;
7fe908 855
c3ac0a 856         //* Check path for symlinks
7fe908 857         $path_parts = explode('/', $path);
c3ac0a 858         $testpath = '';
T 859         foreach($path_parts as $p) {
860             $testpath .= '/'.$p;
861             if(is_link($testpath)) return false;
862         }
7fe908 863
c3ac0a 864         return true;
55da90 865     }
7fe908 866
MC 867
868
869
870
55da90 871     /**
B 872      * Add an user to a specific group
873      *
874      */
875     function add_user_to_group($group, $user = 'admispconfig'){
876         global $app;
7fe908 877         $group_file = $app->file->rf($this->server_conf['group_datei']);
MC 878         $group_file_lines = explode("\n", $group_file);
879         foreach($group_file_lines as $group_file_line){
880             list($group_name, $group_x, $group_id, $group_users) = explode(':', $group_file_line);
881             if($group_name == $group){
882                 $group_users = explode(',', str_replace(' ', '', $group_users));
883                 if(!in_array($user, $group_users)){
884                     $group_users[] = $user;
885                 }
886                 $group_users = implode(',', $group_users);
887                 if(substr($group_users, 0, 1) == ',') $group_users = substr($group_users, 1);
888                 $group_file_line = $group_name.':'.$group_x.':'.$group_id.':'.$group_users;
889             }
890             $new_group_file[] = $group_file_line;
891         }
892         $new_group_file = implode("\n", $new_group_file);
893         $app->file->wf($this->server_conf['group_datei'], $new_group_file);
894         $app->file->remove_blank_lines($this->server_conf['group_datei']);
895         if($this->server_conf['shadow_datei'] != '/etc/shadow'){
896             $app->log->caselog('pwd_mkdb '.$this->server_conf['shadow_datei'].' &> /dev/null', $this->FILE, __LINE__);
897         }
55da90 898     }
7fe908 899
ff6a68 900     /*
55da90 901     function usermod($user, $groups){
B 902         global $app;
903           if($this->is_user($user)){
3b4c28 904             $groups = explode(',', str_replace(' ', '', $groups));
J 905             $group_file = $app->file->rf($this->server_conf['group_datei']);
55da90 906             $group_file_lines = explode("\n", $group_file);
B 907             foreach($group_file_lines as $group_file_line){
908                   if(trim($group_file_line) != ""){
3b4c28 909                     list($f1, $f2, $f3, $f4) = explode(':', $group_file_line);
J 910                     $group_users = explode(',', str_replace(' ', '', $f4));
55da90 911                     if(!in_array($f1, $groups)){
B 912                           if(in_array($user, $group_users)){
913                             $g_users = array();
914                             foreach($group_users as $group_user){
915                                   if($group_user != $user) $g_users[] = $group_user;
916                             }
3b4c28 917                             $f4 = implode(',', $g_users);
55da90 918                           }
B 919                     } else {
920                           if(!in_array($user, $group_users)){
3b4c28 921                             if(trim($group_users[0]) == '') unset($group_users);
55da90 922                             $group_users[] = $user;
B 923                           }
3b4c28 924                           $f4 = implode(',', $group_users);
55da90 925                     }
3b4c28 926                     $new_group_file[] = $f1.':'.$f2.':'.$f3.':'.$f4;
55da90 927                   }
B 928             }
929             $new_group_file = implode("\n", $new_group_file);
3b4c28 930             $app->file->wf($this->server_conf['group_datei'], $new_group_file);
J 931             $app->file->remove_blank_lines($this->server_conf['group_datei']);
932             if($this->server_conf['shadow_datei'] != '/etc/shadow'){
933                   $app->log->caselog('pwd_mkdb '.$this->server_conf['shadow_datei'].' &> /dev/null', $this->FILE, __LINE__);
55da90 934             }
B 935             return true;
936           } else {
937             return false;
938           }
939     }
ff6a68 940     */
7fe908 941
55da90 942     /**boot autostart etc
B 943      *
944      */
945     function rc_edit($service, $rl, $action){
946         // $action = "on|off";
7fe908 947         global $app;
MC 948         $dist_init_scripts = $app->system->server_conf['dist_init_scripts'];
949         $dist_runlevel = $app->system->server_conf['dist_runlevel'];
950         $dist = $app->system->server_conf['dist'];
951         if(trim($dist_runlevel) == ''){ // falls es keine runlevel gibt (FreeBSD)
952             if($action == 'on'){
953                 @symlink($dist_init_scripts.'/'.$service, $dist_init_scripts.'/'.$service.'.sh');
954             }
955             if($action == 'off'){
956                 if(is_link($dist_init_scripts.'/'.$service.'.sh')){
957                     unlink($dist_init_scripts.'/'.$service.'.sh');
958                 } else {
959                     rename($dist_init_scripts.'/'.$service.'.sh', $dist_init_scripts.'/'.$service);
960                 }
961             }
962         } else { // Linux
963             if(substr($dist, 0, 4) == 'suse'){
964                 if($action == 'on'){
965                     exec("chkconfig --add $service &> /dev/null");
966                 }
967                 if($action == 'off'){
968                     exec("chkconfig --del $service &> /dev/null");
969                 }
970             } else {
971                 $runlevels = explode(',', $rl);
972                 foreach($runlevels as $runlevel){
973                     $runlevel = trim($runlevel);
974                     if($runlevel != '' && is_dir($dist_runlevel.'/rc'.$runlevel.'.d')){
975                         $handle=opendir($dist_runlevel.'/rc'.$runlevel.'.d');
976                         while($file = readdir($handle)){
977                             if($file != '.' && $file != '..'){
978                                 $target = @readlink($dist_runlevel.'/rc'.$runlevel.'.d/'.$file);
979                                 if(strstr($file, $service) && strstr($target, $service) && substr($file, 0, 1) == 'S') $ln_arr[$runlevel][] = $dist_runlevel.'/rc'.$runlevel.'.d/'.$file;
980                             }
981                         }
982                         closedir($handle);
983                     }
984                     if($action == 'on'){
985                         if(!is_array($ln_arr[$runlevel])) @symlink($dist_init_scripts.'/'.$service, $dist_runlevel.'/rc'.$runlevel.'.d/S99'.$service);
986                     }
987                     if($action == 'off'){
988                         if(is_array($ln_arr[$runlevel])){
989                             foreach($ln_arr[$runlevel] as $link){
990                                 unlink($link);
991                             }
992                         }
993                     }
994                 }
995             }
996         }
55da90 997     }
7fe908 998
MC 999
1000
1001
1002
55da90 1003     /**
B 1004      * Filter information from the commands
1005      *
1006      */
1007     function grep($content, $string, $params = ''){
1008         global $app;
7fe908 1009         // params: i, v, w
MC 1010         $content = $app->file->unix_nl($content);
1011         $lines = explode("\n", $content);
1012         foreach($lines as $line){
1013             if(!strstr($params, 'w')){
1014                 if(strstr($params, 'i')){
1015                     if(strstr($params, 'v')){
1016                         if(!stristr($line, $string)) $find[] = $line;
1017                     } else {
1018                         if(stristr($line, $string)) $find[] = $line;
1019                     }
1020                 } else {
1021                     if(strstr($params, 'v')){
1022                         if(!strstr($line, $string)) $find[] = $line;
1023                     } else {
1024                         if(strstr($line, $string)) $find[] = $line;
1025                     }
1026                 }
1027             } else {
1028                 if(strstr($params, 'i')){
1029                     if(strstr($params, 'v')){
1030                         if(!$app->string->is_word($string, $line, 'i')) $find[] = $line;
1031                     } else {
1032                         if($app->string->is_word($string, $line, 'i')) $find[] = $line;
1033                     }
1034                 } else {
1035                     if(strstr($params, 'v')){
1036                         if(!$app->string->is_word($string, $line)) $find[] = $line;
1037                     } else {
1038                         if($app->string->is_word($string, $line)) $find[] = $line;
1039                     }
1040                 }
1041             }
1042         }
1043         if(is_array($find)){
1044             $ret_val = implode("\n", $find);
1045             if(substr($ret_val, -1) != "\n") $ret_val .= "\n";
1046             $find = NULL;
1047             return $ret_val;
1048         } else {
1049             return false;
1050         }
55da90 1051     }
7fe908 1052
MC 1053
1054
1055
1056
55da90 1057     /**
B 1058      * Strip content from fields
1059      *
1060      */
1061     function cut($content, $field, $delimiter = ':'){
1062         global $app;
7fe908 1063         $content = $app->file->unix_nl($content);
MC 1064         $lines = explode("\n", $content);
1065         foreach($lines as $line){
1066             $elms = explode($delimiter, $line);
1067             $find[] = $elms[($field-1)];
1068         }
1069         if(is_array($find)){
1070             $ret_val = implode("\n", $find);
1071             if(substr($ret_val, -1) != "\n") $ret_val .= "\n";
1072             $find = NULL;
1073             return $ret_val;
1074         } else {
1075             return false;
1076         }
55da90 1077     }
7fe908 1078
MC 1079
1080
1081
1082
55da90 1083     /**
B 1084      * Get the content off a file
1085      *
1086      */
1087     function cat($file){
1088         global $app;
7fe908 1089         return $app->file->rf($file);
55da90 1090     }
7fe908 1091
MC 1092
1093
1094
1095
55da90 1096     /**
B 1097      * Control services to restart etc
1098      *
1099      */
1100     function daemon_init($daemon, $action){
1101         //* $action = start|stop|restart|reload
7fe908 1102         global $app;
MC 1103         $dist = $this->server_conf['dist'];
1104         $dist_init_scripts = $this->server_conf['dist_init_scripts'];
1105         if(!strstr($dist, 'freebsd')){
1106             $app->log->caselog("$dist_init_scripts/$daemon $action &> /dev/null", $this->FILE, __LINE__);
1107         } else {
1108             if(is_file($dist_init_scripts.'/'.$daemon.'.sh') || is_link($dist_init_scripts.'/'.$daemon.'.sh')){
1109                 if($action == 'start' || $action == 'stop'){
1110                     $app->log->caselog($dist_init_scripts.'/'.$daemon.'.sh '.$action.' &> /dev/null', $this->FILE, __LINE__);
1111                 } else {
1112                     $app->log->caselog($dist_init_scripts.'/'.$daemon.'.sh stop &> /dev/null', $this->FILE, __LINE__);
1113                     sleep(3);
1114                     $app->log->caselog($dist_init_scripts.'/'.$daemon.'.sh start &> /dev/null', $this->FILE, __LINE__);
1115                 }
1116             } else {
1117                 if(is_file($dist_init_scripts.'/'.$daemon) || is_link($dist_init_scripts.'/'.$daemon)){
1118                     if($action == 'start' || $action == 'stop'){
1119                         $app->log->caselog($dist_init_scripts.'/'.$daemon.' '.$action.' &> /dev/null', $this->FILE, __LINE__);
1120                     } else {
1121                         $app->log->caselog($dist_init_scripts.'/'.$daemon.' stop &> /dev/null', $this->FILE, __LINE__);
1122                         sleep(3);
1123                         $app->log->caselog($dist_init_scripts.'/'.$daemon.' start &> /dev/null', $this->FILE, __LINE__);
1124                     }
1125                 } else {
1126                     if(is_file('/etc/rc.d/'.$daemon) || is_link('/etc/rc.d/'.$daemon)){
1127                         if($action == 'start' || $action == 'stop'){
1128                             $app->log->caselog('/etc/rc.d/'.$daemon.' '.$action.' &> /dev/null', $this->FILE, __LINE__);
1129                         } else {
1130                             $app->log->caselog('/etc/rc.d/'.$daemon.' stop &> /dev/null', $this->FILE, __LINE__);
1131                             sleep(3);
1132                             $app->log->caselog('/etc/rc.d/'.$daemon.' start &> /dev/null', $this->FILE, __LINE__);
1133                         }
1134                     }
1135                 }
1136             }
1137         }
55da90 1138     }
7fe908 1139
55da90 1140     function netmask($netmask){
7fe908 1141         list($f1, $f2, $f3, $f4) = explode('.', trim($netmask));
MC 1142         $bin = str_pad(decbin($f1), 8, '0', STR_PAD_LEFT).str_pad(decbin($f2), 8, '0', STR_PAD_LEFT).str_pad(decbin($f3), 8, '0', STR_PAD_LEFT).str_pad(decbin($f4), 8, '0', STR_PAD_LEFT);
1143         $parts = explode('0', $bin);
1144         $bin = str_pad($parts[0], 32, '0', STR_PAD_RIGHT);
1145         $bin = wordwrap($bin, 8, '.', 1);
1146         list($f1, $f2, $f3, $f4) = explode('.', trim($bin));
1147         return bindec($f1).'.'.bindec($f2).'.'.bindec($f3).'.'.bindec($f4);
55da90 1148     }
7fe908 1149
55da90 1150     function binary_netmask($netmask){
7fe908 1151         list($f1, $f2, $f3, $f4) = explode('.', trim($netmask));
MC 1152         $bin = str_pad(decbin($f1), 8, '0', STR_PAD_LEFT).str_pad(decbin($f2), 8, '0', STR_PAD_LEFT).str_pad(decbin($f3), 8, '0', STR_PAD_LEFT).str_pad(decbin($f4), 8, '0', STR_PAD_LEFT);
1153         $parts = explode('0', $bin);
1154         return substr_count($parts[0], '1');
55da90 1155     }
7fe908 1156
55da90 1157     function network($ip, $netmask){
7fe908 1158         $netmask = $this->netmask($netmask);
MC 1159         list($f1, $f2, $f3, $f4) = explode('.', $netmask);
1160         $netmask_bin = str_pad(decbin($f1), 8, '0', STR_PAD_LEFT).str_pad(decbin($f2), 8, '0', STR_PAD_LEFT).str_pad(decbin($f3), 8, '0', STR_PAD_LEFT).str_pad(decbin($f4), 8, '0', STR_PAD_LEFT);
1161         list($f1, $f2, $f3, $f4) = explode('.', $ip);
1162         $ip_bin = str_pad(decbin($f1), 8, '0', STR_PAD_LEFT).str_pad(decbin($f2), 8, '0', STR_PAD_LEFT).str_pad(decbin($f3), 8, '0', STR_PAD_LEFT).str_pad(decbin($f4), 8, '0', STR_PAD_LEFT);
1163         for($i=0;$i<32;$i++){
1164             $network_bin .= substr($netmask_bin, $i, 1) * substr($ip_bin, $i, 1);
1165         }
1166         $network_bin = wordwrap($network_bin, 8, '.', 1);
1167         list($f1, $f2, $f3, $f4) = explode('.', trim($network_bin));
1168         return bindec($f1).'.'.bindec($f2).'.'.bindec($f3).'.'.bindec($f4);
55da90 1169     }
7fe908 1170
MC 1171
1172
1173
1174
55da90 1175     /**
B 1176      * Make a broadcast address from an IP number in combination with netmask
1177      *
1178      */
1179     function broadcast($ip, $netmask){
1180         $netmask = $this->netmask($netmask);
7fe908 1181         $binary_netmask = $this->binary_netmask($netmask);
MC 1182         list($f1, $f2, $f3, $f4) = explode('.', $ip);
1183         $ip_bin = str_pad(decbin($f1), 8, '0', STR_PAD_LEFT).str_pad(decbin($f2), 8, '0', STR_PAD_LEFT).str_pad(decbin($f3), 8, '0', STR_PAD_LEFT).str_pad(decbin($f4), 8, '0', STR_PAD_LEFT);
1184         $broadcast_bin = str_pad(substr($ip_bin, 0, $binary_netmask), 32, '1', STR_PAD_RIGHT);
1185         $broadcast_bin = wordwrap($broadcast_bin, 8, '.', 1);
1186         list($f1, $f2, $f3, $f4) = explode('.', trim($broadcast_bin));
1187         return bindec($f1).'.'.bindec($f2).'.'.bindec($f3).'.'.bindec($f4);
55da90 1188     }
7fe908 1189
MC 1190
1191
1192
1193
55da90 1194     /**
B 1195      * Get the network address information
1196      *
1197      */
1198     function network_info(){
458767 1199         $dist = $this->server_conf['dist'];
7fe908 1200         ob_start();
MC 1201         passthru('ifconfig');
1202         $output = ob_get_contents();
1203         ob_end_clean();
1204         $lines = explode("\n", $output);
1205         foreach($lines as $line){
1206             $elms = explode(' ', $line);
1207             if(trim($elms[0]) != '' && substr($elms[0], 0, 1) != "\t"){
1208                 $elms[0] = trim($elms[0]);
1209                 if(strstr($dist, 'freebsd')) $elms[0] = substr($elms[0], 0, -1);
1210                 $interfaces[] = $elms[0];
1211             }
1212         }
1213         if(!empty($interfaces)){
1214             foreach($interfaces as $interface){
1215                 ob_start();
1216                 if(!strstr($dist, 'freebsd')){
1217                     passthru('ifconfig '.$interface." | grep -iw 'inet' | cut -f2 -d: | cut -f1 -d' '");
1218                 } else {
1219                     passthru('ifconfig '.$interface." | grep -iw 'inet' | grep -iv 'inet6' | cut -f2 -d' '");
1220                 }
1221                 $output = trim(ob_get_contents());
1222                 ob_end_clean();
1223                 if($output != ''){
1224                     $ifconfig['INTERFACE'][$interface] = $output;
1225                     $ifconfig['IP'][$output] = $interface;
1226                 }
1227             }
1228             if(!empty($ifconfig)){
1229                 return $ifconfig;
1230             } else {
1231                 return false;
1232             }
1233         } else {
1234             return false;
1235         }
55da90 1236     }
7fe908 1237
MC 1238
1239
1240
1241
55da90 1242     /**
B 1243      * Configure the network settings from the system
1244      *
1245      */
1246     function network_config(){
1247         $ifconfig = $this->network_info();
7fe908 1248         if($ifconfig){
MC 1249             $main_interface = $ifconfig['IP'][$this->server_conf['server_ip']];
1250             if(strstr($main_interface, ':')){
1251                 $parts = explode(':', $main_interface);
1252                 $main_interface = trim($parts[0]);
1253             }
1254             if($main_interface != ''){
1255                 $ips = $this->data['isp_server_ip'];
1256                 if(!empty($ips)){
1257                     foreach($ips as $ip){
1258                         if(!isset($ifconfig['IP'][$ip['server_ip']])){
1259                             $to_set[] = $ip['server_ip'];
1260                         } else {
1261                             unset($ifconfig['IP'][$ip['server_ip']]);
1262                         }
1263                     }
1264                     if(!empty($ifconfig['IP'])){
1265                         foreach($ifconfig['IP'] as $key => $val){
1266                             if(!strstr($val, 'lo') && !strstr($val, 'lp') && strstr($val, $main_interface)){
1267                                 exec('ifconfig '.$val.' down &> /dev/null');
1268                                 unset($ifconfig['INTERFACE'][$val]);
1269                             }
1270                         }
1271                     }
1272                     if(!empty($to_set)){
1273                         foreach($to_set as $to){
1274                             $i = 0;
1275                             while($i >= 0){
1276                                 if(isset($ifconfig['INTERFACE'][$main_interface.':'.$i])){
1277                                     $i++;
1278                                 } else {
1279                                     $new_interface = $main_interface.':'.$i;
1280                                     $i = -1;
1281                                 }
1282                             }
1283                             exec('ifconfig '.$new_interface.' '.$to.' netmask '.$this->server_conf['server_netzmaske'].' up &> /dev/null');
1284                             $ifconfig['INTERFACE'][$new_interface] = $to;
1285                         }
1286                     }
1287                 }
1288             }
1289         }
55da90 1290     }
7fe908 1291
55da90 1292     function quota_dirs(){
7fe908 1293         global $app;
MC 1294         $content = $app->file->unix_nl($app->file->no_comments('/etc/fstab'));
1295         $lines = explode("\n", $content);
1296         foreach($lines as $line){
1297             $line = trim($line);
1298             if($line != ''){
1299                 $elms = explode("\t", $line);
1300                 foreach($elms as $elm){
1301                     if(trim($elm) != '') $f[] = $elm;
1302                 }
1303                 if(!empty($f) && stristr($f[3], 'userquota') && stristr($f[3], 'groupquota')){
1304                     $q_dirs[] = trim($f[1]);
1305                 }
1306                 unset($f);
1307             }
1308         }
1309         if(!empty($q_dirs)){
1310             return $q_dirs;
1311         } else {
1312             return false;
1313         }
55da90 1314     }
7fe908 1315
MC 1316
1317
1318
1319
55da90 1320     /**
B 1321      * Scan the trash for virusses infection
1322      *
1323      */
1324     function make_trashscan(){
1325         global $app;
7fe908 1326         //trashscan erstellen
MC 1327         // Template Ã–ffnen
1328         $app->tpl->clear_all();
1329         $app->tpl->define( array(table    => 'trashscan.master'));
1330
1331         if(!isset($this->server_conf['virusadmin']) || trim($this->server_conf['virusadmin']) == '') $this->server_conf['virusadmin'] = 'admispconfig@localhost';
1332         if(substr($this->server_conf['virusadmin'], 0, 1) == '#'){
1333             $notify = 'no';
1334         } else {
1335             $notify = 'yes';
1336         }
1337
1338         // Variablen zuweisen
1339         $app->tpl->assign( array(VIRUSADMIN => $this->server_conf['virusadmin'],
1340                 NOTIFICATION => $notify));
1341
1342         $app->tpl->parse(TABLE, table);
1343
1344         $trashscan_text = $app->tpl->fetch();
1345
1346         $datei = '/home/admispconfig/ispconfig/tools/clamav/bin/trashscan';
1347         $app->file->wf($datei, $trashscan_text);
1348
1349         chmod($datei, 0755);
1350         chown($datei, 'admispconfig');
1351         chgrp($datei, 'admispconfig');
55da90 1352     }
7fe908 1353
MC 1354
1355
1356
1357
55da90 1358     /**
B 1359      * Get the current time
1360      *
1361      */
1362     function get_time(){
7fe908 1363         $addr = 'http://www.ispconfig.org/';
MC 1364         $timeout = 1;
1365         $url_parts = parse_url($addr);
1366         $path = $url_parts['path'];
1367         $port = 80;
1368         $urlHandle = @fsockopen($url_parts['host'], $port, $errno, $errstr, $timeout);
1369         if ($urlHandle){
1370             socket_set_timeout($urlHandle, $timeout);
1371
1372             $urlString = 'GET '.$path." HTTP/1.0\r\nHost: ".$url_parts['host']."\r\nConnection: Keep-Alive\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n";
1373             if ($user) $urlString .= 'Authorization: Basic '.base64_encode($user.':'.$pass)."\r\n";
1374             $urlString .= "\r\n";
1375             fputs($urlHandle, $urlString);
1376
1377             $month['Jan'] = '01';
1378             $month['Feb'] = '02';
1379             $month['Mar'] = '03';
1380             $month['Apr'] = '04';
1381             $month['May'] = '05';
1382             $month['Jun'] = '06';
1383             $month['Jul'] = '07';
1384             $month['Aug'] = '08';
1385             $month['Sep'] = '09';
1386             $month['Oct'] = '10';
1387             $month['Nov'] = '11';
1388             $month['Dec'] = '12';
1389             $c = 0;
1390             $l = 0;
1391             $startzeit = time();
1392             while(!feof($urlHandle) && $c < 2 && $l == 0){
1393                 $line = trim(fgets($urlHandle, 128));
1394                 $response .= $line;
1395                 $c = time() - $startzeit;
1396                 if($line == '' || substr($line, 0, 5) == 'Date:') $l += 1; // nur den Header auslesen
1397                 if(substr($line, 0, 5) == 'Date:'){
1398                     $parts = explode(' ', $line);
1399                     $tag = $parts[2];
1400                     $monat = $month[$parts[3]];
1401                     $jahr = $parts[4];
1402                     list($stunde, $minute, $sekunde) = explode(':', $parts[5]);
1403                     $timestamp = mktime($stunde, $minute, $sekunde, $monat, $tag, $jahr);
1404                 }
1405             }
1406
1407             @fclose($urlHandle);
1408
1409             return $timestamp;
1410         } else {
1411             @fclose($urlHandle);
1412             return false;
1413         }
55da90 1414     }
7fe908 1415
MC 1416     function replaceLine($filename, $search_pattern, $new_line, $strict = 0, $append = 1) {
c77103 1417         global $app;
c3ac0a 1418         if($this->checkpath($filename) == false) {
7fe908 1419             $app->log("Action aborted, file is a symlink: $filename", LOGLEVEL_WARN);
c3ac0a 1420             return false;
T 1421         }
fdb514 1422         $lines = @file($filename);
T 1423         $out = '';
1424         $found = 0;
1425         if(is_array($lines)) {
1426             foreach($lines as $line) {
1427                 if($strict == 0) {
7fe908 1428                     if(stristr($line, $search_pattern)) {
fdb514 1429                         $out .= $new_line."\n";
T 1430                         $found = 1;
1431                     } else {
1432                         $out .= $line;
1433                     }
1434                 } else {
1435                     if(trim($line) == $search_pattern) {
1436                         $out .= $new_line."\n";
1437                         $found = 1;
1438                     } else {
1439                         $out .= $line;
1440                     }
1441                 }
1442             }
1443         }
7fe908 1444
fdb514 1445         if($found == 0) {
T 1446             //* add \n if the last line does not end with \n or \r
7fe908 1447             if(substr($out, -1) != "\n" && substr($out, -1) != "\r" && filesize($filename) > 0) $out .= "\n";
fdb514 1448             //* add the new line at the end of the file
9f56bd 1449             if($append == 1) {
T 1450                 $out .= $new_line."\n";
1451             }
fdb514 1452         }
7fe908 1453         file_put_contents($filename, $out);
fdb514 1454     }
7fe908 1455
MC 1456     function removeLine($filename, $search_pattern, $strict = 0) {
1457         global $app;
1458         if($this->checkpath($filename) == false) {
1459             $app->log("Action aborted, file is a symlink: $filename", LOGLEVEL_WARN);
1460             return false;
1461         }
1462         if($lines = @file($filename)) {
1463             $out = '';
1464             foreach($lines as $line) {
1465                 if($strict == 0) {
1466                     if(!stristr($line, $search_pattern)) {
1467                         $out .= $line;
1468                     }
1469                 } else {
1470                     if(!trim($line) == $search_pattern) {
1471                         $out .= $line;
1472                     }
fdb514 1473                 }
T 1474             }
7fe908 1475             file_put_contents($filename, $out);
fdb514 1476         }
T 1477     }
7fe908 1478
fdb514 1479     function maildirmake($maildir_path, $user = '', $subfolder = '') {
7fe908 1480
128d3b 1481         global $app, $conf;
TB 1482         
1483         // load the server configuration options
1484         $app->uses("getconf");
1485         $mail_config = $app->getconf->get_server_config($conf["server_id"], 'mail');
7fe908 1486
fdb514 1487         if($subfolder != '') {
d2212d 1488             $dir = escapeshellcmd($maildir_path.'/.'.$subfolder);
fdb514 1489         } else {
d2212d 1490             $dir = escapeshellcmd($maildir_path);
2ebadd 1491         }
7fe908 1492
fb3a98 1493         if(!is_dir($dir)) mkdir($dir, 0700, true);
2ebadd 1494
J 1495         if($user != '' && $user != 'root' && $this->is_user($user)) {
d2212d 1496             $user = escapeshellcmd($user);
2ebadd 1497             // I assume that the name of the (vmail group) is the same as the name of the mail user in ISPConfig 3
J 1498             $group = $user;
7fe908 1499             if(is_dir($dir)) $this->chown($dir, $user);
MC 1500             if(is_dir($dir)) $this->chgrp($dir, $group);
2ebadd 1501
J 1502             $chown_mdsub = true;
fdb514 1503         }
7fe908 1504
MC 1505         $maildirsubs = array('cur', 'new', 'tmp');
2ebadd 1506
J 1507         foreach ($maildirsubs as $mdsub) {
9f56bd 1508             if(!is_dir($dir.'/'.$mdsub)) mkdir($dir.'/'.$mdsub, 0700, true);
2ebadd 1509             if ($chown_mdsub) {
J 1510                 chown($dir.'/'.$mdsub, $user);
1511                 chgrp($dir.'/'.$mdsub, $group);
1512             }
1513         }
1514
1515         chmod($dir, 0700);
7fe908 1516
d2212d 1517         /*
fdb514 1518         if($user != '' && $this->is_user($user) && $user != 'root') {
d2212d 1519             $user = escapeshellcmd($user);
3b4c28 1520             // I assume that the name of the (vmail group) is the same as the name of the mail user in ISPConfig 3
a59ad3 1521             $group = $user;
T 1522             exec("chown $user:$group $dir $dir_cur $dir_new $dir_tmp");
fdb514 1523         }
d2212d 1524         */
7fe908 1525
fdb514 1526         //* Add the subfolder to the subscriptions and courierimapsubscribed files
T 1527         if($subfolder != '') {
128d3b 1528             
fdb514 1529             // Courier
128d3b 1530             if($mail_config['pop3_imap_daemon'] == 'courier') {
TB 1531                 if(!is_file($maildir_path.'/courierimapsubscribed')) {
1532                     $tmp_file = escapeshellcmd($maildir_path.'/courierimapsubscribed');
1533                     touch($tmp_file);
1534                     chmod($tmp_file, 0744);
1535                     chown($tmp_file, 'vmail');
1536                     chgrp($tmp_file, 'vmail');
1537                 }
1538                 $this->replaceLine($maildir_path.'/courierimapsubscribed', 'INBOX.'.$subfolder, 'INBOX.'.$subfolder, 1, 1);
fdb514 1539             }
7fe908 1540
fdb514 1541             // Dovecot
128d3b 1542             if($mail_config['pop3_imap_daemon'] == 'dovecot') {
TB 1543                 if(!is_file($maildir_path.'/subscriptions')) {
1544                     $tmp_file = escapeshellcmd($maildir_path.'/subscriptions');
1545                     touch($tmp_file);
1546                     chmod($tmp_file, 0744);
1547                     chown($tmp_file, 'vmail');
1548                     chgrp($tmp_file, 'vmail');
1549                 }
1550                 $this->replaceLine($maildir_path.'/subscriptions', $subfolder, $subfolder, 1, 1);
fdb514 1551             }
T 1552         }
7fe908 1553
MC 1554         $app->log('Created Maildir '.$maildir_path.' with subfolder: '.$subfolder, LOGLEVEL_DEBUG);
1555
fdb514 1556     }
7fe908 1557
355efb 1558     //* Function to create directory paths and chown them to a user and group
T 1559     function mkdirpath($path, $mode = 0755, $user = '', $group = '') {
7fe908 1560         $path_parts = explode('/', $path);
355efb 1561         $new_path = '';
T 1562         if(is_array($path_parts)) {
1563             foreach($path_parts as $part) {
1564                 $new_path .= '/'.$part;
1565                 if(!@is_dir($new_path)) {
c3ac0a 1566                     $this->mkdir($new_path);
7fe908 1567                     $this->chmod($new_path, $mode);
MC 1568                     if($user != '') $this->chown($new_path, $user);
1569                     if($group != '') $this->chgrp($new_path, $group);
355efb 1570                 }
T 1571             }
1572         }
7fe908 1573
355efb 1574     }
7fe908 1575
42f191 1576     //* Check if a application is installed
T 1577     function is_installed($appname) {
7fe908 1578         exec('which '.escapeshellcmd($appname).' 2> /dev/null', $out, $returncode);
MC 1579         if(isset($out[0]) && stristr($out[0], $appname) && $returncode == 0) {
42f191 1580             return true;
T 1581         } else {
1582             return false;
1583         }
1584     }
7fe908 1585
MC 1586     function web_folder_protection($document_root, $protect) {
1587         global $app, $conf;
1588
c3ac0a 1589         if($this->checkpath($document_root) == false) {
7fe908 1590             $app->log("Action aborted, target is a symlink: $document_root", LOGLEVEL_DEBUG);
c3ac0a 1591             return false;
T 1592         }
7fe908 1593
4b9329 1594         //* load the server configuration options
T 1595         $app->uses('getconf');
1596         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
7fe908 1597
4b9329 1598         if($protect == true && $web_config['web_folder_protection'] == 'y') {
T 1599             //* Add protection
7fe908 1600             if($document_root != '' && $document_root != '/' && strlen($document_root) > 6 && !stristr($document_root, '..')) exec('chattr +i '.escapeshellcmd($document_root));
4b9329 1601         } else {
T 1602             //* Remove protection
7fe908 1603             if($document_root != '' && $document_root != '/' && strlen($document_root) > 6 && !stristr($document_root, '..')) exec('chattr -i '.escapeshellcmd($document_root));
4b9329 1604         }
T 1605     }
7fe908 1606
ff6a68 1607     function usermod($username, $uid = 0, $gid = 0, $home = '', $shell = '', $password = '', $login = '') {
T 1608         global $app;
7fe908 1609
ff6a68 1610         if($login == '') $login = $username;
7fe908 1611
ff6a68 1612         //* Change values in /etc/passwd
T 1613         $passwd_file_array = file('/etc/passwd');
1614         if(is_array($passwd_file_array)) {
1615             foreach($passwd_file_array as $line) {
1616                 $line = trim($line);
7fe908 1617                 $parts = explode(':', $line);
ff6a68 1618                 if($parts[0] == $username) {
T 1619                     if(trim($login) != '' && trim($login) != trim($username)) $parts[0] = trim($login);
1620                     if(!empty($uid)) $parts[2] = trim($uid);
1621                     if(!empty($gid)) $parts[3] = trim($gid);
1622                     if(trim($home) != '') $parts[5] = trim($home);
1623                     if(trim($shell) != '') $parts[6] = trim($shell);
7fe908 1624                     $new_line = implode(':', $parts);
MC 1625                     copy('/etc/passwd', '/etc/passwd~');
1626                     chmod('/etc/passwd~', 0600);
ff6a68 1627                     $app->uses('system');
7fe908 1628                     $app->system->replaceLine('/etc/passwd', $line, $new_line, 1, 0);
ff6a68 1629                 }
T 1630             }
1631             unset($passwd_file_array);
1632         }
7fe908 1633
ff6a68 1634         //* If username != login, change username in group and gshadow file
T 1635         if($username  != $login) {
1636             $group_file_array = file('/etc/group');
1637             if(is_array($group_file_array)) {
1638                 foreach($group_file_array as $line) {
1639                     $line = trim($line);
7fe908 1640                     $parts = explode(':', $line);
MC 1641                     if(strstr($parts[3], $username)) {
1642                         $uparts = explode(',', $parts[3]);
ff6a68 1643                         if(is_array($uparts)) {
T 1644                             foreach($uparts as $key => $val) {
1645                                 if($val == $username) $uparts[$key] = $login;
1646                             }
1647                         }
7fe908 1648                         $parts[3] = implode(',', $uparts);
MC 1649                         $new_line = implode(':', $parts);
1650                         copy('/etc/group', '/etc/group~');
1651                         chmod('/etc/group~', 0600);
1652                         $app->system->replaceLine('/etc/group', $line, $new_line, 1, 0);
ff6a68 1653                     }
T 1654                 }
1655             }
1656             unset($group_file_array);
7fe908 1657
ff6a68 1658             $gshadow_file_array = file('/etc/gshadow');
T 1659             if(is_array($gshadow_file_array)) {
1660                 foreach($gshadow_file_array as $line) {
1661                     $line = trim($line);
7fe908 1662                     $parts = explode(':', $line);
MC 1663                     if(strstr($parts[3], $username)) {
1664                         $uparts = explode(',', $parts[3]);
ff6a68 1665                         if(is_array($uparts)) {
T 1666                             foreach($uparts as $key => $val) {
1667                                 if($val == $username) $uparts[$key] = $login;
1668                             }
1669                         }
7fe908 1670                         $parts[3] = implode(',', $uparts);
MC 1671                         $new_line = implode(':', $parts);
1672                         copy('/etc/gshadow', '/etc/gshadow~');
1673                         chmod('/etc/gshadow~', 0600);
1674                         $app->system->replaceLine('/etc/gshadow', $line, $new_line, 1, 0);
ff6a68 1675                     }
T 1676                 }
1677             }
1678             unset($group_file_array);
1679         }
7fe908 1680
MC 1681
ff6a68 1682         //* When password or login name has been changed
T 1683         if($password != '' || $username  != $login) {
1684             $shadow_file_array = file('/etc/shadow');
1685             if(is_array($shadow_file_array)) {
1686                 foreach($shadow_file_array as $line) {
1687                     $line = trim($line);
7fe908 1688                     $parts = explode(':', $line);
ff6a68 1689                     if($parts[0] == $username) {
T 1690                         if(trim($login) != '' && trim($login) != trim($username)) $parts[0] = trim($login);
1691                         if(trim($password) != '') $parts[1] = trim($password);
7fe908 1692                         $new_line = implode(':', $parts);
MC 1693                         copy('/etc/shadow', '/etc/shadow~');
1694                         chmod('/etc/shadow~', 0600);
1695                         $app->system->replaceLine('/etc/shadow', $line, $new_line, 1, 0);
ff6a68 1696                     }
T 1697                 }
1698             }
1699             unset($shadow_file_array);
1700         }
1701     }
7fe908 1702
bfcdef 1703     function intval($string, $force_numeric = false) {
7fe908 1704         if(intval($string) == 2147483647) {
MC 1705             if($force_numeric == true) return floatval($string);
1706             elseif(preg_match('/^([-]?)[0]*([1-9][0-9]*)([^0-9].*)*$/', $string, $match)) return $match[1].$match[2];
1707             else return 0;
1708         } else {
1709             return intval($string);
1710         }
1711     }
1712
526b99 1713     function is_mounted($mountpoint){
cc6568 1714         //$cmd = 'df 2>/dev/null | grep " '.$mountpoint.'$"';
H 1715         $cmd = 'mount 2>/dev/null | grep " on '.$mountpoint.' type "';
526b99 1716         exec($cmd, $output, $return_var);
7fe908 1717         return $return_var == 0 ? true : false;
526b99 1718     }
7fe908 1719
33bcd0 1720     function getinitcommand($servicename, $action, $init_script_directory = ''){
FT 1721         global $conf;
1722         // systemd
1723         if(is_executable('/bin/systemd')){
1724             return 'systemctl '.$action.' '.$servicename.'.service';
1725         }
1726         // upstart
1727         if(is_executable('/sbin/initctl')){
1728             exec('/sbin/initctl version 2>/dev/null | /bin/grep -q upstart', $retval['output'], $retval['retval']);
1729             if(intval($retval['retval']) == 0) return 'service '.$servicename.' '.$action;
1730         }
1731         // sysvinit
1732         if($init_script_directory == '') $init_script_directory = $conf['init_scripts'];
1733         if(substr($init_script_directory, -1) === '/') $init_script_directory = substr($init_script_directory, 0, -1);
1734         return $init_script_directory.'/'.$servicename.' '.$action;
1735     }
8133de 1736     
MC 1737     function getapacheversion($get_minor = false) {
1738         global $app;
1739         
1740         $cmd = '';
1741         if($this->is_installed('apache2ctl')) $cmd = 'apache2ctl -v';
1742         elseif($this->is_installed('apachectl')) $cmd = 'apachectl -v';
1743         else {
1744             $app->log("Could not check apache version, apachectl not found.", LOGLEVEL_WARN);
1745             return '2.2';
1746         }
1747         
1748         exec($cmd, $output, $return_var);
1749         if($return_var != 0 || !$output[0]) {
1750             $app->log("Could not check apache version, apachectl did not return any data.", LOGLEVEL_WARN);
1751             return '2.2';
1752         }
1753         
1754         if(preg_match('/version:\s*Apache\/(\d+)(\.(\d+)(\.(\d+))*)?(\D|$)/i', $output[0], $matches)) {
1755             return $matches[1] . (isset($matches[3]) ? '.' . $matches[3] : '') . (isset($matches[5]) && $get_minor == true ? '.' . $matches[5] : '');
1756         } else {
1757             $app->log("Could not check apache version, did not find version string in apachectl output.", LOGLEVEL_WARN);
1758             return '2.2';
1759         }
1760     }
e2d6ed 1761
60b700 1762     function getapachemodules() {
MC 1763         global $app;
1764         
1765         $cmd = '';
1766         if(is_installed('apache2ctl')) $cmd = 'apache2ctl -t -D DUMP_MODULES';
1767         elseif(is_installed('apachectl')) $cmd = 'apachectl -t -D DUMP_MODULES';
1768         else {
1769             $app->log("Could not check apache modules, apachectl not found.", LOGLEVEL_WARN);
1770             return array();
1771         }
1772         
0a0ca4 1773         exec($cmd . ' 2>/dev/null', $output, $return_var);
60b700 1774         if($return_var != 0 || !$output[0]) {
MC 1775             $app->log("Could not check apache modules, apachectl did not return any data.", LOGLEVEL_WARN);
1776             return array();
1777         }
1778         
1779         $modules = array();
1780         for($i = 0; $i < count($output); $i++) {
1781             if(preg_match('/^\s*(\w+)\s+\((shared|static)\)\s*$/', $output[$i], $matches)) {
1782                 $modules[] = $matches[1];
1783             }
1784         }
1785         
1786         return $modules;
1787     }
e2d6ed 1788 }
7fe908 1789
3b4c28 1790 ?>