Marius Cramer
2015-08-06 37b29231e47a0c4458dc1c15d98588f16f07e1e2
commit | author | age
5a43e7 1 <?php
T 2
3 /*
4 Copyright (c) 2012, Till Brehm, ISPConfig UG
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 backup_plugin {
b1a6a5 32
5a43e7 33     var $plugin_name = 'backup_plugin';
T 34     var $class_name  = 'backup_plugin';
b1a6a5 35
5a43e7 36     //* This function is called during ispconfig installation to determine
T 37     //  if a symlink shall be created for this plugin.
38     public function onInstall() {
39         global $conf;
b1a6a5 40
5a43e7 41         return true;
b1a6a5 42
5a43e7 43     }
b1a6a5 44
MC 45
5a43e7 46     /*
T 47          This function is called when the plugin is loaded
48     */
b1a6a5 49
5a43e7 50     public function onLoad() {
T 51         global $app;
b1a6a5 52
5a43e7 53         //* Register for actions
b1a6a5 54         $app->plugins->registerAction('backup_download', $this->plugin_name, 'backup_action');
MC 55         $app->plugins->registerAction('backup_restore', $this->plugin_name, 'backup_action');
d2c52b 56         //$app->plugins->registerAction('backup_download_mail', $this->plugin_name, 'backup_action_mail');
D 57         $app->plugins->registerAction('backup_restore_mail', $this->plugin_name, 'backup_action_mail');
b51628 58         
5a43e7 59     }
b1a6a5 60
5a43e7 61     //* Do a backup action
b1a6a5 62     public function backup_action($action_name, $data) {
MC 63         global $app, $conf;
64
5a43e7 65         $backup_id = intval($data);
cc7a82 66         $backup = $app->dbmaster->queryOneRecord("SELECT * FROM web_backup WHERE backup_id = ?", $backup_id);
b1a6a5 67
d2c52b 68         if(is_array($backup)) {
b1a6a5 69
056465 70             $app->uses('ini_parser,file,getconf,system');
b1a6a5 71
cc7a82 72             $web = $app->dbmaster->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $backup['parent_domain_id']);
5a43e7 73             $server_config = $app->getconf->get_server_config($conf['server_id'], 'server');
T 74             $backup_dir = $server_config['backup_dir'].'/web'.$web['domain_id'];
056465 75             
FT 76             $backup_dir_is_ready = true;
990ca8 77             //* mount backup directory, if necessary
c41c8f 78             if( $server_config['backup_dir_is_mount'] == 'y' && !$app->system->mount_backup_dir($server_config['backup_dir']) ) $backup_dir_is_ready = false;
bd68aa 79
056465 80             if($backup_dir_is_ready){
FT 81                 //* Make backup available for download
82                 if($action_name == 'backup_download') {
83                     //* Copy the backup file to the backup folder of the website
f75777 84                     if(file_exists($backup_dir.'/'.$backup['filename']) && file_exists($web['document_root'].'/backup/') && !stristr($backup_dir.'/'.$backup['filename'], '..') && !stristr($backup_dir.'/'.$backup['filename'], 'etc')) {
b1a6a5 85                         copy($backup_dir.'/'.$backup['filename'], $web['document_root'].'/backup/'.$backup['filename']);
MC 86                         chgrp($web['document_root'].'/backup/'.$backup['filename'], $web['system_group']);
056465 87                         $app->log('cp '.$backup_dir.'/'.$backup['filename'].' '.$web['document_root'].'/backup/'.$backup['filename'], LOGLEVEL_DEBUG);
5a43e7 88                     }
T 89                 }
ddb461 90
MC 91                 //* Restore a MongoDB backup
92                 if($action_name == 'backup_restore' && $backup['backup_type'] == 'mongodb') {
93                     if(file_exists($backup_dir.'/'.$backup['filename'])) {
94                         //$parts = explode('_',$backup['filename']);
95                         //$db_name = $parts[1];
96                         preg_match('@^db_(.+)_\d{4}-\d{2}-\d{2}_\d{2}-\d{2}\.tar\.gz$@', $backup['filename'], $matches);
97                         $db_name = $matches[1];
98
99                         // extract tar.gz archive
100                         $dump_directory = str_replace(".tar.gz", "", $backup['filename']);
101                         $extracted = "/usr/local/ispconfig/server/temp";
102                         exec("tar -xzvf ".escapeshellarg($backup_dir.'/'.$backup['filename'])." --directory=".escapeshellarg($extracted));
103                         $restore_directory = $extracted."/".$dump_directory."/".$db_name;
104
105                         // mongorestore -h 127.0.0.1 -u root -p 123456 --authenticationDatabase admin -d c1debug --drop ./toRestore
106                         $command = "mongorestore -h 127.0.0.1 --port 27017 -u root -p 123456 --authenticationDatabase admin -d ".$db_name." --drop ".escapeshellarg($restore_directory);
5a43e7 107                         exec($command);
ddb461 108                         exec("rm -rf ".escapeshellarg($extracted."/".$dump_directory));
MC 109                     }
110
111                     unset($clientdb_host);
112                     unset($clientdb_user);
113                     unset($clientdb_password);
114                     $app->log('Restored MongoDB backup '.$backup_dir.'/'.$backup['filename'], LOGLEVEL_DEBUG);
5a43e7 115                 }
056465 116
FT 117                 //* Restore a mysql backup
118                 if($action_name == 'backup_restore' && $backup['backup_type'] == 'mysql') {
119                     //* Load sql dump into db
120                     include 'lib/mysql_clientdb.conf';
121
122                     if(file_exists($backup_dir.'/'.$backup['filename'])) {
123                         //$parts = explode('_',$backup['filename']);
124                         //$db_name = $parts[1];
125                         preg_match('@^db_(.+)_\d{4}-\d{2}-\d{2}_\d{2}-\d{2}\.sql\.gz$@', $backup['filename'], $matches);
126                         $db_name = $matches[1];
127                         $command = "gunzip --stdout ".escapeshellarg($backup_dir.'/'.$backup['filename'])." | mysql -h '".escapeshellcmd($clientdb_host)."' -u '".escapeshellcmd($clientdb_user)."' -p'".escapeshellcmd($clientdb_password)."' '".$db_name."'";
5a43e7 128                         exec($command);
056465 129                     }
FT 130                     unset($clientdb_host);
131                     unset($clientdb_user);
132                     unset($clientdb_password);
133                     $app->log('Restored MySQL backup '.$backup_dir.'/'.$backup['filename'], LOGLEVEL_DEBUG);
134                 }
135
136                 //* Restore a web backup
137                 if($action_name == 'backup_restore' && $backup['backup_type'] == 'web') {
138                     if($backup['backup_mode'] == 'userzip') {
139                         if(file_exists($backup_dir.'/'.$backup['filename']) && $web['document_root'] != '' && $web['document_root'] != '/' && !stristr($backup_dir.'/'.$backup['filename'], '..') && !stristr($backup_dir.'/'.$backup['filename'], 'etc')) {
140                             if(file_exists($web['document_root'].'/backup/'.$backup['filename'])) rename($web['document_root'].'/backup/'.$backup['filename'], $web['document_root'].'/backup/'.$backup['filename'].'.bak');
141                             copy($backup_dir.'/'.$backup['filename'], $web['document_root'].'/backup/'.$backup['filename']);
142                             chgrp($web['document_root'].'/backup/'.$backup['filename'], $web['system_group']);
143                             //chown($web['document_root'].'/backup/'.$backup['filename'],$web['system_user']);
144                             $command = 'sudo -u '.escapeshellarg($web['system_user']).' unzip -qq -o  '.escapeshellarg($web['document_root'].'/backup/'.$backup['filename']).' -d '.escapeshellarg($web['document_root']).' 2> /dev/null';
145                             exec($command);
146                             unlink($web['document_root'].'/backup/'.$backup['filename']);
147                             if(file_exists($web['document_root'].'/backup/'.$backup['filename'].'.bak')) rename($web['document_root'].'/backup/'.$backup['filename'].'.bak', $web['document_root'].'/backup/'.$backup['filename']);
148                             $app->log('Restored Web backup '.$backup_dir.'/'.$backup['filename'], LOGLEVEL_DEBUG);
149                         }
150                     }
151                     if($backup['backup_mode'] == 'rootgz') {
152                         if(file_exists($backup_dir.'/'.$backup['filename']) && $web['document_root'] != '' && $web['document_root'] != '/' && !stristr($backup_dir.'/'.$backup['filename'], '..') && !stristr($backup_dir.'/'.$backup['filename'], 'etc')) {
153                             $command = 'tar xzf '.escapeshellarg($backup_dir.'/'.$backup['filename']).' --directory '.escapeshellarg($web['document_root']);
154                             exec($command);
155                             $app->log('Restored Web backup '.$backup_dir.'/'.$backup['filename'], LOGLEVEL_DEBUG);
156                         }
5a43e7 157                     }
T 158                 }
b73ab0 159                 if( $server_config['backup_dir_is_mount'] == 'y' ) $app->system->umount_backup_dir($backup_dir);
056465 160             } else {
FT 161                 $app->log('Backup directory not ready.', LOGLEVEL_DEBUG);
5a43e7 162             }
d2c52b 163         } else {
D 164             $app->log('No backup with ID '.$backup_id.' found.', LOGLEVEL_DEBUG);
165         }
b1a6a5 166
d2c52b 167         return 'ok';
D 168     }
169
170     //* Restore a mail backup - florian@schaal-24.de
171     public function backup_action_mail($action_name, $data) {
172         global $app, $conf;
173     
174         $backup_id = intval($data);
cc7a82 175         $mail_backup = $app->dbmaster->queryOneRecord("SELECT * FROM mail_backup WHERE backup_id = ?", $backup_id);
d2c52b 176     
D 177         if (is_array($mail_backup) && $action_name == 'backup_restore_mail') {
178             $app->uses('ini_parser,file,getconf');
179     
f17718 180             $server_config = $app->getconf->get_server_config($conf['server_id'], 'server');
caee7b 181             $backup_dir = $server_config['backup_dir'];
f8fda4 182             $backup_dir_is_ready = true;
d2c52b 183     
990ca8 184             //* mount backup directory, if necessary
f8fda4 185             if( $server_config['backup_dir_is_mount'] == 'y' && !$app->system->mount_backup_dir($backup_dir) ) $backup_dir_is_ready = false;
d2c52b 186     
f8fda4 187             if($backup_dir_is_ready){
caee7b 188                 $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail');
cc7a82 189                 $domain_rec = $app->db->queryOneRecord("SELECT * FROM mail_domain WHERE domain_id = ?", $mail_backup['parent_domain_id']);
d2c52b 190             
caee7b 191                 $backup_dir = $server_config['backup_dir'].'/mail'.$domain_rec['domain_id'];
F 192                 $mail_backup_file = $backup_dir.'/'.$mail_backup['filename'];
d2c52b 193             
cc7a82 194                 $sql = "SELECT * FROM mail_user WHERE server_id = ? AND mailuser_id = ?";
MC 195                 $record = $app->db->queryOneRecord($sql, $conf['server_id'], $mail_backup['mailuser_id']);
d2c52b 196             
caee7b 197                 //* strip mailbox from maildir
F 198                 $domain_dir=explode('/',$record['maildir']);
199                 $_temp=array_pop($domain_dir);unset($_temp);
200                 $domain_dir=implode('/',$domain_dir);
d2c52b 201             
caee7b 202                 if(!is_dir($domain_dir)) {
F 203                     mkdir($domain_dir, 0700); //* never create the full path
204                     chown($domain_dir, $mail_config['mailuser_name']);
205                     chgrp($domain_dir, $mail_config['mailuser_group']);
206                 }
f339eb 207                 if (!is_dir($record['maildir'])) {
D 208                     mkdir($record['maildir'], 0700); //* never create the full path
209                     chown($record['maildir'], $mail_config['mailuser_name']);
210                     chgrp($record['maildir'], $mail_config['mailuser_group']);
211                 }
d2c52b 212             
f339eb 213                 if(file_exists($mail_backup_file) && $record['homedir'] != '' && $record['homedir'] != '/' && !stristr($mail_backup_file,'..') && !stristr($mail_backup_file,'etc') && $mail_config['homedir_path'] == $record['homedir'] && is_dir($domain_dir) && is_dir($record['maildir'])) {
D 214                     if ($record['maildir_format'] == 'mdbox') {
215                         $retval = -1;
216                         // First unzip backupfile to local backup-folder
217                         if($mail_backup['backup_mode'] == 'userzip') {
218                             copy($mail_backup_file, $record['maildir'].'/'.$mail_backup['filename']);
219                             chgrp($record['maildir'].'/'.$mail_backup['filename'], $mail_config['mailuser_group']);
220                             $command = 'sudo -u '.$mail_config['mailuser_name'].' unzip -qq -o  '.escapeshellarg($record['maildir'].'/'.$mail_backup['filename']).' -d '.escapeshellarg($record['maildir']).' 2> /dev/null';
221                             exec($command,$tmp_output, $retval);
222                             unlink($record['maildir'].'/'.$mail_backup['filename']);
223                         }
224                         if($mail_backup['backup_mode'] == 'rootgz') {
225                             $command='tar xfz '.escapeshellarg($mail_backup_file).' --directory '.escapeshellarg($record['maildir']);
226                             exec($command,$tmp_output, $retval);
227                         }
228                         
229                         if($retval == 0) {
230                             // Now import backup-mailbox into special backup-folder
231                             $backupname = "backup-".date("Y-m-d", $mail_backup['tstamp']);
232                             exec("doveadm mailbox create -u \"".$record["email"]."\" $backupname");
233                             exec("doveadm import -u \"".$record["email"]."\" mdbox:".$record['maildir']."/backup $backupname all", $tmp_output, $retval);
234                             exec("for f in `doveadm mailbox list -u \"".$record["email"]."\" $backupname*`; do doveadm mailbox subscribe -u \"".$record["email"]."\" \$f; done", $tmp_output, $retval);
235                             exec('rm -rf '.$record['maildir'].'/backup');
236                         }
237                         
caee7b 238                         if($retval == 0){
F 239                             $app->log('Restored Mail backup '.$mail_backup_file,LOGLEVEL_DEBUG);
240                         } else {
f339eb 241                             // cleanup
D 242                             if (file_exists($record['maildir'].'/'.$mail_backup['filename'])) unlink($record['maildir'].'/'.$mail_backup['filename']);
243                             if (file_exists($record['maildir']."/backup")) exec('rm -rf '.$record['maildir']."/backup");
244                             
caee7b 245                             $app->log('Unable to restore Mail backup '.$mail_backup_file.' '.$tmp_output,LOGLEVEL_ERROR);
F 246                         }
247                     }
f339eb 248                     else {
D 249                         if($mail_backup['backup_mode'] == 'userzip') {
250                             copy($mail_backup_file, $domain_dir.'/'.$mail_backup['filename']);
251                             chgrp($domain_dir.'/'.$mail_backup['filename'], $mail_config['mailuser_group']);
252                             $command = 'sudo -u '.$mail_config['mailuser_name'].' unzip -qq -o  '.escapeshellarg($domain_dir.'/'.$mail_backup['filename']).' -d '.escapeshellarg($domain_dir).' 2> /dev/null';
253                             exec($command,$tmp_output, $retval);
254                             unlink($domain_dir.'/'.$mail_backup['filename']);
255                             if($retval == 0){
256                                 $app->log('Restored Mail backup '.$mail_backup_file,LOGLEVEL_DEBUG);
257                             } else {
258                                 $app->log('Unable to restore Mail backup '.$mail_backup_file.' '.$tmp_output,LOGLEVEL_ERROR);
259                             }
260                         }
261                         if($mail_backup['backup_mode'] == 'rootgz') {
262                             $command='tar xfz '.escapeshellarg($mail_backup_file).' --directory '.escapeshellarg($domain_dir);
263                             exec($command,$tmp_output, $retval);
264                             if($retval == 0){
265                                 $app->log('Restored Mail backup '.$mail_backup_file,LOGLEVEL_DEBUG);
266                             } else {
267                                 $app->log('Unable to restore Mail backup '.$mail_backup_file.' '.$tmp_output,LOGLEVEL_ERROR);
268                             }
caee7b 269                         }
f17718 270                     }
FS 271                 }
b73ab0 272                 if( $server_config['backup_dir_is_mount'] == 'y' ) $app->system->umount_backup_dir($backup_dir);
f17718 273             } else {
caee7b 274                 $app->log('Backup directory not ready.', LOGLEVEL_DEBUG);
f17718 275             }
5a43e7 276         } else {
caee7b 277             $app->log('No backup with ID '.$backup_id.' found.', LOGLEVEL_DEBUG);
5a43e7 278         }
b1a6a5 279
5a43e7 280         return 'ok';
T 281     }
d2c52b 282             
D 283                 
5a43e7 284 } // end class
T 285
f17718 286 ?>            
FS 287