1<?php
2/*
3** Zabbix
4** Copyright (C) 2001-2021 Zabbix SIA
5**
6** This program is free software; you can redistribute it and/or modify
7** it under the terms of the GNU General Public License as published by
8** the Free Software Foundation; either version 2 of the License, or
9** (at your option) any later version.
10**
11** This program is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14** GNU General Public License for more details.
15**
16** You should have received a copy of the GNU General Public License
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19**/
20
21
22class CConfigFile {
23
24	const CONFIG_NOT_FOUND = 1;
25	const CONFIG_ERROR = 2;
26
27	const CONFIG_FILE_PATH = '/conf/zabbix.conf.php';
28
29	private static $supported_db_types = [
30		ZBX_DB_DB2 => true,
31		ZBX_DB_MYSQL => true,
32		ZBX_DB_ORACLE => true,
33		ZBX_DB_POSTGRESQL => true
34	];
35
36	public $configFile = null;
37	public $config = [];
38	public $error = '';
39
40	private static function exception($error, $code = self::CONFIG_ERROR) {
41		throw new ConfigFileException($error, $code);
42	}
43
44	public function __construct($file = null) {
45		$this->setDefaults();
46
47		if (!is_null($file)) {
48			$this->setFile($file);
49		}
50	}
51
52	public function setFile($file) {
53		$this->configFile = $file;
54	}
55
56	public function load() {
57		if (!file_exists($this->configFile)) {
58			self::exception('Config file does not exist.', self::CONFIG_NOT_FOUND);
59		}
60		if (!is_readable($this->configFile)) {
61			self::exception('Permission denied.');
62		}
63
64		ob_start();
65		include($this->configFile);
66		ob_end_clean();
67
68		if (!isset($DB['TYPE'])) {
69			self::exception('DB type is not set.');
70		}
71
72		if (!array_key_exists($DB['TYPE'], self::$supported_db_types)) {
73			self::exception(
74				'Incorrect value "'.$DB['TYPE'].'" for DB type. Possible values '.
75				implode(', ', array_keys(self::$supported_db_types)).'.'
76			);
77		}
78
79		$php_supported_db = array_keys(CFrontendSetup::getSupportedDatabases());
80
81		if (!in_array($DB['TYPE'], $php_supported_db)) {
82			self::exception('DB type "'.$DB['TYPE'].'" is not supported by current setup.'.
83				($php_supported_db ? ' Possible values '.implode(', ', $php_supported_db).'.' : '')
84			);
85		}
86
87		if (!isset($DB['DATABASE'])) {
88			self::exception('DB database is not set.');
89		}
90
91		$this->setDefaults();
92
93		$this->config['DB']['TYPE'] = $DB['TYPE'];
94		$this->config['DB']['DATABASE'] = $DB['DATABASE'];
95
96		if (isset($DB['SERVER'])) {
97			$this->config['DB']['SERVER'] = $DB['SERVER'];
98		}
99
100		if (isset($DB['PORT'])) {
101			$this->config['DB']['PORT'] = $DB['PORT'];
102		}
103
104		if (isset($DB['USER'])) {
105			$this->config['DB']['USER'] = $DB['USER'];
106		}
107
108		if (isset($DB['PASSWORD'])) {
109			$this->config['DB']['PASSWORD'] = $DB['PASSWORD'];
110		}
111
112		if (isset($DB['SCHEMA'])) {
113			$this->config['DB']['SCHEMA'] = $DB['SCHEMA'];
114		}
115
116		if (isset($ZBX_SERVER)) {
117			$this->config['ZBX_SERVER'] = $ZBX_SERVER;
118		}
119		if (isset($ZBX_SERVER_PORT)) {
120			$this->config['ZBX_SERVER_PORT'] = $ZBX_SERVER_PORT;
121		}
122		if (isset($ZBX_SERVER_NAME)) {
123			$this->config['ZBX_SERVER_NAME'] = $ZBX_SERVER_NAME;
124		}
125
126		$this->makeGlobal();
127
128		return $this->config;
129	}
130
131	public function makeGlobal() {
132		global $DB, $ZBX_SERVER, $ZBX_SERVER_PORT, $ZBX_SERVER_NAME;
133
134		$DB = $this->config['DB'];
135		$ZBX_SERVER = $this->config['ZBX_SERVER'];
136		$ZBX_SERVER_PORT = $this->config['ZBX_SERVER_PORT'];
137		$ZBX_SERVER_NAME = $this->config['ZBX_SERVER_NAME'];
138	}
139
140	public function save() {
141		try {
142			if (is_null($this->configFile)) {
143				self::exception('Cannot save, config file is not set.');
144			}
145
146			$this->check();
147
148			if (file_put_contents($this->configFile, $this->getString())) {
149				if (!chmod($this->configFile, 0600)) {
150					self::exception(_('Unable to change configuration file permissions to 0600.'));
151				}
152			}
153			else {
154				if (file_exists($this->configFile)) {
155					if (file_get_contents($this->configFile) !== $this->getString()) {
156						self::exception(_('Unable to overwrite the existing configuration file.'));
157					}
158				}
159				else {
160					self::exception(_('Unable to create the configuration file.'));
161				}
162			}
163
164			return true;
165		}
166		catch (Exception $e) {
167			$this->error = $e->getMessage();
168			return false;
169		}
170	}
171
172	public function getString() {
173		return
174'<?php
175// Zabbix GUI configuration file.
176global $DB;
177
178$DB[\'TYPE\']     = \''.addcslashes($this->config['DB']['TYPE'], "'\\").'\';
179$DB[\'SERVER\']   = \''.addcslashes($this->config['DB']['SERVER'], "'\\").'\';
180$DB[\'PORT\']     = \''.addcslashes($this->config['DB']['PORT'], "'\\").'\';
181$DB[\'DATABASE\'] = \''.addcslashes($this->config['DB']['DATABASE'], "'\\").'\';
182$DB[\'USER\']     = \''.addcslashes($this->config['DB']['USER'], "'\\").'\';
183$DB[\'PASSWORD\'] = \''.addcslashes($this->config['DB']['PASSWORD'], "'\\").'\';
184
185// Schema name. Used for IBM DB2 and PostgreSQL.
186$DB[\'SCHEMA\'] = \''.addcslashes($this->config['DB']['SCHEMA'], "'\\").'\';
187
188$ZBX_SERVER      = \''.addcslashes($this->config['ZBX_SERVER'], "'\\").'\';
189$ZBX_SERVER_PORT = \''.addcslashes($this->config['ZBX_SERVER_PORT'], "'\\").'\';
190$ZBX_SERVER_NAME = \''.addcslashes($this->config['ZBX_SERVER_NAME'], "'\\").'\';
191
192$IMAGE_FORMAT_DEFAULT = IMAGE_FORMAT_PNG;
193';
194	}
195
196	protected function setDefaults() {
197		$this->config['DB'] = [
198			'TYPE' => null,
199			'SERVER' => 'localhost',
200			'PORT' => '0',
201			'DATABASE' => null,
202			'USER' => '',
203			'PASSWORD' => '',
204			'SCHEMA' => ''
205		];
206		$this->config['ZBX_SERVER'] = 'localhost';
207		$this->config['ZBX_SERVER_PORT'] = '10051';
208		$this->config['ZBX_SERVER_NAME'] = '';
209	}
210
211	protected function check() {
212		if (!isset($this->config['DB']['TYPE'])) {
213			self::exception('DB type is not set.');
214		}
215
216		if (!array_key_exists($this->config['DB']['TYPE'], self::$supported_db_types)) {
217			self::exception(
218				'Incorrect value "'.$this->config['DB']['TYPE'].'" for DB type. Possible values '.
219				implode(', ', array_keys(self::$supported_db_types)).'.'
220			);
221		}
222
223		if (!isset($this->config['DB']['DATABASE'])) {
224			self::exception('DB database is not set.');
225		}
226	}
227}
228