]> git.sur5r.net Git - bacula/bacula/blob - gui/baculum/protected/Class/Bconsole.php
baculum: Assign Baculum copyright to Kern Sibbald
[bacula/bacula] / gui / baculum / protected / Class / Bconsole.php
1 <?php
2 /*
3  * Bacula(R) - The Network Backup Solution
4  * Baculum   - Bacula web interface
5  *
6  * Copyright (C) 2013-2016 Kern Sibbald
7  *
8  * The main author of Baculum is Marcin Haba.
9  * The original author of Bacula is Kern Sibbald, with contributions
10  * from many others, a complete list can be found in the file AUTHORS.
11  *
12  * You may use this file and others of this release according to the
13  * license defined in the LICENSE file, which includes the Affero General
14  * Public License, v3.0 ("AGPLv3") and some additional permissions and
15  * terms pursuant to its AGPLv3 Section 7.
16  *
17  * This notice must be preserved when any source code is
18  * conveyed and/or propagated.
19  *
20  * Bacula(R) is a registered trademark of Kern Sibbald.
21  */
22
23 Prado::using('Application.Class.ConfigurationManager');
24 Prado::using('Application.Class.Logging');
25 Prado::using('Application.Class.Errors');
26
27 class Bconsole extends TModule {
28
29         const SUDO = 'sudo';
30
31         const BCONSOLE_COMMAND_PATTERN = "%s%s -c %s %s <<END_OF_DATA\n%s\nquit\nEND_OF_DATA";
32
33         const BCONSOLE_DIRECTORS_PATTERN = "%s%s -c %s -l";
34
35         const BCONSOLE_CFG_USER_KEYWORD = '{user}';
36
37         private $availableCommands = array('version', 'status', 'list', 'messages', 'show', 'mount', 'umount', 'release', 'prune', 'purge', 'update', 'estimate', 'run', '.bvfs_update', '.bvfs_lsdirs', '.bvfs_lsfiles', '.bvfs_versions', '.bvfs_get_jobids', '.bvfs_restore', '.bvfs_clear_cache', 'restore', 'cancel', 'delete', '.jobs', 'label', 'reload', '.fileset', '.storage', '.client', '.pool');
38
39         private $useSudo = false;
40
41         private $bconsoleCmdPath;
42
43         private $bconsoleCfgPath;
44
45         private $bconsoleCfgCustomPath;
46
47         public function init($config) {
48                 if($this->Application->getModule('configuration')->isApplicationConfig() === true) {
49                         $params = ConfigurationManager::getApplicationConfig();
50                         $useSudo = ((integer)$params['bconsole']['use_sudo'] === 1);
51                         $bconsoleCmdPath = $params['bconsole']['bin_path'];
52                         $bconsoleCfgPath = $params['bconsole']['cfg_path'];
53                         $bconsoleCfgCustomPath = array_key_exists('cfg_custom_path', $params['bconsole']) ? $params['bconsole']['cfg_custom_path'] : null;
54                         $this->setEnvironmentParams($bconsoleCmdPath, $bconsoleCfgPath, $bconsoleCfgCustomPath, $useSudo);
55                 }
56         }
57
58         private function setEnvironmentParams($bconsoleCmdPath, $bconsoleCfgPath, $bconsoleCfgCustomPath, $useSudo) {
59                 $this->bconsoleCmdPath = $bconsoleCmdPath;
60                 $this->bconsoleCfgPath = $bconsoleCfgPath;
61                 $this->bconsoleCfgCustomPath = $bconsoleCfgCustomPath;
62                 $this->useSudo = $useSudo;
63         }
64
65         private function isCommandValid($command) {
66                 $command = trim($command);
67                 return in_array($command, $this->availableCommands);
68         }
69
70         private function prepareResult(array $output, $exitcode, $bconsoleCommand) {
71                 array_pop($output); // deleted 'quit' bconsole command
72                 for($i = 0; $i < count($output); $i++) {
73                         if(strstr($output[$i], $bconsoleCommand) == false) {
74                                 unset($output[$i]);
75                         } else {
76                                 break;
77                         }
78                 }
79                 $output = count($output) > 1 ? array_values($output) : array_shift($output);
80                 return (object)array('output' => $output, 'exitcode' => (integer)$exitcode);
81         }
82
83         public function bconsoleCommand($director, array $command, $user = null) {
84                 $baseCommand = count($command) > 0 ? $command[0] : null;
85                 if($this->isCommandValid($baseCommand) === true) {
86                         $result = $this->execCommand($director, $command, $user);
87                 } else {
88                         $result = $this->prepareResult(array(BconsoleError::MSG_ERROR_INVALID_COMMAND, ''), BconsoleError::ERROR_INVALID_COMMAND, ' ');
89                 }
90                 return $result;
91         }
92
93         private function execCommand($director, array $command, $user) {
94                 $cmd = '';
95                 if(!is_null($director) && $this->isValidDirector($director) === false) {
96                         $output = array(BconsoleError::MSG_ERROR_INVALID_DIRECTOR, '');
97                         $exitcode = BconsoleError::ERROR_INVALID_DIRECTOR;
98                         $result = $this->prepareResult($output, $exitcode, ' ');
99                 } else {
100                         $dir = is_null($director) ? '': '-D ' . $director;
101                         $sudo = ($this->useSudo === true) ? self::SUDO . ' ' : '';
102                         $bconsoleCommand = implode(' ', $command);
103                         if(!is_null($this->bconsoleCfgCustomPath) && !is_null($user)) {
104                                 $this->bconsoleCfgPath = str_replace(self::BCONSOLE_CFG_USER_KEYWORD, $user, $this->bconsoleCfgCustomPath);
105                         }
106                         $cmd = sprintf(self::BCONSOLE_COMMAND_PATTERN, $sudo, $this->bconsoleCmdPath, $this->bconsoleCfgPath, $dir, $bconsoleCommand);
107                         exec($cmd, $output, $exitcode);
108                         if($exitcode != 0) {
109                                 $output = array(BconsoleError::MSG_ERROR_BCONSOLE_CONNECTION_PROBLEM, '');
110                                 $exitcode = BconsoleError::ERROR_BCONSOLE_CONNECTION_PROBLEM;
111                                 $result = $this->prepareResult($output, $exitcode, ' ');
112                         } else {
113                                 $result = $this->prepareResult($output, $exitcode, $bconsoleCommand);
114                         }
115                 }
116                 $this->Application->getModule('logging')->log($cmd, $result, Logging::CATEGORY_EXECUTE, __FILE__, __LINE__);
117
118                 return $result;
119         }
120
121         public function getDirectors() {
122                 $sudo = ($this->useSudo === true) ? self::SUDO . ' ' : '';
123                 $cmd = sprintf(self::BCONSOLE_DIRECTORS_PATTERN, $sudo, $this->bconsoleCmdPath, $this->bconsoleCfgPath);
124                 exec($cmd, $output, $exitcode);
125                 if($exitcode != 0) {
126                         $output = array(BconsoleError::MSG_ERROR_BCONSOLE_CONNECTION_PROBLEM, '');
127                         $exitcode = BconsoleError::ERROR_BCONSOLE_CONNECTION_PROBLEM;
128                 }
129                 $result = (object)array('output' => $output, 'exitcode' => $exitcode);
130                 return $result;
131         }
132
133         private function isValidDirector($director) {
134                 $ret = in_array($director, $this->getDirectors()->output);
135                 return $ret;
136         }
137
138         public function testBconsoleCommand(array $command, $bconsoleCmdPath, $bconsoleCfgPath, $useSudo) {
139                 $this->setEnvironmentParams($bconsoleCmdPath, $bconsoleCfgPath, null, $useSudo);
140                 $director = array_shift($this->getDirectors()->output);
141                 $result = $this->bconsoleCommand($director, $command);
142                 return $result;
143         }
144 }
145 ?>